@convex-dev/better-auth 0.7.0-alpha.10 → 0.7.0-alpha.11

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 (91) hide show
  1. package/dist/commonjs/client/adapter.d.ts +10 -1
  2. package/dist/commonjs/client/adapter.d.ts.map +1 -1
  3. package/dist/commonjs/client/adapter.js +183 -192
  4. package/dist/commonjs/client/adapter.js.map +1 -1
  5. package/dist/commonjs/client/index.d.ts +238 -179
  6. package/dist/commonjs/client/index.d.ts.map +1 -1
  7. package/dist/commonjs/client/index.js +46 -58
  8. package/dist/commonjs/client/index.js.map +1 -1
  9. package/dist/commonjs/component/adapterTest.d.ts +19 -0
  10. package/dist/commonjs/component/adapterTest.d.ts.map +1 -0
  11. package/dist/commonjs/component/adapterTest.js +82 -0
  12. package/dist/commonjs/component/adapterTest.js.map +1 -0
  13. package/dist/commonjs/component/lib.d.ts +218 -548
  14. package/dist/commonjs/component/lib.d.ts.map +1 -1
  15. package/dist/commonjs/component/lib.js +315 -286
  16. package/dist/commonjs/component/lib.js.map +1 -1
  17. package/dist/commonjs/component/schema.d.ts +90 -28
  18. package/dist/commonjs/component/schema.d.ts.map +1 -1
  19. package/dist/commonjs/component/schema.js +76 -18
  20. package/dist/commonjs/component/schema.js.map +1 -1
  21. package/dist/commonjs/component/util.d.ts +148 -86
  22. package/dist/commonjs/component/util.d.ts.map +1 -1
  23. package/dist/commonjs/nextjs/index.d.ts.map +1 -1
  24. package/dist/commonjs/nextjs/index.js +3 -0
  25. package/dist/commonjs/nextjs/index.js.map +1 -1
  26. package/dist/commonjs/plugins/convex/index.d.ts +14 -11
  27. package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
  28. package/dist/commonjs/plugins/convex/index.js +3 -2
  29. package/dist/commonjs/plugins/convex/index.js.map +1 -1
  30. package/dist/commonjs/plugins/cross-domain/client.d.ts +1 -1
  31. package/dist/commonjs/plugins/cross-domain/index.d.ts +5 -3
  32. package/dist/commonjs/plugins/cross-domain/index.d.ts.map +1 -1
  33. package/dist/commonjs/plugins/cross-domain/index.js +19 -5
  34. package/dist/commonjs/plugins/cross-domain/index.js.map +1 -1
  35. package/dist/commonjs/react-start/index.d.ts +4 -4
  36. package/dist/commonjs/utils/index.d.ts +2 -0
  37. package/dist/commonjs/utils/index.d.ts.map +1 -0
  38. package/dist/commonjs/utils/index.js +8 -0
  39. package/dist/commonjs/utils/index.js.map +1 -0
  40. package/dist/esm/client/adapter.d.ts +10 -1
  41. package/dist/esm/client/adapter.d.ts.map +1 -1
  42. package/dist/esm/client/adapter.js +183 -192
  43. package/dist/esm/client/adapter.js.map +1 -1
  44. package/dist/esm/client/index.d.ts +238 -179
  45. package/dist/esm/client/index.d.ts.map +1 -1
  46. package/dist/esm/client/index.js +46 -58
  47. package/dist/esm/client/index.js.map +1 -1
  48. package/dist/esm/component/adapterTest.d.ts +19 -0
  49. package/dist/esm/component/adapterTest.d.ts.map +1 -0
  50. package/dist/esm/component/adapterTest.js +82 -0
  51. package/dist/esm/component/adapterTest.js.map +1 -0
  52. package/dist/esm/component/lib.d.ts +218 -548
  53. package/dist/esm/component/lib.d.ts.map +1 -1
  54. package/dist/esm/component/lib.js +315 -286
  55. package/dist/esm/component/lib.js.map +1 -1
  56. package/dist/esm/component/schema.d.ts +90 -28
  57. package/dist/esm/component/schema.d.ts.map +1 -1
  58. package/dist/esm/component/schema.js +76 -18
  59. package/dist/esm/component/schema.js.map +1 -1
  60. package/dist/esm/component/util.d.ts +148 -86
  61. package/dist/esm/component/util.d.ts.map +1 -1
  62. package/dist/esm/nextjs/index.d.ts.map +1 -1
  63. package/dist/esm/nextjs/index.js +3 -0
  64. package/dist/esm/nextjs/index.js.map +1 -1
  65. package/dist/esm/plugins/convex/index.d.ts +14 -11
  66. package/dist/esm/plugins/convex/index.d.ts.map +1 -1
  67. package/dist/esm/plugins/convex/index.js +3 -2
  68. package/dist/esm/plugins/convex/index.js.map +1 -1
  69. package/dist/esm/plugins/cross-domain/client.d.ts +1 -1
  70. package/dist/esm/plugins/cross-domain/index.d.ts +5 -3
  71. package/dist/esm/plugins/cross-domain/index.d.ts.map +1 -1
  72. package/dist/esm/plugins/cross-domain/index.js +19 -5
  73. package/dist/esm/plugins/cross-domain/index.js.map +1 -1
  74. package/dist/esm/react-start/index.d.ts +4 -4
  75. package/dist/esm/utils/index.d.ts +2 -0
  76. package/dist/esm/utils/index.d.ts.map +1 -0
  77. package/dist/esm/utils/index.js +8 -0
  78. package/dist/esm/utils/index.js.map +1 -0
  79. package/package.json +20 -5
  80. package/src/client/adapter.test.ts +144 -0
  81. package/src/client/adapter.ts +191 -195
  82. package/src/client/index.ts +46 -71
  83. package/src/component/_generated/api.d.ts +605 -149
  84. package/src/component/adapterTest.ts +141 -0
  85. package/src/component/lib.ts +444 -335
  86. package/src/component/schema.ts +81 -19
  87. package/src/nextjs/index.ts +3 -0
  88. package/src/plugins/convex/index.ts +5 -2
  89. package/src/plugins/cross-domain/index.ts +19 -5
  90. package/src/client/cors.ts +0 -425
  91. /package/src/{util.ts → utils/index.ts} +0 -0
@@ -1,34 +1,139 @@
1
1
  import { BetterAuth } from "./index";
2
- import { transformInput } from "../component/lib";
3
- import { createAdapter } from "better-auth/adapters";
2
+ import {
3
+ AdapterDebugLogs,
4
+ CleanedWhere,
5
+ createAdapter,
6
+ } from "better-auth/adapters";
4
7
  import {
5
8
  GenericActionCtx,
6
9
  GenericMutationCtx,
7
10
  GenericQueryCtx,
11
+ PaginationOptions,
12
+ PaginationResult,
8
13
  } from "convex/server";
14
+ import { SetOptional } from "type-fest";
15
+
16
+ const paginate = async (
17
+ next: ({
18
+ paginationOpts,
19
+ }: {
20
+ paginationOpts: PaginationOptions;
21
+ }) => Promise<
22
+ SetOptional<PaginationResult<any>, "page"> & { count?: number }
23
+ >,
24
+ { limit, numItems }: { limit?: number; numItems?: number } = {}
25
+ ) => {
26
+ const state: {
27
+ isDone: boolean;
28
+ cursor: string | null;
29
+ docs: any[];
30
+ count: number;
31
+ } = {
32
+ isDone: false,
33
+ cursor: null,
34
+ docs: [],
35
+ count: 0,
36
+ };
37
+ const onResult = (
38
+ result: SetOptional<PaginationResult<any>, "page"> & { count?: number }
39
+ ) => {
40
+ state.cursor =
41
+ result.pageStatus === "SplitRecommended" ||
42
+ result.pageStatus === "SplitRequired"
43
+ ? result.splitCursor ?? result.continueCursor
44
+ : result.continueCursor;
45
+ if (result.page) {
46
+ state.docs.push(...result.page);
47
+ state.isDone = (limit && state.docs.length >= limit) || result.isDone;
48
+ return;
49
+ }
50
+ if (result.count) {
51
+ state.count += result.count;
52
+ state.isDone = (limit && state.count >= limit) || result.isDone;
53
+ return;
54
+ }
55
+ state.isDone = result.isDone;
56
+ };
57
+
58
+ do {
59
+ const result = await next({
60
+ paginationOpts: {
61
+ numItems: Math.min(numItems ?? 200, limit ?? 200, 200),
62
+ cursor: state.cursor,
63
+ },
64
+ });
65
+ onResult(result);
66
+ } while (!state.isDone);
67
+ return state;
68
+ };
69
+
70
+ type ConvexCleanedWhere = CleanedWhere & {
71
+ value: string | number | boolean | string[] | number[] | null;
72
+ };
73
+
74
+ const parseWhere = (where?: CleanedWhere[]): ConvexCleanedWhere[] => {
75
+ return where?.map((where) => {
76
+ if (where.value instanceof Date) {
77
+ return {
78
+ ...where,
79
+ value: where.value.getTime(),
80
+ };
81
+ }
82
+ return where;
83
+ }) as ConvexCleanedWhere[];
84
+ };
9
85
 
10
- export const convexAdapter = <
11
- Ctx extends
12
- | GenericQueryCtx<any>
13
- | GenericMutationCtx<any>
14
- | GenericActionCtx<any>,
15
- >(
16
- ctx: Ctx,
17
- component: BetterAuth
18
- ) =>
19
- createAdapter({
86
+ type GenericCtx =
87
+ | GenericQueryCtx<any>
88
+ | GenericMutationCtx<any>
89
+ | GenericActionCtx<any>;
90
+
91
+ interface ConvexAdapterConfig {
92
+ /**
93
+ * Helps you debug issues with the adapter.
94
+ */
95
+ debugLogs?: AdapterDebugLogs;
96
+ }
97
+ export const convexAdapter = (
98
+ ctx: GenericCtx,
99
+ component: BetterAuth,
100
+ config: ConvexAdapterConfig = {}
101
+ ) => {
102
+ const { debugLogs } = config;
103
+ return createAdapter({
20
104
  config: {
21
105
  adapterId: "convex",
22
106
  adapterName: "Convex Adapter",
23
- debugLogs: component.config.verbose ?? false,
107
+ debugLogs: component.config.verbose ?? debugLogs ?? false,
24
108
  disableIdGeneration: true,
109
+ supportsNumericIds: false,
110
+ usePlural: false,
111
+ mapKeysTransformOutput: {
112
+ _id: "id",
113
+ },
114
+ customTransformInput: ({ data, fieldAttributes, field }) => {
115
+ if (data && fieldAttributes.type === "date") {
116
+ const result = data.getTime();
117
+ console.log("transformed input", field, result);
118
+ return result;
119
+ }
120
+ return data;
121
+ },
122
+ customTransformOutput: ({ data, fieldAttributes, field }) => {
123
+ if (data && fieldAttributes.type === "date") {
124
+ const result = new Date(data);
125
+ console.log("transformed output", field, result);
126
+ return result;
127
+ }
128
+ return data;
129
+ },
25
130
  },
26
131
  adapter: ({ schema }) => {
27
132
  return {
28
133
  id: "convex",
29
134
  create: async ({ model, data, select }): Promise<any> => {
30
135
  if (!("runMutation" in ctx)) {
31
- throw new Error("ctx is not an action ctx");
136
+ throw new Error("ctx is not a mutation ctx");
32
137
  }
33
138
  if (select) {
34
139
  throw new Error("select is not supported");
@@ -39,223 +144,114 @@ export const convexAdapter = <
39
144
  : model === "session"
40
145
  ? component.config.authFunctions.createSession
41
146
  : component.component.lib.create;
42
- return ctx.runMutation(createFn, {
43
- input: { table: model, ...transformInput(model, data) },
147
+ return await ctx.runMutation(createFn, {
148
+ input: { model, data },
44
149
  });
45
150
  },
46
- findOne: async ({ model, where }): Promise<any> => {
47
- if (where.length === 1 && where[0].operator === "eq") {
48
- const { value, field } = where[0];
49
- const result = await ctx.runQuery(component.component.lib.getBy, {
50
- table: model,
51
- field,
52
- unique:
53
- field === "id" ? true : schema[model].fields[field].unique,
54
- value: value instanceof Date ? value.getTime() : value,
55
- });
56
- return result;
57
- }
58
- if (
59
- model === "account" &&
60
- where.length === 2 &&
61
- where[0].field === "accountId" &&
62
- where[1].field === "providerId" &&
63
- where[0].connector === "AND"
64
- ) {
65
- return ctx.runQuery(
66
- component.component.lib.getAccountByAccountIdAndProviderId,
67
- {
68
- accountId: where[0].value as string,
69
- providerId: where[1].value as string,
70
- }
71
- );
72
- }
73
- throw new Error("where clause not supported");
151
+ findOne: async (data): Promise<any> => {
152
+ return await ctx.runQuery(component.component.lib.findOne, {
153
+ ...data,
154
+ where: parseWhere(data.where),
155
+ });
74
156
  },
75
- findMany: async ({
76
- model,
77
- where,
78
- sortBy,
79
- offset,
80
- limit,
81
- }): Promise<any[]> => {
82
- if (offset) {
157
+ findMany: async (data): Promise<any[]> => {
158
+ if (data.offset) {
83
159
  throw new Error("offset not supported");
84
160
  }
85
- if (
86
- model === "jwks" &&
87
- !where &&
88
- (!sortBy ||
89
- (sortBy?.field === "createdAt" && sortBy?.direction === "desc"))
90
- ) {
91
- return ctx.runQuery(component.component.lib.getJwks, { limit });
92
- }
93
- if (
94
- where?.length !== 1 ||
95
- (where[0].operator && where[0].operator !== "eq")
96
- ) {
97
- throw new Error("where clause not supported");
98
- }
99
- if (model === "verification" && where[0].field === "identifier") {
100
- return ctx.runQuery(
101
- component.component.lib.listVerificationsByIdentifier,
102
- {
103
- identifier: where[0].value as string,
104
- sortBy,
105
- limit,
106
- }
107
- );
108
- }
109
- if (model === "account" && where[0].field === "userId" && !sortBy) {
110
- return ctx.runQuery(component.component.lib.getAccountsByUserId, {
111
- userId: where[0].value as any,
112
- limit,
113
- });
114
- }
115
- if (model === "session" && where[0].field === "userId" && !sortBy) {
116
- return ctx.runQuery(component.component.lib.getSessionsByUserId, {
117
- userId: where[0].value as any,
118
- limit,
161
+ if (data.where?.length === 1 && data.where[0].operator === "in") {
162
+ return ctx.runQuery(component.component.lib.getIn, {
163
+ ...data,
164
+ where: parseWhere(data.where),
119
165
  });
120
166
  }
121
- throw new Error("where clause not supported");
167
+ const result = await paginate(
168
+ async ({ paginationOpts }) => {
169
+ return await ctx.runQuery(component.component.lib.findMany, {
170
+ ...data,
171
+ where: parseWhere(data.where),
172
+ paginationOpts,
173
+ });
174
+ },
175
+ { limit: data.limit }
176
+ );
177
+ return result.docs;
122
178
  },
123
- count: async ({ where }) => {
179
+ count: async () => {
124
180
  throw new Error("count not implemented");
125
- // return 0;
126
181
  },
127
- update: async ({ model, where, update }): Promise<any> => {
182
+ update: async (data): Promise<any> => {
128
183
  if (!("runMutation" in ctx)) {
129
- throw new Error("ctx is not an action ctx");
184
+ throw new Error("ctx is not a mutation ctx");
130
185
  }
131
- if (where?.length === 1 && where[0].operator === "eq") {
132
- const { value, field } = where[0];
186
+ if (data.where?.length === 1 && data.where[0].operator === "eq") {
133
187
  const updateFn =
134
- model === "user"
188
+ data.model === "user"
135
189
  ? component.config.authFunctions.updateUser
136
- : component.component.lib.update;
190
+ : component.component.lib.updateOne;
137
191
  return ctx.runMutation(updateFn, {
138
192
  input: {
139
- table: model as any,
140
- where: {
141
- field,
142
- value: value instanceof Date ? value.getTime() : value,
143
- },
144
- value: transformInput(model, update as any),
193
+ model: data.model,
194
+ where: parseWhere(data.where),
195
+ update: data.update as any,
145
196
  },
146
197
  });
147
198
  }
148
199
  throw new Error("where clause not supported");
149
200
  },
150
- delete: async ({ model, where }) => {
201
+ delete: async (data) => {
151
202
  if (!("runMutation" in ctx)) {
152
- throw new Error("ctx is not an action ctx");
203
+ throw new Error("ctx is not a mutation ctx");
153
204
  }
154
- if (where?.length === 1 && where[0].operator === "eq") {
155
- const { field, value } = where[0];
156
- const deleteFn =
157
- model === "user"
158
- ? component.config.authFunctions.deleteUser
159
- : component.component.lib.deleteBy;
160
- await ctx.runMutation(deleteFn, {
161
- table: model,
162
- field,
163
- value: value instanceof Date ? value.getTime() : value,
164
- });
165
- return;
166
- }
167
- throw new Error("where clause not supported");
168
- // return null
205
+ const deleteFn =
206
+ data.model === "user"
207
+ ? component.config.authFunctions.deleteUser
208
+ : component.component.lib.deleteOne;
209
+ await ctx.runMutation(deleteFn, {
210
+ model: data.model,
211
+ where: parseWhere(data.where),
212
+ });
213
+ return;
169
214
  },
170
- deleteMany: async ({ model, where }) => {
171
- if (!("runAction" in ctx)) {
172
- throw new Error("ctx is not an action ctx");
215
+ deleteMany: async (data) => {
216
+ if (!("runMutation" in ctx)) {
217
+ throw new Error("ctx is not a mutation ctx");
173
218
  }
174
219
  if (
175
- model === "verification" &&
176
- where?.length === 1 &&
177
- where[0].operator === "lt" &&
178
- where[0].field === "expiresAt"
220
+ data.model === "session" &&
221
+ data.where?.length === 1 &&
222
+ data.where[0].operator === "in"
179
223
  ) {
180
- return ctx.runAction(
181
- component.component.lib.deleteOldVerifications,
182
- {
183
- currentTimestamp: Date.now(),
184
- }
185
- );
186
- }
187
- if (where?.length === 1 && where[0].field === "userId") {
188
- return ctx.runAction(component.component.lib.deleteAllForUser, {
189
- table: model,
190
- userId: where[0].value as any,
224
+ return ctx.runMutation(component.component.lib.deleteIn, {
225
+ input: {
226
+ table: data.model,
227
+ field: data.where[0].field as any,
228
+ values: data.where[0].value as string[],
229
+ },
191
230
  });
192
231
  }
193
- if (
194
- model === "session" &&
195
- where?.length === 2 &&
196
- where[0].operator === "eq" &&
197
- where[0].connector === "AND" &&
198
- where[0].field === "userId" &&
199
- where[1].operator === "lte" &&
200
- where[1].field === "expiresAt" &&
201
- typeof where[1].value === "number"
202
- ) {
203
- return ctx.runMutation(
204
- component.component.lib.deleteExpiredSessions,
205
- {
206
- userId: where[0].value as string,
207
- expiresAt: where[1].value as number,
208
- }
209
- );
210
- }
211
- throw new Error("where clause not supported");
212
- // return count;
232
+ const result = await paginate(async ({ paginationOpts }) => {
233
+ return await ctx.runMutation(component.component.lib.deleteMany, {
234
+ ...data,
235
+ where: parseWhere(data.where),
236
+ paginationOpts,
237
+ });
238
+ });
239
+ return result.count;
213
240
  },
214
- updateMany: async ({ model, where, update }) => {
241
+ updateMany: async (data) => {
215
242
  if (!("runMutation" in ctx)) {
216
243
  throw new Error("ctx is not an action ctx");
217
244
  }
218
- if (
219
- model === "twoFactor" &&
220
- where?.length === 1 &&
221
- where[0].operator === "eq" &&
222
- where[0].field === "userId"
223
- ) {
224
- return ctx.runMutation(component.component.lib.updateTwoFactor, {
225
- userId: where[0].value as string,
226
- update: transformInput(model, update as any),
245
+ const result = await paginate(async ({ paginationOpts }) => {
246
+ return await ctx.runMutation(component.component.lib.updateMany, {
247
+ ...data,
248
+ where: parseWhere(data.where),
249
+ paginationOpts,
227
250
  });
228
- }
229
- if (
230
- model === "account" &&
231
- where?.length === 2 &&
232
- where[0].operator === "eq" &&
233
- where[0].connector === "AND" &&
234
- where[0].field === "userId" &&
235
- where[1].operator === "eq" &&
236
- where[1].field === "providerId"
237
- ) {
238
- return ctx.runMutation(
239
- component.component.lib.updateUserProviderAccounts,
240
- {
241
- userId: where[0].value as string,
242
- providerId: where[1].value as string,
243
- update: transformInput(model, update as any),
244
- }
245
- );
246
- }
247
- throw new Error("updateMany not implemented");
248
- //return 0;
249
- /*
250
- const { model, where, update } = data;
251
- const table = db[model];
252
- const res = convertWhereClause(where, table, model);
253
- res.forEach((record) => {
254
- Object.assign(record, update);
255
251
  });
256
- return res[0] || null;
257
- */
252
+ return result.count;
258
253
  },
259
254
  };
260
255
  },
261
256
  });
257
+ };
@@ -16,33 +16,36 @@ import { type GenericId, Infer, v } from "convex/values";
16
16
  import type { api } from "../component/_generated/api";
17
17
  import schema from "../component/schema";
18
18
  import { convexAdapter } from "./adapter";
19
- import corsRouter from "./cors";
20
- import { getByArgsValidator, updateArgsInputValidator } from "../component/lib";
21
19
  import { betterAuth } from "better-auth";
22
20
  import { omit } from "convex-helpers";
23
21
  import { createCookieGetter } from "better-auth/cookies";
24
22
  import { fetchQuery } from "convex/nextjs";
25
23
  import { JWT_COOKIE_NAME } from "../plugins/convex";
26
- import { requireEnv } from "../util";
24
+ import { requireEnv } from "../utils";
25
+ import { partial } from "convex-helpers/validators";
26
+ import { adapterArgsValidator, adapterWhereValidator } from "../component/lib";
27
+ import { corsRouter } from "convex-helpers/server/cors";
27
28
  export { convexAdapter };
28
29
 
29
30
  const createUserFields = omit(schema.tables.user.validator.fields, ["userId"]);
30
31
  const createUserValidator = v.object(createUserFields);
31
32
  const createUserArgsValidator = v.object({
32
33
  input: v.object({
33
- ...createUserFields,
34
- table: v.literal("user"),
34
+ model: v.literal("user"),
35
+ data: v.object(createUserFields),
35
36
  }),
36
37
  });
37
38
  const updateUserArgsValidator = v.object({
38
- input: updateArgsInputValidator("user"),
39
+ input: v.object({
40
+ model: v.literal("user"),
41
+ where: v.optional(v.array(adapterWhereValidator)),
42
+ update: v.object(partial(createUserFields)),
43
+ }),
39
44
  });
40
- const deleteUserArgsValidator = v.object(getByArgsValidator);
41
-
42
45
  const createSessionArgsValidator = v.object({
43
46
  input: v.object({
44
- table: v.literal("session"),
45
- ...schema.tables.session.validator.fields,
47
+ model: v.literal("session"),
48
+ data: v.object(schema.tables.session.validator.fields),
46
49
  }),
47
50
  });
48
51
 
@@ -61,7 +64,7 @@ export type AuthFunctions = {
61
64
  deleteUser: FunctionReference<
62
65
  "mutation",
63
66
  "internal",
64
- Infer<typeof deleteUserArgsValidator>
67
+ Infer<typeof adapterArgsValidator>
65
68
  >;
66
69
  updateUser: FunctionReference<
67
70
  "mutation",
@@ -128,10 +131,14 @@ export class BetterAuth<UserId extends string = string> {
128
131
  if (!identity) {
129
132
  return null;
130
133
  }
131
- const doc = await ctx.runQuery(this.component.lib.getBy, {
132
- table: "user",
133
- field: "userId",
134
- value: identity.subject,
134
+ const doc = await ctx.runQuery(this.component.lib.findOne, {
135
+ model: "user",
136
+ where: [
137
+ {
138
+ field: "userId",
139
+ value: identity.subject,
140
+ },
141
+ ],
135
142
  });
136
143
  if (!doc) {
137
144
  return null;
@@ -182,35 +189,38 @@ export class BetterAuth<UserId extends string = string> {
182
189
  createUser: internalMutationGeneric({
183
190
  args: createUserArgsValidator,
184
191
  handler: async (ctx, args) => {
185
- const userId = await opts.onCreateUser(ctx, args.input);
186
- const input = { ...args.input, table: "user", userId };
192
+ const userId = await opts.onCreateUser(ctx, args.input.data);
187
193
  return ctx.runMutation(this.component.lib.create, {
188
- input,
194
+ input: {
195
+ ...args.input,
196
+ data: { ...args.input.data, userId },
197
+ },
189
198
  });
190
199
  },
191
200
  }),
192
201
  deleteUser: internalMutationGeneric({
193
- args: deleteUserArgsValidator,
202
+ args: adapterArgsValidator,
194
203
  handler: async (ctx, args) => {
195
- const doc = await ctx.runMutation(this.component.lib.deleteBy, args);
196
- if (opts.onDeleteUser) {
204
+ const doc = await ctx.runMutation(this.component.lib.deleteOne, args);
205
+ if (doc && opts.onDeleteUser) {
197
206
  await opts.onDeleteUser(ctx, doc.userId as UserId);
198
207
  }
208
+ return doc;
199
209
  },
200
210
  }),
201
211
  updateUser: internalMutationGeneric({
202
212
  args: updateUserArgsValidator,
203
213
  handler: async (ctx, args) => {
204
214
  const updatedUser = await ctx.runMutation(
205
- this.component.lib.update,
206
- args
215
+ this.component.lib.updateOne,
216
+ { input: args.input }
207
217
  );
208
218
  // Type narrowing
209
219
  if (!("emailVerified" in updatedUser)) {
210
220
  throw new Error("invalid user");
211
221
  }
212
222
  if (opts.onUpdateUser) {
213
- await opts.onUpdateUser(ctx, omit(updatedUser, ["id"]));
223
+ await opts.onUpdateUser(ctx, omit(updatedUser, ["_id"]));
214
224
  }
215
225
  return updatedUser;
216
226
  },
@@ -218,14 +228,9 @@ export class BetterAuth<UserId extends string = string> {
218
228
  createSession: internalMutationGeneric({
219
229
  args: createSessionArgsValidator,
220
230
  handler: async (ctx, args) => {
221
- const session = await ctx.runMutation(
222
- this.component.lib.create,
223
- args
224
- );
225
- // Type narrowing
226
- if (!("ipAddress" in session)) {
227
- throw new Error("invalid session");
228
- }
231
+ const session = await ctx.runMutation(this.component.lib.create, {
232
+ input: args.input,
233
+ });
229
234
  await opts.onCreateSession?.(ctx, session);
230
235
  return session;
231
236
  },
@@ -283,50 +288,20 @@ export class BetterAuth<UserId extends string = string> {
283
288
 
284
289
  return;
285
290
  }
286
-
287
- const trustedOrigins = [
288
- ...(Array.isArray(betterAuthOptions.trustedOrigins)
289
- ? betterAuthOptions.trustedOrigins
290
- : [betterAuthOptions.trustedOrigins]),
291
- betterAuthOptions.baseURL!,
292
- ];
293
- // The crossDomain plugin adds siteUrl to trustedOrigins
294
- const trustedOriginsFromPlugins =
295
- betterAuthOptions.plugins?.reduce((acc, plugin) => {
296
- if (plugin.options?.trustedOrigins) {
297
- acc.push(...plugin.options.trustedOrigins);
298
- }
299
- return acc;
300
- }, [] as string[]) ?? [];
301
-
302
- // Reuse trustedOrigins as default for allowedOrigins
303
- const allowedOrigins = async (request: Request) => {
304
- return (
305
- await Promise.all(
306
- [...trustedOrigins, ...trustedOriginsFromPlugins].map(
307
- async (origin) => {
308
- if (!origin) {
309
- return [];
310
- }
311
- if (typeof origin === "function") {
312
- return origin(request);
313
- }
314
- return [origin];
315
- }
316
- )
317
- )
318
- )
319
- .flat()
320
- .map((origin) =>
291
+ const cors = corsRouter(http, {
292
+ allowedOrigins: async (request) => {
293
+ const trustedOriginsOption =
294
+ (await createAuth({} as any).$context).options.trustedOrigins ?? [];
295
+ const trustedOrigins = Array.isArray(trustedOriginsOption)
296
+ ? trustedOriginsOption
297
+ : await trustedOriginsOption(request);
298
+ return trustedOrigins.map((origin) =>
321
299
  // Strip trailing wildcards, unsupported for allowedOrigins
322
300
  origin.endsWith("*") && origin.length > 1
323
301
  ? origin.slice(0, -1)
324
302
  : origin
325
303
  );
326
- };
327
-
328
- const cors = corsRouter(http, {
329
- allowedOrigins,
304
+ },
330
305
  allowCredentials: true,
331
306
  allowedHeaders: ["Content-Type", "Better-Auth-Cookie"],
332
307
  exposedHeaders: ["Set-Better-Auth-Cookie"],