@edgespark/web 0.0.0-beta.8b6c080

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.
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Is the web app running in local-dev mode?
3
+ *
4
+ * Reads a `<meta name="edgespark-local-dev" content="true">` tag that
5
+ * the `edgespark dev` reverse proxy splices into every HTML response.
6
+ * The dev proxy only runs under `edgespark dev`; the meta tag is absent
7
+ * on deployed apps (served through the CF dispatcher, which doesn't
8
+ * inject).
9
+ *
10
+ * Uses a <meta> tag rather than an inline <script> so the signal works
11
+ * under strict CSP — `script-src 'self'` without `'unsafe-inline'`
12
+ * would silently drop a script-based marker. Meta tags carry no
13
+ * script-src constraint.
14
+ *
15
+ * No server round-trip, no build-time macro, no hostname heuristic, no
16
+ * framework assumptions. Survives SDK pre-bundling — the SDK reads the
17
+ * DOM at call time, not a value captured at build time.
18
+ */
19
+ export declare function isLocalDev(): boolean;
20
+ /**
21
+ * Auto-verify email in local dev. The server reads the pending verification
22
+ * token from D1, drives Better Auth's verify-email handler, and returns with
23
+ * the session cookie already set. Single round-trip — no token round-trip on
24
+ * the client.
25
+ */
26
+ export declare function autoVerifyLocalDev(email: string): Promise<boolean>;
27
+ /**
28
+ * Fetch the pending OTP for password reset in local dev.
29
+ * Returns the OTP string or null if not available.
30
+ */
31
+ export declare function fetchOtpLocalDev(email: string): Promise<string | null>;
32
+ /**
33
+ * Fetch the pending OTP for email sign-in in local dev.
34
+ * Returns the OTP string or null if not available.
35
+ */
36
+ export declare function fetchSignInOtpLocalDev(email: string): Promise<string | null>;
@@ -0,0 +1,84 @@
1
+ import { createAuthClient } from 'better-auth/client';
2
+ /**
3
+ * Direct better-auth client instance returned by createAuthClient().
4
+ */
5
+ export type BetterAuthClientInstance = ReturnType<typeof createAuthClient>;
6
+ export type SessionResult = Awaited<ReturnType<BetterAuthClientInstance["getSession"]>>;
7
+ export type AuthSession = NonNullable<SessionResult["data"]>;
8
+ export type AuthUser = AuthSession["user"];
9
+ export type SessionChangeCallback = (session: AuthSession | null) => void;
10
+ export interface AuthEndpointError {
11
+ code?: string;
12
+ message?: string;
13
+ status?: number;
14
+ }
15
+ export interface AuthEndpointResult<TData = unknown> {
16
+ data?: TData | null;
17
+ error?: AuthEndpointError | null;
18
+ }
19
+ /**
20
+ * EdgeSpark keeps the auth API shape aligned with better-auth while adding a
21
+ * small set of session helpers on top.
22
+ *
23
+ * Most upstream auth methods remain available on the familiar better-auth
24
+ * shape. Some upstream methods may still be intentionally unsupported by the
25
+ * current EdgeSpark platform capability set even though they exist on the
26
+ * underlying better-auth client surface. In those cases, the facade throws an
27
+ * `EdgeSparkAuthError` with code `UNSUPPORTED_AUTH_METHOD` instead of deferring
28
+ * to a platform-specific 400/404 response.
29
+ */
30
+ export type EdgeSparkAuth = BetterAuthClientInstance & {
31
+ /**
32
+ * Resolves with the current session, or throws when the browser is not authenticated.
33
+ *
34
+ * Use this for route guards and other flows where nullable session checks add noise.
35
+ *
36
+ * If the session lookup itself fails (offline, 5xx, etc.), this throws an
37
+ * `EdgeSparkAuthError` that preserves the upstream error code/status instead
38
+ * of collapsing the failure into `UNAUTHENTICATED`.
39
+ */
40
+ requireSession(): Promise<AuthSession>;
41
+ /**
42
+ * Subscribes to session changes for the current browser context.
43
+ *
44
+ * The first emission is hydration-safe: it waits for the initial server
45
+ * session lookup to complete before firing, so subscribers never receive a
46
+ * premature `null` while a cookie session is still settling.
47
+ *
48
+ * After hydration, successful session atom updates are forwarded immediately.
49
+ * Successful auth mutations that create or clear a session in the current
50
+ * tab also prompt other tabs to refetch their session state, so logout and
51
+ * same-tab sign-in/sign-up converge quickly across tabs.
52
+ *
53
+ * Transient lookup failures that temporarily clear the atom to `null` are
54
+ * ignored so subscribers do not mistake a backend error for a real sign-out.
55
+ *
56
+ * Returns an unsubscribe function.
57
+ */
58
+ onSessionChange(callback: SessionChangeCallback): () => void;
59
+ /**
60
+ * Signs out and then best-effort synchronizes session state for the current
61
+ * tab and other open tabs.
62
+ *
63
+ * The underlying better-auth result is returned unchanged.
64
+ */
65
+ signOut(...args: Parameters<BetterAuthClientInstance["signOut"]>): ReturnType<BetterAuthClientInstance["signOut"]>;
66
+ /**
67
+ * Currently unsupported by EdgeSpark platform auth.
68
+ *
69
+ * The method remains present to preserve the familiar better-auth API shape,
70
+ * but the facade throws `UNSUPPORTED_AUTH_METHOD` until the platform enables
71
+ * this capability. For browser auth, prefer supported `client.auth` methods
72
+ * or `authUI.mount()` instead of dropping to raw `/api/_es/auth/*` routes.
73
+ */
74
+ changeEmail(...args: Parameters<BetterAuthClientInstance["changeEmail"]>): ReturnType<BetterAuthClientInstance["changeEmail"]>;
75
+ /**
76
+ * Currently unsupported by EdgeSpark platform auth.
77
+ *
78
+ * The method remains present to preserve the familiar better-auth API shape,
79
+ * but the facade throws `UNSUPPORTED_AUTH_METHOD` until the platform enables
80
+ * this capability. Handle account removal through your own app flow until the
81
+ * platform adds first-class support.
82
+ */
83
+ deleteUser(...args: Parameters<BetterAuthClientInstance["deleteUser"]>): ReturnType<BetterAuthClientInstance["deleteUser"]>;
84
+ };
@@ -0,0 +1,105 @@
1
+ import { BetterAuthClientInstance } from '../auth/types';
2
+ import { NormalizedAuthUIConfig } from './config';
3
+ import { AuthUIModuleRuntimeOptions } from './mount';
4
+ import { MountAuthUIOptions, MountedAuthUI } from './types';
5
+ /**
6
+ * Internal managed auth UI implementation.
7
+ *
8
+ * The public API only exposes `authUI.mount(...)`; this class owns the DOM,
9
+ * form flows, and lifecycle.
10
+ *
11
+ * DOM ownership: the instance owns a single root element it appends to the
12
+ * mount container. It never writes to `container.innerHTML`. This keeps
13
+ * tear-down safe when the container is a DOM node a reconciling framework
14
+ * (React/Vue/Solid) reuses across conditional branches — wiping the
15
+ * container would erase sibling content the framework just rendered.
16
+ */
17
+ export declare class ManagedAuthUI implements MountedAuthUI {
18
+ private readonly container;
19
+ private readonly auth;
20
+ private readonly options;
21
+ private readonly loadConfig;
22
+ private readonly runtimeOptions?;
23
+ private readonly fieldIdPrefix;
24
+ private readonly labels;
25
+ private readonly root;
26
+ private readonly state;
27
+ private destroyed;
28
+ private terminalActionInProgress;
29
+ private config;
30
+ private countdownUntil;
31
+ private countdownTimer;
32
+ private pendingFocusSnapshot;
33
+ private focusRestoreTimer;
34
+ private verificationCompletionAction;
35
+ constructor(container: HTMLElement, auth: BetterAuthClientInstance, options: MountAuthUIOptions, loadConfig: () => Promise<NormalizedAuthUIConfig>, runtimeOptions?: AuthUIModuleRuntimeOptions | undefined);
36
+ destroy(): void;
37
+ private initialize;
38
+ private redirectAfterManagedReturnLookupFailure;
39
+ private navigateToRedirect;
40
+ private readMountSession;
41
+ private render;
42
+ private renderLoading;
43
+ private renderDevModeBanner;
44
+ private renderStatus;
45
+ private renderCurrentView;
46
+ private renderSignInView;
47
+ private renderSignUpView;
48
+ private renderVerifyEmailView;
49
+ private renderForgotPasswordView;
50
+ private renderResetPasswordView;
51
+ private renderOAuthProviders;
52
+ private renderInput;
53
+ private bindDOM;
54
+ private switchView;
55
+ private handleSignIn;
56
+ private handleEmailOtpSignIn;
57
+ private sendSignInOtp;
58
+ private resendSignInCode;
59
+ private handleSignUp;
60
+ private handleOAuthSignIn;
61
+ private handleForgotPassword;
62
+ private resendResetCode;
63
+ private handleResetPassword;
64
+ private resendVerificationEmail;
65
+ /**
66
+ * Drive the local-dev auto-verify endpoint and, on success, complete the
67
+ * auth flow. Returns whether auto-verify completed — callers decide what
68
+ * to do on `false` (sign-up falls through to a retry UI; resend throws).
69
+ */
70
+ private tryDevAutoVerify;
71
+ private sendVerificationEmail;
72
+ private completeAuth;
73
+ private retryAuthCompletionDataIfNeeded;
74
+ private syncPublicSessionBestEffort;
75
+ private resolveAuthCompletionData;
76
+ private completePasswordReset;
77
+ private handleExistingSessionOnMount;
78
+ private runAction;
79
+ private maybeHandleVerificationRequired;
80
+ private handleVerificationEmailSent;
81
+ private invokeRedirectModeSuccessHook;
82
+ private handleError;
83
+ private failValidation;
84
+ private getManagedReturnURL;
85
+ private consumeManagedReturnContext;
86
+ private startCountdown;
87
+ private updateCountdownControls;
88
+ private clearCountdown;
89
+ private captureFocusSnapshot;
90
+ private scheduleFocusRestore;
91
+ private clearFocusRestoreTimer;
92
+ private passwordResetEndpoints;
93
+ private emailOtpSignInEndpoints;
94
+ private resolveInitialSignInMethod;
95
+ private setSignInMethod;
96
+ private canUseEmailOtpSignIn;
97
+ private extractRedirectURL;
98
+ private extractUser;
99
+ private canUsePasswordResetEmailOtp;
100
+ private handleSessionlessManagedReturn;
101
+ private isCountdownActive;
102
+ private getCountdownSecondsRemaining;
103
+ private countdownText;
104
+ private escape;
105
+ }
@@ -0,0 +1,64 @@
1
+ export declare const AUTH_UI_THEME: {
2
+ readonly LIGHT: "light";
3
+ readonly DARK: "dark";
4
+ };
5
+ export declare const AUTH_UI_THEME_LIGHT: "light";
6
+ export declare const AUTH_UI_THEME_DARK: "dark";
7
+ export declare const AUTH_UI_THEMES: readonly ["light", "dark"];
8
+ export declare const AUTH_UI_DEFAULT_THEME: "light";
9
+ export type AuthUITheme = (typeof AUTH_UI_THEME)[keyof typeof AUTH_UI_THEME];
10
+ export declare const AUTH_UI_APPEARANCE_VARIABLE: {
11
+ readonly BACKGROUND: "--edgespark-auth-bg";
12
+ readonly BACKGROUND_MUTED: "--edgespark-auth-bg-muted";
13
+ readonly CARD_BACKGROUND: "--edgespark-auth-card-bg";
14
+ readonly BORDER: "--edgespark-auth-border";
15
+ readonly TEXT: "--edgespark-auth-text";
16
+ readonly TEXT_MUTED: "--edgespark-auth-text-muted";
17
+ readonly DIVIDER_BACKGROUND: "--edgespark-auth-divider-bg";
18
+ readonly PRIMARY: "--edgespark-auth-primary";
19
+ readonly PRIMARY_HOVER: "--edgespark-auth-primary-hover";
20
+ readonly PRIMARY_CONTRAST: "--edgespark-auth-primary-contrast";
21
+ readonly ERROR: "--edgespark-auth-error";
22
+ readonly INFO: "--edgespark-auth-info";
23
+ readonly CARD_RADIUS: "--edgespark-auth-radius-card";
24
+ readonly CONTROL_RADIUS: "--edgespark-auth-radius-control";
25
+ readonly SHADOW: "--edgespark-auth-shadow";
26
+ readonly FONT: "--edgespark-auth-font";
27
+ readonly MODAL_BACKDROP: "--edgespark-auth-modal-backdrop";
28
+ readonly MODAL_CARD_BACKGROUND: "--edgespark-auth-modal-card-bg";
29
+ readonly MODAL_SHADOW: "--edgespark-auth-modal-shadow";
30
+ };
31
+ export type AuthUIAppearanceVariableName = (typeof AUTH_UI_APPEARANCE_VARIABLE)[keyof typeof AUTH_UI_APPEARANCE_VARIABLE];
32
+ export declare const AUTH_UI_APPEARANCE_VARIABLE_NAMES: readonly AuthUIAppearanceVariableName[];
33
+ export type AuthUIAppearanceVariables = Partial<Record<AuthUIAppearanceVariableName, string>>;
34
+ export interface AuthUIAppearance {
35
+ /**
36
+ * Built-in visual preset for the managed auth UI root.
37
+ *
38
+ * Defaults to `"light"` when omitted. Variable overrides apply on top of the
39
+ * selected preset instead of replacing the entire theme contract.
40
+ */
41
+ theme?: AuthUITheme;
42
+ /**
43
+ * Optional class applied to the managed auth UI root container.
44
+ *
45
+ * Use this to scope additional app-level CSS around the stable root element.
46
+ */
47
+ className?: string;
48
+ /**
49
+ * Stable CSS custom properties supported by the managed auth UI.
50
+ *
51
+ * This is the supported appearance contract for light-touch theming. When a
52
+ * variable is omitted, the current theme preset keeps its default value.
53
+ */
54
+ variables?: AuthUIAppearanceVariables;
55
+ }
56
+ interface NormalizedAuthUIAppearance {
57
+ theme: AuthUITheme;
58
+ className: string;
59
+ variables: AuthUIAppearanceVariables;
60
+ }
61
+ export declare function isAuthUITheme(value: unknown): value is AuthUITheme;
62
+ export declare function isAuthUIAppearanceVariableName(value: string): value is AuthUIAppearanceVariableName;
63
+ export declare function normalizeAuthUIAppearance(appearance?: AuthUIAppearance): NormalizedAuthUIAppearance;
64
+ export {};
@@ -0,0 +1,54 @@
1
+ export type OAuthProviderId = "google" | "apple" | "microsoft" | "github" | "gitlab" | "discord";
2
+ interface OAuthProviderConfig {
3
+ /**
4
+ * OAuth Client ID resolved server-side. Present only when both the Client
5
+ * ID var and the corresponding secret resolve, so a non-empty value is
6
+ * the "this provider is fully wired browser-side" signal.
7
+ */
8
+ clientId?: string;
9
+ }
10
+ interface OAuthProviderBlock {
11
+ enabled?: boolean;
12
+ config?: OAuthProviderConfig;
13
+ }
14
+ interface ProviderEmailPassword {
15
+ enabled?: boolean;
16
+ config?: {
17
+ minPasswordLength?: number;
18
+ requireEmailVerification?: boolean;
19
+ requirePasswordResetEmailVerification?: boolean;
20
+ };
21
+ }
22
+ interface ProviderEmailOtp {
23
+ enabled?: boolean;
24
+ }
25
+ interface AuthConfigResponse {
26
+ disableSignUp?: boolean;
27
+ providerEmailPassword?: ProviderEmailPassword;
28
+ providerEmailOtp?: ProviderEmailOtp;
29
+ providerGoogle?: OAuthProviderBlock;
30
+ providerApple?: OAuthProviderBlock;
31
+ providerMicrosoft?: OAuthProviderBlock;
32
+ providerGithub?: OAuthProviderBlock;
33
+ providerGitlab?: OAuthProviderBlock;
34
+ providerDiscord?: OAuthProviderBlock;
35
+ }
36
+ export interface NormalizedAuthUIConfig {
37
+ disableSignUp: boolean;
38
+ emailPasswordEnabled: boolean;
39
+ emailOtpSignInEnabled: boolean;
40
+ minPasswordLength: number;
41
+ requireEmailVerification: boolean;
42
+ passwordResetEmailOtpEnabled: boolean;
43
+ oauthProviders: OAuthProviderId[];
44
+ /**
45
+ * Resolved Google OAuth Client ID when Google is enabled and both
46
+ * credentials resolved server-side; `null` otherwise. Signals that
47
+ * Google client-side wiring is ready.
48
+ */
49
+ googleClientId: string | null;
50
+ isLocalDev: boolean;
51
+ }
52
+ export declare function loadNormalizedAuthUIConfig(): Promise<NormalizedAuthUIConfig>;
53
+ export declare function normalizeAuthUIConfig(config: AuthConfigResponse, isLocalDev?: boolean): NormalizedAuthUIConfig;
54
+ export {};
@@ -0,0 +1,2 @@
1
+ import { AuthUILabelOverrides, AuthUILabels } from './types';
2
+ export declare function mergeAuthUILabels(base: AuthUILabels, overrides?: AuthUILabelOverrides): AuthUILabels;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Minimal helpers for driving Google Identity Services (One Tap) from the
3
+ * managed auth UI. Loads the GIS client script on demand and exposes a tiny
4
+ * typed surface around the global `google.accounts.id` namespace.
5
+ *
6
+ * GIS is treated as a UX enhancement: any load failure falls back silently
7
+ * to the regular "Continue with Google" OAuth button.
8
+ */
9
+ interface GsiCredentialResponse {
10
+ credential: string;
11
+ select_by?: string;
12
+ }
13
+ interface GsiInitializeOptions {
14
+ client_id: string;
15
+ callback: (response: GsiCredentialResponse) => void;
16
+ auto_select?: boolean;
17
+ cancel_on_tap_outside?: boolean;
18
+ use_fedcm_for_prompt?: boolean;
19
+ context?: "signin" | "signup" | "use";
20
+ }
21
+ /**
22
+ * Subset of Google's `PromptMomentNotification`. Methods are optional because
23
+ * GIS's FedCM-era roadmap retires some of them, and EdgeSpark does not depend
24
+ * on `@types/google.accounts` for the full type surface.
25
+ */
26
+ interface GsiPromptNotification {
27
+ isNotDisplayed?: () => boolean;
28
+ isSkippedMoment?: () => boolean;
29
+ isDismissedMoment?: () => boolean;
30
+ getDismissedReason?: () => string | undefined;
31
+ }
32
+ interface GsiIdAccounts {
33
+ initialize(options: GsiInitializeOptions): void;
34
+ prompt(notificationCallback?: (notification: GsiPromptNotification) => void): void;
35
+ cancel(): void;
36
+ disableAutoSelect(): void;
37
+ }
38
+ /**
39
+ * Loads `accounts.google.com/gsi/client` once per page and resolves with
40
+ * the `google.accounts.id` namespace. Subsequent calls return the same
41
+ * promise; load failures reject and reset so a caller can retry next mount.
42
+ */
43
+ export declare function loadGoogleIdentityServices(): Promise<GsiIdAccounts>;
44
+ export type GoogleIdentityServices = GsiIdAccounts;
45
+ export type GoogleCredentialResponse = GsiCredentialResponse;
46
+ export type GooglePromptNotification = GsiPromptNotification;
47
+ export {};
@@ -0,0 +1,4 @@
1
+ export { createAuthUIModule } from './mount';
2
+ export { AUTH_UI_APPEARANCE_VARIABLE, AUTH_UI_APPEARANCE_VARIABLE_NAMES, AUTH_UI_THEME, AUTH_UI_DEFAULT_THEME, AUTH_UI_THEME_DARK, AUTH_UI_THEME_LIGHT, AUTH_UI_THEMES, } from './appearance';
3
+ export type { AuthUIAppearance, AuthUIAppearanceVariableName, AuthUIAppearanceVariables, AuthUITheme, } from './appearance';
4
+ export type { AuthenticatedAuthSuccessEvent, AuthSuccessEvent, AuthUILabelOverrides, AuthUILabels, ControlledAuthUIOptions, EdgeSparkAuthUI, MountAuthUIOptions, MountedAuthUI, OneTapPromptHandle, PromptGoogleOneTapOptions, RedirectAuthUIOptions, } from './types';
@@ -0,0 +1,22 @@
1
+ import { BetterAuthClientInstance } from '../auth/types';
2
+ import { EdgeSparkAuthUI } from './types';
3
+ /**
4
+ * Internal runtime config for the auth-UI module factory. Threads cross-cutting
5
+ * auth wiring into `ManagedAuthUI` (modal/redirect flows) and
6
+ * `promptGoogleOneTap` (page-load One Tap prompt).
7
+ */
8
+ export interface AuthUIModuleRuntimeOptions {
9
+ /**
10
+ * Best-effort hook to nudge the public auth session after the managed UI
11
+ * completes a sign-in. Used by `ManagedAuthUI`'s email and OAuth flows.
12
+ */
13
+ syncPublicSession?: () => Promise<void> | void;
14
+ /**
15
+ * The public auth client used by `promptGoogleOneTap` for credential
16
+ * exchange. Routing One Tap through the same client as `signIn`/`signUp`
17
+ * keeps session updates and `onSessionChange` consistent across all
18
+ * sign-in methods.
19
+ */
20
+ publicAuthClient: BetterAuthClientInstance;
21
+ }
22
+ export declare function createAuthUIModule(auth: BetterAuthClientInstance, runtimeOptions: AuthUIModuleRuntimeOptions): EdgeSparkAuthUI;
@@ -0,0 +1,43 @@
1
+ import { BetterAuthClientInstance } from '../auth/types';
2
+ import { EdgeSparkAuthError } from '../errors';
3
+ import { NormalizedAuthUIConfig } from './config';
4
+ import { AuthenticatedAuthSuccessEvent } from './types';
5
+ export interface PromptGoogleOneTapOptions {
6
+ /**
7
+ * Fires when Google One Tap sign-in completes.
8
+ *
9
+ * **Most apps should prefer `client.auth.onSessionChange`** as the single
10
+ * source of truth — it fires for One Tap, modal sign-in, sign-out, and
11
+ * cross-tab session changes. Use `onSuccess` only for flow-local concerns
12
+ * scoped to this specific prompt (e.g., per-flow analytics).
13
+ */
14
+ onSuccess?: (event: AuthenticatedAuthSuccessEvent) => void;
15
+ /**
16
+ * Fires on credential-exchange or post-sign-in errors.
17
+ */
18
+ onError?: (error: EdgeSparkAuthError) => void;
19
+ /**
20
+ * Fires when Google declines to display the prompt — e.g., FedCM cooldown,
21
+ * no eligible accounts, or browser permission denied. Use this to render a
22
+ * fallback "Sign in with Google" button.
23
+ */
24
+ onUnavailable?: () => void;
25
+ }
26
+ export interface OneTapPromptHandle {
27
+ /**
28
+ * Dismiss the prompt and suppress any pending callbacks. Idempotent and
29
+ * safe to call after the prompt has already closed.
30
+ */
31
+ cancel(): void;
32
+ }
33
+ interface PromptRuntime {
34
+ /**
35
+ * The wrapped public auth client. Calls flow through its path-proxy so
36
+ * `oneTap.callback` triggers the same session-atom refresh and
37
+ * `onSessionChange` emit as `signIn`/`signUp`.
38
+ */
39
+ authClient: BetterAuthClientInstance;
40
+ loadConfig: () => Promise<NormalizedAuthUIConfig>;
41
+ }
42
+ export declare function createPromptGoogleOneTap(runtime: PromptRuntime): (options?: PromptGoogleOneTapOptions) => OneTapPromptHandle;
43
+ export {};
@@ -0,0 +1,7 @@
1
+ import { AuthSession, AuthUser, BetterAuthClientInstance } from '../auth/types';
2
+ import { EdgeSparkAuthError } from '../errors';
3
+ export declare function normalizeAuthError(error: unknown, fallbackMessage?: string): EdgeSparkAuthError;
4
+ export declare function readCurrentSession(auth: BetterAuthClientInstance): Promise<{
5
+ user: AuthUser | null;
6
+ session: AuthSession | null;
7
+ }>;
@@ -0,0 +1,187 @@
1
+ import { AuthSession, AuthUser } from '../auth/types';
2
+ import { EdgeSparkAuthError } from '../errors';
3
+ import { RedirectTarget } from '../redirect';
4
+ import { DeepPartial } from '../shared/types';
5
+ import { AuthUIAppearance } from './appearance';
6
+ import { OneTapPromptHandle, PromptGoogleOneTapOptions } from './prompt-google-one-tap';
7
+ export type { OneTapPromptHandle, PromptGoogleOneTapOptions } from './prompt-google-one-tap';
8
+ /** Sign-in or sign-up completed with an authenticated session. */
9
+ export type AuthenticatedAuthSuccessEvent = {
10
+ action: "sign-in";
11
+ user: AuthUser;
12
+ session: AuthSession;
13
+ } | {
14
+ action: "sign-up";
15
+ user: AuthUser;
16
+ session: AuthSession;
17
+ };
18
+ /** Password was reset. No session — the user must sign in again. */
19
+ export interface PasswordResetSuccessEvent {
20
+ action: "password-reset";
21
+ user: null;
22
+ session: null;
23
+ }
24
+ /**
25
+ * Payload emitted by `onSuccess` after a managed auth flow completes.
26
+ *
27
+ * Switch on `event.action` to narrow `user` and `session`:
28
+ * - `"sign-in"` / `"sign-up"` → `user: AuthUser`, `session: AuthSession`
29
+ * - `"password-reset"` → `user: null`, `session: null`
30
+ */
31
+ export type AuthSuccessEvent = AuthenticatedAuthSuccessEvent | PasswordResetSuccessEvent;
32
+ export interface AuthUILabels {
33
+ common: {
34
+ loading: string;
35
+ redirecting: string;
36
+ backToSignIn: string;
37
+ };
38
+ signIn: {
39
+ title: string;
40
+ subtitle: string;
41
+ emailLabel: string;
42
+ emailPlaceholder?: string;
43
+ codePlaceholder?: string;
44
+ sendingCode?: string;
45
+ signingIn?: string;
46
+ passwordLabel: string;
47
+ codeLabel?: string;
48
+ submitButton: string;
49
+ sendCodeButton?: string;
50
+ verifyCodeButton?: string;
51
+ resendCodeButton?: string;
52
+ resendCountdown?: string;
53
+ passwordTab?: string;
54
+ codeTab?: string;
55
+ forgotPassword: string;
56
+ switchToSignUp: string;
57
+ signUpPrompt: string;
58
+ };
59
+ signUp: {
60
+ title: string;
61
+ subtitle: string;
62
+ nameLabel: string;
63
+ emailLabel: string;
64
+ passwordLabel: string;
65
+ confirmPasswordLabel: string;
66
+ submitButton: string;
67
+ switchToSignIn: string;
68
+ signInPrompt: string;
69
+ };
70
+ verifyEmail: {
71
+ title: string;
72
+ subtitle: string;
73
+ sentToLabel: string;
74
+ resendButton: string;
75
+ resendCountdown: string;
76
+ changeEmailButton: string;
77
+ };
78
+ forgotPassword: {
79
+ title: string;
80
+ subtitle: string;
81
+ emailLabel: string;
82
+ submitButton: string;
83
+ };
84
+ resetPassword: {
85
+ title: string;
86
+ subtitle: string;
87
+ codeLabel: string;
88
+ newPasswordLabel: string;
89
+ confirmPasswordLabel: string;
90
+ submitButton: string;
91
+ resendCodeButton: string;
92
+ resendCountdown: string;
93
+ };
94
+ oauth: {
95
+ dividerText: string;
96
+ continueWith: string;
97
+ /** Use {provider} for the provider display name. */
98
+ redirecting?: string;
99
+ };
100
+ errors: {
101
+ invalidEmail: string;
102
+ requiredField: string;
103
+ passwordTooShort: string;
104
+ passwordMismatch: string;
105
+ invalidCode: string;
106
+ generic: string;
107
+ };
108
+ }
109
+ export type AuthUILabelOverrides = DeepPartial<AuthUILabels>;
110
+ interface BaseAuthUIOptions {
111
+ onError?: (error: EdgeSparkAuthError) => void;
112
+ labels?: AuthUILabelOverrides;
113
+ /**
114
+ * Optional, constrained visual customization for the managed auth UI.
115
+ *
116
+ * This is intentionally smaller than the headless auth path. Use
117
+ * `client.auth` when the app needs full UI ownership.
118
+ */
119
+ appearance?: AuthUIAppearance;
120
+ }
121
+ /**
122
+ * Redirect mode — use when the auth UI is a full-page login gate.
123
+ *
124
+ * After successful auth the SDK navigates to `redirectTo` automatically.
125
+ * This is the common case: dedicated `/login` page → redirect to `/dashboard`.
126
+ *
127
+ * `onSuccess` is optional and fires *before* the redirect (useful for analytics).
128
+ */
129
+ export interface RedirectAuthUIOptions extends BaseAuthUIOptions {
130
+ redirectTo: RedirectTarget;
131
+ onSuccess?: (event: AuthSuccessEvent) => void;
132
+ }
133
+ /**
134
+ * Controlled mode — use when the app owns what happens after auth.
135
+ *
136
+ * The SDK will not navigate. Instead, `onSuccess` fires with the auth event
137
+ * and the app decides the next step (close a modal, update state, navigate
138
+ * programmatically via a router, etc.).
139
+ *
140
+ * Use this for: modals, embedded auth widgets, SPA routing, onboarding flows.
141
+ */
142
+ export interface ControlledAuthUIOptions extends BaseAuthUIOptions {
143
+ onSuccess: (event: AuthSuccessEvent) => void;
144
+ redirectTo?: never;
145
+ }
146
+ /**
147
+ * Two post-auth strategies — pick one:
148
+ *
149
+ * - **Redirect mode** (`{ redirectTo }`) — SDK navigates after auth.
150
+ * Best for dedicated login pages.
151
+ *
152
+ * - **Controlled mode** (`{ onSuccess }`) — app handles post-auth behavior.
153
+ * Best for modals, embedded widgets, or SPA routing.
154
+ */
155
+ export type MountAuthUIOptions = RedirectAuthUIOptions | ControlledAuthUIOptions;
156
+ export interface MountedAuthUI {
157
+ /**
158
+ * Removes the mounted UI and clears internal timers/listeners.
159
+ */
160
+ destroy(): void;
161
+ }
162
+ export interface EdgeSparkAuthUI {
163
+ /**
164
+ * Mounts the managed auth UI into a container element.
165
+ *
166
+ * Pass `redirectTo` for the common login-page case, or `onSuccess` when the
167
+ * surrounding app wants to control routing/state after auth completes.
168
+ */
169
+ mount(container: HTMLElement, options: MountAuthUIOptions): MountedAuthUI;
170
+ /**
171
+ * Triggers a Google One Tap prompt. Calling the function is the opt-in —
172
+ * there is no separate server config or option flag.
173
+ *
174
+ * The prompt shows only when Google is fully wired server-side (the
175
+ * project's `auth-config.yaml` enables Google with resolvable credentials).
176
+ * Otherwise the call logs a clear error to the console and returns an
177
+ * inert handle.
178
+ *
179
+ * @example
180
+ * useEffect(() => {
181
+ * if (session) return;
182
+ * const prompt = client.authUI.promptGoogleOneTap();
183
+ * return () => prompt.cancel();
184
+ * }, [session]);
185
+ */
186
+ promptGoogleOneTap(options?: PromptGoogleOneTapOptions): OneTapPromptHandle;
187
+ }
@@ -0,0 +1,2 @@
1
+ export declare function assertBrowserRuntime(): void;
2
+ export declare function getBrowserOrigin(): string;