{"_id":"@aizvi/auth-postgres","name":"@aizvi/auth-postgres","dist-tags":{"latest":"1.1.0"},"versions":{"1.1.0":{"name":"@aizvi/auth-postgres","version":"1.1.0","description":"PostgreSQL storage adapter for @aizvi/auth. postgresAdapter() opens its own connection pool via pg; createPostgresAuthAdapter() also works with any client you already have open, including pg.Pool, pg.Client, or @electric-sql/pglite.","keywords":["auth","authentication","postgres","postgresql","pg","database-adapter","storage-adapter","typescript"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Aizvi/auth.git","directory":"packages/postgres"},"homepage":"https://github.com/Aizvi/auth/tree/main/packages/postgres#readme","bugs":{"url":"https://github.com/Aizvi/auth/issues"},"type":"commonjs","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"tsx --test \"test/adapter.test.ts\"","typecheck":"tsc --noEmit"},"peerDependencies":{"@aizvi/auth":"^1.1.1"},"dependencies":{"pg":"^8.13.1"},"devDependencies":{"@aizvi/auth":"workspace:*","@electric-sql/pglite":"^0.2.17","@types/pg":"^8.11.10","tsup":"^8.3.0","tsx":"^4.23.1","typescript":"^5.6.3"},"_id":"@aizvi/auth-postgres@1.1.0","gitHead":"84e0dbaa3ce5633305b3ffbf653eaef9c7b51727","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-y7etAsh5sdE1RjqiZg7UNF8W8Eg1LI/JuKU1kh3K/3XwzUNdBR6LZLetFf4kVMJZw9kT7bpMPn242p2OBQixVw==","shasum":"100335e930da6ccee2cf750b5560c246fa034250","tarball":"https://registry.npmjs.org/@aizvi/auth-postgres/-/auth-postgres-1.1.0.tgz","fileCount":9,"unpackedSize":42617,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBzHPD7k0y+iJkvXM/tNzE90XsWpOo7r6l4lkjr8i/WxAiEAuVIroyhqjGA+VFEvCQ4cZ5SKXL3AHF8JewcDV4ZHc+I="}]},"_npmUser":{"name":"ahmadhuss","email":"ahmadhussnain787@gmail.com"},"directories":{},"maintainers":[{"name":"ahmadhuss","email":"ahmadhussnain787@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/auth-postgres_1.1.0_1785562305505_0.8190670868399135"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-01T05:31:45.287Z","1.1.0":"2026-08-01T05:31:45.664Z","modified":"2026-08-01T05:31:45.975Z"},"maintainers":[{"name":"ahmadhuss","email":"ahmadhussnain787@gmail.com"}],"description":"PostgreSQL storage adapter for @aizvi/auth. postgresAdapter() opens its own connection pool via pg; createPostgresAuthAdapter() also works with any client you already have open, including pg.Pool, pg.Client, or @electric-sql/pglite.","homepage":"https://github.com/Aizvi/auth/tree/main/packages/postgres#readme","keywords":["auth","authentication","postgres","postgresql","pg","database-adapter","storage-adapter","typescript"],"repository":{"type":"git","url":"git+https://github.com/Aizvi/auth.git","directory":"packages/postgres"},"bugs":{"url":"https://github.com/Aizvi/auth/issues"},"license":"MIT","readme":"# @aizvi/auth-postgres\n\nA PostgreSQL storage adapter for [`@aizvi/auth`](https://www.npmjs.com/package/@aizvi/auth).\nPoint it at a connection string, or a `pg` connection you already have, and\nyour auth system has somewhere to store users and sessions.\n\nIt creates its own `users` and `mobile_auth_sessions` tables the first time\nit runs, and never touches anything else in your database.\n\n## Install\n\n```bash\nnpm install @aizvi/auth @aizvi/auth-postgres\npnpm add @aizvi/auth @aizvi/auth-postgres\nyarn add @aizvi/auth @aizvi/auth-postgres\nbun add @aizvi/auth @aizvi/auth-postgres\n```\n\n## Quick start\n\nThe easiest way to use this package: give it a connection string, and it\nopens a connection pool for you.\n\n```ts\nimport { createAuthRouter } from '@aizvi/auth';\nimport { postgresAdapter } from '@aizvi/auth-postgres';\n\napp.use(\n  '/auth',\n  createAuthRouter({\n    adapter: await postgresAdapter({ connectionString: process.env.DATABASE_URL! }),\n    mailer: myEmailSender,\n    jwtSecret: process.env.JWT_SECRET!,\n  })\n);\n```\n\n`postgresAdapter()` is async, unlike `@aizvi/auth-sqlite`'s `sqliteAdapter()`.\nOpening a pool and creating the tables both need a round trip to the\ndatabase, so there's no synchronous \"open and go\" for Postgres the way\nthere is for a local SQLite file.\n\n### Which driver does this use?\n\n`postgresAdapter()` opens its connection pool with\n[`pg`](https://node-postgres.com/) (`node-postgres`), the standard Postgres\ndriver for Node.js. It also works unchanged under Bun, since `pg` is pure\nJavaScript.\n\n## Already have a connection? Use that instead\n\nIf your app already has its own `pg.Pool`, `pg.Client`, or a\n[`@electric-sql/pglite`](https://pglite.dev/) instance, you don't need\n`postgresAdapter()` to open a second pool. Hand your existing connection\nstraight to `createPostgresAuthAdapter()` instead:\n\n```ts\nimport { Pool } from 'pg';\nimport { createAuthRouter } from '@aizvi/auth';\nimport { createPostgresAuthAdapter } from '@aizvi/auth-postgres';\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL }); // the pool your app already uses\n\napp.use(\n  '/auth',\n  createAuthRouter({\n    adapter: await createPostgresAuthAdapter(pool),\n    mailer: myEmailSender,\n    jwtSecret: process.env.JWT_SECRET!,\n  })\n);\n```\n\nThis works with any client that has a `query(text, params)` method\nreturning `{ rows }`, which covers `pg.Pool`, `pg.Client`, and\n`@electric-sql/pglite`. That way you only ever have one open pool to your\ndatabase, shared between your auth tables and everything else your app\nstores.\n\nIf you're adding auth to an app that already has its own `users` table with\nthe same columns this package expects (see [Schema](#schema) below),\n`createPostgresAuthAdapter()` simply uses it as is. It only creates the\ntables if they don't already exist.\n\nNote that `createPostgresAuthAdapter()` doesn't add a `.close()` method the\nway `@aizvi/auth-sqlite`'s adapter does. A connection you already opened is\nyours to close however your own driver requires (`pool.end()` for `pg`,\n`db.close()` for pglite); the adapter never closes it for you. Only the\npool `postgresAdapter()` opens itself comes with `.close()`, since in that\ncase this package owns the pool's lifecycle.\n\n### More examples\n\n**Sharing one pool between auth and the rest of your app:**\n\n```ts\nimport { Pool } from 'pg';\nimport { createPostgresAuthAdapter } from '@aizvi/auth-postgres';\n\n// Your app's single, shared pool, used everywhere.\nexport const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n\n// Your own tables, created however you already do it.\nawait pool.query('CREATE TABLE IF NOT EXISTS posts (id TEXT PRIMARY KEY, title TEXT NOT NULL)');\n\n// The auth adapter reuses the exact same pool.\nexport const authAdapter = await createPostgresAuthAdapter(pool);\n```\n\n**Running the migration yourself, ahead of time:**\n\n```ts\nimport { Pool } from 'pg';\nimport { migrate, createPostgresAuthAdapter } from '@aizvi/auth-postgres';\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL });\nawait migrate(pool); // creates users / mobile_auth_sessions if they don't exist yet\n\n// ...later, once you're ready to build the router:\nconst adapter = await createPostgresAuthAdapter(pool);\n```\n\n**Using this alongside Prisma.** Prisma's client doesn't expose a\n`query(text, params)` method, so it can't be passed to\n`createPostgresAuthAdapter()` directly. Since this package manages its own\n`users` and `mobile_auth_sessions` tables independently of your Prisma\nschema anyway, open a small separate `pg.Pool` with the same connection\nstring instead:\n\n```ts\nimport { PrismaClient } from '@prisma/client';\nimport { Pool } from 'pg';\nimport { createPostgresAuthAdapter } from '@aizvi/auth-postgres';\n\nexport const prisma = new PrismaClient(); // the rest of your app keeps using this\n\nconst authPool = new Pool({ connectionString: process.env.DATABASE_URL });\nexport const authAdapter = await createPostgresAuthAdapter(authPool);\n```\n\nTwo connections to the same database is normal and much simpler than\nadapting Prisma's `$queryRawUnsafe` to this package's driver interface.\n\n**Testing against a real Postgres without a server**, using\n[`@electric-sql/pglite`](https://pglite.dev/) (a real Postgres compiled to\nWASM, runs in-process):\n\n```ts\nimport { PGlite } from '@electric-sql/pglite';\nimport { createPostgresAuthAdapter } from '@aizvi/auth-postgres';\n\nconst db = new PGlite(); // in-memory, no server, no Docker\nconst adapter = await createPostgresAuthAdapter(db);\n```\n\n## Schema\n\nOn first use, this creates:\n\n```sql\nCREATE TABLE IF NOT EXISTS users (\n  id TEXT PRIMARY KEY,\n  email TEXT UNIQUE NOT NULL,\n  password_hash TEXT NOT NULL,\n  is_verified BOOLEAN NOT NULL DEFAULT FALSE,\n  verification_code TEXT,\n  verification_expires TEXT,\n  reset_code TEXT,\n  reset_expires TEXT,\n  created_at TEXT NOT NULL,\n  updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS mobile_auth_sessions (\n  id TEXT PRIMARY KEY,\n  user_id TEXT NOT NULL REFERENCES users(id),\n  refresh_token_hash TEXT NOT NULL,\n  expires_at TEXT NOT NULL,\n  revoked_at TEXT,\n  created_at TEXT NOT NULL,\n  updated_at TEXT NOT NULL\n);\n```\n\nOnly the SHA-256 hash of a refresh token is ever stored, never the raw\ntoken itself.\n\n## API\n\n### `postgresAdapter(options)`\n\n| Option             | Required | Description                                                                    |\n| ------------------ | -------- | ------------------------------------------------------------------------------ |\n| `connectionString` | yes      | A Postgres connection string, for example `postgres://user:pass@host:5432/db`. |\n\nAny other field is passed straight through to `pg`'s `Pool` constructor\n(`max`, `ssl`, `idleTimeoutMillis`, and so on).\n\nReturns a promise for an adapter ready to pass to `createAuthRouter`. Also\nhas a `.close()` method if you need to close the pool manually. Most apps\nnever need to call this.\n\n### `createPostgresAuthAdapter(db)`\n\nTakes an already open client (anything implementing `query(text, params)`\nreturning `{ rows }`; see [`src/driver.ts`](./src/driver.ts) for the exact\nminimal interface) and returns a promise for an adapter with the same\nmethods, minus `.close()`.\n\n### `migrate(db)`\n\nRuns the table creation step on its own, if you want to control exactly\nwhen it happens rather than letting `postgresAdapter`/\n`createPostgresAuthAdapter` run it for you automatically.\n\n## Code of Conduct\n\nSee [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).\n\n## License\n\nMIT (see [license.txt](./license.txt))\n","readmeFilename":"README.md","_rev":"1-d9d227083d701b62ca16d41a65ac5f0c"}