@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,173 @@
1
+ import * as drizzle_orm from 'drizzle-orm';
2
+ import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
3
+ import { SQLiteTableWithColumns } from 'drizzle-orm/sqlite-core';
4
+ import { PasskeyAdapter } from '@holeauth/plugin-passkey';
5
+
6
+ type SqliteUsersTable = SQLiteTableWithColumns<any> & {
7
+ id: any;
8
+ };
9
+ interface CreatePasskeyTablesOptions<U extends SqliteUsersTable> {
10
+ usersTable: U;
11
+ prefix?: string;
12
+ }
13
+ declare function createPasskeyTables<U extends SqliteUsersTable>(opts: CreatePasskeyTablesOptions<U>): {
14
+ tables: {
15
+ passkeys: SQLiteTableWithColumns<{
16
+ name: string;
17
+ schema: undefined;
18
+ columns: {
19
+ id: drizzle_orm_sqlite_core.SQLiteColumn<{
20
+ name: "id";
21
+ tableName: string;
22
+ dataType: "string";
23
+ columnType: "SQLiteText";
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
+ }, object>;
36
+ userId: drizzle_orm_sqlite_core.SQLiteColumn<{
37
+ name: "user_id";
38
+ tableName: string;
39
+ dataType: "string";
40
+ columnType: "SQLiteText";
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
+ }, object>;
53
+ credentialId: drizzle_orm_sqlite_core.SQLiteColumn<{
54
+ name: "credential_id";
55
+ tableName: string;
56
+ dataType: "string";
57
+ columnType: "SQLiteText";
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
+ }, object>;
70
+ publicKey: drizzle_orm_sqlite_core.SQLiteColumn<{
71
+ name: "public_key";
72
+ tableName: string;
73
+ dataType: "string";
74
+ columnType: "SQLiteText";
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
+ }, object>;
87
+ counter: drizzle_orm_sqlite_core.SQLiteColumn<{
88
+ name: "counter";
89
+ tableName: string;
90
+ dataType: "number";
91
+ columnType: "SQLiteInteger";
92
+ data: number;
93
+ driverParam: 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
+ }, object>;
104
+ transports: drizzle_orm_sqlite_core.SQLiteColumn<{
105
+ name: "transports";
106
+ tableName: string;
107
+ dataType: "json";
108
+ columnType: "SQLiteTextJson";
109
+ data: string[];
110
+ driverParam: string;
111
+ notNull: false;
112
+ hasDefault: false;
113
+ isPrimaryKey: false;
114
+ isAutoincrement: false;
115
+ hasRuntimeDefault: false;
116
+ enumValues: undefined;
117
+ baseColumn: never;
118
+ identity: undefined;
119
+ generated: undefined;
120
+ }, object>;
121
+ deviceName: drizzle_orm_sqlite_core.SQLiteColumn<{
122
+ name: "device_name";
123
+ tableName: string;
124
+ dataType: "string";
125
+ columnType: "SQLiteText";
126
+ data: string;
127
+ driverParam: string;
128
+ notNull: false;
129
+ hasDefault: false;
130
+ isPrimaryKey: false;
131
+ isAutoincrement: false;
132
+ hasRuntimeDefault: false;
133
+ enumValues: [string, ...string[]];
134
+ baseColumn: never;
135
+ identity: undefined;
136
+ generated: undefined;
137
+ }, object>;
138
+ createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
139
+ name: "created_at";
140
+ tableName: string;
141
+ dataType: "date";
142
+ columnType: "SQLiteTimestamp";
143
+ data: Date;
144
+ driverParam: number;
145
+ notNull: true;
146
+ hasDefault: true;
147
+ isPrimaryKey: false;
148
+ isAutoincrement: false;
149
+ hasRuntimeDefault: true;
150
+ enumValues: undefined;
151
+ baseColumn: never;
152
+ identity: undefined;
153
+ generated: undefined;
154
+ }, object>;
155
+ };
156
+ dialect: "sqlite";
157
+ }>;
158
+ };
159
+ relations: {
160
+ passkeysRelations: drizzle_orm.Relations<string, {
161
+ user: drizzle_orm.One<U["_"]["name"], true>;
162
+ }>;
163
+ };
164
+ };
165
+ type Tables = ReturnType<typeof createPasskeyTables>['tables'];
166
+ interface CreatePasskeyAdapterOptions {
167
+ db: any;
168
+ tables: Tables;
169
+ generateId?: () => string;
170
+ }
171
+ declare function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter;
172
+
173
+ export { type CreatePasskeyAdapterOptions, type CreatePasskeyTablesOptions, type SqliteUsersTable, createPasskeyAdapter, createPasskeyTables };
@@ -0,0 +1,173 @@
1
+ import * as drizzle_orm from 'drizzle-orm';
2
+ import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
3
+ import { SQLiteTableWithColumns } from 'drizzle-orm/sqlite-core';
4
+ import { PasskeyAdapter } from '@holeauth/plugin-passkey';
5
+
6
+ type SqliteUsersTable = SQLiteTableWithColumns<any> & {
7
+ id: any;
8
+ };
9
+ interface CreatePasskeyTablesOptions<U extends SqliteUsersTable> {
10
+ usersTable: U;
11
+ prefix?: string;
12
+ }
13
+ declare function createPasskeyTables<U extends SqliteUsersTable>(opts: CreatePasskeyTablesOptions<U>): {
14
+ tables: {
15
+ passkeys: SQLiteTableWithColumns<{
16
+ name: string;
17
+ schema: undefined;
18
+ columns: {
19
+ id: drizzle_orm_sqlite_core.SQLiteColumn<{
20
+ name: "id";
21
+ tableName: string;
22
+ dataType: "string";
23
+ columnType: "SQLiteText";
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
+ }, object>;
36
+ userId: drizzle_orm_sqlite_core.SQLiteColumn<{
37
+ name: "user_id";
38
+ tableName: string;
39
+ dataType: "string";
40
+ columnType: "SQLiteText";
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
+ }, object>;
53
+ credentialId: drizzle_orm_sqlite_core.SQLiteColumn<{
54
+ name: "credential_id";
55
+ tableName: string;
56
+ dataType: "string";
57
+ columnType: "SQLiteText";
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
+ }, object>;
70
+ publicKey: drizzle_orm_sqlite_core.SQLiteColumn<{
71
+ name: "public_key";
72
+ tableName: string;
73
+ dataType: "string";
74
+ columnType: "SQLiteText";
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
+ }, object>;
87
+ counter: drizzle_orm_sqlite_core.SQLiteColumn<{
88
+ name: "counter";
89
+ tableName: string;
90
+ dataType: "number";
91
+ columnType: "SQLiteInteger";
92
+ data: number;
93
+ driverParam: 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
+ }, object>;
104
+ transports: drizzle_orm_sqlite_core.SQLiteColumn<{
105
+ name: "transports";
106
+ tableName: string;
107
+ dataType: "json";
108
+ columnType: "SQLiteTextJson";
109
+ data: string[];
110
+ driverParam: string;
111
+ notNull: false;
112
+ hasDefault: false;
113
+ isPrimaryKey: false;
114
+ isAutoincrement: false;
115
+ hasRuntimeDefault: false;
116
+ enumValues: undefined;
117
+ baseColumn: never;
118
+ identity: undefined;
119
+ generated: undefined;
120
+ }, object>;
121
+ deviceName: drizzle_orm_sqlite_core.SQLiteColumn<{
122
+ name: "device_name";
123
+ tableName: string;
124
+ dataType: "string";
125
+ columnType: "SQLiteText";
126
+ data: string;
127
+ driverParam: string;
128
+ notNull: false;
129
+ hasDefault: false;
130
+ isPrimaryKey: false;
131
+ isAutoincrement: false;
132
+ hasRuntimeDefault: false;
133
+ enumValues: [string, ...string[]];
134
+ baseColumn: never;
135
+ identity: undefined;
136
+ generated: undefined;
137
+ }, object>;
138
+ createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
139
+ name: "created_at";
140
+ tableName: string;
141
+ dataType: "date";
142
+ columnType: "SQLiteTimestamp";
143
+ data: Date;
144
+ driverParam: number;
145
+ notNull: true;
146
+ hasDefault: true;
147
+ isPrimaryKey: false;
148
+ isAutoincrement: false;
149
+ hasRuntimeDefault: true;
150
+ enumValues: undefined;
151
+ baseColumn: never;
152
+ identity: undefined;
153
+ generated: undefined;
154
+ }, object>;
155
+ };
156
+ dialect: "sqlite";
157
+ }>;
158
+ };
159
+ relations: {
160
+ passkeysRelations: drizzle_orm.Relations<string, {
161
+ user: drizzle_orm.One<U["_"]["name"], true>;
162
+ }>;
163
+ };
164
+ };
165
+ type Tables = ReturnType<typeof createPasskeyTables>['tables'];
166
+ interface CreatePasskeyAdapterOptions {
167
+ db: any;
168
+ tables: Tables;
169
+ generateId?: () => string;
170
+ }
171
+ declare function createPasskeyAdapter(opts: CreatePasskeyAdapterOptions): PasskeyAdapter;
172
+
173
+ export { type CreatePasskeyAdapterOptions, type CreatePasskeyTablesOptions, type SqliteUsersTable, createPasskeyAdapter, createPasskeyTables };
@@ -0,0 +1,67 @@
1
+ import { sqliteTable, integer, text, index, uniqueIndex } from 'drizzle-orm/sqlite-core';
2
+ import { relations, eq } from 'drizzle-orm';
3
+
4
+ // src/sqlite/index.ts
5
+ function createPasskeyTables(opts) {
6
+ const { usersTable, prefix = "holeauth_passkey_" } = opts;
7
+ const p = (s) => `${prefix}${s}`;
8
+ const passkeys = sqliteTable(
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", { mode: "json" }).$type(),
17
+ deviceName: text("device_name"),
18
+ createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
19
+ },
20
+ (t) => ({
21
+ credIdx: uniqueIndex(`${p("credential")}_cred_idx`).on(t.credentialId),
22
+ userIdx: index(`${p("credential")}_user_idx`).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/sqlite/index.ts"],"names":[],"mappings":";;;;AAmBO,SAAS,oBAAgD,IAAA,EAAqC;AACnG,EAAA,MAAM,EAAE,UAAA,EAAY,MAAA,GAAS,mBAAA,EAAoB,GAAI,IAAA;AACrD,EAAA,MAAM,IAAI,CAAC,CAAA,KAAc,CAAA,EAAG,MAAM,GAAG,CAAC,CAAA,CAAA;AACtC,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,EAAE,YAAY,CAAA;AAAA,IACd;AAAA,MACE,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,UAAA,EAAW;AAAA,MAC1B,MAAA,EAAQ,IAAA,CAAK,SAAS,CAAA,CACnB,OAAA,EAAQ,CACR,UAAA,CAAW,MAAM,UAAA,CAAW,EAAA,EAAI,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,MAC1D,YAAA,EAAc,IAAA,CAAK,eAAe,CAAA,CAAE,OAAA,EAAQ;AAAA,MAC5C,SAAA,EAAW,IAAA,CAAK,YAAY,CAAA,CAAE,OAAA,EAAQ;AAAA,MACtC,SAAS,OAAA,CAAQ,SAAS,EAAE,OAAA,EAAQ,CAAE,QAAQ,CAAC,CAAA;AAAA,MAC/C,UAAA,EAAY,KAAK,YAAA,EAAc,EAAE,MAAM,MAAA,EAAQ,EAAE,KAAA,EAAgB;AAAA,MACjE,UAAA,EAAY,KAAK,aAAa,CAAA;AAAA,MAC9B,SAAA,EAAW,OAAA,CAAQ,YAAA,EAAc,EAAE,MAAM,cAAA,EAAgB,CAAA,CACtD,OAAA,EAAQ,CACR,UAAA,CAAW,sBAAM,IAAI,MAAM;AAAA,KAChC;AAAA,IACA,CAAC,CAAA,MAAO;AAAA,MACN,OAAA,EAAS,WAAA,CAAY,CAAA,EAAG,CAAA,CAAE,YAAY,CAAC,CAAA,SAAA,CAAW,CAAA,CAAE,EAAA,CAAG,CAAA,CAAE,YAAY,CAAA;AAAA,MACrE,OAAA,EAAS,KAAA,CAAM,CAAA,EAAG,CAAA,CAAE,YAAY,CAAC,CAAA,SAAA,CAAW,CAAA,CAAE,EAAA,CAAG,CAAA,CAAE,MAAM;AAAA,KAC3D;AAAA,GACF;AACA,EAAA,MAAM,oBAAoB,SAAA,CAAU,QAAA,EAAU,CAAC,EAAE,KAAI,MAAO;AAAA,IAC1D,IAAA,EAAM,GAAA,CAAI,UAAA,EAAY,EAAE,QAAQ,CAAC,QAAA,CAAS,MAAM,CAAA,EAAG,UAAA,EAAY,CAAC,UAAA,CAAW,EAAE,GAAG;AAAA,GAClF,CAAE,CAAA;AACF,EAAA,OAAO,EAAE,QAAQ,EAAE,QAAA,IAAY,SAAA,EAAW,EAAE,mBAAkB,EAAE;AAClE;AAWA,IAAM,WAAA,GAAc,CAAC,CAAA,MAA+C;AAAA,EAClE,EAAA,EAAI,MAAA,CAAO,CAAA,CAAE,EAAE,CAAA;AAAA,EACf,MAAA,EAAQ,MAAA,CAAO,CAAA,CAAE,MAAM,CAAA;AAAA,EACvB,YAAA,EAAc,MAAA,CAAO,CAAA,CAAE,YAAY,CAAA;AAAA,EACnC,SAAA,EAAW,MAAA,CAAO,CAAA,CAAE,SAAS,CAAA;AAAA,EAC7B,OAAA,EAAS,MAAA,CAAO,CAAA,CAAE,OAAO,CAAA;AAAA,EACzB,UAAA,EAAa,EAAE,UAAA,IAA8C,IAAA;AAAA,EAC7D,UAAA,EAAa,EAAE,UAAA,IAA4C,IAAA;AAAA,EAC3D,WAAW,CAAA,CAAE;AACf,CAAA,CAAA;AAEO,SAAS,qBAAqB,IAAA,EAAmD;AACtF,EAAA,MAAM,EAAE,IAAI,MAAA,EAAQ,UAAA,GAAa,MAAM,MAAA,CAAO,UAAA,IAAa,GAAI,IAAA;AAC/D,EAAA,MAAM,EAAE,UAAS,GAAI,MAAA;AACrB,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,MAAA,EAAQ;AACjB,MAAA,MAAM,IAAA,GAAO,MAAM,EAAA,CAAG,MAAA,EAAO,CAAE,IAAA,CAAK,QAAQ,CAAA,CAAE,KAAA,CAAM,EAAA,CAAG,QAAA,CAAS,MAAA,EAAQ,MAAM,CAAC,CAAA;AAC/E,MAAA,OAAQ,IAAA,CAAmC,IAAI,WAAW,CAAA;AAAA,IAC5D,CAAA;AAAA,IACA,MAAM,kBAAkB,YAAA,EAAc;AACpC,MAAA,MAAM,OAAO,MAAM,EAAA,CAChB,MAAA,EAAO,CACP,KAAK,QAAQ,CAAA,CACb,KAAA,CAAM,EAAA,CAAG,SAAS,YAAA,EAAc,YAAY,CAAC,CAAA,CAC7C,MAAM,CAAC,CAAA;AACV,MAAA,OAAO,KAAK,CAAC,CAAA,GAAI,YAAY,IAAA,CAAK,CAAC,CAAC,CAAA,GAAI,IAAA;AAAA,IAC1C,CAAA;AAAA,IACA,MAAM,OAAO,IAAA,EAAM;AACjB,MAAA,MAAM,CAAC,GAAG,CAAA,GAAI,MAAM,EAAA,CAAG,OAAO,QAAQ,CAAA,CAAE,MAAA,CAAO,EAAE,IAAI,UAAA,EAAW,EAAG,GAAG,IAAA,EAAM,EAAE,SAAA,EAAU;AACxF,MAAA,OAAO,YAAY,GAAG,CAAA;AAAA,IACxB,CAAA;AAAA,IACA,MAAM,aAAA,CAAc,YAAA,EAAc,OAAA,EAAS;AACzC,MAAA,MAAM,EAAA,CAAG,MAAA,CAAO,QAAQ,CAAA,CAAE,IAAI,EAAE,OAAA,EAAS,CAAA,CAAE,KAAA,CAAM,EAAA,CAAG,QAAA,CAAS,YAAA,EAAc,YAAY,CAAC,CAAA;AAAA,IAC1F,CAAA;AAAA,IACA,MAAM,OAAO,EAAA,EAAI;AACf,MAAA,MAAM,EAAA,CAAG,OAAO,QAAQ,CAAA,CAAE,MAAM,EAAA,CAAG,QAAA,CAAS,EAAA,EAAI,EAAE,CAAC,CAAA;AAAA,IACrD;AAAA,GACF;AACF","file":"index.js","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"]}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@holeauth/passkey-drizzle",
3
+ "version": "0.0.1-alpha.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/robert-kratz/holeauth.git",
7
+ "directory": "packages/passkey-drizzle"
8
+ },
9
+ "description": "Drizzle adapter for @holeauth/plugin-passkey (WebAuthn credentials).",
10
+ "license": "MIT",
11
+ "author": "Robert Kratz",
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.cjs"
20
+ },
21
+ "./pg": {
22
+ "types": "./dist/pg/index.d.ts",
23
+ "import": "./dist/pg/index.js",
24
+ "require": "./dist/pg/index.cjs"
25
+ },
26
+ "./mysql": {
27
+ "types": "./dist/mysql/index.d.ts",
28
+ "import": "./dist/mysql/index.js",
29
+ "require": "./dist/mysql/index.cjs"
30
+ },
31
+ "./sqlite": {
32
+ "types": "./dist/sqlite/index.d.ts",
33
+ "import": "./dist/sqlite/index.js",
34
+ "require": "./dist/sqlite/index.cjs"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "publishConfig": {
44
+ "access": "public",
45
+ "provenance": true
46
+ },
47
+ "peerDependencies": {
48
+ "drizzle-orm": ">=0.33.0",
49
+ "@holeauth/plugin-passkey": "0.0.1-alpha.0"
50
+ },
51
+ "devDependencies": {
52
+ "@testcontainers/mysql": "^11.14.0",
53
+ "@testcontainers/postgresql": "^11.14.0",
54
+ "@types/better-sqlite3": "^7.6.13",
55
+ "@types/node": "^20.16.10",
56
+ "@types/pg": "^8.11.10",
57
+ "@vitest/coverage-v8": "^2.1.9",
58
+ "better-sqlite3": "^12.9.0",
59
+ "drizzle-orm": "^0.36.0",
60
+ "mysql2": "^3.22.2",
61
+ "pg": "^8.13.0",
62
+ "testcontainers": "^11.14.0",
63
+ "tsup": "^8.3.0",
64
+ "typescript": "^5.6.2",
65
+ "vitest": "^2.1.2",
66
+ "@holeauth/eslint-config": "0.0.0",
67
+ "@holeauth/tsconfig": "0.0.0",
68
+ "@holeauth/plugin-passkey": "0.0.1-alpha.0"
69
+ },
70
+ "scripts": {
71
+ "build": "tsup",
72
+ "dev": "tsup --watch",
73
+ "clean": "rm -rf dist .turbo",
74
+ "lint": "echo 'lint skipped'",
75
+ "typecheck": "tsc --noEmit",
76
+ "test": "vitest run --passWithNoTests",
77
+ "test:coverage": "vitest run --coverage"
78
+ }
79
+ }