@hook-sdk/template 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/internal/TemplateConfigContext.tsx","../src/internal/ThemeProvider.tsx","../src/internal/AuthGate.tsx","../src/hooks/useAuth.ts","../src/defaults/LoadingState.tsx","../src/hooks/usePaywallState.ts","../src/internal/SubscriptionGate.tsx","../src/internal/PushPrompt.tsx","../src/defaults/ErrorBoundary.tsx","../src/hooks/useLoginForm.ts","../src/errors.ts","../src/defaults/DefaultLoginScreen.tsx","../src/hooks/useSignupForm.ts","../src/defaults/DefaultSignupScreen.tsx","../src/hooks/useForgotForm.ts","../src/defaults/DefaultForgotScreen.tsx","../src/hooks/useResetForm.ts","../src/defaults/DefaultResetScreen.tsx","../src/defaults/DefaultPaywall.tsx","../src/AppRoot.tsx","../src/defaults/EmptyState.tsx","../src/hooks/useAuthPrimitives.ts","../src/hooks/useSubscription.ts","../src/hooks/usePush.ts","../src/hooks/useToast.ts"],"sourcesContent":["// Entry point\nexport { AppRoot, type AppRootProps } from './AppRoot';\n\n// Defaults\nexport { DefaultLoginScreen, type AuthScreenProps, type AuthScreen } from './defaults/DefaultLoginScreen';\nexport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nexport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nexport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nexport { DefaultPaywall } from './defaults/DefaultPaywall';\nexport { LoadingState } from './defaults/LoadingState';\nexport { EmptyState } from './defaults/EmptyState';\nexport { ErrorBoundary } from './defaults/ErrorBoundary';\n\n// Hooks padrão\nexport { useLoginForm, type UseLoginFormResult } from './hooks/useLoginForm';\nexport { useSignupForm } from './hooks/useSignupForm';\nexport { useForgotForm } from './hooks/useForgotForm';\nexport { useResetForm, type UseResetFormResult } from './hooks/useResetForm';\nexport { usePaywallState, type SubscriptionStatus } from './hooks/usePaywallState';\n\n// Escape hatch\nexport { useAuthPrimitives } from './hooks/useAuthPrimitives';\n\n// Convenience\nexport { useAuth } from './hooks/useAuth';\nexport { useSubscription } from './hooks/useSubscription';\nexport { usePush } from './hooks/usePush';\nexport { useToast, type ToastItem } from './hooks/useToast';\n\n// Types\nexport type { AuthFormError, AuthFormErrorCode } from './errors';\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { AppConfig } from '../../../scripts/schemas/app-config';\n\nconst TemplateConfigContext = createContext<AppConfig | null>(null);\n\nexport function TemplateConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n return (\n <TemplateConfigContext.Provider value={config}>\n {children}\n </TemplateConfigContext.Provider>\n );\n}\n\nexport function useTemplateConfig(): AppConfig {\n const ctx = useContext(TemplateConfigContext);\n if (ctx === null) {\n throw new Error('useTemplateConfig must be used inside <TemplateConfigProvider>');\n }\n return ctx;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const config = useTemplateConfig();\n const style = {\n '--hook-color-primary': config.theme.primary_color,\n ...(config.theme.background_color && {\n '--hook-color-background': config.theme.background_color,\n }),\n } as CSSProperties;\n\n return <div style={style}>{children}</div>;\n}\n","import { useEffect, useState, type ComponentType, type ReactNode } from 'react';\nimport { useAuth } from '../hooks/useAuth';\nimport { LoadingState } from '../defaults/LoadingState';\nimport type { AuthScreenProps, AuthScreen } from '../defaults/DefaultLoginScreen';\n\ninterface Props {\n Login: ComponentType<AuthScreenProps>;\n Signup: ComponentType<AuthScreenProps>;\n Forgot: ComponentType<AuthScreenProps>;\n Reset: ComponentType<AuthScreenProps>;\n children: ReactNode;\n}\n\n/**\n * Detecta `?token=` + `?screen=reset` na URL — link do email de password_reset.\n * Se presente E user não autenticado, força tela Reset antes do Login default.\n *\n * `useResetForm` limpa `?token=&screen=reset` via `history.replaceState` após\n * reset bem-sucedido — evita re-dispatch do Reset no próximo logout (F22\n * follow-up descoberto no smoke).\n *\n * Query é snapshot no mount + re-avalia em popstate (permite link aberto em\n * tab já montada). Não re-avalia em re-render normal; AuthGate remontar seria\n * indicador de reset state mal-limpado.\n */\nfunction detectResetFromUrl(): boolean {\n if (typeof window === 'undefined') return false;\n const params = new URLSearchParams(window.location.search);\n return params.get('token') !== null && params.get('screen') === 'reset';\n}\n\nexport function AuthGate({ Login, Signup, Forgot, Reset, children }: Props) {\n const { user, authStatus } = useAuth();\n const [screen, setScreen] = useState<AuthScreen>(() =>\n detectResetFromUrl() ? 'reset' : 'login',\n );\n\n // Reset é fluxo exclusivamente pre-auth. Se user autenticou (login OU logout\n // que recicla useAuth state), AuthGate volta pra 'login' default.\n // Isso corrige F22 follow-up: logout pós-reset jogava user de volta no Reset\n // porque ?token= ainda estava na URL (fix principal é clear URL no useResetForm,\n // este é cinto-e-suspensório).\n useEffect(() => {\n if (user && screen !== 'login') {\n setScreen('login');\n }\n }, [user, screen]);\n\n // Se URL mudar em runtime (SPA navigation), re-avalia. Raro mas permite\n // e-mail abrir em tab já montada.\n useEffect(() => {\n const onPop = () => {\n if (detectResetFromUrl()) setScreen('reset');\n };\n window.addEventListener('popstate', onPop);\n return () => window.removeEventListener('popstate', onPop);\n }, []);\n\n if (authStatus === 'loading') return <LoadingState />;\n if (!user) {\n if (screen === 'reset') return <Reset onNavigate={setScreen} />;\n if (screen === 'signup') return <Signup onNavigate={setScreen} />;\n if (screen === 'forgot') return <Forgot onNavigate={setScreen} />;\n return <Login onNavigate={setScreen} />;\n }\n return <>{children}</>;\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`\n * pros consumidores que não precisam das methods completas do auth.\n */\nexport function useAuth() {\n const { user, authStatus, auth } = useHook();\n return {\n user,\n authStatus,\n refresh: auth.refresh,\n };\n}\n","export function LoadingState({ message }: { message?: string }) {\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ padding: 24, textAlign: 'center' }}>\n <span>{message ?? 'Carregando...'}</span>\n </div>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'none';\n\n/**\n * Hook headless pro Paywall. Expõe status atual da subscription + ação\n * `checkout(cpf)` que chama `POST /payments/checkout/card` e redireciona\n * o browser pro `invoiceUrl` hosted do Asaas. Após o checkout, Asaas\n * redireciona de volta com query string indicativa; subscription real\n * é atualizada via webhook (`PAYMENT_RECEIVED` / `SUBSCRIPTION_ACTIVATED`).\n *\n * MVP: checkout só cartão. Pix vem depois (gatilho documentado em P10.7).\n */\nexport function usePaywallState() {\n const { subscription } = useHook();\n const [opening, setOpening] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n\n const checkout = useCallback(\n async (args: { cpf: string; cycle?: 'MONTHLY' | 'YEARLY' }) => {\n setOpening(true);\n setError(null);\n try {\n const result = await subscription.checkoutCard({\n cpf: args.cpf,\n cycle: args.cycle ?? 'MONTHLY',\n });\n // Redireciona pro checkout hosted do Asaas. Após confirmação,\n // Asaas redireciona de volta e webhook atualiza DB.\n window.location.href = result.invoiceUrl;\n } catch (err) {\n setError(err as Error);\n setOpening(false); // só reseta em erro; success navega away\n }\n },\n [subscription],\n );\n\n const cancel = useCallback(async () => {\n try {\n await subscription.cancel();\n await subscription.refresh();\n } catch (err) {\n setError(err as Error);\n }\n }, [subscription]);\n\n return { status, daysLeftInTrial, checkout, cancel, opening, error };\n}\n","import type { ComponentType, ReactNode } from 'react';\nimport { usePaywallState } from '../hooks/usePaywallState';\n\ninterface Props {\n Paywall: ComponentType;\n children: ReactNode;\n}\n\nexport function SubscriptionGate({ Paywall, children }: Props) {\n const { status } = usePaywallState();\n // MVP: stub retorna 'none' — não bloqueia. Quando P10 entregar real,\n // 'expired'|'canceled'|'past_due' bloqueiam com Paywall.\n if (status === 'expired' || status === 'canceled' || status === 'past_due') {\n return <Paywall />;\n }\n return <>{children}</>;\n}\n","// Side-effect-only component: observa estado e dispara push.subscribe() quando\n// apropriado. NUNCA renderiza UI bloqueante — sempre retorna null. No MVP, o SDK\n// stub de push lança 'unsupported_mvp', então este componente não faz nada.\n// Quando P14 entregar VAPID real, adicionar gate por 2ª sessão + dismissed_at.\nexport function PushPrompt() {\n return null;\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error) {\n console.error('[ErrorBoundary] caught', error);\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback ?? (\n <div role=\"alert\" style={{ padding: 24, textAlign: 'center' }}>\n <h2>Algo deu errado</h2>\n <p style={{ opacity: 0.7 }}>Recarregue a página pra tentar de novo.</p>\n </div>\n );\n }\n return <>{this.props.children}</>;\n }\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseLoginFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useLoginForm(): UseLoginFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.login({ email, password });\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, password, canSubmit]);\n\n return {\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { SdkError, SdkAuthError, SdkRateLimitError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\n | 'account_locked'\n | 'network'\n | 'server';\n\nexport interface AuthFormError {\n code: AuthFormErrorCode;\n message: string;\n retryAfter?: number;\n}\n\n/**\n * Mapeia SdkError do @hook-sdk/sdk pra AuthFormError tipado do template.\n * Usado por useLoginForm/useSignupForm/useForgotForm.\n */\nexport function mapSdkError(err: unknown): AuthFormError {\n if (err instanceof SdkRateLimitError) {\n return {\n code: 'rate_limited',\n message: `Aguarde ${err.retryAfter}s e tente novamente.`,\n retryAfter: err.retryAfter,\n };\n }\n if (err instanceof SdkAuthError) {\n const detail = (err as { detail?: string }).detail;\n if (detail === 'email_unverified') {\n return { code: 'email_unverified', message: 'Confirme seu e-mail antes de entrar.' };\n }\n if (detail === 'account_locked') {\n return { code: 'account_locked', message: 'Conta bloqueada. Contate o suporte.' };\n }\n return { code: 'invalid_credentials', message: 'E-mail ou senha inválidos.' };\n }\n if (err instanceof SdkError && err.httpStatus === 0) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n // Falhas de rede em POST/PATCH/DELETE não são envolvidas em SdkError pelo\n // HttpClient (só GET tem retry wrap). fetch() lança TypeError cru — tratamos\n // como 'network' pra manter UX consistente com GETs.\n if (err instanceof TypeError) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n return { code: 'server', message: 'Algo deu errado. Tente novamente em instantes.' };\n}\n","import { useLoginForm } from '../hooks/useLoginForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport type AuthScreen = 'login' | 'signup' | 'forgot' | 'reset';\nexport interface AuthScreenProps {\n onNavigate: (to: AuthScreen) => void;\n}\n\nexport function DefaultLoginScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useLoginForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Entre na sua conta</p>\n\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input\n data-testid=\"login-email\"\n type=\"email\"\n value={f.email}\n onChange={(e) => f.setEmail(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input\n data-testid=\"login-password\"\n type=\"password\"\n value={f.password}\n onChange={(e) => f.setPassword(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n\n {f.error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {f.error.message}\n </div>\n )}\n\n <button\n data-testid=\"login-submit\"\n type=\"submit\"\n disabled={!f.canSubmit}\n style={{\n width: '100%', padding: 12,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: f.canSubmit ? 1 : 0.5,\n }}\n >\n {f.submitting ? 'Entrando...' : 'Entrar'}\n </button>\n </form>\n\n <div style={{ marginTop: 16, display: 'flex', justifyContent: 'space-between' }}>\n <button data-testid=\"login-goto-signup\" type=\"button\" onClick={() => onNavigate('signup')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Criar conta\n </button>\n <button data-testid=\"login-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Esqueci senha\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseSignupFormResult {\n name: string;\n setName: (v: string) => void;\n nameError: string | null;\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useSignupForm(): UseSignupFormResult {\n const { auth } = useHook();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const nameError = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n name.trim().length >= 2 &&\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n nameError === null &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.signup({ name, email, password });\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, name, email, password, canSubmit]);\n\n return {\n name, setName, nameError,\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { useSignupForm } from '../hooks/useSignupForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultSignupScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useSignupForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Criar sua conta</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nome\n <input data-testid=\"signup-name\" value={f.name} onChange={(e) => f.setName(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.nameError && <small style={{ color: '#c00' }}>{f.nameError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"signup-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input data-testid=\"signup-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"signup-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Criando...' : 'Criar conta'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"signup-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Já tem conta? Entre\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface UseForgotFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n sent: boolean;\n error: AuthFormError | null;\n}\n\nexport function useForgotForm(): UseForgotFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [sent, setSent] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const canSubmit = email.length > 0 && emailError === null && !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.forgot({ email });\n setSent(true);\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, canSubmit]);\n\n return {\n email, setEmail, emailError,\n submit, submitting, canSubmit, sent, error,\n };\n}\n","import { useForgotForm } from '../hooks/useForgotForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultForgotScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useForgotForm();\n\n if (f.sent) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Verifique seu e-mail</h1>\n <p style={{ opacity: 0.7 }}>Enviamos um link pra redefinir sua senha.</p>\n <button data-testid=\"forgot-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Voltar pro login</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Redefinir senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"forgot-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"forgot-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Enviando...' : 'Enviar link'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"forgot-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Voltar pro login\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst MIN_PASSWORD = 12;\n\nexport interface UseResetFormResult {\n /** Token JWT lido de `?token=` da URL. null se ausente. */\n token: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n confirm: string;\n setConfirm: (v: string) => void;\n confirmError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n /** true após submit 200. UI deve mostrar \"senha alterada, volte pro login\". */\n done: boolean;\n error: AuthFormError | null;\n}\n\n/**\n * Hook headless pro fluxo de reset de senha via link do email.\n *\n * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).\n * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar\n * mensagem \"link inválido\".\n *\n * Após submit 200, todos os refresh tokens do user são revogados pelo\n * backend (forçar re-login). UI deve direcionar pra LoginScreen.\n */\nexport function useResetForm(): UseResetFormResult {\n const { auth } = useHook();\n const [token, setToken] = useState<string | null>(null);\n const [password, setPassword] = useState('');\n const [confirm, setConfirm] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [done, setDone] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n useEffect(() => {\n // Snapshot no mount. URL pode ter sido limpa depois (history.replaceState)\n // mas token deve estar no primeiro render.\n if (typeof window === 'undefined') return;\n const params = new URLSearchParams(window.location.search);\n const t = params.get('token');\n setToken(t && t.length > 0 ? t : null);\n }, []);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const confirmError = useMemo(() => {\n if (confirm.length === 0) return null;\n if (confirm !== password) return 'Senhas não coincidem.';\n return null;\n }, [confirm, password]);\n\n const canSubmit =\n token !== null &&\n password.length >= MIN_PASSWORD &&\n confirm === password &&\n passwordError === null &&\n confirmError === null &&\n !submitting &&\n !done;\n\n const submit = useCallback(async () => {\n if (!canSubmit || token === null) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.reset({ token, newPassword: password });\n setDone(true);\n // Limpa `?token=&screen=reset` da URL pra AuthGate não re-disparar Reset\n // em re-renders futuros (logout depois do reset, popstate, etc.).\n // Mantém mesmo path, só strip dos query params de auth.\n if (typeof window !== 'undefined') {\n const url = new URL(window.location.href);\n url.searchParams.delete('token');\n url.searchParams.delete('screen');\n window.history.replaceState({}, '', url.toString());\n }\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, token, password, canSubmit]);\n\n return {\n token,\n password, setPassword, passwordError,\n confirm, setConfirm, confirmError,\n submit, submitting, canSubmit, done, error,\n };\n}\n","import { useResetForm } from '../hooks/useResetForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\n/**\n * Tela default de reset de senha. Renderizada pelo AuthGate quando\n * `?token=` está presente na URL (link vindo do email de password_reset).\n *\n * AuthScreenProps.onNavigate é usado pra voltar pro login após reset\n * bem-sucedido (usuário precisa re-autenticar — backend revoga todos\n * os refresh tokens na chamada de `auth.reset`).\n */\nexport function DefaultResetScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useResetForm();\n\n if (f.done) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Senha alterada</h1>\n <p style={{ opacity: 0.7 }}>Agora é só fazer login com a nova senha.</p>\n <button data-testid=\"reset-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Ir pro login</button>\n </main>\n );\n }\n\n if (f.token === null) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Link inválido</h1>\n <p style={{ opacity: 0.7 }}>Peça um novo link de reset.</p>\n <button data-testid=\"reset-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')}>Pedir novo link</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Escolha uma nova senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nova senha\n <input data-testid=\"reset-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Confirmar senha\n <input data-testid=\"reset-confirm\" type=\"password\" value={f.confirm} onChange={(e) => f.setConfirm(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.confirmError && <small style={{ color: '#c00' }}>{f.confirmError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"reset-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Alterando...' : 'Alterar senha'}\n </button>\n </form>\n </main>\n );\n}\n","import { useState } from 'react';\nimport { usePaywallState } from '../hooks/usePaywallState';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport function DefaultPaywall() {\n const config = useTemplateConfig();\n const { checkout, opening, error } = usePaywallState();\n const p = config.subscription.paywall_config;\n const [cpf, setCpf] = useState('');\n const cpfDigits = cpf.replace(/\\D/g, '');\n const canCheckout = cpfDigits.length === 11 && !opening;\n\n return (\n <main style={{ padding: 24, maxWidth: 440, margin: '0 auto', textAlign: 'center' }}>\n <h1 style={{ marginBottom: 8 }}>{p.title}</h1>\n {p.subtitle && <p style={{ opacity: 0.7, marginBottom: 24 }}>{p.subtitle}</p>}\n\n <ul style={{ listStyle: 'none', padding: 0, textAlign: 'left', marginBottom: 24 }}>\n {p.benefits.map((b) => (\n <li key={b} style={{ padding: '8px 0', display: 'flex', alignItems: 'center' }}>\n <span aria-hidden style={{ marginRight: 8 }}>✓</span>\n <span>{b}</span>\n </li>\n ))}\n </ul>\n\n <div style={{ textAlign: 'left', marginBottom: 16 }}>\n <label style={{ display: 'block', fontSize: 14, opacity: 0.7, marginBottom: 4 }}>\n Seu CPF (pra emissão de recibo)\n </label>\n <input\n data-testid=\"paywall-cpf\"\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"000.000.000-00\"\n value={cpf}\n onChange={(e) => setCpf(e.target.value)}\n style={{ width: '100%', padding: 10, fontSize: 14, borderRadius: 8, border: '1px solid #ccc' }}\n />\n </div>\n\n {error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {error.message}\n </div>\n )}\n\n <button\n data-testid=\"paywall-cta\"\n type=\"button\"\n onClick={() => void checkout({ cpf: cpfDigits })}\n disabled={!canCheckout}\n style={{\n width: '100%', padding: 14,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: canCheckout ? 1 : 0.5,\n fontSize: 16, fontWeight: 600,\n }}\n >\n {opening ? 'Abrindo...' : p.cta}\n </button>\n\n {p.priceHint && <p style={{ opacity: 0.6, marginTop: 12 }}>{p.priceHint}</p>}\n {p.footerNote && <p style={{ opacity: 0.5, marginTop: 16, fontSize: 12 }}>{p.footerNote}</p>}\n </main>\n );\n}\n","/**\n * @golden-path — único componente público do template.\n * Consumidores (apps) usam via: <AppRoot config={appConfig}>{children}</AppRoot>\n * Pra customizar auth/paywall screens: passe Login/Signup/Forgot/Paywall como props.\n *\n * IMPORTANTE: AppRoot NÃO embrulha em <HookProvider>. O shell (frontend/shell/AppLoader.tsx)\n * já embrulha o bundle com config real ({ appId, apiHost: API_HOST }). Embrulhar de novo\n * criaria duplo HookProvider → dois useAuthState + dois HTTP clients no mesmo bundle, e\n * o interno (com apiHost relativo) sobrescreveria o externo via Context mais próximo —\n * quebra em staging/prod onde shell e API moram em hosts distintos.\n *\n * Testes que precisam de HookProvider montam explicitamente no wrapper de teste.\n */\nimport type { ComponentType, ReactNode } from 'react';\nimport type { AppConfig } from '../../scripts/schemas/app-config';\nimport { TemplateConfigProvider } from './internal/TemplateConfigContext';\nimport { ThemeProvider } from './internal/ThemeProvider';\nimport { AuthGate } from './internal/AuthGate';\nimport { SubscriptionGate } from './internal/SubscriptionGate';\nimport { PushPrompt } from './internal/PushPrompt';\nimport { ErrorBoundary } from './defaults/ErrorBoundary';\nimport { DefaultLoginScreen, type AuthScreenProps } from './defaults/DefaultLoginScreen';\nimport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nimport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nimport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nimport { DefaultPaywall } from './defaults/DefaultPaywall';\n\nexport interface AppRootProps {\n config: AppConfig;\n children: ReactNode;\n Login?: ComponentType<AuthScreenProps>;\n Signup?: ComponentType<AuthScreenProps>;\n Forgot?: ComponentType<AuthScreenProps>;\n /**\n * Tela de reset de senha (form com nova senha via link do email).\n * Renderizada pelo AuthGate quando URL tem `?token=` + user não logado.\n * Default: DefaultResetScreen.\n */\n Reset?: ComponentType<AuthScreenProps>;\n Paywall?: ComponentType;\n}\n\nexport function AppRoot({\n config,\n children,\n Login = DefaultLoginScreen,\n Signup = DefaultSignupScreen,\n Forgot = DefaultForgotScreen,\n Reset = DefaultResetScreen,\n Paywall = DefaultPaywall,\n}: AppRootProps) {\n return (\n <TemplateConfigProvider config={config}>\n <ErrorBoundary>\n <ThemeProvider>\n <AuthGate Login={Login} Signup={Signup} Forgot={Forgot} Reset={Reset}>\n <SubscriptionGate Paywall={Paywall}>\n {children}\n <PushPrompt />\n </SubscriptionGate>\n </AuthGate>\n </ThemeProvider>\n </ErrorBoundary>\n </TemplateConfigProvider>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function EmptyState({ title, description, action }: {\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div role=\"status\" style={{ padding: 32, textAlign: 'center' }}>\n <h2 style={{ marginBottom: 8 }}>{title}</h2>\n {description && <p style={{ opacity: 0.7 }}>{description}</p>}\n {action && <div style={{ marginTop: 16 }}>{action}</div>}\n </div>\n );\n}\n","import { useEffect } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nlet warned = false;\n\n/** Test-only: reseta flag pra permitir validar warn uma única vez em re-mounts de test */\nexport function __resetWarnForTest() { warned = false; }\n\n/**\n * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).\n * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.\n */\nexport function useAuthPrimitives() {\n const { auth } = useHook();\n\n useEffect(() => {\n if (!warned && process.env.NODE_ENV !== 'production') {\n warned = true;\n console.warn(\n '[@hook-sdk/template] useAuthPrimitives() é escape hatch. ' +\n 'Pra login/signup/forgot, use useLoginForm/useSignupForm/useForgotForm. ' +\n 'Docs: docs/19-golden-template.md#escape-hatch',\n );\n }\n }, []);\n\n return {\n login: auth.login,\n signup: auth.signup,\n logout: auth.logout,\n logoutAll: auth.logoutAll,\n forgot: auth.forgot,\n resendVerify: auth.resendVerify,\n changePassword: auth.changePassword,\n changeEmail: auth.changeEmail,\n refresh: auth.refresh,\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').\n */\nexport function useSubscription() {\n const { subscription } = useHook();\n return {\n status: subscription.status(),\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `push` do SDK. MVP: stub retorna 'unsupported' no status\n * e subscribe/unsubscribe lançam SdkError. A shape segue o SDK real.\n */\nexport function usePush() {\n const { push } = useHook();\n return {\n status: push.status(),\n subscribe: push.subscribe,\n unsubscribe: push.unsubscribe,\n };\n}\n","import { useCallback, useState } from 'react';\n\nexport interface ToastItem {\n id: string;\n message: string;\n kind: 'info' | 'error' | 'success';\n}\n\n/**\n * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).\n * Não opina sobre UI; retorna items + actions.\n */\nexport function useToast() {\n const [items, setItems] = useState<ToastItem[]>([]);\n\n const show = useCallback((message: string, kind: ToastItem['kind'] = 'info') => {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n setItems((prev) => [...prev, { id, message, kind }]);\n setTimeout(() => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, 4000);\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return { items, show, dismiss };\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_sdk","import_sdk","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","MIN_PASSWORD","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","import_jsx_runtime","import_react","import_sdk","MIN_PASSWORD","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_sdk","import_sdk","import_react"]}
@@ -0,0 +1,288 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode, ComponentType, Component } from 'react';
3
+ import { z } from 'zod';
4
+ import * as _hook_sdk_sdk from '@hook-sdk/sdk';
5
+
6
+ declare const AppConfigSchema: z.ZodObject<{
7
+ $schema: z.ZodOptional<z.ZodString>;
8
+ slug: z.ZodString;
9
+ name: z.ZodString;
10
+ display_name: z.ZodOptional<z.ZodString>;
11
+ email_alias: z.ZodString;
12
+ theme: z.ZodObject<{
13
+ primary_color: z.ZodString;
14
+ background_color: z.ZodOptional<z.ZodString>;
15
+ logo_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
16
+ icon_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ }, z.core.$strict>;
18
+ features_enabled: z.ZodArray<z.ZodEnum<{
19
+ db: "db";
20
+ storage: "storage";
21
+ upload: "upload";
22
+ leaderboard: "leaderboard";
23
+ push: "push";
24
+ subscription: "subscription";
25
+ }>>;
26
+ dependencies_allowlist: z.ZodArray<z.ZodString>;
27
+ subscription: z.ZodObject<{
28
+ price_cents: z.ZodNumber;
29
+ currency: z.ZodLiteral<"brl">;
30
+ trial_days: z.ZodNumber;
31
+ paywall_config: z.ZodObject<{
32
+ title: z.ZodString;
33
+ subtitle: z.ZodOptional<z.ZodString>;
34
+ benefits: z.ZodArray<z.ZodString>;
35
+ cta: z.ZodString;
36
+ priceHint: z.ZodOptional<z.ZodString>;
37
+ footerNote: z.ZodOptional<z.ZodString>;
38
+ }, z.core.$strict>;
39
+ }, z.core.$strict>;
40
+ sdk_version_required: z.ZodString;
41
+ max_bundle_size_kb: z.ZodNumber;
42
+ }, z.core.$strict>;
43
+ type AppConfig = z.infer<typeof AppConfigSchema>;
44
+
45
+ type AuthScreen = 'login' | 'signup' | 'forgot' | 'reset';
46
+ interface AuthScreenProps {
47
+ onNavigate: (to: AuthScreen) => void;
48
+ }
49
+ declare function DefaultLoginScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
50
+
51
+ interface AppRootProps {
52
+ config: AppConfig;
53
+ children: ReactNode;
54
+ Login?: ComponentType<AuthScreenProps>;
55
+ Signup?: ComponentType<AuthScreenProps>;
56
+ Forgot?: ComponentType<AuthScreenProps>;
57
+ /**
58
+ * Tela de reset de senha (form com nova senha via link do email).
59
+ * Renderizada pelo AuthGate quando URL tem `?token=` + user não logado.
60
+ * Default: DefaultResetScreen.
61
+ */
62
+ Reset?: ComponentType<AuthScreenProps>;
63
+ Paywall?: ComponentType;
64
+ }
65
+ declare function AppRoot({ config, children, Login, Signup, Forgot, Reset, Paywall, }: AppRootProps): react_jsx_runtime.JSX.Element;
66
+
67
+ declare function DefaultSignupScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
68
+
69
+ declare function DefaultForgotScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
70
+
71
+ /**
72
+ * Tela default de reset de senha. Renderizada pelo AuthGate quando
73
+ * `?token=` está presente na URL (link vindo do email de password_reset).
74
+ *
75
+ * AuthScreenProps.onNavigate é usado pra voltar pro login após reset
76
+ * bem-sucedido (usuário precisa re-autenticar — backend revoga todos
77
+ * os refresh tokens na chamada de `auth.reset`).
78
+ */
79
+ declare function DefaultResetScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
80
+
81
+ declare function DefaultPaywall(): react_jsx_runtime.JSX.Element;
82
+
83
+ declare function LoadingState({ message }: {
84
+ message?: string;
85
+ }): react_jsx_runtime.JSX.Element;
86
+
87
+ declare function EmptyState({ title, description, action }: {
88
+ title: string;
89
+ description?: string;
90
+ action?: ReactNode;
91
+ }): react_jsx_runtime.JSX.Element;
92
+
93
+ interface Props {
94
+ children: ReactNode;
95
+ fallback?: ReactNode;
96
+ }
97
+ interface State {
98
+ error: Error | null;
99
+ }
100
+ declare class ErrorBoundary extends Component<Props, State> {
101
+ state: State;
102
+ static getDerivedStateFromError(error: Error): State;
103
+ componentDidCatch(error: Error): void;
104
+ render(): string | number | boolean | Iterable<ReactNode> | react_jsx_runtime.JSX.Element;
105
+ }
106
+
107
+ type AuthFormErrorCode = 'invalid_credentials' | 'rate_limited' | 'email_unverified' | 'account_locked' | 'network' | 'server';
108
+ interface AuthFormError {
109
+ code: AuthFormErrorCode;
110
+ message: string;
111
+ retryAfter?: number;
112
+ }
113
+
114
+ interface UseLoginFormResult {
115
+ email: string;
116
+ setEmail: (v: string) => void;
117
+ emailError: string | null;
118
+ password: string;
119
+ setPassword: (v: string) => void;
120
+ passwordError: string | null;
121
+ submit: () => Promise<void>;
122
+ submitting: boolean;
123
+ canSubmit: boolean;
124
+ error: AuthFormError | null;
125
+ }
126
+ declare function useLoginForm(): UseLoginFormResult;
127
+
128
+ interface UseSignupFormResult {
129
+ name: string;
130
+ setName: (v: string) => void;
131
+ nameError: string | null;
132
+ email: string;
133
+ setEmail: (v: string) => void;
134
+ emailError: string | null;
135
+ password: string;
136
+ setPassword: (v: string) => void;
137
+ passwordError: string | null;
138
+ submit: () => Promise<void>;
139
+ submitting: boolean;
140
+ canSubmit: boolean;
141
+ error: AuthFormError | null;
142
+ }
143
+ declare function useSignupForm(): UseSignupFormResult;
144
+
145
+ interface UseForgotFormResult {
146
+ email: string;
147
+ setEmail: (v: string) => void;
148
+ emailError: string | null;
149
+ submit: () => Promise<void>;
150
+ submitting: boolean;
151
+ canSubmit: boolean;
152
+ sent: boolean;
153
+ error: AuthFormError | null;
154
+ }
155
+ declare function useForgotForm(): UseForgotFormResult;
156
+
157
+ interface UseResetFormResult {
158
+ /** Token JWT lido de `?token=` da URL. null se ausente. */
159
+ token: string | null;
160
+ password: string;
161
+ setPassword: (v: string) => void;
162
+ passwordError: string | null;
163
+ confirm: string;
164
+ setConfirm: (v: string) => void;
165
+ confirmError: string | null;
166
+ submit: () => Promise<void>;
167
+ submitting: boolean;
168
+ canSubmit: boolean;
169
+ /** true após submit 200. UI deve mostrar "senha alterada, volte pro login". */
170
+ done: boolean;
171
+ error: AuthFormError | null;
172
+ }
173
+ /**
174
+ * Hook headless pro fluxo de reset de senha via link do email.
175
+ *
176
+ * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).
177
+ * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar
178
+ * mensagem "link inválido".
179
+ *
180
+ * Após submit 200, todos os refresh tokens do user são revogados pelo
181
+ * backend (forçar re-login). UI deve direcionar pra LoginScreen.
182
+ */
183
+ declare function useResetForm(): UseResetFormResult;
184
+
185
+ type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'none';
186
+ /**
187
+ * Hook headless pro Paywall. Expõe status atual da subscription + ação
188
+ * `checkout(cpf)` que chama `POST /payments/checkout/card` e redireciona
189
+ * o browser pro `invoiceUrl` hosted do Asaas. Após o checkout, Asaas
190
+ * redireciona de volta com query string indicativa; subscription real
191
+ * é atualizada via webhook (`PAYMENT_RECEIVED` / `SUBSCRIPTION_ACTIVATED`).
192
+ *
193
+ * MVP: checkout só cartão. Pix vem depois (gatilho documentado em P10.7).
194
+ */
195
+ declare function usePaywallState(): {
196
+ status: SubscriptionStatus;
197
+ daysLeftInTrial: number | null;
198
+ checkout: (args: {
199
+ cpf: string;
200
+ cycle?: "MONTHLY" | "YEARLY";
201
+ }) => Promise<void>;
202
+ cancel: () => Promise<void>;
203
+ opening: boolean;
204
+ error: Error | null;
205
+ };
206
+
207
+ /**
208
+ * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).
209
+ * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.
210
+ */
211
+ declare function useAuthPrimitives(): {
212
+ login: (args: {
213
+ email: string;
214
+ password: string;
215
+ }) => Promise<void>;
216
+ signup: (args: {
217
+ email: string;
218
+ password: string;
219
+ name?: string;
220
+ }) => Promise<void>;
221
+ logout: () => Promise<void>;
222
+ logoutAll: () => Promise<void>;
223
+ forgot: (args: {
224
+ email: string;
225
+ }) => Promise<void>;
226
+ resendVerify: () => Promise<void>;
227
+ changePassword: (args: {
228
+ oldPassword: string;
229
+ newPassword: string;
230
+ }) => Promise<void>;
231
+ changeEmail: (args: {
232
+ newEmail: string;
233
+ }) => Promise<void>;
234
+ refresh: () => Promise<void>;
235
+ };
236
+
237
+ /**
238
+ * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`
239
+ * pros consumidores que não precisam das methods completas do auth.
240
+ */
241
+ declare function useAuth(): {
242
+ user: {
243
+ id: string;
244
+ email: string;
245
+ emailVerified: boolean;
246
+ createdAt: string;
247
+ } | null;
248
+ authStatus: _hook_sdk_sdk.AuthStatus;
249
+ refresh: () => Promise<void>;
250
+ };
251
+
252
+ /**
253
+ * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').
254
+ */
255
+ declare function useSubscription(): {
256
+ status: _hook_sdk_sdk.SdkSubscriptionStatus;
257
+ };
258
+
259
+ /**
260
+ * Wrapper fino sobre `push` do SDK. MVP: stub retorna 'unsupported' no status
261
+ * e subscribe/unsubscribe lançam SdkError. A shape segue o SDK real.
262
+ */
263
+ declare function usePush(): {
264
+ status: _hook_sdk_sdk.PushStatus;
265
+ subscribe: () => Promise<{
266
+ subscribed: true;
267
+ }>;
268
+ unsubscribe: () => Promise<{
269
+ subscribed: false;
270
+ }>;
271
+ };
272
+
273
+ interface ToastItem {
274
+ id: string;
275
+ message: string;
276
+ kind: 'info' | 'error' | 'success';
277
+ }
278
+ /**
279
+ * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).
280
+ * Não opina sobre UI; retorna items + actions.
281
+ */
282
+ declare function useToast(): {
283
+ items: ToastItem[];
284
+ show: (message: string, kind?: ToastItem["kind"]) => void;
285
+ dismiss: (id: string) => void;
286
+ };
287
+
288
+ export { AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, LoadingState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, useAuth, useAuthPrimitives, useForgotForm, useLoginForm, usePaywallState, usePush, useResetForm, useSignupForm, useSubscription, useToast };