@usebetterdev/console 0.3.0-beta.2

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.
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/drizzle.ts
21
+ var drizzle_exports = {};
22
+ __export(drizzle_exports, {
23
+ consoleMagicLinksTable: () => consoleMagicLinksTable,
24
+ consoleSessionsTable: () => consoleSessionsTable,
25
+ createConsoleMagicLinkRepository: () => createConsoleMagicLinkRepository,
26
+ createConsoleSessionRepository: () => createConsoleSessionRepository,
27
+ drizzleConsoleAdapter: () => drizzleConsoleAdapter
28
+ });
29
+ module.exports = __toCommonJS(drizzle_exports);
30
+
31
+ // src/drizzle/repository.ts
32
+ var import_drizzle_orm = require("drizzle-orm");
33
+
34
+ // src/drizzle/schema.ts
35
+ var import_pg_core = require("drizzle-orm/pg-core");
36
+ var consoleSessionsTable = (0, import_pg_core.pgTable)("better_console_sessions", {
37
+ id: (0, import_pg_core.uuid)("id").primaryKey().defaultRandom(),
38
+ email: (0, import_pg_core.text)("email").notNull(),
39
+ tokenHash: (0, import_pg_core.text)("token_hash").notNull().unique(),
40
+ permissions: (0, import_pg_core.text)("permissions").notNull(),
41
+ expiresAt: (0, import_pg_core.timestamp)("expires_at", { withTimezone: true }).notNull(),
42
+ createdAt: (0, import_pg_core.timestamp)("created_at", { withTimezone: true }).defaultNow().notNull()
43
+ });
44
+ var consoleMagicLinksTable = (0, import_pg_core.pgTable)("better_console_magic_links", {
45
+ id: (0, import_pg_core.uuid)("id").primaryKey().defaultRandom(),
46
+ email: (0, import_pg_core.text)("email").notNull(),
47
+ codeHash: (0, import_pg_core.text)("code_hash").notNull(),
48
+ sessionId: (0, import_pg_core.uuid)("session_id").notNull().unique(),
49
+ tokenHash: (0, import_pg_core.text)("token_hash"),
50
+ failedAttempts: (0, import_pg_core.integer)("failed_attempts").notNull().default(0),
51
+ expiresAt: (0, import_pg_core.timestamp)("expires_at", { withTimezone: true }).notNull(),
52
+ usedAt: (0, import_pg_core.timestamp)("used_at", { withTimezone: true }),
53
+ createdAt: (0, import_pg_core.timestamp)("created_at", { withTimezone: true }).defaultNow().notNull()
54
+ });
55
+
56
+ // src/drizzle/repository.ts
57
+ var VALID_PERMISSIONS = /* @__PURE__ */ new Set(["read", "write", "admin"]);
58
+ function parsePermission(value) {
59
+ const str = String(value);
60
+ if (!VALID_PERMISSIONS.has(str)) {
61
+ throw new Error(
62
+ `better-console: invalid permission "${str}", expected one of: read, write, admin`
63
+ );
64
+ }
65
+ return str;
66
+ }
67
+ function toDate(value) {
68
+ if (value instanceof Date) {
69
+ return value;
70
+ }
71
+ return new Date(String(value));
72
+ }
73
+ function toDateOrNull(value) {
74
+ if (value === null || value === void 0) {
75
+ return null;
76
+ }
77
+ return toDate(value);
78
+ }
79
+ function rowToSession(row) {
80
+ const createdAt = row.createdAt ?? row.created_at;
81
+ const expiresAt = row.expiresAt ?? row.expires_at;
82
+ if (createdAt === void 0 || createdAt === null) {
83
+ throw new Error("better-console: session row missing created_at / createdAt");
84
+ }
85
+ if (expiresAt === void 0 || expiresAt === null) {
86
+ throw new Error("better-console: session row missing expires_at / expiresAt");
87
+ }
88
+ return {
89
+ id: String(row.id),
90
+ email: String(row.email),
91
+ permissions: parsePermission(row.permissions),
92
+ expiresAt: toDate(expiresAt),
93
+ createdAt: toDate(createdAt)
94
+ };
95
+ }
96
+ function rowToMagicLink(row) {
97
+ const createdAt = row.createdAt ?? row.created_at;
98
+ const expiresAt = row.expiresAt ?? row.expires_at;
99
+ const usedAt = row.usedAt ?? row.used_at;
100
+ const codeHash = row.codeHash ?? row.code_hash;
101
+ const sessionId = row.sessionId ?? row.session_id;
102
+ const tokenHash = row.tokenHash ?? row.token_hash;
103
+ const failedAttempts = row.failedAttempts ?? row.failed_attempts;
104
+ if (createdAt === void 0 || createdAt === null) {
105
+ throw new Error("better-console: magic link row missing created_at / createdAt");
106
+ }
107
+ if (expiresAt === void 0 || expiresAt === null) {
108
+ throw new Error("better-console: magic link row missing expires_at / expiresAt");
109
+ }
110
+ return {
111
+ id: String(row.id),
112
+ email: String(row.email),
113
+ codeHash: String(codeHash),
114
+ sessionId: String(sessionId),
115
+ tokenHash: tokenHash === null || tokenHash === void 0 ? null : String(tokenHash),
116
+ failedAttempts: typeof failedAttempts === "number" ? failedAttempts : Number(failedAttempts ?? 0),
117
+ expiresAt: toDate(expiresAt),
118
+ usedAt: toDateOrNull(usedAt),
119
+ createdAt: toDate(createdAt)
120
+ };
121
+ }
122
+ function createConsoleSessionRepository(database, table = consoleSessionsTable) {
123
+ return {
124
+ async createSession(data) {
125
+ const rows = await database.insert(table).values({
126
+ email: data.email,
127
+ tokenHash: data.tokenHash,
128
+ permissions: data.permissions,
129
+ expiresAt: data.expiresAt
130
+ }).returning();
131
+ const row = rows[0];
132
+ if (!row || typeof row !== "object") {
133
+ throw new Error("better-console: createSession failed to return row");
134
+ }
135
+ return rowToSession(row);
136
+ },
137
+ async getSessionByTokenHash(tokenHash) {
138
+ const rows = await database.select().from(table).where((0, import_drizzle_orm.eq)(table.tokenHash, tokenHash)).limit(1);
139
+ const row = Array.isArray(rows) ? rows[0] : void 0;
140
+ if (!row || typeof row !== "object") {
141
+ return null;
142
+ }
143
+ return rowToSession(row);
144
+ },
145
+ async deleteSession(sessionId) {
146
+ await database.delete(table).where((0, import_drizzle_orm.eq)(table.id, sessionId));
147
+ },
148
+ async deleteAllSessions() {
149
+ await database.delete(table);
150
+ },
151
+ async deleteExpiredSessions() {
152
+ await database.delete(table).where((0, import_drizzle_orm.lt)(table.expiresAt, /* @__PURE__ */ new Date()));
153
+ }
154
+ };
155
+ }
156
+ function createConsoleMagicLinkRepository(database, table = consoleMagicLinksTable) {
157
+ return {
158
+ async createMagicLink(data) {
159
+ const rows = await database.insert(table).values({
160
+ email: data.email,
161
+ codeHash: data.codeHash,
162
+ sessionId: data.sessionId,
163
+ expiresAt: data.expiresAt
164
+ }).returning();
165
+ const row = rows[0];
166
+ if (!row || typeof row !== "object") {
167
+ throw new Error("better-console: createMagicLink failed to return row");
168
+ }
169
+ return rowToMagicLink(row);
170
+ },
171
+ async getMagicLinkBySessionId(sessionId) {
172
+ const rows = await database.select().from(table).where((0, import_drizzle_orm.eq)(table.sessionId, sessionId)).limit(1);
173
+ const row = Array.isArray(rows) ? rows[0] : void 0;
174
+ if (!row || typeof row !== "object") {
175
+ return null;
176
+ }
177
+ return rowToMagicLink(row);
178
+ },
179
+ async markMagicLinkUsed(id) {
180
+ await database.update(table).set({ usedAt: /* @__PURE__ */ new Date() }).where((0, import_drizzle_orm.eq)(table.id, id)).returning();
181
+ },
182
+ async setMagicLinkTokenHash(id, tokenHash) {
183
+ const rows = await database.update(table).set({ tokenHash }).where((0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(table.id, id), (0, import_drizzle_orm.isNull)(table.tokenHash))).returning();
184
+ return rows.length > 0;
185
+ },
186
+ async clearMagicLinkTokenHash(id) {
187
+ await database.update(table).set({ tokenHash: null }).where((0, import_drizzle_orm.eq)(table.id, id)).returning();
188
+ },
189
+ async incrementFailedAttempts(id) {
190
+ const rows = await database.update(table).set({ failedAttempts: import_drizzle_orm.sql`${table.failedAttempts} + 1` }).where((0, import_drizzle_orm.eq)(table.id, id)).returning();
191
+ const row = rows[0];
192
+ if (!row || typeof row !== "object") {
193
+ return 0;
194
+ }
195
+ const record = row;
196
+ const failedAttempts = record.failedAttempts ?? record.failed_attempts;
197
+ return typeof failedAttempts === "number" ? failedAttempts : Number(failedAttempts ?? 0);
198
+ },
199
+ async deleteExpiredMagicLinks() {
200
+ await database.delete(table).where((0, import_drizzle_orm.lt)(table.expiresAt, /* @__PURE__ */ new Date()));
201
+ }
202
+ };
203
+ }
204
+
205
+ // src/drizzle/adapter.ts
206
+ function drizzleConsoleAdapter(database, options) {
207
+ return {
208
+ sessions: createConsoleSessionRepository(database, options?.sessionsTable),
209
+ magicLinks: createConsoleMagicLinkRepository(database, options?.magicLinksTable)
210
+ };
211
+ }
212
+ // Annotate the CommonJS export names for ESM import in node:
213
+ 0 && (module.exports = {
214
+ consoleMagicLinksTable,
215
+ consoleSessionsTable,
216
+ createConsoleMagicLinkRepository,
217
+ createConsoleSessionRepository,
218
+ drizzleConsoleAdapter
219
+ });
220
+ //# sourceMappingURL=drizzle.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/drizzle.ts","../src/drizzle/repository.ts","../src/drizzle/schema.ts","../src/drizzle/adapter.ts"],"sourcesContent":["// @usebetterdev/console/drizzle — Drizzle adapter entry point\n\nexport { drizzleConsoleAdapter } from \"./drizzle/adapter.js\";\nexport type { DrizzleConsoleAdapterOptions } from \"./drizzle/adapter.js\";\n\nexport {\n consoleSessionsTable,\n consoleMagicLinksTable,\n} from \"./drizzle/schema.js\";\n\nexport {\n createConsoleSessionRepository,\n createConsoleMagicLinkRepository,\n} from \"./drizzle/repository.js\";\nexport type {\n DrizzleLikeDatabase,\n ConsoleSessionsTableLike,\n ConsoleMagicLinksTableLike,\n} from \"./drizzle/repository.js\";\n","import { and, eq, isNull, lt, sql } from \"drizzle-orm\";\nimport type {\n ConsoleSession,\n ConsolePermission,\n ConsoleSessionRepository,\n ConsoleMagicLink,\n ConsoleMagicLinkRepository,\n} from \"../types.js\";\nimport {\n consoleSessionsTable,\n consoleMagicLinksTable,\n} from \"./schema.js\";\n\n// ---------------------------------------------------------------------------\n// Table type aliases\n// ---------------------------------------------------------------------------\n\nexport type ConsoleSessionsTableLike = typeof consoleSessionsTable;\nexport type ConsoleMagicLinksTableLike = typeof consoleMagicLinksTable;\n\n// ---------------------------------------------------------------------------\n// Permissions validation\n// ---------------------------------------------------------------------------\n\nconst VALID_PERMISSIONS = new Set<string>([\"read\", \"write\", \"admin\"]);\n\nfunction parsePermission(value: unknown): ConsolePermission {\n const str = String(value);\n if (!VALID_PERMISSIONS.has(str)) {\n throw new Error(\n `better-console: invalid permission \"${str}\", expected one of: read, write, admin`,\n );\n }\n return str as ConsolePermission;\n}\n\n// ---------------------------------------------------------------------------\n// Date coercion helpers\n// ---------------------------------------------------------------------------\n\nfunction toDate(value: unknown): Date {\n if (value instanceof Date) {\n return value;\n }\n return new Date(String(value));\n}\n\nfunction toDateOrNull(value: unknown): Date | null {\n if (value === null || value === undefined) {\n return null;\n }\n return toDate(value);\n}\n\n// ---------------------------------------------------------------------------\n// Row → domain mappers\n// ---------------------------------------------------------------------------\n\n/**\n * Maps a database row to ConsoleSession.\n * tokenHash is intentionally omitted — the domain type doesn't include it,\n * and the hash should not leave the persistence layer.\n */\nfunction rowToSession(row: Record<string, unknown>): ConsoleSession {\n const createdAt = row.createdAt ?? row.created_at;\n const expiresAt = row.expiresAt ?? row.expires_at;\n if (createdAt === undefined || createdAt === null) {\n throw new Error(\"better-console: session row missing created_at / createdAt\");\n }\n if (expiresAt === undefined || expiresAt === null) {\n throw new Error(\"better-console: session row missing expires_at / expiresAt\");\n }\n return {\n id: String(row.id),\n email: String(row.email),\n permissions: parsePermission(row.permissions),\n expiresAt: toDate(expiresAt),\n createdAt: toDate(createdAt),\n };\n}\n\nfunction rowToMagicLink(row: Record<string, unknown>): ConsoleMagicLink {\n const createdAt = row.createdAt ?? row.created_at;\n const expiresAt = row.expiresAt ?? row.expires_at;\n const usedAt = row.usedAt ?? row.used_at;\n const codeHash = row.codeHash ?? row.code_hash;\n const sessionId = row.sessionId ?? row.session_id;\n const tokenHash = row.tokenHash ?? row.token_hash;\n const failedAttempts = row.failedAttempts ?? row.failed_attempts;\n if (createdAt === undefined || createdAt === null) {\n throw new Error(\"better-console: magic link row missing created_at / createdAt\");\n }\n if (expiresAt === undefined || expiresAt === null) {\n throw new Error(\"better-console: magic link row missing expires_at / expiresAt\");\n }\n return {\n id: String(row.id),\n email: String(row.email),\n codeHash: String(codeHash),\n sessionId: String(sessionId),\n tokenHash: tokenHash === null || tokenHash === undefined ? null : String(tokenHash),\n failedAttempts: typeof failedAttempts === \"number\" ? failedAttempts : Number(failedAttempts ?? 0),\n expiresAt: toDate(expiresAt),\n usedAt: toDateOrNull(usedAt),\n createdAt: toDate(createdAt),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Duck-typed Drizzle database interface\n// ---------------------------------------------------------------------------\n\ntype SessionInsertValues = {\n email: string;\n tokenHash: string;\n permissions: string;\n expiresAt: Date;\n};\n\ntype MagicLinkInsertValues = {\n email: string;\n codeHash: string;\n sessionId: string;\n expiresAt: Date;\n};\n\nexport interface DrizzleLikeDatabase {\n insert: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {\n values: (v: SessionInsertValues | MagicLinkInsertValues) => {\n returning: () => Promise<unknown[]>;\n };\n };\n update: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {\n set: (v: Record<string, unknown>) => {\n where: (c: unknown) => {\n returning: () => Promise<unknown[]>;\n };\n };\n };\n select: () => {\n from: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {\n where: (c: unknown) => {\n limit: (n: number) => Promise<unknown[]>;\n };\n };\n };\n delete: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => Promise<unknown> & {\n where: (c: unknown) => Promise<unknown>;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Session repository\n// ---------------------------------------------------------------------------\n\nexport function createConsoleSessionRepository(\n database: DrizzleLikeDatabase,\n table: ConsoleSessionsTableLike = consoleSessionsTable,\n): ConsoleSessionRepository {\n return {\n async createSession(data) {\n const rows = await database\n .insert(table)\n .values({\n email: data.email,\n tokenHash: data.tokenHash,\n permissions: data.permissions,\n expiresAt: data.expiresAt,\n })\n .returning();\n const row = rows[0];\n if (!row || typeof row !== \"object\") {\n throw new Error(\"better-console: createSession failed to return row\");\n }\n return rowToSession(row as Record<string, unknown>);\n },\n\n async getSessionByTokenHash(tokenHash) {\n const rows = await database\n .select()\n .from(table)\n .where(eq(table.tokenHash, tokenHash))\n .limit(1);\n const row = Array.isArray(rows) ? rows[0] : undefined;\n if (!row || typeof row !== \"object\") {\n return null;\n }\n return rowToSession(row as Record<string, unknown>);\n },\n\n async deleteSession(sessionId) {\n await database.delete(table).where(eq(table.id, sessionId));\n },\n\n async deleteAllSessions() {\n await database.delete(table);\n },\n\n async deleteExpiredSessions() {\n await database.delete(table).where(lt(table.expiresAt, new Date()));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Magic link repository\n// ---------------------------------------------------------------------------\n\nexport function createConsoleMagicLinkRepository(\n database: DrizzleLikeDatabase,\n table: ConsoleMagicLinksTableLike = consoleMagicLinksTable,\n): ConsoleMagicLinkRepository {\n return {\n async createMagicLink(data) {\n const rows = await database\n .insert(table)\n .values({\n email: data.email,\n codeHash: data.codeHash,\n sessionId: data.sessionId,\n expiresAt: data.expiresAt,\n })\n .returning();\n const row = rows[0];\n if (!row || typeof row !== \"object\") {\n throw new Error(\"better-console: createMagicLink failed to return row\");\n }\n return rowToMagicLink(row as Record<string, unknown>);\n },\n\n async getMagicLinkBySessionId(sessionId) {\n const rows = await database\n .select()\n .from(table)\n .where(eq(table.sessionId, sessionId))\n .limit(1);\n const row = Array.isArray(rows) ? rows[0] : undefined;\n if (!row || typeof row !== \"object\") {\n return null;\n }\n return rowToMagicLink(row as Record<string, unknown>);\n },\n\n async markMagicLinkUsed(id) {\n await database\n .update(table)\n .set({ usedAt: new Date() })\n .where(eq(table.id, id))\n .returning();\n },\n\n async setMagicLinkTokenHash(id, tokenHash) {\n const rows = await database\n .update(table)\n .set({ tokenHash })\n .where(and(eq(table.id, id), isNull(table.tokenHash)))\n .returning();\n return rows.length > 0;\n },\n\n async clearMagicLinkTokenHash(id) {\n await database\n .update(table)\n .set({ tokenHash: null })\n .where(eq(table.id, id))\n .returning();\n },\n\n async incrementFailedAttempts(id) {\n const rows = await database\n .update(table)\n .set({ failedAttempts: sql`${table.failedAttempts} + 1` })\n .where(eq(table.id, id))\n .returning();\n const row = rows[0];\n if (!row || typeof row !== \"object\") {\n return 0;\n }\n const record = row as Record<string, unknown>;\n const failedAttempts = record.failedAttempts ?? record.failed_attempts;\n return typeof failedAttempts === \"number\" ? failedAttempts : Number(failedAttempts ?? 0);\n },\n\n async deleteExpiredMagicLinks() {\n await database.delete(table).where(lt(table.expiresAt, new Date()));\n },\n };\n}\n","import { integer, pgTable, text, timestamp, uuid } from \"drizzle-orm/pg-core\";\n\n/**\n * Console sessions table — stores DB-backed sessions (magic link flow).\n * Auto-approve sessions use stateless JWTs and bypass this table entirely.\n */\nexport const consoleSessionsTable = pgTable(\"better_console_sessions\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n email: text(\"email\").notNull(),\n tokenHash: text(\"token_hash\").notNull().unique(),\n permissions: text(\"permissions\").notNull(),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }).notNull(),\n createdAt: timestamp(\"created_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n\n/**\n * Console magic links table — stores magic link codes for the\n * init → verify → claim session flow. The sessionId is a correlation\n * ID used for polling; the actual DB session is created at claim time.\n */\nexport const consoleMagicLinksTable = pgTable(\"better_console_magic_links\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n email: text(\"email\").notNull(),\n codeHash: text(\"code_hash\").notNull(),\n sessionId: uuid(\"session_id\").notNull().unique(),\n tokenHash: text(\"token_hash\"),\n failedAttempts: integer(\"failed_attempts\").notNull().default(0),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }).notNull(),\n usedAt: timestamp(\"used_at\", { withTimezone: true }),\n createdAt: timestamp(\"created_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n","import type { ConsoleAdapter } from \"../types.js\";\nimport {\n createConsoleSessionRepository,\n createConsoleMagicLinkRepository,\n} from \"./repository.js\";\nimport type {\n DrizzleLikeDatabase,\n ConsoleSessionsTableLike,\n ConsoleMagicLinksTableLike,\n} from \"./repository.js\";\n\nexport interface DrizzleConsoleAdapterOptions {\n /** Custom sessions table definition. Defaults to the built-in consoleSessionsTable. */\n sessionsTable?: ConsoleSessionsTableLike;\n /** Custom magic links table definition. Defaults to the built-in consoleMagicLinksTable. */\n magicLinksTable?: ConsoleMagicLinksTableLike;\n}\n\n/**\n * Creates a ConsoleAdapter backed by Drizzle ORM.\n *\n * ```ts\n * import { drizzleConsoleAdapter } from \"@usebetterdev/console/drizzle\";\n * import { db } from \"./db.js\";\n *\n * const adapter = drizzleConsoleAdapter(db);\n * const console = betterConsole({ adapter, ... });\n * ```\n */\nexport function drizzleConsoleAdapter(\n database: DrizzleLikeDatabase,\n options?: DrizzleConsoleAdapterOptions,\n): ConsoleAdapter {\n return {\n sessions: createConsoleSessionRepository(database, options?.sessionsTable),\n magicLinks: createConsoleMagicLinkRepository(database, options?.magicLinksTable),\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,343 @@
1
+ import { C as ConsoleMagicLinkRepository, a as ConsoleSessionRepository, b as ConsoleAdapter } from './types-Bm35VBpM.cjs';
2
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
3
+
4
+ /**
5
+ * Console sessions table — stores DB-backed sessions (magic link flow).
6
+ * Auto-approve sessions use stateless JWTs and bypass this table entirely.
7
+ */
8
+ declare const consoleSessionsTable: drizzle_orm_pg_core.PgTableWithColumns<{
9
+ name: "better_console_sessions";
10
+ schema: undefined;
11
+ columns: {
12
+ id: drizzle_orm_pg_core.PgColumn<{
13
+ name: "id";
14
+ tableName: "better_console_sessions";
15
+ dataType: "string";
16
+ columnType: "PgUUID";
17
+ data: string;
18
+ driverParam: string;
19
+ notNull: true;
20
+ hasDefault: true;
21
+ isPrimaryKey: true;
22
+ isAutoincrement: false;
23
+ hasRuntimeDefault: false;
24
+ enumValues: undefined;
25
+ baseColumn: never;
26
+ identity: undefined;
27
+ generated: undefined;
28
+ }, {}, {}>;
29
+ email: drizzle_orm_pg_core.PgColumn<{
30
+ name: "email";
31
+ tableName: "better_console_sessions";
32
+ dataType: "string";
33
+ columnType: "PgText";
34
+ data: string;
35
+ driverParam: string;
36
+ notNull: true;
37
+ hasDefault: false;
38
+ isPrimaryKey: false;
39
+ isAutoincrement: false;
40
+ hasRuntimeDefault: false;
41
+ enumValues: [string, ...string[]];
42
+ baseColumn: never;
43
+ identity: undefined;
44
+ generated: undefined;
45
+ }, {}, {}>;
46
+ tokenHash: drizzle_orm_pg_core.PgColumn<{
47
+ name: "token_hash";
48
+ tableName: "better_console_sessions";
49
+ dataType: "string";
50
+ columnType: "PgText";
51
+ data: string;
52
+ driverParam: string;
53
+ notNull: true;
54
+ hasDefault: false;
55
+ isPrimaryKey: false;
56
+ isAutoincrement: false;
57
+ hasRuntimeDefault: false;
58
+ enumValues: [string, ...string[]];
59
+ baseColumn: never;
60
+ identity: undefined;
61
+ generated: undefined;
62
+ }, {}, {}>;
63
+ permissions: drizzle_orm_pg_core.PgColumn<{
64
+ name: "permissions";
65
+ tableName: "better_console_sessions";
66
+ dataType: "string";
67
+ columnType: "PgText";
68
+ data: string;
69
+ driverParam: string;
70
+ notNull: true;
71
+ hasDefault: false;
72
+ isPrimaryKey: false;
73
+ isAutoincrement: false;
74
+ hasRuntimeDefault: false;
75
+ enumValues: [string, ...string[]];
76
+ baseColumn: never;
77
+ identity: undefined;
78
+ generated: undefined;
79
+ }, {}, {}>;
80
+ expiresAt: drizzle_orm_pg_core.PgColumn<{
81
+ name: "expires_at";
82
+ tableName: "better_console_sessions";
83
+ dataType: "date";
84
+ columnType: "PgTimestamp";
85
+ data: Date;
86
+ driverParam: string;
87
+ notNull: true;
88
+ hasDefault: false;
89
+ isPrimaryKey: false;
90
+ isAutoincrement: false;
91
+ hasRuntimeDefault: false;
92
+ enumValues: undefined;
93
+ baseColumn: never;
94
+ identity: undefined;
95
+ generated: undefined;
96
+ }, {}, {}>;
97
+ createdAt: drizzle_orm_pg_core.PgColumn<{
98
+ name: "created_at";
99
+ tableName: "better_console_sessions";
100
+ dataType: "date";
101
+ columnType: "PgTimestamp";
102
+ data: Date;
103
+ driverParam: string;
104
+ notNull: true;
105
+ hasDefault: true;
106
+ isPrimaryKey: false;
107
+ isAutoincrement: false;
108
+ hasRuntimeDefault: false;
109
+ enumValues: undefined;
110
+ baseColumn: never;
111
+ identity: undefined;
112
+ generated: undefined;
113
+ }, {}, {}>;
114
+ };
115
+ dialect: "pg";
116
+ }>;
117
+ /**
118
+ * Console magic links table — stores magic link codes for the
119
+ * init → verify → claim session flow. The sessionId is a correlation
120
+ * ID used for polling; the actual DB session is created at claim time.
121
+ */
122
+ declare const consoleMagicLinksTable: drizzle_orm_pg_core.PgTableWithColumns<{
123
+ name: "better_console_magic_links";
124
+ schema: undefined;
125
+ columns: {
126
+ id: drizzle_orm_pg_core.PgColumn<{
127
+ name: "id";
128
+ tableName: "better_console_magic_links";
129
+ dataType: "string";
130
+ columnType: "PgUUID";
131
+ data: string;
132
+ driverParam: string;
133
+ notNull: true;
134
+ hasDefault: true;
135
+ isPrimaryKey: true;
136
+ isAutoincrement: false;
137
+ hasRuntimeDefault: false;
138
+ enumValues: undefined;
139
+ baseColumn: never;
140
+ identity: undefined;
141
+ generated: undefined;
142
+ }, {}, {}>;
143
+ email: drizzle_orm_pg_core.PgColumn<{
144
+ name: "email";
145
+ tableName: "better_console_magic_links";
146
+ dataType: "string";
147
+ columnType: "PgText";
148
+ data: string;
149
+ driverParam: string;
150
+ notNull: true;
151
+ hasDefault: false;
152
+ isPrimaryKey: false;
153
+ isAutoincrement: false;
154
+ hasRuntimeDefault: false;
155
+ enumValues: [string, ...string[]];
156
+ baseColumn: never;
157
+ identity: undefined;
158
+ generated: undefined;
159
+ }, {}, {}>;
160
+ codeHash: drizzle_orm_pg_core.PgColumn<{
161
+ name: "code_hash";
162
+ tableName: "better_console_magic_links";
163
+ dataType: "string";
164
+ columnType: "PgText";
165
+ data: string;
166
+ driverParam: string;
167
+ notNull: true;
168
+ hasDefault: false;
169
+ isPrimaryKey: false;
170
+ isAutoincrement: false;
171
+ hasRuntimeDefault: false;
172
+ enumValues: [string, ...string[]];
173
+ baseColumn: never;
174
+ identity: undefined;
175
+ generated: undefined;
176
+ }, {}, {}>;
177
+ sessionId: drizzle_orm_pg_core.PgColumn<{
178
+ name: "session_id";
179
+ tableName: "better_console_magic_links";
180
+ dataType: "string";
181
+ columnType: "PgUUID";
182
+ data: string;
183
+ driverParam: string;
184
+ notNull: true;
185
+ hasDefault: false;
186
+ isPrimaryKey: false;
187
+ isAutoincrement: false;
188
+ hasRuntimeDefault: false;
189
+ enumValues: undefined;
190
+ baseColumn: never;
191
+ identity: undefined;
192
+ generated: undefined;
193
+ }, {}, {}>;
194
+ tokenHash: drizzle_orm_pg_core.PgColumn<{
195
+ name: "token_hash";
196
+ tableName: "better_console_magic_links";
197
+ dataType: "string";
198
+ columnType: "PgText";
199
+ data: string;
200
+ driverParam: string;
201
+ notNull: false;
202
+ hasDefault: false;
203
+ isPrimaryKey: false;
204
+ isAutoincrement: false;
205
+ hasRuntimeDefault: false;
206
+ enumValues: [string, ...string[]];
207
+ baseColumn: never;
208
+ identity: undefined;
209
+ generated: undefined;
210
+ }, {}, {}>;
211
+ failedAttempts: drizzle_orm_pg_core.PgColumn<{
212
+ name: "failed_attempts";
213
+ tableName: "better_console_magic_links";
214
+ dataType: "number";
215
+ columnType: "PgInteger";
216
+ data: number;
217
+ driverParam: string | number;
218
+ notNull: true;
219
+ hasDefault: true;
220
+ isPrimaryKey: false;
221
+ isAutoincrement: false;
222
+ hasRuntimeDefault: false;
223
+ enumValues: undefined;
224
+ baseColumn: never;
225
+ identity: undefined;
226
+ generated: undefined;
227
+ }, {}, {}>;
228
+ expiresAt: drizzle_orm_pg_core.PgColumn<{
229
+ name: "expires_at";
230
+ tableName: "better_console_magic_links";
231
+ dataType: "date";
232
+ columnType: "PgTimestamp";
233
+ data: Date;
234
+ driverParam: string;
235
+ notNull: true;
236
+ hasDefault: false;
237
+ isPrimaryKey: false;
238
+ isAutoincrement: false;
239
+ hasRuntimeDefault: false;
240
+ enumValues: undefined;
241
+ baseColumn: never;
242
+ identity: undefined;
243
+ generated: undefined;
244
+ }, {}, {}>;
245
+ usedAt: drizzle_orm_pg_core.PgColumn<{
246
+ name: "used_at";
247
+ tableName: "better_console_magic_links";
248
+ dataType: "date";
249
+ columnType: "PgTimestamp";
250
+ data: Date;
251
+ driverParam: string;
252
+ notNull: false;
253
+ hasDefault: false;
254
+ isPrimaryKey: false;
255
+ isAutoincrement: false;
256
+ hasRuntimeDefault: false;
257
+ enumValues: undefined;
258
+ baseColumn: never;
259
+ identity: undefined;
260
+ generated: undefined;
261
+ }, {}, {}>;
262
+ createdAt: drizzle_orm_pg_core.PgColumn<{
263
+ name: "created_at";
264
+ tableName: "better_console_magic_links";
265
+ dataType: "date";
266
+ columnType: "PgTimestamp";
267
+ data: Date;
268
+ driverParam: string;
269
+ notNull: true;
270
+ hasDefault: true;
271
+ isPrimaryKey: false;
272
+ isAutoincrement: false;
273
+ hasRuntimeDefault: false;
274
+ enumValues: undefined;
275
+ baseColumn: never;
276
+ identity: undefined;
277
+ generated: undefined;
278
+ }, {}, {}>;
279
+ };
280
+ dialect: "pg";
281
+ }>;
282
+
283
+ type ConsoleSessionsTableLike = typeof consoleSessionsTable;
284
+ type ConsoleMagicLinksTableLike = typeof consoleMagicLinksTable;
285
+ type SessionInsertValues = {
286
+ email: string;
287
+ tokenHash: string;
288
+ permissions: string;
289
+ expiresAt: Date;
290
+ };
291
+ type MagicLinkInsertValues = {
292
+ email: string;
293
+ codeHash: string;
294
+ sessionId: string;
295
+ expiresAt: Date;
296
+ };
297
+ interface DrizzleLikeDatabase {
298
+ insert: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {
299
+ values: (v: SessionInsertValues | MagicLinkInsertValues) => {
300
+ returning: () => Promise<unknown[]>;
301
+ };
302
+ };
303
+ update: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {
304
+ set: (v: Record<string, unknown>) => {
305
+ where: (c: unknown) => {
306
+ returning: () => Promise<unknown[]>;
307
+ };
308
+ };
309
+ };
310
+ select: () => {
311
+ from: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => {
312
+ where: (c: unknown) => {
313
+ limit: (n: number) => Promise<unknown[]>;
314
+ };
315
+ };
316
+ };
317
+ delete: (table: ConsoleSessionsTableLike | ConsoleMagicLinksTableLike) => Promise<unknown> & {
318
+ where: (c: unknown) => Promise<unknown>;
319
+ };
320
+ }
321
+ declare function createConsoleSessionRepository(database: DrizzleLikeDatabase, table?: ConsoleSessionsTableLike): ConsoleSessionRepository;
322
+ declare function createConsoleMagicLinkRepository(database: DrizzleLikeDatabase, table?: ConsoleMagicLinksTableLike): ConsoleMagicLinkRepository;
323
+
324
+ interface DrizzleConsoleAdapterOptions {
325
+ /** Custom sessions table definition. Defaults to the built-in consoleSessionsTable. */
326
+ sessionsTable?: ConsoleSessionsTableLike;
327
+ /** Custom magic links table definition. Defaults to the built-in consoleMagicLinksTable. */
328
+ magicLinksTable?: ConsoleMagicLinksTableLike;
329
+ }
330
+ /**
331
+ * Creates a ConsoleAdapter backed by Drizzle ORM.
332
+ *
333
+ * ```ts
334
+ * import { drizzleConsoleAdapter } from "@usebetterdev/console/drizzle";
335
+ * import { db } from "./db.js";
336
+ *
337
+ * const adapter = drizzleConsoleAdapter(db);
338
+ * const console = betterConsole({ adapter, ... });
339
+ * ```
340
+ */
341
+ declare function drizzleConsoleAdapter(database: DrizzleLikeDatabase, options?: DrizzleConsoleAdapterOptions): ConsoleAdapter;
342
+
343
+ export { type ConsoleMagicLinksTableLike, type ConsoleSessionsTableLike, type DrizzleConsoleAdapterOptions, type DrizzleLikeDatabase, consoleMagicLinksTable, consoleSessionsTable, createConsoleMagicLinkRepository, createConsoleSessionRepository, drizzleConsoleAdapter };