{"_id":"@charlieuy711/auth","name":"@charlieuy711/auth","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@charlieuy711/auth","version":"1.0.0","private":false,"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./supabase/client":{"import":"./dist/supabase/client.js","types":"./dist/supabase/client.d.ts"},"./supabase/server":{"import":"./dist/supabase/server.js","types":"./dist/supabase/server.d.ts"}},"scripts":{"build":"tsc"},"devDependencies":{"typescript":"^5","@types/react":"^18"},"peerDependencies":{"@supabase/ssr":">=0.1.0","@supabase/supabase-js":">=2.0.0","next":">=14.0.0","react":">=18.0.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"_id":"@charlieuy711/auth@1.0.0","gitHead":"09cfb53662d88898a59b29555a52bcec4a4e981c","description":"Auth compartido del ecosistema CORE. Base: core-biblio — probado en producción.","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-+MOl59rsJcIOBynFh57gFZSiypaJ6icnU5JTRGuHs95tXtDHe4IQ1vznHAVt99Z7p0lAeE/u+2IvWdipkd8isg==","shasum":"11efa95a7f135ac06e8b002d3ae9be4be8612f56","tarball":"https://registry.npmjs.org/@charlieuy711/auth/-/auth-1.0.0.tgz","fileCount":32,"unpackedSize":18493,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDixSJUatT0TX9KfCSeWlmGxEPGXyPauhjrWUO3d92CRQIgFrfWRp8Mhxg53SbsjGL2VgHZ/xBPtoLz9ujw4b285Ho="}]},"_npmUser":{"name":"charlieuy711","email":"cvaralla@gmail.com"},"directories":{},"maintainers":[{"name":"charlieuy711","email":"cvaralla@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/auth_1.0.0_1780757066481_0.4062624222214102"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-06T14:44:26.304Z","1.0.0":"2026-06-06T14:44:26.617Z","modified":"2026-06-06T14:44:26.774Z"},"maintainers":[{"name":"charlieuy711","email":"cvaralla@gmail.com"}],"description":"Auth compartido del ecosistema CORE. Base: core-biblio — probado en producción.","readme":"# @core/auth\n\nAuth compartido del ecosistema CORE.\nBase: core-biblio — probado en producción.\n\n---\n\n## Estructura\n\n```\npackages/core-auth/\n├── supabase/\n│   ├── client.ts     ← browser client (createClient)\n│   └── server.ts     ← server client (createServerSupabaseClient)\n├── components/\n│   ├── Button.tsx    ← botón con loading state\n│   ├── Input.tsx     ← input con label y error\n│   └── index.ts\n├── types/\n│   └── supabase.ts   ← tipos de base de datos\n├── middleware.ts      ← createCoreMiddleware()\n└── index.ts          ← exports principales\n```\n\n---\n\n## Uso en cada app Next.js\n\n### middleware.ts\n```ts\nimport { createCoreMiddleware, defaultMatcher } from '@core/auth/middleware'\n\nexport const middleware = createCoreMiddleware({\n  publicRoutes:    ['/login'],\n  loginRoute:      '/login',\n  defaultRedirect: '/dashboard',  // cambiar según la app\n})\n\nexport const config = { matcher: defaultMatcher }\n```\n\n### Login page (app/login/page.tsx)\n```tsx\n'use client'\nimport { useState } from 'react'\nimport { useRouter } from 'next/navigation'\nimport { createClient } from '@core/auth/client'\nimport { Button, Input } from '@core/auth/components'\n\nexport default function LoginPage() {\n  const router = useRouter()\n  const [email, setEmail] = useState('')\n  const [password, setPassword] = useState('')\n  const [loading, setLoading] = useState(false)\n  const [error, setError] = useState('')\n\n  async function handleLogin(e: React.FormEvent) {\n    e.preventDefault()\n    setError('')\n    setLoading(true)\n    const supabase = createClient()\n    const { error: authError } = await supabase.auth.signInWithPassword({ email, password })\n    setLoading(false)\n    if (authError) { setError('Credenciales incorrectas.'); return }\n    router.refresh()\n    router.push('/dashboard')  // cambiar según la app\n  }\n\n  return (\n    <main style={{ backgroundColor: '#0B1E35' }} className=\"min-h-screen flex items-center justify-center\">\n      <form onSubmit={handleLogin} className=\"w-full max-w-sm px-8 py-12\">\n        <Input label=\"Email\" type=\"email\" value={email} onChange={e => setEmail(e.target.value)} required />\n        <Input label=\"Contraseña\" type=\"password\" value={password} onChange={e => setPassword(e.target.value)} required />\n        {error && <p className=\"text-xs text-red-400\">{error}</p>}\n        <Button type=\"submit\" loading={loading}>Ingresar</Button>\n      </form>\n    </main>\n  )\n}\n```\n\n### Server component (verificar sesión)\n```ts\nimport { createServerSupabaseClient } from '@core/auth/server'\n\nexport default async function Page() {\n  const supabase = await createServerSupabaseClient()\n  const { data: { session } } = await supabase.auth.getSession()\n  if (!session) redirect('/login')\n  // ...\n}\n```\n\n---\n\n## Notas importantes\n\n- Usar `getSession()` en el middleware — NO `getUser()`\n- El login usa `router.refresh()` ANTES de `router.push()` — ese orden es crítico\n- Cada app define su propio `defaultRedirect` según su ruta principal\n\n---\n\nv1.0 — 2026 | CORE\n","readmeFilename":"README.md","_rev":"1-e81132006c345f7536813ecc18c8a70d"}