@convex-dev/better-auth 0.8.9 → 0.9.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.
- package/dist/commonjs/client/adapter.d.ts +8 -4
- package/dist/commonjs/client/adapter.d.ts.map +1 -1
- package/dist/commonjs/client/adapter.js +45 -8
- package/dist/commonjs/client/adapter.js.map +1 -1
- package/dist/commonjs/client/adapterUtils.d.ts +6 -6
- package/dist/commonjs/client/adapterUtils.d.ts.map +1 -1
- package/dist/commonjs/client/adapterUtils.js +17 -9
- package/dist/commonjs/client/adapterUtils.js.map +1 -1
- package/dist/commonjs/client/createSchema.d.ts +0 -5
- package/dist/commonjs/client/createSchema.d.ts.map +1 -1
- package/dist/commonjs/client/createSchema.js +0 -8
- package/dist/commonjs/client/createSchema.js.map +1 -1
- package/dist/commonjs/client/index.d.ts +64 -3355
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +100 -33
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/component/adapter.d.ts +11 -9
- package/dist/commonjs/component/adapter.d.ts.map +1 -1
- package/dist/commonjs/component/adapter.js +1 -1
- package/dist/commonjs/component/adapter.js.map +1 -1
- package/dist/commonjs/component/adapterTest.d.ts +1 -1
- package/dist/commonjs/component/adapterTest.d.ts.map +1 -1
- package/dist/commonjs/component/schema.d.ts +16 -419
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +6 -196
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/plugins/convex/index.d.ts +10 -2
- package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
- package/dist/commonjs/plugins/convex/index.js +17 -1
- package/dist/commonjs/plugins/convex/index.js.map +1 -1
- package/dist/commonjs/plugins/cross-domain/index.d.ts +5 -0
- package/dist/commonjs/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/commonjs/plugins/cross-domain/index.js +8 -0
- package/dist/commonjs/plugins/cross-domain/index.js.map +1 -1
- package/dist/commonjs/react-start/index.d.ts.map +1 -1
- package/dist/commonjs/react-start/index.js +10 -2
- package/dist/commonjs/react-start/index.js.map +1 -1
- package/dist/commonjs/utils/index.d.ts +5 -5
- package/dist/commonjs/utils/index.d.ts.map +1 -1
- package/dist/commonjs/utils/index.js +9 -11
- package/dist/commonjs/utils/index.js.map +1 -1
- package/dist/esm/client/adapter.d.ts +8 -4
- package/dist/esm/client/adapter.d.ts.map +1 -1
- package/dist/esm/client/adapter.js +45 -8
- package/dist/esm/client/adapter.js.map +1 -1
- package/dist/esm/client/adapterUtils.d.ts +6 -6
- package/dist/esm/client/adapterUtils.d.ts.map +1 -1
- package/dist/esm/client/adapterUtils.js +17 -9
- package/dist/esm/client/adapterUtils.js.map +1 -1
- package/dist/esm/client/createSchema.d.ts +0 -5
- package/dist/esm/client/createSchema.d.ts.map +1 -1
- package/dist/esm/client/createSchema.js +0 -8
- package/dist/esm/client/createSchema.js.map +1 -1
- package/dist/esm/client/index.d.ts +64 -3355
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +100 -33
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/component/adapter.d.ts +11 -9
- package/dist/esm/component/adapter.d.ts.map +1 -1
- package/dist/esm/component/adapter.js +1 -1
- package/dist/esm/component/adapter.js.map +1 -1
- package/dist/esm/component/adapterTest.d.ts +1 -1
- package/dist/esm/component/adapterTest.d.ts.map +1 -1
- package/dist/esm/component/schema.d.ts +16 -419
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +6 -196
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/plugins/convex/index.d.ts +10 -2
- package/dist/esm/plugins/convex/index.d.ts.map +1 -1
- package/dist/esm/plugins/convex/index.js +17 -1
- package/dist/esm/plugins/convex/index.js.map +1 -1
- package/dist/esm/plugins/cross-domain/index.d.ts +5 -0
- package/dist/esm/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/esm/plugins/cross-domain/index.js +8 -0
- package/dist/esm/plugins/cross-domain/index.js.map +1 -1
- package/dist/esm/react-start/index.d.ts.map +1 -1
- package/dist/esm/react-start/index.js +10 -2
- package/dist/esm/react-start/index.js.map +1 -1
- package/dist/esm/utils/index.d.ts +5 -5
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +9 -11
- package/dist/esm/utils/index.js.map +1 -1
- package/package.json +13 -8
- package/src/client/adapter.test.ts +94 -34
- package/src/client/adapter.ts +66 -14
- package/src/client/adapterUtils.ts +23 -8
- package/src/client/createSchema.ts +0 -8
- package/src/client/index.ts +124 -63
- package/src/component/_generated/api.d.ts +133 -1303
- package/src/component/adapter.ts +1 -0
- package/src/component/schema.ts +11 -214
- package/src/plugins/convex/index.ts +21 -1
- package/src/plugins/cross-domain/index.ts +8 -0
- package/src/react-start/index.ts +10 -2
- package/src/utils/index.ts +20 -10
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.
|
|
9
|
+
"version": "0.9.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"keywords": [
|
|
12
12
|
"convex",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"build:cjs": "tsc --project ./commonjs.json && npm run build:cjs:generatePackageJson",
|
|
24
24
|
"build:esm:generatePackageJson": "echo '{\\n \"type\": \"module\"\\n}' > dist/esm/package.json",
|
|
25
25
|
"build:cjs:generatePackageJson": "echo '{\\n \"type\": \"commonjs\"\\n}' > dist/commonjs/package.json",
|
|
26
|
-
"build:watch": "chokidar 'tsconfig*.json' 'src/**/*.ts' -c 'npm run build' --initial",
|
|
26
|
+
"build:watch": "chokidar 'tsconfig*.json' 'src/**/*.{ts,tsx}' -c 'npm run build' --initial",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
28
|
"prepack": "node node10stubs.mjs",
|
|
29
29
|
"prepublishOnly": "npm run build",
|
|
@@ -79,10 +79,12 @@
|
|
|
79
79
|
},
|
|
80
80
|
"./nextjs": {
|
|
81
81
|
"import": {
|
|
82
|
+
"@convex-dev/component-source": "./src/nextjs/index.ts",
|
|
82
83
|
"types": "./dist/esm/nextjs/index.d.ts",
|
|
83
84
|
"default": "./dist/esm/nextjs/index.js"
|
|
84
85
|
},
|
|
85
86
|
"require": {
|
|
87
|
+
"@convex-dev/component-source": "./src/nextjs/index.ts",
|
|
86
88
|
"types": "./dist/commonjs/nextjs/index.d.ts",
|
|
87
89
|
"default": "./dist/commonjs/nextjs/index.js"
|
|
88
90
|
}
|
|
@@ -113,10 +115,12 @@
|
|
|
113
115
|
},
|
|
114
116
|
"./react-start": {
|
|
115
117
|
"import": {
|
|
118
|
+
"@convex-dev/component-source": "./src/react-start/index.ts",
|
|
116
119
|
"types": "./dist/esm/react-start/index.d.ts",
|
|
117
120
|
"default": "./dist/esm/react-start/index.js"
|
|
118
121
|
},
|
|
119
122
|
"require": {
|
|
123
|
+
"@convex-dev/component-source": "./src/react-start/index.ts",
|
|
120
124
|
"types": "./dist/commonjs/react-start/index.d.ts",
|
|
121
125
|
"default": "./dist/commonjs/react-start/index.js"
|
|
122
126
|
}
|
|
@@ -149,18 +153,16 @@
|
|
|
149
153
|
}
|
|
150
154
|
},
|
|
151
155
|
"peerDependencies": {
|
|
152
|
-
"better-auth": "1.3.
|
|
156
|
+
"better-auth": "1.3.27",
|
|
153
157
|
"convex": "^1.26.2",
|
|
154
158
|
"react": "^18.3.1 || ^19.0.0",
|
|
155
159
|
"react-dom": "^18.3.1 || ^19.0.0"
|
|
156
160
|
},
|
|
157
161
|
"devDependencies": {
|
|
158
|
-
"@better-
|
|
162
|
+
"@better-fetch/fetch": "^1.1.18",
|
|
159
163
|
"@edge-runtime/vm": "^5.0.0",
|
|
160
164
|
"@eslint/js": "^9.9.1",
|
|
161
|
-
"@
|
|
162
|
-
"@polar-sh/sdk": "^0.34.5",
|
|
163
|
-
"@tanstack/react-start": "^1.120.19",
|
|
165
|
+
"@tanstack/react-start": "^1.132.37",
|
|
164
166
|
"@types/common-tags": "^1.8.4",
|
|
165
167
|
"@types/node": "^20",
|
|
166
168
|
"@types/react": "19.1.6",
|
|
@@ -183,11 +185,14 @@
|
|
|
183
185
|
"types": "./dist/commonjs/client/index.d.ts",
|
|
184
186
|
"module": "./dist/esm/client/index.js",
|
|
185
187
|
"dependencies": {
|
|
186
|
-
"@
|
|
188
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
187
189
|
"common-tags": "^1.8.2",
|
|
188
190
|
"convex-helpers": "^0.1.95",
|
|
189
191
|
"is-network-error": "^1.1.0",
|
|
192
|
+
"remeda": "^2.32.0",
|
|
190
193
|
"type-fest": "^4.39.1",
|
|
194
|
+
"vite": "^7.1.9",
|
|
195
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
191
196
|
"zod": "^3.24.4"
|
|
192
197
|
}
|
|
193
198
|
}
|
|
@@ -42,47 +42,62 @@ export const getAdapter = (t: ReturnType<typeof convexTest>) => async () => {
|
|
|
42
42
|
deleteMany: async (data) => {
|
|
43
43
|
return t.mutation(api.adapterTest.deleteMany, data);
|
|
44
44
|
},
|
|
45
|
+
transaction: false as any,
|
|
45
46
|
} satisfies Adapter;
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
describe("Better Auth Adapter Tests", async () => {
|
|
49
50
|
const _t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
51
|
+
const status = {
|
|
52
|
+
active: "active",
|
|
53
|
+
only: "only",
|
|
54
|
+
notSupported: "not supported",
|
|
55
|
+
} as const;
|
|
56
|
+
const tests: Record<string, (typeof status)[keyof typeof status]> = {
|
|
57
|
+
CREATE_MODEL: status.active,
|
|
58
|
+
CREATE_MODEL_SHOULD_ALWAYS_RETURN_AN_ID: status.active,
|
|
59
|
+
FIND_MODEL: status.active,
|
|
60
|
+
FIND_MODEL_WITHOUT_ID: status.active,
|
|
61
|
+
FIND_MODEL_WITH_SELECT: status.active,
|
|
62
|
+
FIND_MODEL_WITH_MODIFIED_FIELD_NAME: status.active,
|
|
63
|
+
UPDATE_MODEL: status.active,
|
|
64
|
+
SHOULD_FIND_MANY: status.active,
|
|
65
|
+
SHOULD_FIND_MANY_WITH_WHERE: status.active,
|
|
66
|
+
SHOULD_FIND_MANY_WITH_OPERATORS: status.active,
|
|
67
|
+
SHOULD_WORK_WITH_REFERENCE_FIELDS: status.active,
|
|
68
|
+
SHOULD_FIND_MANY_WITH_NOT_IN_OPERATOR: status.active,
|
|
69
|
+
SHOULD_FIND_MANY_WITH_SORT_BY: status.active,
|
|
70
|
+
SHOULD_FIND_MANY_WITH_LIMIT: status.active,
|
|
71
|
+
SHOULD_UPDATE_WITH_MULTIPLE_WHERE: status.active,
|
|
72
|
+
DELETE_MODEL: status.active,
|
|
73
|
+
SHOULD_DELETE_MANY: status.active,
|
|
74
|
+
SHOULD_NOT_THROW_ON_DELETE_RECORD_NOT_FOUND: status.active,
|
|
75
|
+
SHOULD_NOT_THROW_ON_RECORD_NOT_FOUND: status.active,
|
|
76
|
+
SHOULD_FIND_MANY_WITH_CONTAINS_OPERATOR: status.active,
|
|
77
|
+
SHOULD_SEARCH_USERS_WITH_STARTS_WITH: status.active,
|
|
78
|
+
SHOULD_SEARCH_USERS_WITH_ENDS_WITH: status.active,
|
|
79
|
+
// Use local install and Convex paginated queries
|
|
80
|
+
SHOULD_FIND_MANY_WITH_OFFSET: status.notSupported,
|
|
81
|
+
// Convex generates ids on insert
|
|
82
|
+
SHOULD_PREFER_GENERATE_ID_IF_PROVIDED: status.notSupported,
|
|
83
|
+
// Transactions are inherent for auth.api and not possible for authClient
|
|
84
|
+
SHOULD_ROLLBACK_FAILING_TRANSACTION: status.notSupported,
|
|
85
|
+
SHOULD_RETURN_TRANSACTION_RESULT: status.notSupported,
|
|
86
|
+
SHOULD_FIND_MANY_WITH_CONNECTORS: status.active,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const disableTests = Object.fromEntries(
|
|
90
|
+
Object.entries(tests).map((entry, idx, arr) => {
|
|
91
|
+
if (arr.some((e) => e[1] === status.only)) {
|
|
92
|
+
return [entry[0], !(entry[1] === status.only)];
|
|
93
|
+
}
|
|
94
|
+
return [entry[0], !(entry[1] === status.active)];
|
|
95
|
+
})
|
|
96
|
+
);
|
|
79
97
|
|
|
80
98
|
await runAdapterTest({
|
|
81
99
|
getAdapter: getAdapter(_t),
|
|
82
|
-
disableTests
|
|
83
|
-
...activeTests.map((test) => [test, false]),
|
|
84
|
-
...inactiveTests.map((test) => [test, true]),
|
|
85
|
-
]),
|
|
100
|
+
disableTests,
|
|
86
101
|
});
|
|
87
102
|
});
|
|
88
103
|
|
|
@@ -338,6 +353,51 @@ describe("Convex Adapter Tests", async () => {
|
|
|
338
353
|
})
|
|
339
354
|
).toEqual(user);
|
|
340
355
|
});
|
|
356
|
+
test("should handle OR where clauses with sortBy", async () => {
|
|
357
|
+
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
358
|
+
const adapter = await getAdapter(t)();
|
|
359
|
+
const fooUser = await adapter.create({
|
|
360
|
+
model: "user",
|
|
361
|
+
data: {
|
|
362
|
+
name: "foo",
|
|
363
|
+
email: "foo@bar.com",
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
const barUser = await adapter.create({
|
|
367
|
+
model: "user",
|
|
368
|
+
data: {
|
|
369
|
+
name: "bar",
|
|
370
|
+
email: "bar@bar.com",
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
await adapter.create({
|
|
374
|
+
model: "user",
|
|
375
|
+
data: {
|
|
376
|
+
name: "baz",
|
|
377
|
+
email: "baz@bar.com",
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
expect(
|
|
381
|
+
await adapter.findMany({
|
|
382
|
+
model: "user",
|
|
383
|
+
where: [
|
|
384
|
+
{ field: "name", value: "bar", connector: "OR" },
|
|
385
|
+
{ field: "name", value: "foo", connector: "OR" },
|
|
386
|
+
],
|
|
387
|
+
sortBy: { field: "name", direction: "asc" },
|
|
388
|
+
})
|
|
389
|
+
).toEqual([barUser, fooUser]);
|
|
390
|
+
expect(
|
|
391
|
+
await adapter.findMany({
|
|
392
|
+
model: "user",
|
|
393
|
+
where: [
|
|
394
|
+
{ field: "name", value: "bar", connector: "OR" },
|
|
395
|
+
{ field: "name", value: "foo", connector: "OR" },
|
|
396
|
+
],
|
|
397
|
+
sortBy: { field: "name", direction: "desc" },
|
|
398
|
+
})
|
|
399
|
+
).toEqual([fooUser, barUser]);
|
|
400
|
+
});
|
|
341
401
|
test("should handle count", async () => {
|
|
342
402
|
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
343
403
|
const adapter = await getAdapter(t)();
|
|
@@ -387,7 +447,7 @@ describe("Convex Adapter Tests", async () => {
|
|
|
387
447
|
).toEqual(null);
|
|
388
448
|
});
|
|
389
449
|
|
|
390
|
-
test("should handle compound operator on non-unique
|
|
450
|
+
test("should handle compound operator on non-unique field without an index", async () => {
|
|
391
451
|
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
392
452
|
const adapter = await getAdapter(t)();
|
|
393
453
|
await adapter.create({
|
package/src/client/adapter.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
createAdapter,
|
|
2
|
+
createAdapterFactory,
|
|
3
|
+
DBAdapterDebugLogOption,
|
|
5
4
|
} from "better-auth/adapters";
|
|
6
5
|
import {
|
|
7
6
|
createFunctionHandle,
|
|
@@ -13,10 +12,13 @@ import {
|
|
|
13
12
|
SchemaDefinition,
|
|
14
13
|
} from "convex/server";
|
|
15
14
|
import { SetOptional } from "type-fest";
|
|
16
|
-
import { createSchema } from "./createSchema";
|
|
17
15
|
import { AuthFunctions, GenericCtx, Triggers, UseApi } from ".";
|
|
18
16
|
import defaultSchema from "../component/schema";
|
|
19
17
|
import { api as componentApi } from "../component/_generated/api";
|
|
18
|
+
import { Where } from "better-auth/types";
|
|
19
|
+
import { asyncMap } from "convex-helpers";
|
|
20
|
+
import { prop, sortBy, unique } from "remeda";
|
|
21
|
+
import { isRunMutationCtx } from "../utils";
|
|
20
22
|
|
|
21
23
|
const handlePagination = async (
|
|
22
24
|
next: ({
|
|
@@ -77,11 +79,11 @@ const handlePagination = async (
|
|
|
77
79
|
return state;
|
|
78
80
|
};
|
|
79
81
|
|
|
80
|
-
type ConvexCleanedWhere =
|
|
82
|
+
type ConvexCleanedWhere = Where & {
|
|
81
83
|
value: string | number | boolean | string[] | number[] | null;
|
|
82
84
|
};
|
|
83
85
|
|
|
84
|
-
const parseWhere = (where?:
|
|
86
|
+
const parseWhere = (where?: Where[]): ConvexCleanedWhere[] => {
|
|
85
87
|
return where?.map((where) => {
|
|
86
88
|
if (where.value instanceof Date) {
|
|
87
89
|
return {
|
|
@@ -99,21 +101,31 @@ export const convexAdapter = <
|
|
|
99
101
|
Schema extends SchemaDefinition<any, any> = typeof defaultSchema,
|
|
100
102
|
>(
|
|
101
103
|
ctx: Ctx,
|
|
102
|
-
api:
|
|
104
|
+
api: {
|
|
105
|
+
adapter: SetOptional<
|
|
106
|
+
UseApi<typeof componentApi>["adapter"],
|
|
107
|
+
"migrationRemoveUserId"
|
|
108
|
+
>;
|
|
109
|
+
adapterTest?: UseApi<typeof componentApi>["adapterTest"];
|
|
110
|
+
},
|
|
103
111
|
config: {
|
|
104
|
-
debugLogs?:
|
|
112
|
+
debugLogs?: DBAdapterDebugLogOption;
|
|
105
113
|
authFunctions?: AuthFunctions;
|
|
106
114
|
triggers?: Triggers<DataModel, Schema>;
|
|
107
115
|
} = {}
|
|
108
116
|
) => {
|
|
109
|
-
return
|
|
117
|
+
return createAdapterFactory({
|
|
110
118
|
config: {
|
|
111
119
|
adapterId: "convex",
|
|
112
120
|
adapterName: "Convex Adapter",
|
|
113
121
|
debugLogs: config.debugLogs || false,
|
|
114
122
|
disableIdGeneration: true,
|
|
123
|
+
transaction: false,
|
|
115
124
|
supportsNumericIds: false,
|
|
116
125
|
usePlural: false,
|
|
126
|
+
mapKeysTransformInput: {
|
|
127
|
+
id: "_id",
|
|
128
|
+
},
|
|
117
129
|
mapKeysTransformOutput: {
|
|
118
130
|
_id: "id",
|
|
119
131
|
},
|
|
@@ -135,10 +147,17 @@ export const convexAdapter = <
|
|
|
135
147
|
},
|
|
136
148
|
},
|
|
137
149
|
adapter: ({ options }) => {
|
|
150
|
+
// Disable telemetry in all cases because it requires Node
|
|
138
151
|
options.telemetry = { enabled: false };
|
|
139
152
|
return {
|
|
140
153
|
id: "convex",
|
|
141
|
-
|
|
154
|
+
options: {
|
|
155
|
+
isRunMutationCtx: isRunMutationCtx(ctx),
|
|
156
|
+
},
|
|
157
|
+
createSchema: async ({ file, tables }) => {
|
|
158
|
+
const { createSchema } = await import("./createSchema");
|
|
159
|
+
return createSchema({ file, tables });
|
|
160
|
+
},
|
|
142
161
|
create: async ({ model, data, select }): Promise<any> => {
|
|
143
162
|
if (!("runMutation" in ctx)) {
|
|
144
163
|
throw new Error("ctx is not a mutation ctx");
|
|
@@ -177,8 +196,30 @@ export const convexAdapter = <
|
|
|
177
196
|
throw new Error("offset not supported");
|
|
178
197
|
}
|
|
179
198
|
if (data.where?.some((w) => w.connector === "OR")) {
|
|
180
|
-
|
|
199
|
+
const results = await asyncMap(data.where, async (w) =>
|
|
200
|
+
handlePagination(
|
|
201
|
+
async ({ paginationOpts }) => {
|
|
202
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
203
|
+
...data,
|
|
204
|
+
where: parseWhere([w]),
|
|
205
|
+
paginationOpts,
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
{ limit: data.limit }
|
|
209
|
+
)
|
|
210
|
+
);
|
|
211
|
+
const docs = unique(results.flatMap((r) => r.docs));
|
|
212
|
+
if (data.sortBy) {
|
|
213
|
+
const result = sortBy(docs, [
|
|
214
|
+
prop(data.sortBy.field),
|
|
215
|
+
data.sortBy.direction,
|
|
216
|
+
]);
|
|
217
|
+
console.log(result);
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
return docs;
|
|
181
221
|
}
|
|
222
|
+
|
|
182
223
|
const result = await handlePagination(
|
|
183
224
|
async ({ paginationOpts }) => {
|
|
184
225
|
return await ctx.runQuery(api.adapter.findMany, {
|
|
@@ -194,8 +235,19 @@ export const convexAdapter = <
|
|
|
194
235
|
count: async (data) => {
|
|
195
236
|
// Yes, count is just findMany returning a number.
|
|
196
237
|
if (data.where?.some((w) => w.connector === "OR")) {
|
|
197
|
-
|
|
238
|
+
const results = await asyncMap(data.where, async (w) =>
|
|
239
|
+
handlePagination(async ({ paginationOpts }) => {
|
|
240
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
241
|
+
...data,
|
|
242
|
+
where: parseWhere([w]),
|
|
243
|
+
paginationOpts,
|
|
244
|
+
});
|
|
245
|
+
})
|
|
246
|
+
);
|
|
247
|
+
const docs = unique(results.flatMap((r) => r.docs));
|
|
248
|
+
return docs.length;
|
|
198
249
|
}
|
|
250
|
+
|
|
199
251
|
const result = await handlePagination(async ({ paginationOpts }) => {
|
|
200
252
|
return await ctx.runQuery(api.adapter.findMany, {
|
|
201
253
|
...data,
|
|
@@ -203,7 +255,7 @@ export const convexAdapter = <
|
|
|
203
255
|
paginationOpts,
|
|
204
256
|
});
|
|
205
257
|
});
|
|
206
|
-
return result.docs
|
|
258
|
+
return result.docs.length;
|
|
207
259
|
},
|
|
208
260
|
update: async (data): Promise<any> => {
|
|
209
261
|
if (!("runMutation" in ctx)) {
|
|
@@ -272,7 +324,7 @@ export const convexAdapter = <
|
|
|
272
324
|
},
|
|
273
325
|
updateMany: async (data) => {
|
|
274
326
|
if (!("runMutation" in ctx)) {
|
|
275
|
-
throw new Error("ctx is not
|
|
327
|
+
throw new Error("ctx is not a mutation ctx");
|
|
276
328
|
}
|
|
277
329
|
const onUpdateHandle =
|
|
278
330
|
config.authFunctions?.onUpdate &&
|
|
@@ -24,6 +24,7 @@ export const adapterWhereValidator = v.object({
|
|
|
24
24
|
v.literal("gte"),
|
|
25
25
|
v.literal("eq"),
|
|
26
26
|
v.literal("in"),
|
|
27
|
+
v.literal("not_in"),
|
|
27
28
|
v.literal("ne"),
|
|
28
29
|
v.literal("contains"),
|
|
29
30
|
v.literal("starts_with"),
|
|
@@ -96,6 +97,7 @@ const findIndex = (
|
|
|
96
97
|
| "gte"
|
|
97
98
|
| "eq"
|
|
98
99
|
| "in"
|
|
100
|
+
| "not_in"
|
|
99
101
|
| "ne"
|
|
100
102
|
| "contains"
|
|
101
103
|
| "starts_with"
|
|
@@ -120,8 +122,10 @@ const findIndex = (
|
|
|
120
122
|
const where = args.where?.filter((w) => {
|
|
121
123
|
return (
|
|
122
124
|
(!w.operator ||
|
|
123
|
-
["lt", "lte", "gt", "gte", "eq", "in"].includes(
|
|
124
|
-
|
|
125
|
+
["lt", "lte", "gt", "gte", "eq", "in", "not_in"].includes(
|
|
126
|
+
w.operator
|
|
127
|
+
)) &&
|
|
128
|
+
w.field !== "_id"
|
|
125
129
|
);
|
|
126
130
|
});
|
|
127
131
|
if (!where?.length && !args.sortBy) {
|
|
@@ -341,6 +345,12 @@ const filterByWhere = <
|
|
|
341
345
|
case "in": {
|
|
342
346
|
return Array.isArray(w.value) && (w.value as any[]).includes(value);
|
|
343
347
|
}
|
|
348
|
+
case "not_in": {
|
|
349
|
+
const result =
|
|
350
|
+
Array.isArray(w.value) && !(w.value as any[]).includes(value);
|
|
351
|
+
console.log(doc, "not_in", w, value, result);
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
344
354
|
case "lt": {
|
|
345
355
|
return isLessThan(value, w.value);
|
|
346
356
|
}
|
|
@@ -439,7 +449,9 @@ const generateQuery = (
|
|
|
439
449
|
// incompatible with Convex statically.
|
|
440
450
|
(w) =>
|
|
441
451
|
w.operator &&
|
|
442
|
-
["contains", "starts_with", "ends_with", "ne"].includes(
|
|
452
|
+
["contains", "starts_with", "ends_with", "ne", "not_in"].includes(
|
|
453
|
+
w.operator
|
|
454
|
+
)
|
|
443
455
|
);
|
|
444
456
|
});
|
|
445
457
|
return filteredQuery;
|
|
@@ -470,11 +482,13 @@ export const paginate = async <
|
|
|
470
482
|
if (
|
|
471
483
|
args.where?.some(
|
|
472
484
|
(w) =>
|
|
473
|
-
w.field === "
|
|
485
|
+
w.field === "_id" &&
|
|
486
|
+
w.operator &&
|
|
487
|
+
!["eq", "in", "not_in"].includes(w.operator)
|
|
474
488
|
)
|
|
475
489
|
) {
|
|
476
490
|
throw new Error(
|
|
477
|
-
`
|
|
491
|
+
`_id can only be used with eq, in, or not_in operator: ${JSON.stringify(args.where)}`
|
|
478
492
|
);
|
|
479
493
|
}
|
|
480
494
|
// If any where clause is "eq" (or missing operator) on a unique field,
|
|
@@ -483,7 +497,8 @@ export const paginate = async <
|
|
|
483
497
|
const uniqueWhere = args.where?.find(
|
|
484
498
|
(w) =>
|
|
485
499
|
(!w.operator || w.operator === "eq") &&
|
|
486
|
-
(isUniqueField(betterAuthSchema, args.model, w.field) ||
|
|
500
|
+
(isUniqueField(betterAuthSchema, args.model, w.field) ||
|
|
501
|
+
w.field === "_id")
|
|
487
502
|
);
|
|
488
503
|
if (uniqueWhere) {
|
|
489
504
|
const { index } =
|
|
@@ -492,7 +507,7 @@ export const paginate = async <
|
|
|
492
507
|
where: [uniqueWhere],
|
|
493
508
|
}) || {};
|
|
494
509
|
const doc =
|
|
495
|
-
uniqueWhere.field === "
|
|
510
|
+
uniqueWhere.field === "_id"
|
|
496
511
|
? await ctx.db.get(uniqueWhere.value as GenericId<T>)
|
|
497
512
|
: await ctx.db
|
|
498
513
|
.query(args.model as any)
|
|
@@ -533,7 +548,7 @@ export const paginate = async <
|
|
|
533
548
|
throw new Error("in clause value must be an array");
|
|
534
549
|
}
|
|
535
550
|
// For ids, just use asyncMap + .get()
|
|
536
|
-
if (inWhere.field === "
|
|
551
|
+
if (inWhere.field === "_id") {
|
|
537
552
|
const docs = await asyncMap(inWhere.value as any[], async (value) => {
|
|
538
553
|
return ctx.db.get(value as GenericId<T>);
|
|
539
554
|
});
|
|
@@ -9,15 +9,7 @@ export const indexFields = {
|
|
|
9
9
|
verification: ["expiresAt", "identifier"],
|
|
10
10
|
user: [["email", "name"], "name", "userId"],
|
|
11
11
|
passkey: ["credentialID"],
|
|
12
|
-
apikey: ["key"],
|
|
13
|
-
member: [["organizationId", "userId"]],
|
|
14
|
-
invitation: [
|
|
15
|
-
["email", "organizationId", "status"],
|
|
16
|
-
["organizationId", "status"],
|
|
17
|
-
],
|
|
18
12
|
oauthConsent: [["clientId", "userId"]],
|
|
19
|
-
ssoProvider: ["organizationId", "domain"],
|
|
20
|
-
subscription: ["stripeSubscriptionId", "stripeCustomerId", "referenceId"],
|
|
21
13
|
};
|
|
22
14
|
|
|
23
15
|
// Return map of unique, sortable, and reference fields
|