// Generated by scripts/generate-manifest.mjs. Do not edit by hand. import type { AddOnCompiled } from '../../../../../types.js' type TemplateRecord = Record type TemplateAddOn = TemplateRecord & { integrations?: Array routes?: Array } type TemplateRenderContext = { [key: string]: any packageManager: any projectName: any typescript: any tailwind: any blank: any js: any jsx: any fileRouter: any codeRouter: any routerOnly: any includeExamples: any addOnEnabled: Record addOnOption: Record addOns: Array integrations: Array routes: Array getPackageManagerAddScript: (...args: Array) => string getPackageManagerRunScript: (...args: Array) => string getPackageManagerExecuteScript: (...args: Array) => string relativePath: (...args: Array) => string integrationImportContent: (...args: Array) => string integrationImportCode: (...args: Array) => string | undefined renderTemplate: (content: string) => string ignoreFile: () => never } type TemplateRenderer = (context: TemplateRenderContext) => string | undefined function __escapeXML(value: unknown) { if (value === undefined || value === null) { return '' } return String(value).replace(/[&<>'"]/g, (character) => { switch (character) { case '&': return '&' case '<': return '<' case '>': return '>' case '"': return '"' case "'": return ''' default: return character } }) } export function getManifestTemplateKey(template: string) { let hash = 0x811c9dc5 for (let i = 0; i < template.length; i++) { hash ^= template.charCodeAt(i) hash = Math.imul(hash, 0x01000193) >>> 0 } return `${hash.toString(16).padStart(8, '0')}:${template.length}` } function __render_2ca117a6_183(context: TemplateRenderContext) { const { packageManager, projectName, typescript, tailwind, blank, js, jsx, fileRouter, codeRouter, routerOnly, includeExamples, addOnEnabled, addOnOption, addOns, integrations, routes, getPackageManagerAddScript, getPackageManagerRunScript, getPackageManagerExecuteScript, relativePath, integrationImportContent, integrationImportCode, renderTemplate, ignoreFile, } = context let __output = '' const __append = (value: unknown) => { if (value !== undefined && value !== null) { __output += String(value) } } __append("# Better Auth configuration\nBETTER_AUTH_URL=http://localhost:3000\nBETTER_AUTH_SECRET= # Generate a secret key: `") __append(getPackageManagerExecuteScript('@better-auth/cli', ['secret'])) __append("`\n") return __output } function __render_a1f5176f_1766(context: TemplateRenderContext) { const { packageManager, projectName, typescript, tailwind, blank, js, jsx, fileRouter, codeRouter, routerOnly, includeExamples, addOnEnabled, addOnOption, addOns, integrations, routes, getPackageManagerAddScript, getPackageManagerRunScript, getPackageManagerExecuteScript, relativePath, integrationImportContent, integrationImportCode, renderTemplate, ignoreFile, } = context let __output = '' const __append = (value: unknown) => { if (value !== undefined && value !== null) { __output += String(value) } } __append("import { authClient } from \"#/lib/auth-client\";") if (routes.some(r => r.url === '/demo/better-auth')) { __append("import { Link } from \"@tanstack/react-router\";") } __append("export default function BetterAuthHeader() {\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return (\n
\n );\n }\n\n if (session?.user) {\n return (\n
\n {session.user.image ? (\n \"\"\n ) : (\n
\n \n {session.user.name?.charAt(0).toUpperCase() || \"U\"}\n \n
\n )}\n {\n void authClient.signOut()\n }}\n className=\"flex-1 h-9 px-4 text-sm font-medium bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-50 border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n Sign out\n \n
\n );\n }") if (routes.some(r => r.url === '/demo/better-auth')) { __append("return (\n \n Sign in\n \n );") } else { __append("return null;") } __append("}\n") return __output } function __render_f1192baf_807(context: TemplateRenderContext) { const { packageManager, projectName, typescript, tailwind, blank, js, jsx, fileRouter, codeRouter, routerOnly, includeExamples, addOnEnabled, addOnOption, addOns, integrations, routes, getPackageManagerAddScript, getPackageManagerRunScript, getPackageManagerExecuteScript, relativePath, integrationImportContent, integrationImportCode, renderTemplate, ignoreFile, } = context let __output = '' const __append = (value: unknown) => { if (value !== undefined && value !== null) { __output += String(value) } } __append("## Setting up Better Auth\n\n1. Generate and set the `BETTER_AUTH_SECRET` environment variable in your `.env.local`:\n\n ```bash\n ") __append(getPackageManagerExecuteScript('@better-auth/cli', ['secret'])) __append("\n ```\n\n2. Visit the [Better Auth documentation](https://www.better-auth.com) to unlock the full potential of authentication in your app.\n\n### Adding a Database (Optional)\n\nBetter Auth can work in stateless mode, but to persist user data, add a database:\n\n```typescript\n// src/lib/auth.ts\nimport { betterAuth } from \"better-auth\";\nimport { Pool } from \"pg\";\n\nexport const auth = betterAuth({\n database: new Pool({\n connectionString: process.env.DATABASE_URL,\n }),\n // ... rest of config\n});\n```\n\nThen run migrations:\n\n```bash\n") __append(getPackageManagerExecuteScript('@better-auth/cli', ['migrate'])) __append("\n```\n") return __output } const templateRenderers: Record = { "2ca117a6:183": __render_2ca117a6_183, "a1f5176f:1766": __render_a1f5176f_1766, "f1192baf:807": __render_f1192baf_807, } export function hasManifestTemplate(template: string) { return getManifestTemplateKey(template) in templateRenderers } export function renderManifestTemplate( template: string, context: TemplateRenderContext, ) { const key = getManifestTemplateKey(template) const renderer = templateRenderers[key] if (!renderer) { throw new Error(`Template ${key} was not precompiled into the manifest`) } return renderer(context) ?? '' } export const addOn = { "name": "Better Auth", "description": "Self-hosted user accounts and sessions (open source, full control).", "phase": "add-on", "type": "add-on", "category": "auth", "exclusive": [ "auth" ], "color": "#000000", "priority": 26, "link": "https://www.better-auth.com", "modes": [ "file-router" ], "routes": [ { "url": "/demo/better-auth", "name": "Better Auth", "path": "src/routes/demo/better-auth.tsx", "jsName": "BetterAuthDemo" } ], "integrations": [ { "type": "header-user", "jsName": "BetterAuthHeader", "path": "src/integrations/better-auth/header-user.tsx" } ], "id": "better-auth", "version": "0.0.0", "packageAdditions": { "dependencies": { "better-auth": "^1.5.3" } }, "readme": "## Setting up Better Auth\n\n1. Generate and set the `BETTER_AUTH_SECRET` environment variable in your `.env.local`:\n\n ```bash\n <%- getPackageManagerExecuteScript('@better-auth/cli', ['secret']) %>\n ```\n\n2. Visit the [Better Auth documentation](https://www.better-auth.com) to unlock the full potential of authentication in your app.\n\n### Adding a Database (Optional)\n\nBetter Auth can work in stateless mode, but to persist user data, add a database:\n\n```typescript\n// src/lib/auth.ts\nimport { betterAuth } from \"better-auth\";\nimport { Pool } from \"pg\";\n\nexport const auth = betterAuth({\n database: new Pool({\n connectionString: process.env.DATABASE_URL,\n }),\n // ... rest of config\n});\n```\n\nThen run migrations:\n\n```bash\n<%- getPackageManagerExecuteScript('@better-auth/cli', ['migrate']) %>\n```\n", "readmeIsEjs": true, "files": { "_dot_env.local.append.ejs": "# Better Auth configuration\nBETTER_AUTH_URL=http://localhost:3000\nBETTER_AUTH_SECRET= # Generate a secret key: `<%- getPackageManagerExecuteScript('@better-auth/cli', ['secret']) %>`\n", "src/integrations/better-auth/header-user.tsx.ejs": "import { authClient } from \"#/lib/auth-client\";\n<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>\nimport { Link } from \"@tanstack/react-router\";\n<%_ } _%>\n\nexport default function BetterAuthHeader() {\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return (\n
\n );\n }\n\n if (session?.user) {\n return (\n
\n {session.user.image ? (\n \"\"\n ) : (\n
\n \n {session.user.name?.charAt(0).toUpperCase() || \"U\"}\n \n
\n )}\n {\n void authClient.signOut()\n }}\n className=\"flex-1 h-9 px-4 text-sm font-medium bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-50 border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n Sign out\n \n
\n );\n }\n\n<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>\n return (\n \n Sign in\n \n );\n<%_ } else { _%>\n return null;\n<%_ } _%>\n}\n", "src/lib/auth-client.ts": "import { createAuthClient } from 'better-auth/react'\n\nexport const authClient = createAuthClient()\n", "src/lib/auth.ts": "import { betterAuth } from 'better-auth'\nimport { tanstackStartCookies } from 'better-auth/tanstack-start'\n\nexport const auth = betterAuth({\n emailAndPassword: {\n enabled: true,\n },\n plugins: [tanstackStartCookies()],\n})\n", "src/routes/api/auth/$.ts": "import { createFileRoute } from '@tanstack/react-router'\nimport { auth } from '#/lib/auth'\n\nexport const Route = createFileRoute('/api/auth/$')({\n server: {\n handlers: {\n GET: ({ request }) => auth.handler(request),\n POST: ({ request }) => auth.handler(request),\n },\n },\n})\n", "src/routes/demo/better-auth.tsx": "import { createFileRoute } from '@tanstack/react-router'\nimport { useState } from 'react'\nimport { authClient } from '#/lib/auth-client'\n\nexport const Route = createFileRoute('/demo/better-auth')({\n component: BetterAuthDemo,\n})\n\nfunction BetterAuthDemo() {\n const { data: session, isPending } = authClient.useSession()\n const [isSignUp, setIsSignUp] = useState(false)\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [name, setName] = useState('')\n const [error, setError] = useState('')\n const [loading, setLoading] = useState(false)\n\n if (isPending) {\n return (\n
\n
\n
\n )\n }\n\n if (session?.user) {\n return (\n
\n
\n
\n

Better Auth

\n

Welcome back

\n

\n You're signed in as {session.user.email}\n

\n
\n\n
\n {session.user.image ? (\n \"\"\n ) : (\n
\n \n {session.user.name?.charAt(0).toUpperCase() || 'U'}\n \n
\n )}\n
\n

\n {session.user.name}\n

\n

\n {session.user.email}\n

\n
\n
\n\n {\n void authClient.signOut()\n }}\n className=\"demo-button demo-button-secondary w-full\"\n >\n Sign out\n \n\n

\n Built with{' '}\n \n BETTER-AUTH\n \n .\n

\n
\n
\n )\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n setError('')\n setLoading(true)\n\n try {\n if (isSignUp) {\n const result = await authClient.signUp.email({\n email,\n password,\n name,\n })\n if (result.error) {\n setError(result.error.message || 'Sign up failed')\n }\n } else {\n const result = await authClient.signIn.email({\n email,\n password,\n })\n if (result.error) {\n setError(result.error.message || 'Sign in failed')\n }\n }\n } catch (err) {\n setError('An unexpected error occurred')\n } finally {\n setLoading(false)\n }\n }\n\n return (\n
\n
\n

Better Auth

\n

\n {isSignUp ? 'Create an account' : 'Sign in'}\n

\n

\n {isSignUp\n ? 'Enter your information to create an account'\n : 'Enter your email below to login to your account'}\n

\n\n
\n {isSignUp && (\n
\n \n Name\n \n setName(e.target.value)}\n className=\"demo-input\"\n required\n />\n
\n )}\n\n
\n \n setEmail(e.target.value)}\n className=\"demo-input\"\n required\n />\n
\n\n
\n \n Password\n \n setPassword(e.target.value)}\n className=\"demo-input\"\n required\n minLength={8}\n />\n
\n\n {error && (\n
\n

{error}

\n
\n )}\n\n \n {loading ? (\n \n \n Please wait\n \n ) : isSignUp ? (\n 'Create account'\n ) : (\n 'Sign in'\n )}\n \n \n\n
\n {\n setIsSignUp(!isSignUp)\n setError('')\n }}\n className=\"demo-muted text-sm transition-colors hover:text-[var(--sea-ink)]\"\n >\n {isSignUp\n ? 'Already have an account? Sign in'\n : \"Don't have an account? Sign up\"}\n \n
\n\n

\n Built with{' '}\n \n BETTER-AUTH\n \n .\n

\n
\n
\n )\n}\n" }, "deletedFiles": [], "smallLogo": "\n\n\n\n\n\n\n\n\n" } satisfies AddOnCompiled