jazz-tools 0.18.14 → 0.18.16

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.
Files changed (63) hide show
  1. package/.turbo/turbo-build.log +45 -33
  2. package/CHANGELOG.md +23 -0
  3. package/dist/better-auth/database-adapter/index.d.ts +50 -0
  4. package/dist/better-auth/database-adapter/index.d.ts.map +1 -0
  5. package/dist/better-auth/database-adapter/index.js +920 -0
  6. package/dist/better-auth/database-adapter/index.js.map +1 -0
  7. package/dist/better-auth/database-adapter/repository/account.d.ts +24 -0
  8. package/dist/better-auth/database-adapter/repository/account.d.ts.map +1 -0
  9. package/dist/better-auth/database-adapter/repository/generic.d.ts +45 -0
  10. package/dist/better-auth/database-adapter/repository/generic.d.ts.map +1 -0
  11. package/dist/better-auth/database-adapter/repository/index.d.ts +6 -0
  12. package/dist/better-auth/database-adapter/repository/index.d.ts.map +1 -0
  13. package/dist/better-auth/database-adapter/repository/session.d.ts +29 -0
  14. package/dist/better-auth/database-adapter/repository/session.d.ts.map +1 -0
  15. package/dist/better-auth/database-adapter/repository/user.d.ts +30 -0
  16. package/dist/better-auth/database-adapter/repository/user.d.ts.map +1 -0
  17. package/dist/better-auth/database-adapter/repository/verification.d.ts +18 -0
  18. package/dist/better-auth/database-adapter/repository/verification.d.ts.map +1 -0
  19. package/dist/better-auth/database-adapter/schema.d.ts +27 -0
  20. package/dist/better-auth/database-adapter/schema.d.ts.map +1 -0
  21. package/dist/better-auth/database-adapter/tests/index.test.d.ts +2 -0
  22. package/dist/better-auth/database-adapter/tests/index.test.d.ts.map +1 -0
  23. package/dist/better-auth/database-adapter/tests/repository/account.test.d.ts +2 -0
  24. package/dist/better-auth/database-adapter/tests/repository/account.test.d.ts.map +1 -0
  25. package/dist/better-auth/database-adapter/tests/repository/generic.test.d.ts +2 -0
  26. package/dist/better-auth/database-adapter/tests/repository/generic.test.d.ts.map +1 -0
  27. package/dist/better-auth/database-adapter/tests/repository/session.test.d.ts +2 -0
  28. package/dist/better-auth/database-adapter/tests/repository/session.test.d.ts.map +1 -0
  29. package/dist/better-auth/database-adapter/tests/repository/user.test.d.ts +2 -0
  30. package/dist/better-auth/database-adapter/tests/repository/user.test.d.ts.map +1 -0
  31. package/dist/better-auth/database-adapter/tests/repository/verification.test.d.ts +2 -0
  32. package/dist/better-auth/database-adapter/tests/repository/verification.test.d.ts.map +1 -0
  33. package/dist/better-auth/database-adapter/tests/sync-utils.d.ts +16 -0
  34. package/dist/better-auth/database-adapter/tests/sync-utils.d.ts.map +1 -0
  35. package/dist/better-auth/database-adapter/tests/utils.test.d.ts +2 -0
  36. package/dist/better-auth/database-adapter/tests/utils.test.d.ts.map +1 -0
  37. package/dist/better-auth/database-adapter/utils.d.ts +16 -0
  38. package/dist/better-auth/database-adapter/utils.d.ts.map +1 -0
  39. package/dist/worker/edge-wasm.d.ts +2 -0
  40. package/dist/worker/edge-wasm.d.ts.map +1 -0
  41. package/dist/worker/edge-wasm.js +5 -0
  42. package/dist/worker/edge-wasm.js.map +1 -0
  43. package/jazz-tools-0.18.6.tgz +0 -0
  44. package/package.json +15 -5
  45. package/src/better-auth/database-adapter/index.ts +228 -0
  46. package/src/better-auth/database-adapter/repository/account.ts +131 -0
  47. package/src/better-auth/database-adapter/repository/generic.ts +297 -0
  48. package/src/better-auth/database-adapter/repository/index.ts +5 -0
  49. package/src/better-auth/database-adapter/repository/session.ts +190 -0
  50. package/src/better-auth/database-adapter/repository/user.ts +158 -0
  51. package/src/better-auth/database-adapter/repository/verification.ts +37 -0
  52. package/src/better-auth/database-adapter/schema.ts +222 -0
  53. package/src/better-auth/database-adapter/tests/index.test.ts +690 -0
  54. package/src/better-auth/database-adapter/tests/repository/account.test.ts +149 -0
  55. package/src/better-auth/database-adapter/tests/repository/generic.test.ts +183 -0
  56. package/src/better-auth/database-adapter/tests/repository/session.test.ts +419 -0
  57. package/src/better-auth/database-adapter/tests/repository/user.test.ts +673 -0
  58. package/src/better-auth/database-adapter/tests/repository/verification.test.ts +101 -0
  59. package/src/better-auth/database-adapter/tests/sync-utils.ts +127 -0
  60. package/src/better-auth/database-adapter/tests/utils.test.ts +787 -0
  61. package/src/better-auth/database-adapter/utils.ts +178 -0
  62. package/src/worker/edge-wasm.ts +5 -0
  63. package/tsup.config.ts +8 -0
@@ -0,0 +1,690 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { runAdapterTest } from "better-auth/adapters/test";
3
+ import {
4
+ assert,
5
+ afterAll,
6
+ beforeAll,
7
+ describe,
8
+ expect,
9
+ it,
10
+ test,
11
+ beforeEach,
12
+ vi,
13
+ } from "vitest";
14
+ import { Account, co, Group } from "jazz-tools";
15
+ import { startWorker } from "jazz-tools/worker";
16
+ import { createWorkerAccount, startSyncServer } from "./sync-utils.js";
17
+ import { JazzBetterAuthDatabaseAdapter } from "../index.js";
18
+ import { TableItem } from "../schema.js";
19
+
20
+ describe("JazzBetterAuthDatabaseAdapter tests", async () => {
21
+ describe("better-auth internal tests", async () => {
22
+ let syncServer: any;
23
+ let accountID: string;
24
+ let accountSecret: string;
25
+ let adapter: ReturnType<typeof JazzBetterAuthDatabaseAdapter>;
26
+
27
+ beforeAll(async () => {
28
+ syncServer = await startSyncServer();
29
+
30
+ const workerAccount = await createWorkerAccount({
31
+ name: "test",
32
+ peer: `ws://localhost:${syncServer.port}`,
33
+ });
34
+
35
+ accountID = workerAccount.accountID;
36
+ accountSecret = workerAccount.agentSecret;
37
+
38
+ adapter = JazzBetterAuthDatabaseAdapter({
39
+ debugLogs: {
40
+ // If your adapter config allows passing in debug logs, then pass this here.
41
+ isRunningAdapterTests: true, // This is our super secret flag to let us know to only log debug logs if a test fails.
42
+ },
43
+ syncServer: `ws://localhost:${syncServer.port}`,
44
+ accountID,
45
+ accountSecret,
46
+ });
47
+ });
48
+
49
+ afterAll(async () => {
50
+ syncServer.close();
51
+ });
52
+
53
+ await runAdapterTest({
54
+ disableTests: {
55
+ SHOULD_PREFER_GENERATE_ID_IF_PROVIDED: true,
56
+ },
57
+ getAdapter: async (betterAuthOptions = {}) => {
58
+ return adapter(betterAuthOptions);
59
+ },
60
+ });
61
+ });
62
+
63
+ describe("persistence tests", async () => {
64
+ let syncServer: Awaited<ReturnType<typeof startSyncServer>>;
65
+ let accountID: string;
66
+ let accountSecret: string;
67
+
68
+ beforeAll(async () => {
69
+ syncServer = await startSyncServer();
70
+
71
+ const workerAccount = await createWorkerAccount({
72
+ name: "test",
73
+ peer: `ws://localhost:${syncServer.port}`,
74
+ });
75
+
76
+ accountID = workerAccount.accountID;
77
+ accountSecret = workerAccount.agentSecret;
78
+ });
79
+
80
+ it("data should be persisted", async () => {
81
+ const auth = betterAuth({
82
+ emailAndPassword: {
83
+ enabled: true,
84
+ },
85
+ database: JazzBetterAuthDatabaseAdapter({
86
+ syncServer: `ws://localhost:${syncServer.port}`,
87
+ accountID,
88
+ accountSecret,
89
+ debugLogs: true,
90
+ }),
91
+ });
92
+
93
+ const res = await auth.api.signUpEmail({
94
+ body: {
95
+ name: "test",
96
+ email: "test@test.com",
97
+ password: "123445678",
98
+ },
99
+ });
100
+
101
+ expect(res.user.id).match(/^co_\w+$/);
102
+
103
+ const log1 = await auth.api.signInEmail({
104
+ body: {
105
+ email: "test@test.com",
106
+ password: "123445678",
107
+ },
108
+ });
109
+
110
+ expect(log1.user.id).match(/^co_\w+$/);
111
+ });
112
+
113
+ it("data should be isolated by accounts", async () => {
114
+ const auth1 = betterAuth({
115
+ emailAndPassword: {
116
+ enabled: true,
117
+ },
118
+ database: JazzBetterAuthDatabaseAdapter({
119
+ syncServer: `ws://localhost:${syncServer.port}`,
120
+ accountID,
121
+ accountSecret,
122
+ }),
123
+ });
124
+
125
+ await auth1.api.signUpEmail({
126
+ body: {
127
+ name: "test",
128
+ email: "isolated@test.com",
129
+ password: "123445678",
130
+ },
131
+ });
132
+
133
+ const newWorker = await createWorkerAccount({
134
+ name: "test2",
135
+ peer: `ws://localhost:${syncServer.port}`,
136
+ });
137
+
138
+ const auth2 = betterAuth({
139
+ emailAndPassword: {
140
+ enabled: true,
141
+ },
142
+ database: JazzBetterAuthDatabaseAdapter({
143
+ syncServer: `ws://localhost:${syncServer.port}`,
144
+ accountID: newWorker.accountID,
145
+ accountSecret: newWorker.agentSecret,
146
+ }),
147
+ });
148
+
149
+ await expect(() =>
150
+ auth2.api.signInEmail({
151
+ body: {
152
+ email: "isolated@test.com",
153
+ password: "123445678",
154
+ },
155
+ }),
156
+ ).rejects.toThrow("Invalid email or password");
157
+ });
158
+
159
+ it("tables can be shared with another account", async () => {
160
+ // Create a new account as main worker
161
+ const auth1 = betterAuth({
162
+ emailAndPassword: {
163
+ enabled: true,
164
+ },
165
+ database: JazzBetterAuthDatabaseAdapter({
166
+ syncServer: `ws://localhost:${syncServer.port}`,
167
+ accountID,
168
+ accountSecret,
169
+ }),
170
+ });
171
+
172
+ await auth1.api.signUpEmail({
173
+ body: {
174
+ name: "test",
175
+ email: "shared@test.com",
176
+ password: "123445678",
177
+ },
178
+ });
179
+
180
+ // Get the owner Group from the main worker
181
+ const { worker } = await startWorker({
182
+ syncServer: `ws://localhost:${syncServer.port}`,
183
+ accountID,
184
+ accountSecret,
185
+ });
186
+
187
+ const DatabaseRoot = co.map({
188
+ group: Group,
189
+ tables: co.map({}),
190
+ });
191
+
192
+ const db = await DatabaseRoot.loadUnique("better-auth-root", accountID, {
193
+ loadAs: worker,
194
+ resolve: {
195
+ group: true,
196
+ tables: true,
197
+ },
198
+ });
199
+
200
+ assert(db);
201
+ assert(db.group);
202
+ assert(db.tables);
203
+
204
+ // Create a new worker account
205
+ const newWorkerAccount = await createWorkerAccount({
206
+ name: "test2",
207
+ peer: `ws://localhost:${syncServer.port}`,
208
+ });
209
+
210
+ const newWorkerRef = await Account.load(newWorkerAccount.accountID);
211
+ assert(newWorkerRef);
212
+
213
+ // Add the new worker to the group
214
+ db.group.addMember(newWorkerRef, "admin");
215
+ // Remove the previous worker if you want to rotate the worker
216
+ // db.group.removeMember(worker);
217
+
218
+ await db.group.$jazz.waitForSync();
219
+
220
+ // Start the new worker
221
+ const { worker: newWorker } = await startWorker({
222
+ syncServer: `ws://localhost:${syncServer.port}`,
223
+ accountID: newWorkerAccount.accountID,
224
+ accountSecret: newWorkerAccount.agentSecret,
225
+ });
226
+
227
+ // create the database root on the new worker with the same group and tables
228
+ await DatabaseRoot.upsertUnique({
229
+ unique: "better-auth-root",
230
+ value: {
231
+ group: db.group,
232
+ tables: db.tables,
233
+ },
234
+ owner: newWorker,
235
+ });
236
+
237
+ // Try to authenticate with the authorized new worker
238
+ const auth2 = betterAuth({
239
+ emailAndPassword: {
240
+ enabled: true,
241
+ },
242
+ database: JazzBetterAuthDatabaseAdapter({
243
+ syncServer: `ws://localhost:${syncServer.port}`,
244
+ accountID: newWorkerAccount.accountID,
245
+ accountSecret: newWorkerAccount.agentSecret,
246
+ }),
247
+ });
248
+
249
+ const res = await auth2.api.signInEmail({
250
+ body: {
251
+ email: "shared@test.com",
252
+ password: "123445678",
253
+ },
254
+ });
255
+
256
+ expect(res.user.id).match(/^co_\w+$/);
257
+ });
258
+
259
+ it("should wait for sync before returning", async () => {
260
+ const { localNode } = syncServer;
261
+
262
+ const auth = betterAuth({
263
+ database: JazzBetterAuthDatabaseAdapter({
264
+ syncServer: `ws://localhost:${syncServer.port}`,
265
+ accountID,
266
+ accountSecret,
267
+ }),
268
+ });
269
+
270
+ const adapter = (await auth.$context).adapter;
271
+
272
+ const handleSyncMessageSpy = vi.spyOn(
273
+ localNode.syncManager,
274
+ "handleNewContent",
275
+ );
276
+
277
+ const user = await adapter.create({
278
+ model: "user",
279
+ data: {
280
+ name: "test",
281
+ email: "test-sync@test.com",
282
+ password: "12345678",
283
+ },
284
+ });
285
+
286
+ expect(user.id).toMatch("co_");
287
+
288
+ expect(
289
+ handleSyncMessageSpy.mock.calls.filter(([msg]) => msg.id === user.id),
290
+ ).toHaveLength(3);
291
+ });
292
+
293
+ it("should return the new entity with date objects", async () => {
294
+ const auth = betterAuth({
295
+ database: JazzBetterAuthDatabaseAdapter({
296
+ syncServer: `ws://localhost:${syncServer.port}`,
297
+ accountID,
298
+ accountSecret,
299
+ }),
300
+ });
301
+
302
+ const date = new Date();
303
+
304
+ await (await auth.$context).internalAdapter.createVerificationValue({
305
+ identifier: "test",
306
+ value: "test",
307
+ expiresAt: date,
308
+ });
309
+
310
+ const verification = await (
311
+ await auth.$context
312
+ ).internalAdapter.findVerificationValue("test");
313
+
314
+ expect(verification).toMatchObject({
315
+ id: expect.any(String),
316
+ identifier: "test",
317
+ value: "test",
318
+ expiresAt: date,
319
+ createdAt: expect.any(Date),
320
+ updatedAt: expect.any(Date),
321
+ });
322
+ });
323
+ });
324
+
325
+ /**
326
+ * These adapter's calls are taken logging Better Auth's queries
327
+ */
328
+ describe("common user flows", async () => {
329
+ let syncServer: any;
330
+ let accountID: string;
331
+ let accountSecret: string;
332
+
333
+ beforeEach(async () => {
334
+ syncServer = await startSyncServer();
335
+
336
+ const workerAccount = await createWorkerAccount({
337
+ name: "test",
338
+ peer: `ws://localhost:${syncServer.port}`,
339
+ });
340
+
341
+ accountID = workerAccount.accountID;
342
+ accountSecret = workerAccount.agentSecret;
343
+ });
344
+
345
+ test("Email and Password: signup + signin + logout", async () => {
346
+ const adapter = JazzBetterAuthDatabaseAdapter({
347
+ syncServer: `ws://localhost:${syncServer.port}`,
348
+ accountID,
349
+ accountSecret,
350
+ })({});
351
+
352
+ // Signup process
353
+ const existingUser = await adapter.findOne({
354
+ model: "user",
355
+ where: [
356
+ {
357
+ operator: "eq",
358
+ connector: "AND",
359
+ field: "email",
360
+ value: "test@test.com",
361
+ },
362
+ ],
363
+ select: undefined,
364
+ });
365
+ expect(existingUser).toBeNull();
366
+
367
+ const user = await adapter.create({
368
+ model: "user",
369
+ data: {
370
+ name: "test",
371
+ email: "test@test.com",
372
+ emailVerified: false,
373
+ createdAt: new Date(),
374
+ updatedAt: new Date(),
375
+ },
376
+ });
377
+
378
+ expect(user.id).toMatch("co_");
379
+
380
+ const account = await adapter.create({
381
+ model: "account",
382
+ data: {
383
+ userId: user.id,
384
+ providerId: "credential",
385
+ accountId: user.id,
386
+ password: "test:test",
387
+ createdAt: new Date(),
388
+ updatedAt: new Date(),
389
+ },
390
+ });
391
+
392
+ expect(account.id).toMatch("co_");
393
+
394
+ const session = await adapter.create({
395
+ model: "session",
396
+ data: {
397
+ expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
398
+ token: "Gij57x0dpEkZAtwtAsXjXxgsWOBor5SH",
399
+ createdAt: new Date(),
400
+ updatedAt: new Date(),
401
+ ipAddress: "",
402
+ userAgent:
403
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
404
+ userId: user.id,
405
+ },
406
+ });
407
+
408
+ expect(session.id).toMatch("co_");
409
+
410
+ // Get session
411
+ const getSession = await adapter.findOne<{ userId: string }>({
412
+ model: "session",
413
+ where: [
414
+ {
415
+ operator: "eq",
416
+ connector: "AND",
417
+ field: "token",
418
+ value: "Gij57x0dpEkZAtwtAsXjXxgsWOBor5SH",
419
+ },
420
+ ],
421
+ select: undefined,
422
+ });
423
+
424
+ expect(getSession).toEqual(session);
425
+
426
+ const getSessionUser = await adapter.findOne({
427
+ model: "user",
428
+ where: [
429
+ {
430
+ operator: "eq",
431
+ connector: "AND",
432
+ field: "id",
433
+ value: getSession!.userId,
434
+ },
435
+ ],
436
+ select: undefined,
437
+ });
438
+
439
+ expect(getSessionUser).toEqual(user);
440
+
441
+ // Logout
442
+ await adapter.delete({
443
+ model: "session",
444
+ where: [
445
+ {
446
+ operator: "eq",
447
+ connector: "AND",
448
+ field: "token",
449
+ value: "Gij57x0dpEkZAtwtAsXjXxgsWOBor5SH",
450
+ },
451
+ ],
452
+ });
453
+
454
+ const postLogoutSession = await adapter.findOne<{ userId: string }>({
455
+ model: "session",
456
+ where: [
457
+ {
458
+ operator: "eq",
459
+ connector: "AND",
460
+ field: "token",
461
+ value: "Gij57x0dpEkZAtwtAsXjXxgsWOBor5SH",
462
+ },
463
+ ],
464
+ select: undefined,
465
+ });
466
+
467
+ expect(postLogoutSession).toBeNull();
468
+
469
+ // SignIn process
470
+ const signInUser = await adapter.findOne<{ id: string }>({
471
+ model: "user",
472
+ where: [
473
+ {
474
+ operator: "eq",
475
+ connector: "AND",
476
+ field: "email",
477
+ value: "test@test.com",
478
+ },
479
+ ],
480
+ select: undefined,
481
+ });
482
+
483
+ expect(signInUser).not.toBeNull();
484
+
485
+ const signInAccounts = await adapter.findMany({
486
+ model: "account",
487
+ where: [
488
+ {
489
+ operator: "eq",
490
+ connector: "AND",
491
+ field: "userId",
492
+ value: signInUser!.id,
493
+ },
494
+ ],
495
+ limit: 100,
496
+ sortBy: undefined,
497
+ offset: undefined,
498
+ });
499
+
500
+ expect(signInAccounts.length).toBe(1);
501
+
502
+ await adapter.create({
503
+ model: "session",
504
+ data: {
505
+ ipAddress: "",
506
+ userAgent:
507
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
508
+ expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
509
+ userId: signInUser!.id,
510
+ token: "s2JKPEV2eN0sio9JzvtlDwddHYcZjptW",
511
+ createdAt: new Date(),
512
+ updatedAt: new Date(),
513
+ },
514
+ });
515
+ });
516
+
517
+ test("Social Authentication: signup + signin", async () => {
518
+ const adapter = JazzBetterAuthDatabaseAdapter({
519
+ syncServer: `ws://localhost:${syncServer.port}`,
520
+ accountID,
521
+ accountSecret,
522
+ })({});
523
+
524
+ // Verification creation before leaving to Social Provider
525
+ await adapter.create({
526
+ model: "verification",
527
+ data: {
528
+ createdAt: new Date(),
529
+ updatedAt: new Date(),
530
+ value:
531
+ '{"callbackURL":"http://localhost:3000","codeVerifier":"oNjY8cSPUXUc4mU_8-wNQ1IiZGV2UzKCxjjJpPx-O3nxetLyHlViXsDLzPh_5jdgizq77mzZpnR_fTnQ52hRvBWgYA1J0Z6qrMpn-GQ0S9fgJgjmnWpwClEiKKVd2e2-","expiresAt":1755607745884}',
532
+ identifier: "Hsj2TincfRy5e96ReAwVfrkgJUa4CAcg",
533
+ expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
534
+ },
535
+ });
536
+
537
+ // Once back
538
+ const verifications = await adapter.findMany<{ id: string }>({
539
+ model: "verification",
540
+ where: [
541
+ {
542
+ operator: "eq",
543
+ connector: "AND",
544
+ field: "identifier",
545
+ value: "Hsj2TincfRy5e96ReAwVfrkgJUa4CAcg",
546
+ },
547
+ ],
548
+ limit: 1,
549
+ sortBy: { field: "createdAt", direction: "desc" },
550
+ offset: undefined,
551
+ });
552
+
553
+ expect(verifications.length).toBe(1);
554
+
555
+ await adapter.delete({
556
+ model: "verification",
557
+ where: [
558
+ {
559
+ operator: "eq",
560
+ connector: "AND",
561
+ field: "id",
562
+ value: verifications[0]!.id,
563
+ },
564
+ ],
565
+ });
566
+
567
+ const accounts = await adapter.findMany({
568
+ model: "account",
569
+ where: [
570
+ {
571
+ operator: "eq",
572
+ connector: "AND",
573
+ field: "accountId",
574
+ value: "account000",
575
+ },
576
+ ],
577
+ limit: 100,
578
+ sortBy: undefined,
579
+ offset: undefined,
580
+ });
581
+
582
+ expect(accounts.length).toBe(0);
583
+
584
+ const userWithSSOEmail = await adapter.findOne({
585
+ model: "user",
586
+ where: [
587
+ {
588
+ operator: "eq",
589
+ connector: "AND",
590
+ field: "email",
591
+ value: "test@test.com",
592
+ },
593
+ ],
594
+ select: undefined,
595
+ });
596
+
597
+ expect(userWithSSOEmail).toBeNull();
598
+
599
+ const user = await adapter.create({
600
+ model: "user",
601
+ data: {
602
+ name: "test",
603
+ email: "test@test.com",
604
+ emailVerified: false,
605
+ createdAt: new Date(),
606
+ updatedAt: new Date(),
607
+ },
608
+ });
609
+
610
+ const account = await adapter.create({
611
+ model: "account",
612
+ data: {
613
+ userId: user.id,
614
+ providerId: "github",
615
+ accountId: "account000",
616
+ accessToken: "xyz",
617
+ refreshToken: undefined,
618
+ idToken: undefined,
619
+ accessTokenExpiresAt: undefined,
620
+ refreshTokenExpiresAt: undefined,
621
+ scope: "read:user,user:email",
622
+ createdAt: new Date(),
623
+ updatedAt: new Date(),
624
+ },
625
+ });
626
+
627
+ expect(account.id).toMatch("co_");
628
+
629
+ // Verification creation before leaving to Social Provider
630
+ await adapter.create({
631
+ model: "verification",
632
+ data: {
633
+ createdAt: new Date(),
634
+ updatedAt: new Date(),
635
+ value:
636
+ '{"callbackURL":"http://localhost:3000","codeVerifier":"oNjY8cSPUXUc4mU_8-wNQ1IiZGV2UzKCxjjJpPx-O3nxetLyHlViXsDLzPh_5jdgizq77mzZpnR_fTnQ52hRvBWgYA1J0Z6qrMpn-GQ0S9fgJgjmnWpwClEiKKVd2e2-","expiresAt":1755607745884}',
637
+ identifier: "identifier002",
638
+ expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
639
+ },
640
+ });
641
+
642
+ // Once back
643
+ const verificationsSignIn = await adapter.findMany<{ id: string }>({
644
+ model: "verification",
645
+ where: [
646
+ {
647
+ operator: "eq",
648
+ connector: "AND",
649
+ field: "identifier",
650
+ value: "identifier002",
651
+ },
652
+ ],
653
+ limit: 1,
654
+ sortBy: { field: "createdAt", direction: "desc" },
655
+ offset: undefined,
656
+ });
657
+
658
+ expect(verificationsSignIn.length).toBe(1);
659
+
660
+ await adapter.delete({
661
+ model: "verification",
662
+ where: [
663
+ {
664
+ operator: "eq",
665
+ connector: "AND",
666
+ field: "id",
667
+ value: verificationsSignIn[0]!.id,
668
+ },
669
+ ],
670
+ });
671
+
672
+ const accountsSignIn = await adapter.findMany({
673
+ model: "account",
674
+ where: [
675
+ {
676
+ operator: "eq",
677
+ connector: "AND",
678
+ field: "accountId",
679
+ value: "account000",
680
+ },
681
+ ],
682
+ limit: 100,
683
+ sortBy: undefined,
684
+ offset: undefined,
685
+ });
686
+
687
+ expect(accountsSignIn.length).toBe(1);
688
+ });
689
+ });
690
+ });