@holeauth/passkey-drizzle 0.0.1-alpha.0

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 @@
1
+ {"version":3,"sources":["../../src/pg/index.ts"],"names":["pgTable","text","integer","timestamp","uniqueIndex","index","relations","eq"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n pgTable,\n text,\n integer,\n timestamp,\n uniqueIndex,\n index,\n type PgTableWithColumns,\n} from 'drizzle-orm/pg-core';\nimport { relations, eq } from 'drizzle-orm';\nimport type { PasskeyAdapter, PasskeyRecord } from '@holeauth/plugin-passkey';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PgUsersTable = PgTableWithColumns<any> & { id: any };\n\nexport interface CreatePasskeyTablesOptions<U extends PgUsersTable> {\n usersTable: U;\n prefix?: string;\n}\n\nexport function createPasskeyTables<U extends PgUsersTable>(opts: CreatePasskeyTablesOptions<U>) {\n const { usersTable, prefix = 'holeauth_passkey_' } = opts;\n const p = (s: string) => `${prefix}${s}`;\n const passkeys = pgTable(\n p('credential'),\n {\n id: text('id').primaryKey(),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n credentialId: text('credential_id').notNull(),\n publicKey: text('public_key').notNull(),\n counter: integer('counter').notNull().default(0),\n transports: text('transports').array(),\n deviceName: text('device_name'),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' }).notNull().defaultNow(),\n },\n (t) => ({\n credIdx: uniqueIndex().on(t.credentialId),\n userIdx: index().on(t.userId),\n }),\n );\n const passkeysRelations = relations(passkeys, ({ one }) => ({\n user: one(usersTable, { fields: [passkeys.userId], references: [usersTable.id] }),\n }));\n return { tables: { passkeys }, relations: { passkeysRelations } };\n}\n\ntype Tables = ReturnType<typeof createPasskeyTables>['tables'];\n\nexport interface CreatePasskeyAdapterOptions {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n db: any;\n tables: Tables;\n generateId?: () => string;\n}\n\nconst rowToRecord = (r: Record<string, unknown>): PasskeyRecord => ({\n id: String(r.id),\n userId: String(r.userId),\n credentialId: String(r.credentialId),\n publicKey: String(r.publicKey),\n counter: Number(r.counter),\n transports: (r.transports as string[] | null | undefined) ?? null,\n deviceName: (r.deviceName as string | null | undefined) ?? null,\n createdAt: r.createdAt as Date | undefined,\n});\n\nexport function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter {\n const { db, tables, generateId = () => crypto.randomUUID() } = opts;\n const { passkeys } = tables;\n return {\n async list(userId) {\n const rows = await db.select().from(passkeys).where(eq(passkeys.userId, userId));\n return (rows as Record<string, unknown>[]).map(rowToRecord);\n },\n async getByCredentialId(credentialId) {\n const rows = await db\n .select()\n .from(passkeys)\n .where(eq(passkeys.credentialId, credentialId))\n .limit(1);\n return rows[0] ? rowToRecord(rows[0]) : null;\n },\n async create(data) {\n const [row] = await db\n .insert(passkeys)\n .values({ id: generateId(), ...data })\n .returning();\n return rowToRecord(row);\n },\n async updateCounter(credentialId, counter) {\n await db.update(passkeys).set({ counter }).where(eq(passkeys.credentialId, credentialId));\n },\n async delete(id) {\n await db.delete(passkeys).where(eq(passkeys.id, id));\n },\n };\n}\n"]}
@@ -0,0 +1,189 @@
1
+ import * as drizzle_orm from 'drizzle-orm';
2
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
3
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
4
+ import { PasskeyAdapter } from '@holeauth/plugin-passkey';
5
+
6
+ type PgUsersTable = PgTableWithColumns<any> & {
7
+ id: any;
8
+ };
9
+ interface CreatePasskeyTablesOptions<U extends PgUsersTable> {
10
+ usersTable: U;
11
+ prefix?: string;
12
+ }
13
+ declare function createPasskeyTables<U extends PgUsersTable>(opts: CreatePasskeyTablesOptions<U>): {
14
+ tables: {
15
+ passkeys: PgTableWithColumns<{
16
+ name: string;
17
+ schema: undefined;
18
+ columns: {
19
+ id: drizzle_orm_pg_core.PgColumn<{
20
+ name: "id";
21
+ tableName: string;
22
+ dataType: "string";
23
+ columnType: "PgText";
24
+ data: string;
25
+ driverParam: string;
26
+ notNull: true;
27
+ hasDefault: false;
28
+ isPrimaryKey: true;
29
+ isAutoincrement: false;
30
+ hasRuntimeDefault: false;
31
+ enumValues: [string, ...string[]];
32
+ baseColumn: never;
33
+ identity: undefined;
34
+ generated: undefined;
35
+ }, {}, {}>;
36
+ userId: drizzle_orm_pg_core.PgColumn<{
37
+ name: "user_id";
38
+ tableName: string;
39
+ dataType: "string";
40
+ columnType: "PgText";
41
+ data: string;
42
+ driverParam: string;
43
+ notNull: true;
44
+ hasDefault: false;
45
+ isPrimaryKey: false;
46
+ isAutoincrement: false;
47
+ hasRuntimeDefault: false;
48
+ enumValues: [string, ...string[]];
49
+ baseColumn: never;
50
+ identity: undefined;
51
+ generated: undefined;
52
+ }, {}, {}>;
53
+ credentialId: drizzle_orm_pg_core.PgColumn<{
54
+ name: "credential_id";
55
+ tableName: string;
56
+ dataType: "string";
57
+ columnType: "PgText";
58
+ data: string;
59
+ driverParam: string;
60
+ notNull: true;
61
+ hasDefault: false;
62
+ isPrimaryKey: false;
63
+ isAutoincrement: false;
64
+ hasRuntimeDefault: false;
65
+ enumValues: [string, ...string[]];
66
+ baseColumn: never;
67
+ identity: undefined;
68
+ generated: undefined;
69
+ }, {}, {}>;
70
+ publicKey: drizzle_orm_pg_core.PgColumn<{
71
+ name: "public_key";
72
+ tableName: string;
73
+ dataType: "string";
74
+ columnType: "PgText";
75
+ data: string;
76
+ driverParam: string;
77
+ notNull: true;
78
+ hasDefault: false;
79
+ isPrimaryKey: false;
80
+ isAutoincrement: false;
81
+ hasRuntimeDefault: false;
82
+ enumValues: [string, ...string[]];
83
+ baseColumn: never;
84
+ identity: undefined;
85
+ generated: undefined;
86
+ }, {}, {}>;
87
+ counter: drizzle_orm_pg_core.PgColumn<{
88
+ name: "counter";
89
+ tableName: string;
90
+ dataType: "number";
91
+ columnType: "PgInteger";
92
+ data: number;
93
+ driverParam: string | number;
94
+ notNull: true;
95
+ hasDefault: true;
96
+ isPrimaryKey: false;
97
+ isAutoincrement: false;
98
+ hasRuntimeDefault: false;
99
+ enumValues: undefined;
100
+ baseColumn: never;
101
+ identity: undefined;
102
+ generated: undefined;
103
+ }, {}, {}>;
104
+ transports: drizzle_orm_pg_core.PgColumn<{
105
+ name: "transports";
106
+ tableName: string;
107
+ dataType: "array";
108
+ columnType: "PgArray";
109
+ data: string[];
110
+ driverParam: string | string[];
111
+ notNull: false;
112
+ hasDefault: false;
113
+ isPrimaryKey: false;
114
+ isAutoincrement: false;
115
+ hasRuntimeDefault: false;
116
+ enumValues: [string, ...string[]];
117
+ baseColumn: drizzle_orm.Column<{
118
+ name: "transports";
119
+ tableName: string;
120
+ dataType: "string";
121
+ columnType: "PgText";
122
+ data: string;
123
+ driverParam: string;
124
+ notNull: false;
125
+ hasDefault: false;
126
+ isPrimaryKey: false;
127
+ isAutoincrement: false;
128
+ hasRuntimeDefault: false;
129
+ enumValues: [string, ...string[]];
130
+ baseColumn: never;
131
+ identity: undefined;
132
+ generated: undefined;
133
+ }, object, object>;
134
+ identity: undefined;
135
+ generated: undefined;
136
+ }, {}, {}>;
137
+ deviceName: drizzle_orm_pg_core.PgColumn<{
138
+ name: "device_name";
139
+ tableName: string;
140
+ dataType: "string";
141
+ columnType: "PgText";
142
+ data: string;
143
+ driverParam: string;
144
+ notNull: false;
145
+ hasDefault: false;
146
+ isPrimaryKey: false;
147
+ isAutoincrement: false;
148
+ hasRuntimeDefault: false;
149
+ enumValues: [string, ...string[]];
150
+ baseColumn: never;
151
+ identity: undefined;
152
+ generated: undefined;
153
+ }, {}, {}>;
154
+ createdAt: drizzle_orm_pg_core.PgColumn<{
155
+ name: "created_at";
156
+ tableName: string;
157
+ dataType: "date";
158
+ columnType: "PgTimestamp";
159
+ data: Date;
160
+ driverParam: string;
161
+ notNull: true;
162
+ hasDefault: true;
163
+ isPrimaryKey: false;
164
+ isAutoincrement: false;
165
+ hasRuntimeDefault: false;
166
+ enumValues: undefined;
167
+ baseColumn: never;
168
+ identity: undefined;
169
+ generated: undefined;
170
+ }, {}, {}>;
171
+ };
172
+ dialect: "pg";
173
+ }>;
174
+ };
175
+ relations: {
176
+ passkeysRelations: drizzle_orm.Relations<string, {
177
+ user: drizzle_orm.One<U["_"]["name"], true>;
178
+ }>;
179
+ };
180
+ };
181
+ type Tables = ReturnType<typeof createPasskeyTables>['tables'];
182
+ interface CreatePasskeyAdapterOptions {
183
+ db: any;
184
+ tables: Tables;
185
+ generateId?: () => string;
186
+ }
187
+ declare function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter;
188
+
189
+ export { type CreatePasskeyAdapterOptions, type CreatePasskeyTablesOptions, type PgUsersTable, createPasskeyAdapter, createPasskeyTables };
@@ -0,0 +1,189 @@
1
+ import * as drizzle_orm from 'drizzle-orm';
2
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
3
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
4
+ import { PasskeyAdapter } from '@holeauth/plugin-passkey';
5
+
6
+ type PgUsersTable = PgTableWithColumns<any> & {
7
+ id: any;
8
+ };
9
+ interface CreatePasskeyTablesOptions<U extends PgUsersTable> {
10
+ usersTable: U;
11
+ prefix?: string;
12
+ }
13
+ declare function createPasskeyTables<U extends PgUsersTable>(opts: CreatePasskeyTablesOptions<U>): {
14
+ tables: {
15
+ passkeys: PgTableWithColumns<{
16
+ name: string;
17
+ schema: undefined;
18
+ columns: {
19
+ id: drizzle_orm_pg_core.PgColumn<{
20
+ name: "id";
21
+ tableName: string;
22
+ dataType: "string";
23
+ columnType: "PgText";
24
+ data: string;
25
+ driverParam: string;
26
+ notNull: true;
27
+ hasDefault: false;
28
+ isPrimaryKey: true;
29
+ isAutoincrement: false;
30
+ hasRuntimeDefault: false;
31
+ enumValues: [string, ...string[]];
32
+ baseColumn: never;
33
+ identity: undefined;
34
+ generated: undefined;
35
+ }, {}, {}>;
36
+ userId: drizzle_orm_pg_core.PgColumn<{
37
+ name: "user_id";
38
+ tableName: string;
39
+ dataType: "string";
40
+ columnType: "PgText";
41
+ data: string;
42
+ driverParam: string;
43
+ notNull: true;
44
+ hasDefault: false;
45
+ isPrimaryKey: false;
46
+ isAutoincrement: false;
47
+ hasRuntimeDefault: false;
48
+ enumValues: [string, ...string[]];
49
+ baseColumn: never;
50
+ identity: undefined;
51
+ generated: undefined;
52
+ }, {}, {}>;
53
+ credentialId: drizzle_orm_pg_core.PgColumn<{
54
+ name: "credential_id";
55
+ tableName: string;
56
+ dataType: "string";
57
+ columnType: "PgText";
58
+ data: string;
59
+ driverParam: string;
60
+ notNull: true;
61
+ hasDefault: false;
62
+ isPrimaryKey: false;
63
+ isAutoincrement: false;
64
+ hasRuntimeDefault: false;
65
+ enumValues: [string, ...string[]];
66
+ baseColumn: never;
67
+ identity: undefined;
68
+ generated: undefined;
69
+ }, {}, {}>;
70
+ publicKey: drizzle_orm_pg_core.PgColumn<{
71
+ name: "public_key";
72
+ tableName: string;
73
+ dataType: "string";
74
+ columnType: "PgText";
75
+ data: string;
76
+ driverParam: string;
77
+ notNull: true;
78
+ hasDefault: false;
79
+ isPrimaryKey: false;
80
+ isAutoincrement: false;
81
+ hasRuntimeDefault: false;
82
+ enumValues: [string, ...string[]];
83
+ baseColumn: never;
84
+ identity: undefined;
85
+ generated: undefined;
86
+ }, {}, {}>;
87
+ counter: drizzle_orm_pg_core.PgColumn<{
88
+ name: "counter";
89
+ tableName: string;
90
+ dataType: "number";
91
+ columnType: "PgInteger";
92
+ data: number;
93
+ driverParam: string | number;
94
+ notNull: true;
95
+ hasDefault: true;
96
+ isPrimaryKey: false;
97
+ isAutoincrement: false;
98
+ hasRuntimeDefault: false;
99
+ enumValues: undefined;
100
+ baseColumn: never;
101
+ identity: undefined;
102
+ generated: undefined;
103
+ }, {}, {}>;
104
+ transports: drizzle_orm_pg_core.PgColumn<{
105
+ name: "transports";
106
+ tableName: string;
107
+ dataType: "array";
108
+ columnType: "PgArray";
109
+ data: string[];
110
+ driverParam: string | string[];
111
+ notNull: false;
112
+ hasDefault: false;
113
+ isPrimaryKey: false;
114
+ isAutoincrement: false;
115
+ hasRuntimeDefault: false;
116
+ enumValues: [string, ...string[]];
117
+ baseColumn: drizzle_orm.Column<{
118
+ name: "transports";
119
+ tableName: string;
120
+ dataType: "string";
121
+ columnType: "PgText";
122
+ data: string;
123
+ driverParam: string;
124
+ notNull: false;
125
+ hasDefault: false;
126
+ isPrimaryKey: false;
127
+ isAutoincrement: false;
128
+ hasRuntimeDefault: false;
129
+ enumValues: [string, ...string[]];
130
+ baseColumn: never;
131
+ identity: undefined;
132
+ generated: undefined;
133
+ }, object, object>;
134
+ identity: undefined;
135
+ generated: undefined;
136
+ }, {}, {}>;
137
+ deviceName: drizzle_orm_pg_core.PgColumn<{
138
+ name: "device_name";
139
+ tableName: string;
140
+ dataType: "string";
141
+ columnType: "PgText";
142
+ data: string;
143
+ driverParam: string;
144
+ notNull: false;
145
+ hasDefault: false;
146
+ isPrimaryKey: false;
147
+ isAutoincrement: false;
148
+ hasRuntimeDefault: false;
149
+ enumValues: [string, ...string[]];
150
+ baseColumn: never;
151
+ identity: undefined;
152
+ generated: undefined;
153
+ }, {}, {}>;
154
+ createdAt: drizzle_orm_pg_core.PgColumn<{
155
+ name: "created_at";
156
+ tableName: string;
157
+ dataType: "date";
158
+ columnType: "PgTimestamp";
159
+ data: Date;
160
+ driverParam: string;
161
+ notNull: true;
162
+ hasDefault: true;
163
+ isPrimaryKey: false;
164
+ isAutoincrement: false;
165
+ hasRuntimeDefault: false;
166
+ enumValues: undefined;
167
+ baseColumn: never;
168
+ identity: undefined;
169
+ generated: undefined;
170
+ }, {}, {}>;
171
+ };
172
+ dialect: "pg";
173
+ }>;
174
+ };
175
+ relations: {
176
+ passkeysRelations: drizzle_orm.Relations<string, {
177
+ user: drizzle_orm.One<U["_"]["name"], true>;
178
+ }>;
179
+ };
180
+ };
181
+ type Tables = ReturnType<typeof createPasskeyTables>['tables'];
182
+ interface CreatePasskeyAdapterOptions {
183
+ db: any;
184
+ tables: Tables;
185
+ generateId?: () => string;
186
+ }
187
+ declare function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter;
188
+
189
+ export { type CreatePasskeyAdapterOptions, type CreatePasskeyTablesOptions, type PgUsersTable, createPasskeyAdapter, createPasskeyTables };
@@ -0,0 +1,67 @@
1
+ import { pgTable, timestamp, text, integer, index, uniqueIndex } from 'drizzle-orm/pg-core';
2
+ import { relations, eq } from 'drizzle-orm';
3
+
4
+ // src/pg/index.ts
5
+ function createPasskeyTables(opts) {
6
+ const { usersTable, prefix = "holeauth_passkey_" } = opts;
7
+ const p = (s) => `${prefix}${s}`;
8
+ const passkeys = pgTable(
9
+ p("credential"),
10
+ {
11
+ id: text("id").primaryKey(),
12
+ userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
13
+ credentialId: text("credential_id").notNull(),
14
+ publicKey: text("public_key").notNull(),
15
+ counter: integer("counter").notNull().default(0),
16
+ transports: text("transports").array(),
17
+ deviceName: text("device_name"),
18
+ createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).notNull().defaultNow()
19
+ },
20
+ (t) => ({
21
+ credIdx: uniqueIndex().on(t.credentialId),
22
+ userIdx: index().on(t.userId)
23
+ })
24
+ );
25
+ const passkeysRelations = relations(passkeys, ({ one }) => ({
26
+ user: one(usersTable, { fields: [passkeys.userId], references: [usersTable.id] })
27
+ }));
28
+ return { tables: { passkeys }, relations: { passkeysRelations } };
29
+ }
30
+ var rowToRecord = (r) => ({
31
+ id: String(r.id),
32
+ userId: String(r.userId),
33
+ credentialId: String(r.credentialId),
34
+ publicKey: String(r.publicKey),
35
+ counter: Number(r.counter),
36
+ transports: r.transports ?? null,
37
+ deviceName: r.deviceName ?? null,
38
+ createdAt: r.createdAt
39
+ });
40
+ function createPasskeyAdapter(opts) {
41
+ const { db, tables, generateId = () => crypto.randomUUID() } = opts;
42
+ const { passkeys } = tables;
43
+ return {
44
+ async list(userId) {
45
+ const rows = await db.select().from(passkeys).where(eq(passkeys.userId, userId));
46
+ return rows.map(rowToRecord);
47
+ },
48
+ async getByCredentialId(credentialId) {
49
+ const rows = await db.select().from(passkeys).where(eq(passkeys.credentialId, credentialId)).limit(1);
50
+ return rows[0] ? rowToRecord(rows[0]) : null;
51
+ },
52
+ async create(data) {
53
+ const [row] = await db.insert(passkeys).values({ id: generateId(), ...data }).returning();
54
+ return rowToRecord(row);
55
+ },
56
+ async updateCounter(credentialId, counter) {
57
+ await db.update(passkeys).set({ counter }).where(eq(passkeys.credentialId, credentialId));
58
+ },
59
+ async delete(id) {
60
+ await db.delete(passkeys).where(eq(passkeys.id, id));
61
+ }
62
+ };
63
+ }
64
+
65
+ export { createPasskeyAdapter, createPasskeyTables };
66
+ //# sourceMappingURL=index.js.map
67
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pg/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n pgTable,\n text,\n integer,\n timestamp,\n uniqueIndex,\n index,\n type PgTableWithColumns,\n} from 'drizzle-orm/pg-core';\nimport { relations, eq } from 'drizzle-orm';\nimport type { PasskeyAdapter, PasskeyRecord } from '@holeauth/plugin-passkey';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PgUsersTable = PgTableWithColumns<any> & { id: any };\n\nexport interface CreatePasskeyTablesOptions<U extends PgUsersTable> {\n usersTable: U;\n prefix?: string;\n}\n\nexport function createPasskeyTables<U extends PgUsersTable>(opts: CreatePasskeyTablesOptions<U>) {\n const { usersTable, prefix = 'holeauth_passkey_' } = opts;\n const p = (s: string) => `${prefix}${s}`;\n const passkeys = pgTable(\n p('credential'),\n {\n id: text('id').primaryKey(),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n credentialId: text('credential_id').notNull(),\n publicKey: text('public_key').notNull(),\n counter: integer('counter').notNull().default(0),\n transports: text('transports').array(),\n deviceName: text('device_name'),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' }).notNull().defaultNow(),\n },\n (t) => ({\n credIdx: uniqueIndex().on(t.credentialId),\n userIdx: index().on(t.userId),\n }),\n );\n const passkeysRelations = relations(passkeys, ({ one }) => ({\n user: one(usersTable, { fields: [passkeys.userId], references: [usersTable.id] }),\n }));\n return { tables: { passkeys }, relations: { passkeysRelations } };\n}\n\ntype Tables = ReturnType<typeof createPasskeyTables>['tables'];\n\nexport interface CreatePasskeyAdapterOptions {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n db: any;\n tables: Tables;\n generateId?: () => string;\n}\n\nconst rowToRecord = (r: Record<string, unknown>): PasskeyRecord => ({\n id: String(r.id),\n userId: String(r.userId),\n credentialId: String(r.credentialId),\n publicKey: String(r.publicKey),\n counter: Number(r.counter),\n transports: (r.transports as string[] | null | undefined) ?? null,\n deviceName: (r.deviceName as string | null | undefined) ?? null,\n createdAt: r.createdAt as Date | undefined,\n});\n\nexport function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter {\n const { db, tables, generateId = () => crypto.randomUUID() } = opts;\n const { passkeys } = tables;\n return {\n async list(userId) {\n const rows = await db.select().from(passkeys).where(eq(passkeys.userId, userId));\n return (rows as Record<string, unknown>[]).map(rowToRecord);\n },\n async getByCredentialId(credentialId) {\n const rows = await db\n .select()\n .from(passkeys)\n .where(eq(passkeys.credentialId, credentialId))\n .limit(1);\n return rows[0] ? rowToRecord(rows[0]) : null;\n },\n async create(data) {\n const [row] = await db\n .insert(passkeys)\n .values({ id: generateId(), ...data })\n .returning();\n return rowToRecord(row);\n },\n async updateCounter(credentialId, counter) {\n await db.update(passkeys).set({ counter }).where(eq(passkeys.credentialId, credentialId));\n },\n async delete(id) {\n await db.delete(passkeys).where(eq(passkeys.id, id));\n },\n };\n}\n"]}
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ var sqliteCore = require('drizzle-orm/sqlite-core');
4
+ var drizzleOrm = require('drizzle-orm');
5
+
6
+ // src/sqlite/index.ts
7
+ function createPasskeyTables(opts) {
8
+ const { usersTable, prefix = "holeauth_passkey_" } = opts;
9
+ const p = (s) => `${prefix}${s}`;
10
+ const passkeys = sqliteCore.sqliteTable(
11
+ p("credential"),
12
+ {
13
+ id: sqliteCore.text("id").primaryKey(),
14
+ userId: sqliteCore.text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
15
+ credentialId: sqliteCore.text("credential_id").notNull(),
16
+ publicKey: sqliteCore.text("public_key").notNull(),
17
+ counter: sqliteCore.integer("counter").notNull().default(0),
18
+ transports: sqliteCore.text("transports", { mode: "json" }).$type(),
19
+ deviceName: sqliteCore.text("device_name"),
20
+ createdAt: sqliteCore.integer("created_at", { mode: "timestamp_ms" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
21
+ },
22
+ (t) => ({
23
+ credIdx: sqliteCore.uniqueIndex(`${p("credential")}_cred_idx`).on(t.credentialId),
24
+ userIdx: sqliteCore.index(`${p("credential")}_user_idx`).on(t.userId)
25
+ })
26
+ );
27
+ const passkeysRelations = drizzleOrm.relations(passkeys, ({ one }) => ({
28
+ user: one(usersTable, { fields: [passkeys.userId], references: [usersTable.id] })
29
+ }));
30
+ return { tables: { passkeys }, relations: { passkeysRelations } };
31
+ }
32
+ var rowToRecord = (r) => ({
33
+ id: String(r.id),
34
+ userId: String(r.userId),
35
+ credentialId: String(r.credentialId),
36
+ publicKey: String(r.publicKey),
37
+ counter: Number(r.counter),
38
+ transports: r.transports ?? null,
39
+ deviceName: r.deviceName ?? null,
40
+ createdAt: r.createdAt
41
+ });
42
+ function createPasskeyAdapter(opts) {
43
+ const { db, tables, generateId = () => crypto.randomUUID() } = opts;
44
+ const { passkeys } = tables;
45
+ return {
46
+ async list(userId) {
47
+ const rows = await db.select().from(passkeys).where(drizzleOrm.eq(passkeys.userId, userId));
48
+ return rows.map(rowToRecord);
49
+ },
50
+ async getByCredentialId(credentialId) {
51
+ const rows = await db.select().from(passkeys).where(drizzleOrm.eq(passkeys.credentialId, credentialId)).limit(1);
52
+ return rows[0] ? rowToRecord(rows[0]) : null;
53
+ },
54
+ async create(data) {
55
+ const [row] = await db.insert(passkeys).values({ id: generateId(), ...data }).returning();
56
+ return rowToRecord(row);
57
+ },
58
+ async updateCounter(credentialId, counter) {
59
+ await db.update(passkeys).set({ counter }).where(drizzleOrm.eq(passkeys.credentialId, credentialId));
60
+ },
61
+ async delete(id) {
62
+ await db.delete(passkeys).where(drizzleOrm.eq(passkeys.id, id));
63
+ }
64
+ };
65
+ }
66
+
67
+ exports.createPasskeyAdapter = createPasskeyAdapter;
68
+ exports.createPasskeyTables = createPasskeyTables;
69
+ //# sourceMappingURL=index.cjs.map
70
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sqlite/index.ts"],"names":["sqliteTable","text","integer","uniqueIndex","index","relations","eq"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n sqliteTable,\n text,\n integer,\n uniqueIndex,\n index,\n type SQLiteTableWithColumns,\n} from 'drizzle-orm/sqlite-core';\nimport { relations, eq } from 'drizzle-orm';\nimport type { PasskeyAdapter, PasskeyRecord } from '@holeauth/plugin-passkey';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type SqliteUsersTable = SQLiteTableWithColumns<any> & { id: any };\n\nexport interface CreatePasskeyTablesOptions<U extends SqliteUsersTable> {\n usersTable: U;\n prefix?: string;\n}\n\nexport function createPasskeyTables<U extends SqliteUsersTable>(opts: CreatePasskeyTablesOptions<U>) {\n const { usersTable, prefix = 'holeauth_passkey_' } = opts;\n const p = (s: string) => `${prefix}${s}`;\n const passkeys = sqliteTable(\n p('credential'),\n {\n id: text('id').primaryKey(),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n credentialId: text('credential_id').notNull(),\n publicKey: text('public_key').notNull(),\n counter: integer('counter').notNull().default(0),\n transports: text('transports', { mode: 'json' }).$type<string[]>(),\n deviceName: text('device_name'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .$defaultFn(() => new Date()),\n },\n (t) => ({\n credIdx: uniqueIndex(`${p('credential')}_cred_idx`).on(t.credentialId),\n userIdx: index(`${p('credential')}_user_idx`).on(t.userId),\n }),\n );\n const passkeysRelations = relations(passkeys, ({ one }) => ({\n user: one(usersTable, { fields: [passkeys.userId], references: [usersTable.id] }),\n }));\n return { tables: { passkeys }, relations: { passkeysRelations } };\n}\n\ntype Tables = ReturnType<typeof createPasskeyTables>['tables'];\n\nexport interface CreatePasskeyAdapterOptions {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n db: any;\n tables: Tables;\n generateId?: () => string;\n}\n\nconst rowToRecord = (r: Record<string, unknown>): PasskeyRecord => ({\n id: String(r.id),\n userId: String(r.userId),\n credentialId: String(r.credentialId),\n publicKey: String(r.publicKey),\n counter: Number(r.counter),\n transports: (r.transports as string[] | null | undefined) ?? null,\n deviceName: (r.deviceName as string | null | undefined) ?? null,\n createdAt: r.createdAt as Date | undefined,\n});\n\nexport function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter {\n const { db, tables, generateId = () => crypto.randomUUID() } = opts;\n const { passkeys } = tables;\n return {\n async list(userId) {\n const rows = await db.select().from(passkeys).where(eq(passkeys.userId, userId));\n return (rows as Record<string, unknown>[]).map(rowToRecord);\n },\n async getByCredentialId(credentialId) {\n const rows = await db\n .select()\n .from(passkeys)\n .where(eq(passkeys.credentialId, credentialId))\n .limit(1);\n return rows[0] ? rowToRecord(rows[0]) : null;\n },\n async create(data) {\n const [row] = await db.insert(passkeys).values({ id: generateId(), ...data }).returning();\n return rowToRecord(row);\n },\n async updateCounter(credentialId, counter) {\n await db.update(passkeys).set({ counter }).where(eq(passkeys.credentialId, credentialId));\n },\n async delete(id) {\n await db.delete(passkeys).where(eq(passkeys.id, id));\n },\n };\n}\n"]}