@convex-dev/better-auth 0.10.12 → 0.11.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.
Files changed (185) hide show
  1. package/dist/auth-options.d.ts.map +1 -1
  2. package/dist/auth-options.js +0 -2
  3. package/dist/auth-options.js.map +1 -1
  4. package/dist/client/adapter-utils.d.ts +10 -10
  5. package/dist/client/adapter-utils.d.ts.map +1 -1
  6. package/dist/client/adapter-utils.js +41 -32
  7. package/dist/client/adapter-utils.js.map +1 -1
  8. package/dist/client/adapter.d.ts +1 -1
  9. package/dist/client/adapter.d.ts.map +1 -1
  10. package/dist/client/adapter.js +113 -7
  11. package/dist/client/adapter.js.map +1 -1
  12. package/dist/client/create-api.d.ts +8 -7
  13. package/dist/client/create-api.d.ts.map +1 -1
  14. package/dist/client/create-api.js +1 -0
  15. package/dist/client/create-api.js.map +1 -1
  16. package/dist/client/create-client.d.ts +1 -1
  17. package/dist/client/create-client.d.ts.map +1 -1
  18. package/dist/client/create-client.js +8 -7
  19. package/dist/client/create-client.js.map +1 -1
  20. package/dist/client/create-schema.d.ts +0 -1
  21. package/dist/client/create-schema.d.ts.map +1 -1
  22. package/dist/client/create-schema.js +0 -1
  23. package/dist/client/create-schema.js.map +1 -1
  24. package/dist/component/_generated/api.d.ts +12 -0
  25. package/dist/component/_generated/api.d.ts.map +1 -1
  26. package/dist/component/_generated/api.js.map +1 -1
  27. package/dist/component/_generated/component.d.ts +7407 -92
  28. package/dist/component/_generated/component.d.ts.map +1 -1
  29. package/dist/component/adapter.d.ts +8 -7
  30. package/dist/component/adapter.d.ts.map +1 -1
  31. package/dist/component/adapterTest.d.ts +1 -7
  32. package/dist/component/adapterTest.d.ts.map +1 -1
  33. package/dist/component/adapterTest.js +193 -390
  34. package/dist/component/adapterTest.js.map +1 -1
  35. package/dist/component/schema.d.ts +35 -74
  36. package/dist/component/schema.d.ts.map +1 -1
  37. package/dist/component/schema.js +16 -21
  38. package/dist/component/schema.js.map +1 -1
  39. package/dist/component/testProfiles/adapterAdditionalFields.d.ts +131 -0
  40. package/dist/component/testProfiles/adapterAdditionalFields.d.ts.map +1 -0
  41. package/dist/component/testProfiles/adapterAdditionalFields.js +5 -0
  42. package/dist/component/testProfiles/adapterAdditionalFields.js.map +1 -0
  43. package/dist/component/testProfiles/adapterOrganizationJoins.d.ts +131 -0
  44. package/dist/component/testProfiles/adapterOrganizationJoins.d.ts.map +1 -0
  45. package/dist/component/testProfiles/adapterOrganizationJoins.js +5 -0
  46. package/dist/component/testProfiles/adapterOrganizationJoins.js.map +1 -0
  47. package/dist/component/testProfiles/adapterPluginTable.d.ts +131 -0
  48. package/dist/component/testProfiles/adapterPluginTable.d.ts.map +1 -0
  49. package/dist/component/testProfiles/adapterPluginTable.js +5 -0
  50. package/dist/component/testProfiles/adapterPluginTable.js.map +1 -0
  51. package/dist/component/testProfiles/adapterRenameField.d.ts +131 -0
  52. package/dist/component/testProfiles/adapterRenameField.d.ts.map +1 -0
  53. package/dist/component/testProfiles/adapterRenameField.js +5 -0
  54. package/dist/component/testProfiles/adapterRenameField.js.map +1 -0
  55. package/dist/component/testProfiles/adapterRenameUserCustom.d.ts +131 -0
  56. package/dist/component/testProfiles/adapterRenameUserCustom.d.ts.map +1 -0
  57. package/dist/component/testProfiles/adapterRenameUserCustom.js +5 -0
  58. package/dist/component/testProfiles/adapterRenameUserCustom.js.map +1 -0
  59. package/dist/component/testProfiles/adapterRenameUserTable.d.ts +131 -0
  60. package/dist/component/testProfiles/adapterRenameUserTable.d.ts.map +1 -0
  61. package/dist/component/testProfiles/adapterRenameUserTable.js +5 -0
  62. package/dist/component/testProfiles/adapterRenameUserTable.js.map +1 -0
  63. package/dist/component/testProfiles/auth-options.profile-additional-fields.d.ts +3 -0
  64. package/dist/component/testProfiles/auth-options.profile-additional-fields.d.ts.map +1 -0
  65. package/dist/component/testProfiles/auth-options.profile-additional-fields.js +38 -0
  66. package/dist/component/testProfiles/auth-options.profile-additional-fields.js.map +1 -0
  67. package/dist/component/testProfiles/auth-options.profile-plugin-table.d.ts +3 -0
  68. package/dist/component/testProfiles/auth-options.profile-plugin-table.d.ts.map +1 -0
  69. package/dist/component/testProfiles/auth-options.profile-plugin-table.js +92 -0
  70. package/dist/component/testProfiles/auth-options.profile-plugin-table.js.map +1 -0
  71. package/dist/component/testProfiles/auth-options.profile-rename-joins.d.ts +6 -0
  72. package/dist/component/testProfiles/auth-options.profile-rename-joins.d.ts.map +1 -0
  73. package/dist/component/testProfiles/auth-options.profile-rename-joins.js +49 -0
  74. package/dist/component/testProfiles/auth-options.profile-rename-joins.js.map +1 -0
  75. package/dist/component/testProfiles/schema.profile-additional-fields.d.ts +227 -0
  76. package/dist/component/testProfiles/schema.profile-additional-fields.d.ts.map +1 -0
  77. package/dist/component/testProfiles/schema.profile-additional-fields.js +37 -0
  78. package/dist/component/testProfiles/schema.profile-additional-fields.js.map +1 -0
  79. package/dist/component/testProfiles/schema.profile-plugin-table.d.ts +450 -0
  80. package/dist/component/testProfiles/schema.profile-plugin-table.d.ts.map +1 -0
  81. package/dist/component/testProfiles/schema.profile-plugin-table.js +116 -0
  82. package/dist/component/testProfiles/schema.profile-plugin-table.js.map +1 -0
  83. package/dist/nextjs/index.d.ts.map +1 -1
  84. package/dist/nextjs/index.js +1 -0
  85. package/dist/nextjs/index.js.map +1 -1
  86. package/dist/plugins/convex/index.d.ts +131 -12
  87. package/dist/plugins/convex/index.d.ts.map +1 -1
  88. package/dist/plugins/convex/index.js +12 -5
  89. package/dist/plugins/convex/index.js.map +1 -1
  90. package/dist/plugins/cross-domain/client.d.ts +1 -1
  91. package/dist/plugins/cross-domain/index.d.ts +126 -1
  92. package/dist/plugins/cross-domain/index.d.ts.map +1 -1
  93. package/dist/plugins/cross-domain/index.js +11 -16
  94. package/dist/plugins/cross-domain/index.js.map +1 -1
  95. package/dist/react-start/index.d.ts.map +1 -1
  96. package/dist/react-start/index.js +1 -0
  97. package/dist/react-start/index.js.map +1 -1
  98. package/dist/test/adapter-factory/auth-flow.d.ts +42 -0
  99. package/dist/test/adapter-factory/auth-flow.d.ts.map +1 -0
  100. package/dist/test/adapter-factory/auth-flow.js +145 -0
  101. package/dist/test/adapter-factory/auth-flow.js.map +1 -0
  102. package/dist/test/adapter-factory/basic.d.ts +190 -0
  103. package/dist/test/adapter-factory/basic.d.ts.map +1 -0
  104. package/dist/test/adapter-factory/basic.js +2713 -0
  105. package/dist/test/adapter-factory/basic.js.map +1 -0
  106. package/dist/test/adapter-factory/convex-custom.d.ts +18 -0
  107. package/dist/test/adapter-factory/convex-custom.d.ts.map +1 -0
  108. package/dist/test/adapter-factory/convex-custom.js +610 -0
  109. package/dist/test/adapter-factory/convex-custom.js.map +1 -0
  110. package/dist/test/adapter-factory/index.d.ts +11 -0
  111. package/dist/test/adapter-factory/index.d.ts.map +1 -0
  112. package/dist/test/adapter-factory/index.js +11 -0
  113. package/dist/test/adapter-factory/index.js.map +1 -0
  114. package/dist/test/adapter-factory/joins.d.ts +18 -0
  115. package/dist/test/adapter-factory/joins.d.ts.map +1 -0
  116. package/dist/test/adapter-factory/joins.js +22 -0
  117. package/dist/test/adapter-factory/joins.js.map +1 -0
  118. package/dist/test/adapter-factory/number-id.d.ts +18 -0
  119. package/dist/test/adapter-factory/number-id.d.ts.map +1 -0
  120. package/dist/test/adapter-factory/number-id.js +36 -0
  121. package/dist/test/adapter-factory/number-id.js.map +1 -0
  122. package/dist/test/adapter-factory/profile-additional-fields.d.ts +71 -0
  123. package/dist/test/adapter-factory/profile-additional-fields.d.ts.map +1 -0
  124. package/dist/test/adapter-factory/profile-additional-fields.js +44 -0
  125. package/dist/test/adapter-factory/profile-additional-fields.js.map +1 -0
  126. package/dist/test/adapter-factory/profile-plugin-table.d.ts +19 -0
  127. package/dist/test/adapter-factory/profile-plugin-table.d.ts.map +1 -0
  128. package/dist/test/adapter-factory/profile-plugin-table.js +25 -0
  129. package/dist/test/adapter-factory/profile-plugin-table.js.map +1 -0
  130. package/dist/test/adapter-factory/profile-rename-joins.d.ts +73 -0
  131. package/dist/test/adapter-factory/profile-rename-joins.d.ts.map +1 -0
  132. package/dist/test/adapter-factory/profile-rename-joins.js +34 -0
  133. package/dist/test/adapter-factory/profile-rename-joins.js.map +1 -0
  134. package/dist/test/adapter-factory/transactions.d.ts +21 -0
  135. package/dist/test/adapter-factory/transactions.d.ts.map +1 -0
  136. package/dist/test/adapter-factory/transactions.js +28 -0
  137. package/dist/test/adapter-factory/transactions.js.map +1 -0
  138. package/dist/test/adapter-factory/uuid.d.ts +18 -0
  139. package/dist/test/adapter-factory/uuid.d.ts.map +1 -0
  140. package/dist/test/adapter-factory/uuid.js +58 -0
  141. package/dist/test/adapter-factory/uuid.js.map +1 -0
  142. package/dist/utils/index.d.ts +18 -3
  143. package/dist/utils/index.d.ts.map +1 -1
  144. package/dist/utils/index.js.map +1 -1
  145. package/package.json +9 -6
  146. package/src/auth-options.ts +0 -2
  147. package/src/client/adapter-utils.ts +80 -73
  148. package/src/client/adapter.test.ts +2 -74
  149. package/src/client/adapter.ts +142 -7
  150. package/src/client/create-api.ts +1 -0
  151. package/src/client/create-client.ts +14 -6
  152. package/src/client/create-schema.ts +0 -1
  153. package/src/component/_generated/api.ts +12 -0
  154. package/src/component/_generated/component.ts +19454 -215
  155. package/src/component/adapterTest.ts +250 -466
  156. package/src/component/schema.ts +21 -26
  157. package/src/component/testProfiles/adapterAdditionalFields.ts +13 -0
  158. package/src/component/testProfiles/adapterOrganizationJoins.ts +13 -0
  159. package/src/component/testProfiles/adapterPluginTable.ts +13 -0
  160. package/src/component/testProfiles/adapterRenameField.ts +13 -0
  161. package/src/component/testProfiles/adapterRenameUserCustom.ts +13 -0
  162. package/src/component/testProfiles/adapterRenameUserTable.ts +13 -0
  163. package/src/component/testProfiles/auth-options.profile-additional-fields.ts +39 -0
  164. package/src/component/testProfiles/auth-options.profile-plugin-table.ts +93 -0
  165. package/src/component/testProfiles/auth-options.profile-rename-joins.ts +54 -0
  166. package/src/component/testProfiles/schema.profile-additional-fields.ts +39 -0
  167. package/src/component/testProfiles/schema.profile-plugin-table.ts +130 -0
  168. package/src/nextjs/index.ts +1 -0
  169. package/src/plugins/convex/index.test.ts +55 -0
  170. package/src/plugins/convex/index.ts +26 -11
  171. package/src/plugins/cross-domain/index.test.ts +67 -0
  172. package/src/plugins/cross-domain/index.ts +11 -22
  173. package/src/react-start/index.ts +1 -0
  174. package/src/test/adapter-factory/auth-flow.ts +170 -0
  175. package/src/test/adapter-factory/basic.ts +3190 -0
  176. package/src/test/adapter-factory/convex-custom.ts +706 -0
  177. package/src/test/adapter-factory/index.ts +10 -0
  178. package/src/test/adapter-factory/joins.ts +28 -0
  179. package/src/test/adapter-factory/number-id.ts +45 -0
  180. package/src/test/adapter-factory/profile-additional-fields.ts +84 -0
  181. package/src/test/adapter-factory/profile-plugin-table.ts +37 -0
  182. package/src/test/adapter-factory/profile-rename-joins.ts +67 -0
  183. package/src/test/adapter-factory/transactions.ts +38 -0
  184. package/src/test/adapter-factory/uuid.ts +67 -0
  185. package/src/utils/index.ts +25 -3
@@ -1,8 +1,22 @@
1
- import type { Auth } from "better-auth";
2
- import type { betterAuth } from "better-auth/minimal";
3
1
  import type { AuthProvider, DefaultFunctionArgs, FunctionReference, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx } from "convex/server";
4
2
  import type { Jwk } from "better-auth/plugins/jwt";
5
- export type CreateAuth<DataModel extends GenericDataModel, A extends ReturnType<typeof betterAuth> = Auth> = (ctx: GenericCtx<DataModel>) => A;
3
+ type TrustedOriginsOption = (string | null | undefined)[] | ((request?: Request) => (string | null | undefined)[] | Promise<(string | null | undefined)[]>);
4
+ type RegisterableAuth = {
5
+ handler: (request: Request) => Promise<Response>;
6
+ options: {
7
+ baseURL?: string;
8
+ basePath?: string;
9
+ trustedOrigins?: TrustedOriginsOption;
10
+ [key: string]: unknown;
11
+ };
12
+ $context: Promise<{
13
+ options: {
14
+ trustedOrigins?: TrustedOriginsOption;
15
+ [key: string]: unknown;
16
+ };
17
+ }>;
18
+ };
19
+ export type CreateAuth<DataModel extends GenericDataModel, A extends RegisterableAuth = RegisterableAuth> = (ctx: GenericCtx<DataModel>) => A;
6
20
  export type EventFunction<T extends DefaultFunctionArgs> = FunctionReference<"mutation", "internal" | "public", T>;
7
21
  export type GenericCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericQueryCtx<DataModel> | GenericMutationCtx<DataModel> | GenericActionCtx<DataModel>;
8
22
  export type RunMutationCtx<DataModel extends GenericDataModel> = (GenericMutationCtx<DataModel> | GenericActionCtx<DataModel>) & {
@@ -30,4 +44,5 @@ export declare const getToken: (siteUrl: string, headers: Headers, opts?: GetTok
30
44
  token: string | undefined;
31
45
  }>;
32
46
  export declare const parseJwks: (providerConfig: AuthProvider) => Jwk | undefined;
47
+ export {};
33
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "bugs": {
7
7
  "url": "https://github.com/get-convex/better-auth/issues"
8
8
  },
9
- "version": "0.10.12",
9
+ "version": "0.11.0",
10
10
  "license": "Apache-2.0",
11
11
  "keywords": [
12
12
  "convex",
@@ -30,8 +30,10 @@
30
30
  "test:debug": "vitest --inspect-brk --no-file-parallelism",
31
31
  "test:e2e": "npm run build && cd e2e && npm run test",
32
32
  "test:coverage": "vitest run --coverage --coverage.reporter=text",
33
+ "test:adapter-policy": "node test/adapter-policy/validate.mjs",
34
+ "test:adapter-drift": "node test/adapter-policy/check-upstream-drift.mjs",
33
35
  "preversion": "npm ci && npm run build:clean && run-p test lint typecheck",
34
- "prepublishOnly": "npm whoami || npm login",
36
+ "prepublishOnly": "npm whoami || npm login && sleep 1",
35
37
  "alpha": "npm version prerelease --preid alpha && npm publish --tag alpha && git push --follow-tags",
36
38
  "release": "npm version patch && npm publish && git push --follow-tags",
37
39
  "version": "vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md"
@@ -103,12 +105,13 @@
103
105
  }
104
106
  },
105
107
  "peerDependencies": {
106
- "better-auth": ">=1.4.9 <1.5.0",
108
+ "better-auth": ">=1.5.0 <1.6.0",
107
109
  "convex": "^1.25.0",
108
- "react": "^18.3.1 || ^19.0.0",
109
- "react-dom": "^18.3.1 || ^19.0.0"
110
+ "react": "^18.3.1 || ^19.0.0"
110
111
  },
111
112
  "devDependencies": {
113
+ "@better-auth/core": "^1.5.3",
114
+ "@better-auth/test-utils": "^1.5.3",
112
115
  "@edge-runtime/vm": "5.0.0",
113
116
  "@eslint/eslintrc": "3.3.1",
114
117
  "@eslint/js": "9.39.1",
@@ -118,6 +121,7 @@
118
121
  "@types/react": "18.3.26",
119
122
  "@types/react-dom": "18.3.7",
120
123
  "@types/semver": "^7.7.0",
124
+ "better-auth": "^1.5.3",
121
125
  "chokidar-cli": "3.0.0",
122
126
  "concurrently": "^9.2.0",
123
127
  "convex": "^1.31.2",
@@ -142,7 +146,6 @@
142
146
  "types": "./dist/client/index.d.ts",
143
147
  "module": "./dist/client/index.js",
144
148
  "dependencies": {
145
- "@better-auth/passkey": "1.4.9",
146
149
  "@better-fetch/fetch": "^1.1.18",
147
150
  "common-tags": "^1.8.2",
148
151
  "convex-helpers": "^0.1.95",
@@ -13,7 +13,6 @@ import {
13
13
  twoFactor,
14
14
  username,
15
15
  } from "better-auth/plugins";
16
- import { passkey } from "@better-auth/passkey";
17
16
  import { convex } from "./plugins/convex/index.js";
18
17
  import { convexAdapter } from "./client/adapter.js";
19
18
 
@@ -30,7 +29,6 @@ export const options = {
30
29
  phoneNumber(),
31
30
  magicLink({ sendMagicLink: async () => {} }),
32
31
  emailOTP({ sendVerificationOTP: async () => {} }),
33
- passkey(),
34
32
  genericOAuth({
35
33
  config: [
36
34
  {
@@ -279,7 +279,7 @@ export const checkUniqueFields = async <
279
279
 
280
280
  // This handles basic select (stripping out the other fields if there
281
281
  // is a select arg).
282
- export const selectFields = async <
282
+ export const selectFields = <
283
283
  T extends TableNamesInDataModel<GenericDataModel>,
284
284
  D extends DocumentByName<GenericDataModel, T>,
285
285
  >(
@@ -293,7 +293,10 @@ export const selectFields = async <
293
293
  return doc;
294
294
  }
295
295
  return select.reduce((acc, field) => {
296
- (acc as any)[field] = doc[field];
296
+ // Better Auth may request "id" while Convex stores it as "_id".
297
+ // Keep the raw field key here and let Better Auth map "_id" -> "id".
298
+ const sourceField = field === "id" && "_id" in doc ? "_id" : field;
299
+ (acc as any)[sourceField] = doc[sourceField as keyof typeof doc];
297
300
  return acc;
298
301
  }, {} as D);
299
302
  };
@@ -321,19 +324,19 @@ const filterByWhere = <
321
324
  typeof adapterWhereValidator
322
325
  >["value"];
323
326
  const isLessThan = (val: typeof value, wVal: typeof w.value) => {
324
- if (!wVal) {
327
+ if (wVal === undefined || wVal === null) {
325
328
  return false;
326
329
  }
327
- if (!val) {
330
+ if (val === undefined || val === null) {
328
331
  return true;
329
332
  }
330
333
  return val < wVal;
331
334
  };
332
335
  const isGreaterThan = (val: typeof value, wVal: typeof w.value) => {
333
- if (!val) {
336
+ if (val === undefined || val === null) {
334
337
  return false;
335
338
  }
336
- if (!wVal) {
339
+ if (wVal === undefined || wVal === null) {
337
340
  return true;
338
341
  }
339
342
  return val > wVal;
@@ -394,54 +397,57 @@ const generateQuery = (
394
397
  ) => {
395
398
  const { index, values, boundField, indexFields } =
396
399
  findIndex(schema, args) ?? {};
400
+ const usableIndex =
401
+ index?.indexDescriptor === "by_creation_time" ? undefined : index;
397
402
  const query = stream(ctx.db as any, schema).query(args.model as any);
398
403
  const hasValues =
399
- values?.eq?.length ||
400
- values?.lt ||
401
- values?.lte ||
402
- values?.gt ||
403
- values?.gte;
404
- const indexedQuery =
405
- index && index.indexDescriptor !== "by_creation_time"
406
- ? query.withIndex(
407
- index.indexDescriptor,
408
- hasValues
409
- ? (q: any) => {
410
- for (const [idx, value] of (values?.eq ?? []).entries()) {
411
- q = q.eq(index.fields[idx], value);
412
- }
413
- if (values?.lt) {
414
- q = q.lt(boundField, values.lt);
415
- }
416
- if (values?.lte) {
417
- q = q.lte(boundField, values.lte);
418
- }
419
- if (values?.gt) {
420
- q = q.gt(boundField, values.gt);
421
- }
422
- if (values?.gte) {
423
- q = q.gte(boundField, values.gte);
424
- }
425
- return q;
404
+ (values?.eq?.length ?? 0) > 0 ||
405
+ values?.lt !== undefined ||
406
+ values?.lte !== undefined ||
407
+ values?.gt !== undefined ||
408
+ values?.gte !== undefined;
409
+ const indexedQuery = usableIndex
410
+ ? query.withIndex(
411
+ usableIndex.indexDescriptor,
412
+ hasValues
413
+ ? (q: any) => {
414
+ for (const [idx, value] of (values?.eq ?? []).entries()) {
415
+ q = q.eq(usableIndex.fields[idx], value);
426
416
  }
427
- : undefined
428
- )
429
- : query;
417
+ if (values?.lt !== undefined) {
418
+ q = q.lt(boundField, values.lt);
419
+ }
420
+ if (values?.lte !== undefined) {
421
+ q = q.lte(boundField, values.lte);
422
+ }
423
+ if (values?.gt !== undefined) {
424
+ q = q.gt(boundField, values.gt);
425
+ }
426
+ if (values?.gte !== undefined) {
427
+ q = q.gte(boundField, values.gte);
428
+ }
429
+ return q;
430
+ }
431
+ : undefined
432
+ )
433
+ : query;
430
434
  const orderedQuery = args.sortBy
431
435
  ? indexedQuery.order(args.sortBy.direction === "desc" ? "desc" : "asc")
432
436
  : indexedQuery;
437
+ if (!usableIndex && indexFields?.length) {
438
+ // eslint-disable-next-line no-console
439
+ console.warn(
440
+ stripIndent`
441
+ Querying without an index on table "${args.model}".
442
+ This can cause performance issues, and may hit the document read limit.
443
+ To fix, add an index that begins with the following fields in order:
444
+ [${indexFields.join(", ")}]
445
+ `
446
+ );
447
+ }
433
448
  const filteredQuery = orderedQuery.filterWith(async (doc) => {
434
- if (!index && indexFields?.length) {
435
- // eslint-disable-next-line no-console
436
- console.warn(
437
- stripIndent`
438
- Querying without an index on table "${args.model}".
439
- This can cause performance issues, and may hit the document read limit.
440
- To fix, add an index that begins with the following fields in order:
441
- [${indexFields.join(", ")}]
442
- `
443
- );
444
- // No index, handle all where clauses statically.
449
+ if (!usableIndex) {
450
+ // No usable index, handle all where clauses statically.
445
451
  return filterByWhere(doc, args.where);
446
452
  }
447
453
  return filterByWhere(
@@ -521,7 +527,7 @@ export const paginate = async <
521
527
  // Apply all other clauses as static filters to our 0 or 1 result.
522
528
  if (filterByWhere(doc, args.where, (w) => w !== uniqueWhere)) {
523
529
  return {
524
- page: [await selectFields(doc, args.select)].filter(Boolean) as Doc[],
530
+ page: [selectFields(doc, args.select)].filter(Boolean) as Doc[],
525
531
  isDone: true,
526
532
  continueCursor: "",
527
533
  };
@@ -559,28 +565,31 @@ export const paginate = async <
559
565
  .filter((doc) => filterByWhere(doc, args.where, (w) => w !== inWhere));
560
566
 
561
567
  return {
562
- page: filteredDocs.sort((a, b) => {
563
- if (args.sortBy?.field === "createdAt") {
564
- return args.sortBy.direction === "asc"
565
- ? (a._creationTime as number) - (b._creationTime as number)
566
- : (b._creationTime as number) - (a._creationTime as number);
567
- }
568
- if (args.sortBy) {
569
- const aValue = a[args.sortBy.field as keyof typeof a];
570
- const bValue = b[args.sortBy.field as keyof typeof b];
571
- if (aValue === bValue) {
572
- return 0;
568
+ page: filteredDocs
569
+ .sort((a, b) => {
570
+ if (args.sortBy?.field === "createdAt") {
571
+ return args.sortBy.direction === "asc"
572
+ ? (a._creationTime as number) - (b._creationTime as number)
573
+ : (b._creationTime as number) - (a._creationTime as number);
573
574
  }
574
- return args.sortBy.direction === "asc"
575
- ? aValue! > bValue!
576
- ? 1
577
- : -1
578
- : aValue! > bValue!
579
- ? -1
580
- : 1;
581
- }
582
- return 0;
583
- }) as Doc[],
575
+ if (args.sortBy) {
576
+ const aValue = a[args.sortBy.field as keyof typeof a];
577
+ const bValue = b[args.sortBy.field as keyof typeof b];
578
+ if (aValue === bValue) {
579
+ return 0;
580
+ }
581
+ return args.sortBy.direction === "asc"
582
+ ? aValue! > bValue!
583
+ ? 1
584
+ : -1
585
+ : aValue! > bValue!
586
+ ? -1
587
+ : 1;
588
+ }
589
+ return 0;
590
+ })
591
+ .map((doc) => selectFields(doc, args.select))
592
+ .flatMap((doc) => (doc ? [doc] : [])) as Doc[],
584
593
  isDone: true,
585
594
  continueCursor: "",
586
595
  };
@@ -605,9 +614,7 @@ export const paginate = async <
605
614
  ).paginate(paginationOpts);
606
615
  return {
607
616
  ...result,
608
- page: await asyncMap(result.page, (doc) =>
609
- selectFields(doc, args.select)
610
- ),
617
+ page: result.page.map((doc) => selectFields(doc, args.select)),
611
618
  };
612
619
  }
613
620
 
@@ -615,7 +622,7 @@ export const paginate = async <
615
622
  const result = await query.paginate(paginationOpts);
616
623
  return {
617
624
  ...result,
618
- page: await asyncMap(result.page, (doc) => selectFields(doc, args.select)),
625
+ page: result.page.map((doc) => selectFields(doc, args.select)),
619
626
  };
620
627
  };
621
628
 
@@ -1,83 +1,11 @@
1
1
  /// <reference types="vite/client" />
2
2
 
3
3
  import { describe } from "vitest";
4
- import type { runAdapterTest } from "better-auth/adapters/test";
5
4
  import { convexTest } from "convex-test";
6
5
  import { api } from "../component/_generated/api.js";
7
- import schema from "../component/schema.js";
8
- import { createClient } from "./create-client.js";
9
- import type { DataModel } from "../component/_generated/dataModel.js";
10
- import type { BetterAuthOptions } from "better-auth/types";
11
- import type { GenericCtx } from "./index.js";
12
-
13
- export const getAdapter: (
14
- ctx: GenericCtx<DataModel>
15
- ) => Parameters<typeof runAdapterTest>[0]["getAdapter"] =
16
- (ctx: GenericCtx<DataModel>) =>
17
- async (opts?: Omit<BetterAuthOptions, "database">) => {
18
- const authComponent = createClient<DataModel>(api as any, {
19
- verbose: false,
20
- });
21
- const adapterFactory = authComponent.adapter(ctx);
22
- return adapterFactory(opts ?? {});
23
- };
6
+ import schema from "../component/testProfiles/schema.profile-plugin-table.js";
24
7
 
25
8
  describe("Better Auth Adapter Tests", async () => {
26
- const status = {
27
- active: "active",
28
- only: "only",
29
- notSupported: "not supported",
30
- } as const;
31
- const tests: Record<string, (typeof status)[keyof typeof status]> = {
32
- CREATE_MODEL: status.active,
33
- CREATE_MODEL_SHOULD_ALWAYS_RETURN_AN_ID: status.active,
34
- FIND_MODEL: status.active,
35
- FIND_MODEL_WITHOUT_ID: status.active,
36
- FIND_MODEL_WITH_SELECT: status.active,
37
- // Requires a custom schema - we fake success by overriding custom user
38
- // schema in the test adapter because this test creates a user that other
39
- // tests rely on.
40
- FIND_MODEL_WITH_MODIFIED_FIELD_NAME: status.active,
41
- UPDATE_MODEL: status.active,
42
- SHOULD_FIND_MANY: status.active,
43
- SHOULD_FIND_MANY_WITH_WHERE: status.active,
44
- SHOULD_FIND_MANY_WITH_OPERATORS: status.active,
45
- SHOULD_WORK_WITH_REFERENCE_FIELDS: status.active,
46
- SHOULD_FIND_MANY_WITH_NOT_IN_OPERATOR: status.active,
47
- SHOULD_FIND_MANY_WITH_SORT_BY: status.active,
48
- SHOULD_FIND_MANY_WITH_LIMIT: status.active,
49
- SHOULD_UPDATE_WITH_MULTIPLE_WHERE: status.active,
50
- DELETE_MODEL: status.active,
51
- SHOULD_DELETE_MANY: status.active,
52
- SHOULD_NOT_THROW_ON_DELETE_RECORD_NOT_FOUND: status.active,
53
- SHOULD_NOT_THROW_ON_RECORD_NOT_FOUND: status.active,
54
- SHOULD_FIND_MANY_WITH_CONTAINS_OPERATOR: status.active,
55
- SHOULD_SEARCH_USERS_WITH_STARTS_WITH: status.active,
56
- SHOULD_SEARCH_USERS_WITH_ENDS_WITH: status.active,
57
- // Use local install and Convex paginated queries
58
- SHOULD_FIND_MANY_WITH_OFFSET: status.notSupported,
59
- // Convex generates ids on insert
60
- SHOULD_PREFER_GENERATE_ID_IF_PROVIDED: status.notSupported,
61
- // Transactions are inherent for auth.api and not possible for authClient
62
- SHOULD_ROLLBACK_FAILING_TRANSACTION: status.notSupported,
63
- SHOULD_RETURN_TRANSACTION_RESULT: status.notSupported,
64
- SHOULD_FIND_MANY_WITH_CONNECTORS: status.active,
65
- };
66
-
67
- const disableTests = Object.fromEntries(
68
- Object.entries(tests).map((entry, idx, arr) => {
69
- if (arr.some((e) => e[1] === status.only)) {
70
- return [entry[0], !(entry[1] === status.only)];
71
- }
72
- return [entry[0], !(entry[1] === status.active)];
73
- })
74
- );
75
-
76
- const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
77
- await t.action(api.adapterTest.runTests, { disableTests });
78
- });
79
-
80
- describe("Convex Adapter Tests", async () => {
81
9
  const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
82
- await t.action(api.adapterTest.runCustomTests);
10
+ await t.action(api.adapterTest.runTests, {});
83
11
  });
@@ -14,12 +14,14 @@ import type { SetOptional } from "type-fest";
14
14
  import type defaultSchema from "../component/schema.js";
15
15
  import type { Where } from "better-auth/types";
16
16
  import { asyncMap } from "convex-helpers";
17
- import { prop, sortBy, unique } from "remeda";
17
+ import { prop, sortBy } from "remeda";
18
18
  import { isRunMutationCtx } from "../utils/index.js";
19
19
  import type { Doc, TableNames } from "../component/_generated/dataModel.js";
20
20
  import type { ComponentApi } from "../component/_generated/component.js";
21
21
  import type { AuthFunctions, GenericCtx, Triggers } from "./index.js";
22
22
 
23
+ let didWarnExperimentalJoinsUnsupported = false;
24
+
23
25
  const handlePagination = async (
24
26
  next: ({
25
27
  paginationOpts,
@@ -102,6 +104,58 @@ const parseWhere = (
102
104
  }) as ConvexCleanedWhere[];
103
105
  };
104
106
 
107
+ type DocWithFlexibleId = {
108
+ _id?: string | null;
109
+ id?: string | null;
110
+ };
111
+
112
+ const getDocId = (doc: DocWithFlexibleId) => {
113
+ if (doc?._id !== undefined && doc?._id !== null) {
114
+ return String(doc._id);
115
+ }
116
+ if (doc?.id !== undefined && doc?.id !== null) {
117
+ return String(doc.id);
118
+ }
119
+ return undefined;
120
+ };
121
+
122
+ const dedupeDocsById = <T extends DocWithFlexibleId>(docs: T[]) => {
123
+ const seen = new Set<string>();
124
+ const deduped: T[] = [];
125
+ for (const doc of docs) {
126
+ const id = getDocId(doc);
127
+ if (!id) {
128
+ deduped.push(doc);
129
+ continue;
130
+ }
131
+ if (seen.has(id)) {
132
+ continue;
133
+ }
134
+ seen.add(id);
135
+ deduped.push(doc);
136
+ }
137
+ return deduped;
138
+ };
139
+
140
+ const selectDocFields = (
141
+ doc: DocWithFlexibleId & Record<string, unknown>,
142
+ select?: string[]
143
+ ) => {
144
+ if (!select?.length) {
145
+ return doc;
146
+ }
147
+ return select.reduce(
148
+ (acc, field) => {
149
+ // Better Auth may request "id" while Convex stores it as "_id".
150
+ // Keep "_id" so Better Auth output mapping can translate to "id".
151
+ const sourceField = field === "id" && "_id" in doc ? "_id" : field;
152
+ acc[sourceField] = doc[sourceField];
153
+ return acc;
154
+ },
155
+ {} as Record<string, unknown>
156
+ );
157
+ };
158
+
105
159
  export const convexAdapter = <
106
160
  DataModel extends GenericDataModel,
107
161
  Ctx extends GenericCtx<DataModel> = GenericActionCtx<DataModel>,
@@ -154,6 +208,41 @@ export const convexAdapter = <
154
208
  adapter: ({ options }) => {
155
209
  // Disable telemetry in all cases because it requires Node
156
210
  options.telemetry = { enabled: false };
211
+ if (options.experimental?.joins) {
212
+ options.experimental = {
213
+ ...options.experimental,
214
+ joins: false,
215
+ };
216
+ if (!didWarnExperimentalJoinsUnsupported) {
217
+ didWarnExperimentalJoinsUnsupported = true;
218
+ // eslint-disable-next-line no-console
219
+ console.warn(
220
+ "[convex-better-auth] Better Auth experimental.joins is not supported by the Convex adapter yet. Forcing experimental.joins = false."
221
+ );
222
+ }
223
+ }
224
+
225
+ const collectIdsForOrWhere = async (data: {
226
+ model: string;
227
+ where: (Where & { join?: undefined })[];
228
+ }) => {
229
+ const results = await asyncMap(data.where, async (w) =>
230
+ handlePagination(
231
+ async ({ paginationOpts }) => {
232
+ return await ctx.runQuery(api.adapter.findMany, {
233
+ model: data.model as TableNames,
234
+ where: parseWhere(w),
235
+ paginationOpts,
236
+ });
237
+ }
238
+ )
239
+ );
240
+ const ids = dedupeDocsById(results.flatMap((r) => r.docs))
241
+ .map((doc) => getDocId(doc))
242
+ .flatMap((id) => (id ? [id] : []));
243
+ return ids;
244
+ };
245
+
157
246
  return {
158
247
  id: "convex",
159
248
  options: {
@@ -204,11 +293,14 @@ export const convexAdapter = <
204
293
  }
205
294
 
206
295
  if (data.where?.some((w) => w.connector === "OR")) {
296
+ // Always fetch full docs for OR unions so we can dedupe
297
+ // by id and sort/limit before trimming selected fields.
298
+ const { select: _ignoredSelect, ...queryData } = data;
207
299
  const results = await asyncMap(data.where, async (w) =>
208
300
  handlePagination(
209
301
  async ({ paginationOpts }) => {
210
302
  return await ctx.runQuery(api.adapter.findMany, {
211
- ...data,
303
+ ...queryData,
212
304
  model: data.model as TableNames,
213
305
  where: parseWhere(w),
214
306
  paginationOpts,
@@ -217,14 +309,17 @@ export const convexAdapter = <
217
309
  { limit: data.limit }
218
310
  )
219
311
  );
220
- const docs = unique(results.flatMap((r) => r.docs));
312
+ let docs = dedupeDocsById(results.flatMap((r) => r.docs));
221
313
  if (data.sortBy) {
222
- return sortBy(docs, [
314
+ docs = sortBy(docs, [
223
315
  prop(data.sortBy.field),
224
316
  data.sortBy.direction,
225
317
  ]);
226
318
  }
227
- return docs;
319
+ if (data.limit !== undefined) {
320
+ docs = docs.slice(0, data.limit);
321
+ }
322
+ return docs.map((doc) => selectDocFields(doc, data.select));
228
323
  }
229
324
 
230
325
  const result = await handlePagination(
@@ -253,7 +348,7 @@ export const convexAdapter = <
253
348
  });
254
349
  })
255
350
  );
256
- const docs = unique(results.flatMap((r) => r.docs));
351
+ const docs = dedupeDocsById(results.flatMap((r) => r.docs));
257
352
  return docs.length;
258
353
  }
259
354
 
@@ -271,7 +366,7 @@ export const convexAdapter = <
271
366
  if (!("runMutation" in ctx)) {
272
367
  throw new Error("ctx is not a mutation ctx");
273
368
  }
274
- if (data.where?.length === 1 && data.where[0].operator === "eq") {
369
+ if (data.where?.length && !data.where.some((w) => w.connector === "OR")) {
275
370
  const onUpdateHandle =
276
371
  config.authFunctions?.onUpdate &&
277
372
  config.triggers?.[data.model]?.onUpdate
@@ -320,6 +415,22 @@ export const convexAdapter = <
320
415
  config.authFunctions.onDelete
321
416
  )) as FunctionHandle<"mutation">)
322
417
  : undefined;
418
+ if (data.where?.some((w) => w.connector === "OR")) {
419
+ const ids = await collectIdsForOrWhere({
420
+ model: data.model as string,
421
+ where: data.where,
422
+ });
423
+ await asyncMap(ids, async (id) => {
424
+ await ctx.runMutation(api.adapter.deleteOne, {
425
+ input: {
426
+ model: data.model as TableNames,
427
+ where: [{ field: "_id", operator: "eq", value: id }],
428
+ },
429
+ onDeleteHandle: onDeleteHandle,
430
+ });
431
+ });
432
+ return ids.length;
433
+ }
323
434
  const result = await handlePagination(async ({ paginationOpts }) => {
324
435
  return await ctx.runMutation(api.adapter.deleteMany, {
325
436
  input: {
@@ -344,6 +455,30 @@ export const convexAdapter = <
344
455
  config.authFunctions.onUpdate
345
456
  )) as FunctionHandle<"mutation">)
346
457
  : undefined;
458
+ if (data.where?.some((w) => w.connector === "OR")) {
459
+ const ids = await collectIdsForOrWhere({
460
+ model: data.model as string,
461
+ where: data.where,
462
+ });
463
+ if (!ids.length) {
464
+ return 0;
465
+ }
466
+ const result = await handlePagination(
467
+ async ({ paginationOpts }) => {
468
+ return await ctx.runMutation(api.adapter.updateMany, {
469
+ input: {
470
+ model: data.model as TableNames,
471
+ where: [{ field: "_id", operator: "in", value: ids }],
472
+ update: data.update,
473
+ },
474
+ paginationOpts,
475
+ onUpdateHandle: onUpdateHandle,
476
+ });
477
+ },
478
+ { limit: ids.length }
479
+ );
480
+ return result.count ?? 0;
481
+ }
347
482
  const result = await handlePagination(async ({ paginationOpts }) => {
348
483
  return await ctx.runMutation(api.adapter.updateMany, {
349
484
  input: {