@framers/sql-storage-adapter 0.7.3 → 0.7.4

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.
package/README.md CHANGED
@@ -93,6 +93,7 @@ import { createStorageFeatures, runSchemaMigrations, isUniqueViolation } from '@
93
93
  | `./core` | Contracts and errors, dialects, full-text search, codecs, exporters, `createStorageFeatures`, the schema-migration runner, `isUniqueViolation`, the logger. No adapter |
94
94
  | `./postgres`, `./better-sqlite3`, `./sqljs`, `./indexeddb`, `./capacitor` | One adapter each |
95
95
  | `./backup` | S3-compatible backups (`@aws-sdk/client-s3`) |
96
+ | `./authjs` | The Auth.js database adapter (also in `./core`) |
96
97
  | `./electron`, `./electron/renderer`, `./electron/preload` | The Electron adapters. `./electron/renderer` holds only what a window uses; `require('./electron/preload')` gives one bundled CommonJS file for a sandboxed preload |
97
98
  | `./sync`, `./kv`, `./types` | Cross-platform sync, the key-value store, the types |
98
99
 
@@ -381,6 +382,26 @@ const status = await schemaMigrationStatus(db, migrations); // { appl
381
382
  - **Outside a transaction.** A file whose first line is `-- outside transaction` (`outsideTransactionMarker`) runs outside a transaction, for `CREATE INDEX CONCURRENTLY` or `VACUUM`. On PostgreSQL it runs under the session lock on one held connection (`withConnection`).
382
383
  - **Unknown rows.** `unknown: 'ignore'` lets a run go on past ledger rows the list lacks.
383
384
 
385
+ ### Auth.js
386
+
387
+ `createAuthJsAdapter(db)` is an Auth.js database adapter. It keeps users, accounts, sessions and verification tokens in the product's own database through this library, on PostgreSQL or SQLite. Pass it to NextAuth v5 or `@auth/core`; it has the shape of `Adapter` from `@auth/core/adapters`, which CI checks, and needs no dependency on it.
388
+
389
+ ```typescript
390
+ import NextAuth from 'next-auth';
391
+ import { createDatabase } from '@framers/sql-storage-adapter';
392
+ import { createAuthJsAdapter, ensureAuthJsTables } from '@framers/sql-storage-adapter/authjs';
393
+
394
+ const db = await createDatabase({ url: process.env.DATABASE_URL, strict: true });
395
+ await ensureAuthJsTables(db); // or put authJsTablesSql(db) in a migration
396
+ export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: createAuthJsAdapter(db), providers: [/* ... */] });
397
+ ```
398
+
399
+ - **Tables.** They are `auth_users`, `auth_accounts`, `auth_sessions` and `auth_verification_tokens`; `tablePrefix` changes the `auth_`. Ids are text, from `crypto.randomUUID()` unless Auth.js passes one or `generateId` is given. Times are `timestamptz` on PostgreSQL and ISO 8601 text on SQLite, and Dates either way in JavaScript.
400
+ - **Deletes.** `deleteUser` deletes the user's sessions and accounts first, in one transaction, so it holds on engines that leave foreign keys off.
401
+ - **Verification tokens.** `useVerificationToken` deletes and returns the token in one statement (`DELETE ... RETURNING`), so a token works once.
402
+ - **Passkeys.** WebAuthn authenticators are not stored.
403
+ - **Tests.** Auth.js's own adapter test suite runs against it on PostgreSQL, better-sqlite3 and sql.js.
404
+
384
405
  ### Values
385
406
 
386
407
  On SQLite, values convert as they bind, positional and named alike:
@@ -19,5 +19,6 @@ export { createStorageFeatures } from './contracts/features.js';
19
19
  export { isUniqueViolation } from '../shared/errors.js';
20
20
  export { setStorageLogger, getStorageLogger, type StorageLogger } from '../shared/logger.js';
21
21
  export * from '../features/migrations/schemaMigrations.js';
22
+ export * from '../features/auth/authJsAdapter.js';
22
23
  export * from '../shared/parameterUtils.js';
23
24
  //# sourceMappingURL=portable.d.ts.map
@@ -45,6 +45,7 @@ var import_features = require("./contracts/features.js");
45
45
  var import_errors = require("../shared/errors.js");
46
46
  var import_logger = require("../shared/logger.js");
47
47
  __reExport(portable_exports, require("../features/migrations/schemaMigrations.js"), module.exports);
48
+ __reExport(portable_exports, require("../features/auth/authJsAdapter.js"), module.exports);
48
49
  __reExport(portable_exports, require("../shared/parameterUtils.js"), module.exports);
49
50
  // Annotate the CommonJS export names for ESM import in node:
50
51
  0 && (module.exports = {
@@ -62,5 +63,6 @@ __reExport(portable_exports, require("../shared/parameterUtils.js"), module.expo
62
63
  setStorageLogger,
63
64
  ...require("../types/index.js"),
64
65
  ...require("../features/migrations/schemaMigrations.js"),
66
+ ...require("../features/auth/authJsAdapter.js"),
65
67
  ...require("../shared/parameterUtils.js")
66
68
  });
@@ -0,0 +1,110 @@
1
+ /**
2
+ * An Auth.js database adapter over StorageAdapter: users, accounts, sessions
3
+ * and verification tokens kept through this library on PostgreSQL and SQLite
4
+ * alike, so a product's own Auth.js (NextAuth v5, `@auth/core`) stores its
5
+ * auth data where the rest of its data lives.
6
+ *
7
+ * The object `createAuthJsAdapter()` returns has the shape of `Adapter` from
8
+ * `@auth/core/adapters`, without a dependency on it: pass it as `adapter` to
9
+ * `NextAuth()` or `Auth()`. WebAuthn authenticators are not stored.
10
+ *
11
+ * @module
12
+ */
13
+ import type { StorageAdapter } from '../../core/contracts/index.js';
14
+ /** A user as Auth.js reads it (`AdapterUser`). */
15
+ export interface AuthJsUser {
16
+ id: string;
17
+ email: string;
18
+ emailVerified: Date | null;
19
+ name?: string | null;
20
+ image?: string | null;
21
+ }
22
+ /**
23
+ * An account as Auth.js reads it (`AdapterAccount`). A type, not an
24
+ * interface, so it fits Auth.js's account, which allows more token fields.
25
+ * Fields the provider did not give are left out.
26
+ */
27
+ export type AuthJsAccount = {
28
+ userId: string;
29
+ type: 'oauth' | 'oidc' | 'email' | 'webauthn';
30
+ provider: string;
31
+ providerAccountId: string;
32
+ refresh_token?: string;
33
+ access_token?: string;
34
+ expires_at?: number;
35
+ token_type?: Lowercase<string>;
36
+ scope?: string;
37
+ id_token?: string;
38
+ session_state?: string;
39
+ };
40
+ /** A session as Auth.js reads it (`AdapterSession`). */
41
+ export interface AuthJsSession {
42
+ sessionToken: string;
43
+ userId: string;
44
+ expires: Date;
45
+ }
46
+ /** A verification token as Auth.js reads it (`VerificationToken`). */
47
+ export interface AuthJsVerificationToken {
48
+ identifier: string;
49
+ token: string;
50
+ expires: Date;
51
+ }
52
+ /** The methods of Auth.js's `Adapter` this adapter implements. */
53
+ export interface AuthJsAdapter {
54
+ createUser(user: Omit<AuthJsUser, 'id'> & {
55
+ id?: string;
56
+ }): Promise<AuthJsUser>;
57
+ getUser(id: string): Promise<AuthJsUser | null>;
58
+ getUserByEmail(email: string): Promise<AuthJsUser | null>;
59
+ getUserByAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<AuthJsUser | null>;
60
+ updateUser(user: Partial<AuthJsUser> & Pick<AuthJsUser, 'id'>): Promise<AuthJsUser>;
61
+ deleteUser(userId: string): Promise<AuthJsUser | null>;
62
+ linkAccount(account: AuthJsAccount): Promise<AuthJsAccount>;
63
+ unlinkAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<void>;
64
+ getAccount(providerAccountId: string, provider: string): Promise<AuthJsAccount | null>;
65
+ createSession(session: AuthJsSession): Promise<AuthJsSession>;
66
+ getSessionAndUser(sessionToken: string): Promise<{
67
+ session: AuthJsSession;
68
+ user: AuthJsUser;
69
+ } | null>;
70
+ updateSession(session: Partial<AuthJsSession> & Pick<AuthJsSession, 'sessionToken'>): Promise<AuthJsSession | null>;
71
+ deleteSession(sessionToken: string): Promise<void>;
72
+ createVerificationToken(token: AuthJsVerificationToken): Promise<AuthJsVerificationToken>;
73
+ useVerificationToken(params: {
74
+ identifier: string;
75
+ token: string;
76
+ }): Promise<AuthJsVerificationToken | null>;
77
+ }
78
+ /** Where the adapter keeps its tables, and how it makes ids. */
79
+ export interface AuthJsAdapterOptions {
80
+ /** Put before each table name: `<prefix>users`, `<prefix>accounts`, `<prefix>sessions`, `<prefix>verification_tokens`. Default `auth_`. */
81
+ tablePrefix?: string;
82
+ /** Makes a user or account id when Auth.js passes none. Default: `crypto.randomUUID()`. */
83
+ generateId?: () => string;
84
+ }
85
+ /**
86
+ * The statements that create the adapter's tables and indexes on `db`'s
87
+ * engine, each `IF NOT EXISTS`, for a migration file or for
88
+ * ensureAuthJsTables.
89
+ */
90
+ export declare function authJsTablesSql(db: StorageAdapter, options?: AuthJsAdapterOptions): string[];
91
+ /** Creates the adapter's tables and indexes on `db` when they are missing. */
92
+ export declare function ensureAuthJsTables(db: StorageAdapter, options?: AuthJsAdapterOptions): Promise<void>;
93
+ /**
94
+ * An Auth.js database adapter that keeps users, accounts, sessions and
95
+ * verification tokens in `db`, on PostgreSQL or SQLite. Create the tables
96
+ * first with ensureAuthJsTables (or authJsTablesSql in a migration).
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import NextAuth from 'next-auth';
101
+ * import { createDatabase } from '@framers/sql-storage-adapter';
102
+ * import { createAuthJsAdapter, ensureAuthJsTables } from '@framers/sql-storage-adapter/authjs';
103
+ *
104
+ * const db = await createDatabase({ url: process.env.DATABASE_URL, strict: true });
105
+ * await ensureAuthJsTables(db);
106
+ * export const { handlers, auth } = NextAuth({ adapter: createAuthJsAdapter(db), providers: [] });
107
+ * ```
108
+ */
109
+ export declare function createAuthJsAdapter(db: StorageAdapter, options?: AuthJsAdapterOptions): AuthJsAdapter;
110
+ //# sourceMappingURL=authJsAdapter.d.ts.map
@@ -0,0 +1,251 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var authJsAdapter_exports = {};
19
+ __export(authJsAdapter_exports, {
20
+ authJsTablesSql: () => authJsTablesSql,
21
+ createAuthJsAdapter: () => createAuthJsAdapter,
22
+ ensureAuthJsTables: () => ensureAuthJsTables
23
+ });
24
+ module.exports = __toCommonJS(authJsAdapter_exports);
25
+ var import_features = require("../../core/contracts/features.js");
26
+ const PREFIX = /^[A-Za-z_][A-Za-z0-9_]*$/;
27
+ const tablesFor = (options) => {
28
+ const prefix = options.tablePrefix ?? "auth_";
29
+ if (!PREFIX.test(prefix)) {
30
+ throw new Error(`tablePrefix must be letters, digits and underscores, starting with a letter or an underscore; got ${JSON.stringify(prefix)}.`);
31
+ }
32
+ return {
33
+ users: `${prefix}users`,
34
+ accounts: `${prefix}accounts`,
35
+ sessions: `${prefix}sessions`,
36
+ verificationTokens: `${prefix}verification_tokens`
37
+ };
38
+ };
39
+ function authJsTablesSql(db, options = {}) {
40
+ const t = tablesFor(options);
41
+ const d = (0, import_features.createStorageFeatures)(db).dialect;
42
+ const timestamp = d.columnType("timestamp");
43
+ return [
44
+ `CREATE TABLE IF NOT EXISTS ${t.users} (id TEXT PRIMARY KEY, name TEXT, email TEXT UNIQUE, email_verified ${timestamp}, image TEXT)`,
45
+ `CREATE TABLE IF NOT EXISTS ${t.accounts} (
46
+ id TEXT PRIMARY KEY,
47
+ user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE,
48
+ type TEXT NOT NULL,
49
+ provider TEXT NOT NULL,
50
+ provider_account_id TEXT NOT NULL,
51
+ refresh_token TEXT,
52
+ access_token TEXT,
53
+ expires_at ${d.columnType("bigint")},
54
+ token_type TEXT,
55
+ scope TEXT,
56
+ id_token TEXT,
57
+ session_state TEXT,
58
+ UNIQUE (provider, provider_account_id)
59
+ )`,
60
+ `CREATE TABLE IF NOT EXISTS ${t.sessions} (session_token TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE, expires ${timestamp} NOT NULL)`,
61
+ `CREATE TABLE IF NOT EXISTS ${t.verificationTokens} (identifier TEXT NOT NULL, token TEXT NOT NULL, expires ${timestamp} NOT NULL, PRIMARY KEY (identifier, token))`,
62
+ `CREATE INDEX IF NOT EXISTS ${t.accounts}_user_id ON ${t.accounts} (user_id)`,
63
+ `CREATE INDEX IF NOT EXISTS ${t.sessions}_user_id ON ${t.sessions} (user_id)`
64
+ ];
65
+ }
66
+ async function ensureAuthJsTables(db, options = {}) {
67
+ for (const statement of authJsTablesSql(db, options)) {
68
+ await db.exec(statement);
69
+ }
70
+ }
71
+ const toDate = (value) => value == null ? null : value instanceof Date ? value : new Date(String(value));
72
+ const toUser = (row) => ({
73
+ id: String(row.id),
74
+ name: row.name ?? null,
75
+ email: row.email,
76
+ emailVerified: toDate(row.email_verified),
77
+ image: row.image ?? null
78
+ });
79
+ const toAccount = (row) => {
80
+ const account = {
81
+ userId: String(row.user_id),
82
+ type: row.type,
83
+ provider: row.provider,
84
+ providerAccountId: row.provider_account_id
85
+ };
86
+ for (const field of ["refresh_token", "access_token", "token_type", "scope", "id_token", "session_state"]) {
87
+ if (row[field] != null)
88
+ account[field] = String(row[field]);
89
+ }
90
+ if (row.expires_at != null)
91
+ account.expires_at = Number(row.expires_at);
92
+ return account;
93
+ };
94
+ const toSession = (row) => ({
95
+ sessionToken: row.session_token,
96
+ userId: String(row.user_id),
97
+ expires: toDate(row.expires)
98
+ });
99
+ const toVerificationToken = (row) => ({
100
+ identifier: row.identifier,
101
+ token: row.token,
102
+ expires: toDate(row.expires)
103
+ });
104
+ const defaultId = () => {
105
+ const random = globalThis.crypto?.randomUUID;
106
+ if (!random)
107
+ throw new Error("crypto.randomUUID() is not available; pass generateId.");
108
+ return random.call(globalThis.crypto);
109
+ };
110
+ function createAuthJsAdapter(db, options = {}) {
111
+ const t = tablesFor(options);
112
+ const generateId = options.generateId ?? defaultId;
113
+ const getUser = async (id) => {
114
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE id = ?`, [id]);
115
+ return row ? toUser(row) : null;
116
+ };
117
+ const getSession = async (sessionToken) => {
118
+ const row = await db.get(`SELECT * FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
119
+ return row ? toSession(row) : null;
120
+ };
121
+ return {
122
+ async createUser(user) {
123
+ const id = user.id ?? generateId();
124
+ await db.run(`INSERT INTO ${t.users} (id, name, email, email_verified, image) VALUES (?, ?, ?, ?, ?)`, [
125
+ id,
126
+ user.name ?? null,
127
+ user.email,
128
+ user.emailVerified ?? null,
129
+ user.image ?? null
130
+ ]);
131
+ return await getUser(id);
132
+ },
133
+ getUser,
134
+ async getUserByEmail(email) {
135
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE email = ?`, [email]);
136
+ return row ? toUser(row) : null;
137
+ },
138
+ async getUserByAccount({ provider, providerAccountId }) {
139
+ const row = await db.get(`SELECT u.* FROM ${t.users} u JOIN ${t.accounts} a ON a.user_id = u.id WHERE a.provider = ? AND a.provider_account_id = ?`, [provider, providerAccountId]);
140
+ return row ? toUser(row) : null;
141
+ },
142
+ async updateUser(user) {
143
+ const fields = [];
144
+ if ("name" in user)
145
+ fields.push(["name", user.name ?? null]);
146
+ if ("email" in user)
147
+ fields.push(["email", user.email]);
148
+ if ("emailVerified" in user)
149
+ fields.push(["email_verified", user.emailVerified ?? null]);
150
+ if ("image" in user)
151
+ fields.push(["image", user.image ?? null]);
152
+ if (fields.length) {
153
+ await db.run(`UPDATE ${t.users} SET ${fields.map(([column]) => `${column} = ?`).join(", ")} WHERE id = ?`, [
154
+ ...fields.map(([, value]) => value),
155
+ user.id
156
+ ]);
157
+ }
158
+ const updated = await getUser(user.id);
159
+ if (!updated)
160
+ throw new Error(`No user with id ${JSON.stringify(user.id)} to update.`);
161
+ return updated;
162
+ },
163
+ async deleteUser(userId) {
164
+ return db.transaction(async (trx) => {
165
+ const row = await trx.get(`SELECT * FROM ${t.users} WHERE id = ?`, [userId]);
166
+ await trx.run(`DELETE FROM ${t.sessions} WHERE user_id = ?`, [userId]);
167
+ await trx.run(`DELETE FROM ${t.accounts} WHERE user_id = ?`, [userId]);
168
+ await trx.run(`DELETE FROM ${t.users} WHERE id = ?`, [userId]);
169
+ return row ? toUser(row) : null;
170
+ });
171
+ },
172
+ async linkAccount(account) {
173
+ await db.run(`INSERT INTO ${t.accounts} (id, user_id, type, provider, provider_account_id, refresh_token, access_token, expires_at, token_type, scope, id_token, session_state)
174
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
175
+ generateId(),
176
+ account.userId,
177
+ account.type,
178
+ account.provider,
179
+ account.providerAccountId,
180
+ account.refresh_token ?? null,
181
+ account.access_token ?? null,
182
+ account.expires_at ?? null,
183
+ account.token_type ?? null,
184
+ account.scope ?? null,
185
+ account.id_token ?? null,
186
+ account.session_state ?? null
187
+ ]);
188
+ return account;
189
+ },
190
+ async unlinkAccount({ provider, providerAccountId }) {
191
+ await db.run(`DELETE FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [provider, providerAccountId]);
192
+ },
193
+ async getAccount(providerAccountId, provider) {
194
+ const row = await db.get(`SELECT * FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [
195
+ provider,
196
+ providerAccountId
197
+ ]);
198
+ return row ? toAccount(row) : null;
199
+ },
200
+ async createSession(session) {
201
+ await db.run(`INSERT INTO ${t.sessions} (session_token, user_id, expires) VALUES (?, ?, ?)`, [
202
+ session.sessionToken,
203
+ session.userId,
204
+ session.expires
205
+ ]);
206
+ return { sessionToken: session.sessionToken, userId: session.userId, expires: session.expires };
207
+ },
208
+ async getSessionAndUser(sessionToken) {
209
+ const session = await getSession(sessionToken);
210
+ if (!session)
211
+ return null;
212
+ const user = await getUser(session.userId);
213
+ return user ? { session, user } : null;
214
+ },
215
+ async updateSession(session) {
216
+ const fields = [];
217
+ if (session.expires !== void 0)
218
+ fields.push(["expires", session.expires]);
219
+ if (session.userId !== void 0)
220
+ fields.push(["user_id", session.userId]);
221
+ if (fields.length) {
222
+ await db.run(`UPDATE ${t.sessions} SET ${fields.map(([column]) => `${column} = ?`).join(", ")} WHERE session_token = ?`, [
223
+ ...fields.map(([, value]) => value),
224
+ session.sessionToken
225
+ ]);
226
+ }
227
+ return getSession(session.sessionToken);
228
+ },
229
+ async deleteSession(sessionToken) {
230
+ await db.run(`DELETE FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
231
+ },
232
+ async createVerificationToken(token) {
233
+ await db.run(`INSERT INTO ${t.verificationTokens} (identifier, token, expires) VALUES (?, ?, ?)`, [
234
+ token.identifier,
235
+ token.token,
236
+ token.expires
237
+ ]);
238
+ return { identifier: token.identifier, token: token.token, expires: token.expires };
239
+ },
240
+ async useVerificationToken({ identifier, token }) {
241
+ const row = await db.get(`DELETE FROM ${t.verificationTokens} WHERE identifier = ? AND token = ? RETURNING identifier, token, expires`, [identifier, token]);
242
+ return row ? toVerificationToken(row) : null;
243
+ }
244
+ };
245
+ }
246
+ // Annotate the CommonJS export names for ESM import in node:
247
+ 0 && (module.exports = {
248
+ authJsTablesSql,
249
+ createAuthJsAdapter,
250
+ ensureAuthJsTables
251
+ });
@@ -13,6 +13,7 @@ export * from './features/migrations/dataExport.js';
13
13
  export * from './features/migrations/dataImport.js';
14
14
  export * from './features/migrations/migration.js';
15
15
  export * from './features/migrations/schemaMigrations.js';
16
+ export * from './features/auth/authJsAdapter.js';
16
17
  export * from './features/sync/syncManager.js';
17
18
  export * from './shared/parameterUtils.js';
18
19
  export { segmentFilePath, segmentName, validateSegment } from './shared/segment.js';
package/dist/cjs/index.js CHANGED
@@ -50,6 +50,7 @@ __reExport(dist_exports, require("./features/migrations/dataExport.js"), module.
50
50
  __reExport(dist_exports, require("./features/migrations/dataImport.js"), module.exports);
51
51
  __reExport(dist_exports, require("./features/migrations/migration.js"), module.exports);
52
52
  __reExport(dist_exports, require("./features/migrations/schemaMigrations.js"), module.exports);
53
+ __reExport(dist_exports, require("./features/auth/authJsAdapter.js"), module.exports);
53
54
  __reExport(dist_exports, require("./features/sync/syncManager.js"), module.exports);
54
55
  __reExport(dist_exports, require("./shared/parameterUtils.js"), module.exports);
55
56
  var import_segment = require("./shared/segment.js");
@@ -96,6 +97,7 @@ var import_logger = require("./shared/logger.js");
96
97
  ...require("./features/migrations/dataImport.js"),
97
98
  ...require("./features/migrations/migration.js"),
98
99
  ...require("./features/migrations/schemaMigrations.js"),
100
+ ...require("./features/auth/authJsAdapter.js"),
99
101
  ...require("./features/sync/syncManager.js"),
100
102
  ...require("./shared/parameterUtils.js")
101
103
  });
@@ -19,5 +19,6 @@ export { createStorageFeatures } from './contracts/features.js';
19
19
  export { isUniqueViolation } from '../shared/errors.js';
20
20
  export { setStorageLogger, getStorageLogger, type StorageLogger } from '../shared/logger.js';
21
21
  export * from '../features/migrations/schemaMigrations.js';
22
+ export * from '../features/auth/authJsAdapter.js';
22
23
  export * from '../shared/parameterUtils.js';
23
24
  //# sourceMappingURL=portable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -19,5 +19,6 @@ export { createStorageFeatures } from './contracts/features.js';
19
19
  export { isUniqueViolation } from '../shared/errors.js';
20
20
  export { setStorageLogger, getStorageLogger } from '../shared/logger.js';
21
21
  export * from '../features/migrations/schemaMigrations.js';
22
+ export * from '../features/auth/authJsAdapter.js';
22
23
  export * from '../shared/parameterUtils.js';
23
24
  //# sourceMappingURL=portable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * An Auth.js database adapter over StorageAdapter: users, accounts, sessions
3
+ * and verification tokens kept through this library on PostgreSQL and SQLite
4
+ * alike, so a product's own Auth.js (NextAuth v5, `@auth/core`) stores its
5
+ * auth data where the rest of its data lives.
6
+ *
7
+ * The object `createAuthJsAdapter()` returns has the shape of `Adapter` from
8
+ * `@auth/core/adapters`, without a dependency on it: pass it as `adapter` to
9
+ * `NextAuth()` or `Auth()`. WebAuthn authenticators are not stored.
10
+ *
11
+ * @module
12
+ */
13
+ import type { StorageAdapter } from '../../core/contracts/index.js';
14
+ /** A user as Auth.js reads it (`AdapterUser`). */
15
+ export interface AuthJsUser {
16
+ id: string;
17
+ email: string;
18
+ emailVerified: Date | null;
19
+ name?: string | null;
20
+ image?: string | null;
21
+ }
22
+ /**
23
+ * An account as Auth.js reads it (`AdapterAccount`). A type, not an
24
+ * interface, so it fits Auth.js's account, which allows more token fields.
25
+ * Fields the provider did not give are left out.
26
+ */
27
+ export type AuthJsAccount = {
28
+ userId: string;
29
+ type: 'oauth' | 'oidc' | 'email' | 'webauthn';
30
+ provider: string;
31
+ providerAccountId: string;
32
+ refresh_token?: string;
33
+ access_token?: string;
34
+ expires_at?: number;
35
+ token_type?: Lowercase<string>;
36
+ scope?: string;
37
+ id_token?: string;
38
+ session_state?: string;
39
+ };
40
+ /** A session as Auth.js reads it (`AdapterSession`). */
41
+ export interface AuthJsSession {
42
+ sessionToken: string;
43
+ userId: string;
44
+ expires: Date;
45
+ }
46
+ /** A verification token as Auth.js reads it (`VerificationToken`). */
47
+ export interface AuthJsVerificationToken {
48
+ identifier: string;
49
+ token: string;
50
+ expires: Date;
51
+ }
52
+ /** The methods of Auth.js's `Adapter` this adapter implements. */
53
+ export interface AuthJsAdapter {
54
+ createUser(user: Omit<AuthJsUser, 'id'> & {
55
+ id?: string;
56
+ }): Promise<AuthJsUser>;
57
+ getUser(id: string): Promise<AuthJsUser | null>;
58
+ getUserByEmail(email: string): Promise<AuthJsUser | null>;
59
+ getUserByAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<AuthJsUser | null>;
60
+ updateUser(user: Partial<AuthJsUser> & Pick<AuthJsUser, 'id'>): Promise<AuthJsUser>;
61
+ deleteUser(userId: string): Promise<AuthJsUser | null>;
62
+ linkAccount(account: AuthJsAccount): Promise<AuthJsAccount>;
63
+ unlinkAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<void>;
64
+ getAccount(providerAccountId: string, provider: string): Promise<AuthJsAccount | null>;
65
+ createSession(session: AuthJsSession): Promise<AuthJsSession>;
66
+ getSessionAndUser(sessionToken: string): Promise<{
67
+ session: AuthJsSession;
68
+ user: AuthJsUser;
69
+ } | null>;
70
+ updateSession(session: Partial<AuthJsSession> & Pick<AuthJsSession, 'sessionToken'>): Promise<AuthJsSession | null>;
71
+ deleteSession(sessionToken: string): Promise<void>;
72
+ createVerificationToken(token: AuthJsVerificationToken): Promise<AuthJsVerificationToken>;
73
+ useVerificationToken(params: {
74
+ identifier: string;
75
+ token: string;
76
+ }): Promise<AuthJsVerificationToken | null>;
77
+ }
78
+ /** Where the adapter keeps its tables, and how it makes ids. */
79
+ export interface AuthJsAdapterOptions {
80
+ /** Put before each table name: `<prefix>users`, `<prefix>accounts`, `<prefix>sessions`, `<prefix>verification_tokens`. Default `auth_`. */
81
+ tablePrefix?: string;
82
+ /** Makes a user or account id when Auth.js passes none. Default: `crypto.randomUUID()`. */
83
+ generateId?: () => string;
84
+ }
85
+ /**
86
+ * The statements that create the adapter's tables and indexes on `db`'s
87
+ * engine, each `IF NOT EXISTS`, for a migration file or for
88
+ * ensureAuthJsTables.
89
+ */
90
+ export declare function authJsTablesSql(db: StorageAdapter, options?: AuthJsAdapterOptions): string[];
91
+ /** Creates the adapter's tables and indexes on `db` when they are missing. */
92
+ export declare function ensureAuthJsTables(db: StorageAdapter, options?: AuthJsAdapterOptions): Promise<void>;
93
+ /**
94
+ * An Auth.js database adapter that keeps users, accounts, sessions and
95
+ * verification tokens in `db`, on PostgreSQL or SQLite. Create the tables
96
+ * first with ensureAuthJsTables (or authJsTablesSql in a migration).
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import NextAuth from 'next-auth';
101
+ * import { createDatabase } from '@framers/sql-storage-adapter';
102
+ * import { createAuthJsAdapter, ensureAuthJsTables } from '@framers/sql-storage-adapter/authjs';
103
+ *
104
+ * const db = await createDatabase({ url: process.env.DATABASE_URL, strict: true });
105
+ * await ensureAuthJsTables(db);
106
+ * export const { handlers, auth } = NextAuth({ adapter: createAuthJsAdapter(db), providers: [] });
107
+ * ```
108
+ */
109
+ export declare function createAuthJsAdapter(db: StorageAdapter, options?: AuthJsAdapterOptions): AuthJsAdapter;
110
+ //# sourceMappingURL=authJsAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authJsAdapter.d.ts","sourceRoot":"","sources":["../../../src/features/auth/authJsAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,248 @@
1
+ import { createStorageFeatures } from '../../core/contracts/features.js';
2
+ const PREFIX = /^[A-Za-z_][A-Za-z0-9_]*$/;
3
+ const tablesFor = (options) => {
4
+ const prefix = options.tablePrefix ?? 'auth_';
5
+ if (!PREFIX.test(prefix)) {
6
+ throw new Error(`tablePrefix must be letters, digits and underscores, starting with a letter or an underscore; got ${JSON.stringify(prefix)}.`);
7
+ }
8
+ return {
9
+ users: `${prefix}users`,
10
+ accounts: `${prefix}accounts`,
11
+ sessions: `${prefix}sessions`,
12
+ verificationTokens: `${prefix}verification_tokens`,
13
+ };
14
+ };
15
+ /**
16
+ * The statements that create the adapter's tables and indexes on `db`'s
17
+ * engine, each `IF NOT EXISTS`, for a migration file or for
18
+ * ensureAuthJsTables.
19
+ */
20
+ export function authJsTablesSql(db, options = {}) {
21
+ const t = tablesFor(options);
22
+ const d = createStorageFeatures(db).dialect;
23
+ const timestamp = d.columnType('timestamp');
24
+ return [
25
+ `CREATE TABLE IF NOT EXISTS ${t.users} (id TEXT PRIMARY KEY, name TEXT, email TEXT UNIQUE, email_verified ${timestamp}, image TEXT)`,
26
+ `CREATE TABLE IF NOT EXISTS ${t.accounts} (
27
+ id TEXT PRIMARY KEY,
28
+ user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE,
29
+ type TEXT NOT NULL,
30
+ provider TEXT NOT NULL,
31
+ provider_account_id TEXT NOT NULL,
32
+ refresh_token TEXT,
33
+ access_token TEXT,
34
+ expires_at ${d.columnType('bigint')},
35
+ token_type TEXT,
36
+ scope TEXT,
37
+ id_token TEXT,
38
+ session_state TEXT,
39
+ UNIQUE (provider, provider_account_id)
40
+ )`,
41
+ `CREATE TABLE IF NOT EXISTS ${t.sessions} (session_token TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE, expires ${timestamp} NOT NULL)`,
42
+ `CREATE TABLE IF NOT EXISTS ${t.verificationTokens} (identifier TEXT NOT NULL, token TEXT NOT NULL, expires ${timestamp} NOT NULL, PRIMARY KEY (identifier, token))`,
43
+ `CREATE INDEX IF NOT EXISTS ${t.accounts}_user_id ON ${t.accounts} (user_id)`,
44
+ `CREATE INDEX IF NOT EXISTS ${t.sessions}_user_id ON ${t.sessions} (user_id)`,
45
+ ];
46
+ }
47
+ /** Creates the adapter's tables and indexes on `db` when they are missing. */
48
+ export async function ensureAuthJsTables(db, options = {}) {
49
+ for (const statement of authJsTablesSql(db, options)) {
50
+ await db.exec(statement);
51
+ }
52
+ }
53
+ /** A stored time as a Date: PostgreSQL returns one, SQLite ISO 8601 text. */
54
+ const toDate = (value) => value == null ? null : value instanceof Date ? value : new Date(String(value));
55
+ const toUser = (row) => ({
56
+ id: String(row.id),
57
+ name: row.name ?? null,
58
+ email: row.email,
59
+ emailVerified: toDate(row.email_verified),
60
+ image: row.image ?? null,
61
+ });
62
+ const toAccount = (row) => {
63
+ const account = {
64
+ userId: String(row.user_id),
65
+ type: row.type,
66
+ provider: row.provider,
67
+ providerAccountId: row.provider_account_id,
68
+ };
69
+ for (const field of ['refresh_token', 'access_token', 'token_type', 'scope', 'id_token', 'session_state']) {
70
+ if (row[field] != null)
71
+ account[field] = String(row[field]);
72
+ }
73
+ // PostgreSQL returns a BIGINT as text.
74
+ if (row.expires_at != null)
75
+ account.expires_at = Number(row.expires_at);
76
+ return account;
77
+ };
78
+ const toSession = (row) => ({
79
+ sessionToken: row.session_token,
80
+ userId: String(row.user_id),
81
+ expires: toDate(row.expires),
82
+ });
83
+ const toVerificationToken = (row) => ({
84
+ identifier: row.identifier,
85
+ token: row.token,
86
+ expires: toDate(row.expires),
87
+ });
88
+ const defaultId = () => {
89
+ const random = globalThis.crypto?.randomUUID;
90
+ if (!random)
91
+ throw new Error('crypto.randomUUID() is not available; pass generateId.');
92
+ return random.call(globalThis.crypto);
93
+ };
94
+ /**
95
+ * An Auth.js database adapter that keeps users, accounts, sessions and
96
+ * verification tokens in `db`, on PostgreSQL or SQLite. Create the tables
97
+ * first with ensureAuthJsTables (or authJsTablesSql in a migration).
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * import NextAuth from 'next-auth';
102
+ * import { createDatabase } from '@framers/sql-storage-adapter';
103
+ * import { createAuthJsAdapter, ensureAuthJsTables } from '@framers/sql-storage-adapter/authjs';
104
+ *
105
+ * const db = await createDatabase({ url: process.env.DATABASE_URL, strict: true });
106
+ * await ensureAuthJsTables(db);
107
+ * export const { handlers, auth } = NextAuth({ adapter: createAuthJsAdapter(db), providers: [] });
108
+ * ```
109
+ */
110
+ export function createAuthJsAdapter(db, options = {}) {
111
+ const t = tablesFor(options);
112
+ const generateId = options.generateId ?? defaultId;
113
+ const getUser = async (id) => {
114
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE id = ?`, [id]);
115
+ return row ? toUser(row) : null;
116
+ };
117
+ const getSession = async (sessionToken) => {
118
+ const row = await db.get(`SELECT * FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
119
+ return row ? toSession(row) : null;
120
+ };
121
+ return {
122
+ async createUser(user) {
123
+ const id = user.id ?? generateId();
124
+ await db.run(`INSERT INTO ${t.users} (id, name, email, email_verified, image) VALUES (?, ?, ?, ?, ?)`, [
125
+ id,
126
+ user.name ?? null,
127
+ user.email,
128
+ user.emailVerified ?? null,
129
+ user.image ?? null,
130
+ ]);
131
+ return (await getUser(id));
132
+ },
133
+ getUser,
134
+ async getUserByEmail(email) {
135
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE email = ?`, [email]);
136
+ return row ? toUser(row) : null;
137
+ },
138
+ async getUserByAccount({ provider, providerAccountId }) {
139
+ const row = await db.get(`SELECT u.* FROM ${t.users} u JOIN ${t.accounts} a ON a.user_id = u.id WHERE a.provider = ? AND a.provider_account_id = ?`, [provider, providerAccountId]);
140
+ return row ? toUser(row) : null;
141
+ },
142
+ async updateUser(user) {
143
+ const fields = [];
144
+ if ('name' in user)
145
+ fields.push(['name', user.name ?? null]);
146
+ if ('email' in user)
147
+ fields.push(['email', user.email]);
148
+ if ('emailVerified' in user)
149
+ fields.push(['email_verified', user.emailVerified ?? null]);
150
+ if ('image' in user)
151
+ fields.push(['image', user.image ?? null]);
152
+ if (fields.length) {
153
+ await db.run(`UPDATE ${t.users} SET ${fields.map(([column]) => `${column} = ?`).join(', ')} WHERE id = ?`, [
154
+ ...fields.map(([, value]) => value),
155
+ user.id,
156
+ ]);
157
+ }
158
+ const updated = await getUser(user.id);
159
+ if (!updated)
160
+ throw new Error(`No user with id ${JSON.stringify(user.id)} to update.`);
161
+ return updated;
162
+ },
163
+ async deleteUser(userId) {
164
+ // Explicit deletes: sql.js and IndexedDB leave foreign keys off, so ON DELETE CASCADE would not run there.
165
+ return db.transaction(async (trx) => {
166
+ const row = await trx.get(`SELECT * FROM ${t.users} WHERE id = ?`, [userId]);
167
+ await trx.run(`DELETE FROM ${t.sessions} WHERE user_id = ?`, [userId]);
168
+ await trx.run(`DELETE FROM ${t.accounts} WHERE user_id = ?`, [userId]);
169
+ await trx.run(`DELETE FROM ${t.users} WHERE id = ?`, [userId]);
170
+ return row ? toUser(row) : null;
171
+ });
172
+ },
173
+ async linkAccount(account) {
174
+ await db.run(`INSERT INTO ${t.accounts} (id, user_id, type, provider, provider_account_id, refresh_token, access_token, expires_at, token_type, scope, id_token, session_state)
175
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
176
+ generateId(),
177
+ account.userId,
178
+ account.type,
179
+ account.provider,
180
+ account.providerAccountId,
181
+ account.refresh_token ?? null,
182
+ account.access_token ?? null,
183
+ account.expires_at ?? null,
184
+ account.token_type ?? null,
185
+ account.scope ?? null,
186
+ account.id_token ?? null,
187
+ account.session_state ?? null,
188
+ ]);
189
+ return account;
190
+ },
191
+ async unlinkAccount({ provider, providerAccountId }) {
192
+ await db.run(`DELETE FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [provider, providerAccountId]);
193
+ },
194
+ async getAccount(providerAccountId, provider) {
195
+ const row = await db.get(`SELECT * FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [
196
+ provider,
197
+ providerAccountId,
198
+ ]);
199
+ return row ? toAccount(row) : null;
200
+ },
201
+ async createSession(session) {
202
+ await db.run(`INSERT INTO ${t.sessions} (session_token, user_id, expires) VALUES (?, ?, ?)`, [
203
+ session.sessionToken,
204
+ session.userId,
205
+ session.expires,
206
+ ]);
207
+ return { sessionToken: session.sessionToken, userId: session.userId, expires: session.expires };
208
+ },
209
+ async getSessionAndUser(sessionToken) {
210
+ const session = await getSession(sessionToken);
211
+ if (!session)
212
+ return null;
213
+ const user = await getUser(session.userId);
214
+ return user ? { session, user } : null;
215
+ },
216
+ async updateSession(session) {
217
+ const fields = [];
218
+ if (session.expires !== undefined)
219
+ fields.push(['expires', session.expires]);
220
+ if (session.userId !== undefined)
221
+ fields.push(['user_id', session.userId]);
222
+ if (fields.length) {
223
+ await db.run(`UPDATE ${t.sessions} SET ${fields.map(([column]) => `${column} = ?`).join(', ')} WHERE session_token = ?`, [
224
+ ...fields.map(([, value]) => value),
225
+ session.sessionToken,
226
+ ]);
227
+ }
228
+ return getSession(session.sessionToken);
229
+ },
230
+ async deleteSession(sessionToken) {
231
+ await db.run(`DELETE FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
232
+ },
233
+ async createVerificationToken(token) {
234
+ await db.run(`INSERT INTO ${t.verificationTokens} (identifier, token, expires) VALUES (?, ?, ?)`, [
235
+ token.identifier,
236
+ token.token,
237
+ token.expires,
238
+ ]);
239
+ return { identifier: token.identifier, token: token.token, expires: token.expires };
240
+ },
241
+ async useVerificationToken({ identifier, token }) {
242
+ // One statement: a token is used once, however many requests race for it.
243
+ const row = await db.get(`DELETE FROM ${t.verificationTokens} WHERE identifier = ? AND token = ? RETURNING identifier, token, expires`, [identifier, token]);
244
+ return row ? toVerificationToken(row) : null;
245
+ },
246
+ };
247
+ }
248
+ //# sourceMappingURL=authJsAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authJsAdapter.js","sourceRoot":"","sources":["../../../src/features/auth/authJsAdapter.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * from './features/migrations/dataExport.js';
13
13
  export * from './features/migrations/dataImport.js';
14
14
  export * from './features/migrations/migration.js';
15
15
  export * from './features/migrations/schemaMigrations.js';
16
+ export * from './features/auth/authJsAdapter.js';
16
17
  export * from './features/sync/syncManager.js';
17
18
  export * from './shared/parameterUtils.js';
18
19
  export { segmentFilePath, segmentName, validateSegment } from './shared/segment.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAQ9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAM5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAQ9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAM5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ export * from './features/migrations/dataExport.js';
21
21
  export * from './features/migrations/dataImport.js';
22
22
  export * from './features/migrations/migration.js';
23
23
  export * from './features/migrations/schemaMigrations.js';
24
+ export * from './features/auth/authJsAdapter.js';
24
25
  export * from './features/sync/syncManager.js';
25
26
  // Note: Cross-platform sync is available via separate entry point for cleaner imports.
26
27
  // Usage: import { createCrossPlatformSync } from '@framers/sql-storage-adapter/sync';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,SAAS,CAAC;AAExB,8EAA8E;AAC9E,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,+EAA+E;AAC/E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAE9C,wEAAwE;AACxE,yDAAyD;AACzD,2HAA2H;AAC3H,mEAAmE;AAEnE,+EAA+E;AAC/E,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAE5C,uFAAuF;AACvF,sFAAsF;AAEtF,+EAA+E;AAC/E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF,6FAA6F;AAC7F,uGAAuG;AAEvG,iFAAiF;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,SAAS,CAAC;AAExB,8EAA8E;AAC9E,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,+EAA+E;AAC/E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAE9C,wEAAwE;AACxE,yDAAyD;AACzD,2HAA2H;AAC3H,mEAAmE;AAEnE,+EAA+E;AAC/E,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAE5C,uFAAuF;AACvF,sFAAsF;AAEtF,+EAA+E;AAC/E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF,6FAA6F;AAC7F,uGAAuG;AAEvG,iFAAiF;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/sql-storage-adapter",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Robust cross-platform SQL storage abstraction with automatic fallbacks and runtime detection",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",
@@ -87,6 +87,16 @@
87
87
  "default": "./dist/cjs/features/backup/cloudBackup.js"
88
88
  }
89
89
  },
90
+ "./authjs": {
91
+ "import": {
92
+ "types": "./dist/features/auth/authJsAdapter.d.ts",
93
+ "default": "./dist/features/auth/authJsAdapter.js"
94
+ },
95
+ "require": {
96
+ "types": "./dist/cjs/features/auth/authJsAdapter.d.ts",
97
+ "default": "./dist/cjs/features/auth/authJsAdapter.js"
98
+ }
99
+ },
90
100
  "./types": {
91
101
  "import": {
92
102
  "types": "./dist/types/index.d.ts",