{"_id":"@dogbyte-labs/adonisjs-better-auth-adapter","_rev":"2-e59730ca4262af1b4c886d0dbaee069d","name":"@dogbyte-labs/adonisjs-better-auth-adapter","dist-tags":{"latest":"0.0.3"},"versions":{"0.0.1":{"name":"@dogbyte-labs/adonisjs-better-auth-adapter","version":"0.0.1","keywords":[],"author":"","license":"MIT","_id":"@dogbyte-labs/adonisjs-better-auth-adapter@0.0.1","maintainers":[{"name":"josevelaz","email":"jose.c.velazquez@proton.me"}],"c8":{"exclude":["tests/**"],"reporter":["text","html"]},"dist":{"shasum":"8d0f7ad2eb388f5ea5c8c8f76e7a0b70acb9220f","tarball":"https://registry.npmjs.org/@dogbyte-labs/adonisjs-better-auth-adapter/-/adonisjs-better-auth-adapter-0.0.1.tgz","fileCount":17,"integrity":"sha512-+TD772n1zv0+1wl3PrkxvbgmLJKNxc5GL2N6CyDEYqL1w53H1pcPc17pl9VZ9a9lTBK+NB8xkhU6vmYf3voBjw==","signatures":[{"sig":"MEUCIBnSqVr8D6o8W2KE3VUyPWHvhPlD8mO1OFRBlBIr1e+YAiEAz+zrfQLLArJWKISkgstA6OcqQ6v8trDkmLZ6U3uh8BY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37977},"main":"build/index.js","type":"module","types":"./build/index.d.ts","tsdown":{"dts":false,"clean":true,"entry":["./index.ts","./configure.ts"],"format":"esm","minify":"dce-only","outDir":"./build","target":"esnext","treeshake":false,"sourcemaps":false,"fixedExtension":false},"engines":{"node":">=24.0.0"},"exports":{".":"./build/index.js"},"gitHead":"303d2aa7e6f4c974a166dc2899d06f5e3886fef7","scripts":{"lint":"eslint .","test":"c8 npm run quick:test && npm run contract:test","build":"npm run compile && node scripts/verify_build_configure.mjs","format":"prettier --write .","compile":"tsdown && tsc --emitDeclarationOnly --declaration","pretest":"npm run lint","release":"release-it","version":"npm run build","typecheck":"tsc --noEmit","precompile":"npm run lint","quick:test":"node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts","postcompile":"npm run copy:templates","contract:test":"vitest run","copy:templates":"copyfiles -u 1 \"stubs/**/*.stub\" build","prepublishOnly":"npm run build"},"_npmUser":{"name":"josevelaz","email":"jose.c.velazquez@proton.me"},"prettier":"@adonisjs/prettier-config","release-it":{"git":{"push":true,"tagName":"v${version}","commitMessage":"chore(release): ${version}","tagAnnotation":"v${version}","requireUpstream":true,"requireCleanWorkingDir":true},"npm":{"publish":true,"skipChecks":true},"github":{"release":true},"plugins":{"@release-it/conventional-changelog":{"preset":{"name":"angular"}}}},"_npmVersion":"11.9.0","description":"Better Auth database adapter for AdonisJS Lucid","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@opentelemetry/api":"^1.9.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^11.0.0","luxon":"^3.7.2","eslint":"^10.0.3","tsdown":"^0.21.0","vitest":"^4.1.2","prettier":"^3.8.1","copyfiles":"^2.4.1","cross-env":"^10.1.0","release-it":"^19.2.4","typescript":"^5.9.3","@types/node":"^25.3.5","better-auth":"^1.5.6","@japa/assert":"^4.2.0","@japa/runner":"^5.3.0","@adonisjs/core":"^7.0.1","better-sqlite3":"^12.8.0","@adonisjs/lucid":"^22.3.0","@poppinss/ts-exec":"^1.4.4","@adonisjs/tsconfig":"^2.0.0","@adonisjs/assembler":"^8.0.0","@types/better-sqlite3":"^7.6.13","@adonisjs/eslint-config":"^3.0.0","@better-auth/test-utils":"^1.5.6","@adonisjs/prettier-config":"^1.4.5","@release-it/conventional-changelog":"^10.0.5"},"peerDependencies":{"better-auth":"^1.5.0","@adonisjs/core":"^7.0.0","@adonisjs/lucid":"^22.0.0","@opentelemetry/api":"^1.9.1","@adonisjs/assembler":"^8.0.0"},"peerDependenciesMeta":{"@adonisjs/assembler":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/adonisjs-better-auth-adapter_0.0.1_1775044768997_0.6514219991379537","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@dogbyte-labs/adonisjs-better-auth-adapter","description":"Better Auth database adapter for AdonisJS Lucid","version":"0.0.3","engines":{"node":">=24.0.0"},"repository":{"type":"git","url":"git+https://github.com/dogbyte-labs/adonisjs-better-auth-adapter.git"},"type":"module","main":"build/index.js","exports":{".":"./build/index.js"},"scripts":{"copy:templates":"copyfiles -u 1 \"stubs/**/*.stub\" build","typecheck":"tsc --noEmit","lint":"eslint .","format":"prettier --write .","quick:test":"node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts","pretest":"npm run lint","test":"c8 npm run quick:test && npm run contract:test","contract:test":"vitest run","precompile":"npm run lint","compile":"tsdown && tsc --emitDeclarationOnly --declaration","postcompile":"npm run copy:templates","build":"npm run compile && node scripts/verify_build_configure.mjs","release":"release-it","version":"npm run build","prepublishOnly":"npm run build"},"keywords":[],"author":"","license":"MIT","dependencies":{"@opentelemetry/api":"^1.9.1"},"devDependencies":{"@adonisjs/assembler":"^8.0.0","@adonisjs/core":"^7.0.1","@adonisjs/eslint-config":"^3.0.0","@adonisjs/lucid":"^22.3.0","@adonisjs/prettier-config":"^1.4.5","@adonisjs/tsconfig":"^2.0.0","@better-auth/test-utils":"^1.5.6","@japa/assert":"^4.2.0","@japa/runner":"^5.3.0","@poppinss/ts-exec":"^1.4.4","@release-it/conventional-changelog":"^10.0.5","@types/better-sqlite3":"^7.6.13","@types/node":"^25.3.5","better-auth":"^1.5.6","better-sqlite3":"^12.8.0","c8":"^11.0.0","copyfiles":"^2.4.1","cross-env":"^10.1.0","eslint":"^10.0.3","luxon":"^3.7.2","prettier":"^3.8.1","release-it":"^19.2.4","tsdown":"^0.21.0","typescript":"^5.9.3","vitest":"^4.1.2"},"peerDependencies":{"@adonisjs/assembler":"^8.0.0","@adonisjs/core":"^7.0.0","@adonisjs/lucid":"^22.0.0","@opentelemetry/api":"^1.9.1","better-auth":"^1.5.0"},"peerDependenciesMeta":{"@adonisjs/assembler":{"optional":true}},"publishConfig":{"access":"public","provenance":true},"tsdown":{"entry":["./index.ts","./configure.ts"],"outDir":"./build","clean":true,"format":"esm","minify":"dce-only","fixedExtension":false,"dts":false,"treeshake":false,"sourcemaps":false,"target":"esnext"},"release-it":{"git":{"requireCleanWorkingDir":true,"requireUpstream":true,"commitMessage":"chore(release): ${version}","tagAnnotation":"v${version}","push":true,"tagName":"v${version}"},"github":{"release":true},"npm":{"publish":true,"skipChecks":true},"plugins":{"@release-it/conventional-changelog":{"preset":{"name":"angular"}}}},"c8":{"reporter":["text","html"],"exclude":["tests/**"]},"prettier":"@adonisjs/prettier-config","gitHead":"b506faa79563528e7f4eab8d1012995e03230cbe","types":"./build/index.d.ts","_id":"@dogbyte-labs/adonisjs-better-auth-adapter@0.0.3","bugs":{"url":"https://github.com/dogbyte-labs/adonisjs-better-auth-adapter/issues"},"homepage":"https://github.com/dogbyte-labs/adonisjs-better-auth-adapter#readme","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-8ZZ1AsET1PXZWgC9P6TBUpz3zt2LCkQvSRLS2mantRdtM/8KZip91r1PcnlEETifaJNu6Evj9j9S3YTIXNOUIw==","shasum":"7d1d095ee1196576f5521d70a8ac54c55f96d3d5","tarball":"https://registry.npmjs.org/@dogbyte-labs/adonisjs-better-auth-adapter/-/adonisjs-better-auth-adapter-0.0.3.tgz","fileCount":17,"unpackedSize":38069,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dogbyte-labs%2fadonisjs-better-auth-adapter@0.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDJOwQn+5Acr3pGta1zECSZE0Ch4tVllNF50hsWl4hRYwIhAOYH8KoCRg+oyfzpsaXu4xl8XOlgjCnzlBJFKFnxJyPU"}]},"_npmUser":{"name":"josevelaz","email":"jose.c.velazquez@proton.me"},"directories":{},"maintainers":[{"name":"josevelaz","email":"jose.c.velazquez@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/adonisjs-better-auth-adapter_0.0.3_1775054046410_0.28537491110550484"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-01T11:59:28.887Z","modified":"2026-04-01T14:34:06.927Z","0.0.1":"2026-04-01T11:59:29.146Z","0.0.3":"2026-04-01T14:34:06.562Z"},"license":"MIT","keywords":[],"description":"Better Auth database adapter for AdonisJS Lucid","maintainers":[{"name":"josevelaz","email":"jose.c.velazquez@proton.me"}],"readme":"# adonisjs-better-auth-adapter\n\nBetter Auth database adapter for AdonisJS Lucid.\n\nIt provides:\n\n- a Lucid-backed Better Auth adapter\n- Better Auth `createSchema` support\n- a node ace configure hook that publishes starter files\n\n## Status\n\n- AdonisJS v7\n- Node `>=24`\n- Lucid is already installed and configured in the consumer app\n- validated on fresh AdonisJS Hypermedia apps\n- SQLite / `better-sqlite3` is the validated path today\n- PostgreSQL is intended, but not currently covered by the same validation matrix\n\n## Installation\n\n```sh\nnpm install better-auth @adonisjs/lucid adonisjs-better-auth-adapter\nnode ace configure adonisjs-better-auth-adapter\n```\n\nThe configure hook adds:\n\n- `config/better_auth.ts`\n- `auth.ts`\n- `BETTER_AUTH_SECRET` and `BETTER_AUTH_URL` entries to `.env`\n- `.env.example` entries for `BETTER_AUTH_SECRET` and `BETTER_AUTH_URL`\n\n## Generated Files\n\n`config/better_auth.ts`\n\n```ts\nimport type { BetterAuthOptions } from 'better-auth'\n\nconst betterAuthConfig: BetterAuthOptions = {\n  secret: process.env.BETTER_AUTH_SECRET,\n  baseURL: process.env.BETTER_AUTH_URL,\n  emailAndPassword: {\n    enabled: true,\n  },\n}\n\nexport default betterAuthConfig\n```\n\n`auth.ts`\n\n```ts\nimport app from '@adonisjs/core/services/app'\nimport db from '@adonisjs/lucid/services/db'\nimport { betterAuth, type Auth, type BetterAuthOptions } from 'better-auth'\nimport { lucidAdapter } from 'adonisjs-better-auth-adapter'\nimport betterAuthConfig from '#config/better_auth'\n\nconst database = lucidAdapter({ client: db.connection() })\n\ntype RuntimeBetterAuthOptions = BetterAuthOptions & {\n  database: typeof database\n}\n\nlet auth: Auth<RuntimeBetterAuthOptions>\n\nawait app.booted(async () => {\n  auth = betterAuth({\n    ...betterAuthConfig,\n    database,\n  })\n})\n\nexport { auth }\n```\n\n## Runtime Integration\n\nThe generated `auth.ts` is meant for the booted Adonis runtime. For runtime requests, mount Better Auth behind an Adonis controller that creates a fresh Web `Request` for `auth.handler(...)`. Passing `request.request` directly through `toNodeHandler(...)` is not reliable once Adonis bodyparser has already consumed the stream.\n\nExample controller (`app/controllers/better_auth_controller.ts`):\n\n```ts\nimport type { HttpContext } from '@adonisjs/core/http'\n\nexport default class BetterAuthController {\n  async handle({ request, response }: HttpContext) {\n    const { auth } = await import('../../auth.js')\n\n    const headers = new Headers()\n\n    for (const [key, value] of Object.entries(request.headers())) {\n      if (typeof value === 'string') {\n        headers.set(key, value)\n      }\n    }\n\n    const webRequest = new Request(request.completeUrl(true), {\n      method: request.method(),\n      headers,\n      body:\n        request.method() === 'GET' || request.method() === 'HEAD'\n          ? undefined\n          : JSON.stringify(request.all()),\n    })\n\n    const webResponse = await auth.handler(webRequest)\n\n    response.status(webResponse.status)\n\n    webResponse.headers.forEach((value, key) => {\n      if (key.toLowerCase() !== 'set-cookie') {\n        response.header(key, value)\n      }\n    })\n\n    for (const cookie of webResponse.headers.getSetCookie()) {\n      response.append('set-cookie', cookie)\n    }\n\n    response.send(await webResponse.text())\n  }\n}\n```\n\nExample route (`start/routes.ts`):\n\n```ts\nimport BetterAuthController from '#controllers/better_auth_controller'\nimport router from '@adonisjs/core/services/router'\n\nrouter.any('/api/auth/*', [BetterAuthController, 'handle'])\n```\n\n## Shield / CSRF Note\n\nIf your app uses Shield CSRF protection, exempt the Better Auth routes:\n\n```ts\ncsrf: {\n  enabled: true,\n  exceptRoutes: ['/api/auth/*'],\n}\n```\n\nWithout this exemption, Shield intercepts Better Auth POST routes before they reach the auth handler.\n\n## CLI Schema Generation\n\nBetter Auth CLI imports its target file directly. The generated runtime `auth.ts` depends on the booted Adonis container, so for schema generation you need a separate CLI-safe entrypoint.\n\nExample `auth_cli.ts`:\n\n```ts\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport { Emitter } from '@adonisjs/core/events'\nimport { AppFactory } from '@adonisjs/core/factories/app'\nimport { LoggerFactory } from '@adonisjs/core/factories/logger'\nimport { defineConfig } from '@adonisjs/lucid'\nimport { Database } from '@adonisjs/lucid/database'\nimport { betterAuth } from 'better-auth'\nimport { lucidAdapter } from 'adonisjs-better-auth-adapter'\n\nprocess.loadEnvFile(path.join(process.cwd(), '.env'))\n\nconst { default: betterAuthConfig } = await import('./config/better_auth.js')\nconst logger = new LoggerFactory().create()\nconst app = new AppFactory().create(new URL(`file://${process.cwd()}/`), () => {})\nconst emitter = new Emitter(app)\n\nconst db = new Database(\n  defineConfig({\n    connection: 'sqlite',\n    connections: {\n      sqlite: {\n        client: 'better-sqlite3',\n        connection: {\n          filename: path.join(process.cwd(), 'tmp/db.sqlite3'),\n        },\n        useNullAsDefault: true,\n      },\n    },\n  }),\n  logger,\n  emitter\n)\n\nexport const auth = betterAuth({\n  ...betterAuthConfig,\n  database: lucidAdapter({ client: db.connection('sqlite') }),\n})\n```\n\nGenerate the migration:\n\n```sh\nnpx @better-auth/cli@latest generate --config ./auth_cli.ts\n```\n\nThe adapter writes a Lucid migration under `database/migrations` by default.\n\n## Validated Consumer Flow\n\nAfter generating the migration, the validated next steps are:\n\n1. Apply the migration:\n\n```sh\nnode ace migration:run\n```\n\n2. Mount the Better Auth route bridge at `/api/auth/*` using the controller and route shown in [Runtime Integration](#runtime-integration).\n\n3. Exempt Better Auth routes from Shield CSRF as shown in [Shield / CSRF Note](#shield--csrf-note).\n\n4. Prove the auth flow works end-to-end:\n\n- `POST /api/auth/sign-up/email` — create a user with name, email, and password\n- `POST /api/auth/sign-in/email` — log in using a separate cookie jar from signup\n- `GET /api/auth/get-session` — confirm the session is authenticated\n- Verify persisted user and session rows in SQLite\n\nThis flow was validated against fresh AdonisJS Hypermedia apps with SQLite / `better-sqlite3`.\n\n## Model Name Collisions\n\nSome Adonis starter kits already ship their own `users` table and generated schema types. To avoid collisions, add these model names to your Better Auth config:\n\n```ts\nuser: {\n  modelName: 'better_auth_user',\n},\nsession: {\n  modelName: 'better_auth_session',\n},\naccount: {\n  modelName: 'better_auth_account',\n},\nverification: {\n  modelName: 'better_auth_verification',\n}\n```\n\n## Verification\n\nUseful commands while developing this package:\n\n```sh\nnpm run lint\nnpm run typecheck\nnpm run quick:test\nnpm run contract:test\nnpm run build\n```\n\n## Troubleshooting\n\n- If `node ace configure adonisjs-better-auth-adapter` fails with a module/import error, verify the package was installed from a fresh tarball or registry publish and that better-auth, `adonisjs-better-auth-adapter`, and `@opentelemetry/api` resolve in the consumer app.\n- Better Auth CLI must use `auth_cli.ts`, not runtime `auth.ts`, because the runtime file depends on the booted Adonis container.\n- Better Auth POST routes need CSRF exemption when Shield is enabled.\n- Passing `request.request` directly through `toNodeHandler(...)` is not reliable after Adonis bodyparser has consumed the stream — use `auth.handler(webRequest)` with a reconstructed Web `Request` instead.\n- name collisions with starter app auth tables/types can be resolved by configuring explicit `modelName` values as shown in [Model Name Collisions](#model-name-collisions).\n","readmeFilename":"README.md","homepage":"https://github.com/dogbyte-labs/adonisjs-better-auth-adapter#readme","repository":{"type":"git","url":"git+https://github.com/dogbyte-labs/adonisjs-better-auth-adapter.git"},"bugs":{"url":"https://github.com/dogbyte-labs/adonisjs-better-auth-adapter/issues"}}