@convex-dev/better-auth 0.8.0-alpha.9 → 0.8.1
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/auth.d.ts +4 -0
- package/dist/commonjs/auth.d.ts.map +1 -0
- package/dist/commonjs/auth.js +44 -0
- package/dist/commonjs/auth.js.map +1 -0
- package/dist/commonjs/client/adapter.d.ts +8 -10
- package/dist/commonjs/client/adapter.d.ts.map +1 -1
- package/dist/commonjs/client/adapter.js +48 -32
- package/dist/commonjs/client/adapter.js.map +1 -1
- package/dist/commonjs/client/adapterUtils.d.ts +66 -0
- package/dist/commonjs/client/adapterUtils.d.ts.map +1 -0
- package/dist/commonjs/client/adapterUtils.js +429 -0
- package/dist/commonjs/client/adapterUtils.js.map +1 -0
- package/dist/commonjs/client/createSchema.d.ts +24 -0
- package/dist/commonjs/client/createSchema.d.ts.map +1 -0
- package/dist/commonjs/client/createSchema.js +101 -0
- package/dist/commonjs/client/createSchema.js.map +1 -0
- package/dist/commonjs/client/index.d.ts +449 -601
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +337 -212
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/component/adapter.d.ts +128 -0
- package/dist/commonjs/component/adapter.d.ts.map +1 -0
- package/dist/commonjs/component/adapter.js +5 -0
- package/dist/commonjs/component/adapter.js.map +1 -0
- package/dist/commonjs/component/adapterTest.d.ts +3 -5
- package/dist/commonjs/component/adapterTest.d.ts.map +1 -1
- package/dist/commonjs/component/adapterTest.js +3 -17
- package/dist/commonjs/component/adapterTest.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +451 -207
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +50 -177
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/component/util.d.ts.map +1 -1
- package/dist/commonjs/nextjs/index.d.ts +1 -2
- package/dist/commonjs/nextjs/index.d.ts.map +1 -1
- package/dist/commonjs/nextjs/index.js +3 -2
- package/dist/commonjs/nextjs/index.js.map +1 -1
- package/dist/commonjs/plugins/convex/client.d.ts +2 -5
- package/dist/commonjs/plugins/convex/client.d.ts.map +1 -1
- package/dist/commonjs/plugins/convex/client.js.map +1 -1
- package/dist/commonjs/plugins/convex/index.d.ts +7 -134
- package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
- package/dist/commonjs/plugins/convex/index.js +10 -125
- package/dist/commonjs/plugins/convex/index.js.map +1 -1
- package/dist/commonjs/plugins/cross-domain/index.js +2 -2
- package/dist/commonjs/plugins/cross-domain/index.js.map +1 -1
- package/dist/commonjs/react-start/index.d.ts +17 -36
- package/dist/commonjs/react-start/index.d.ts.map +1 -1
- package/dist/commonjs/react-start/index.js +42 -31
- package/dist/commonjs/react-start/index.js.map +1 -1
- package/dist/commonjs/src/auth.d.ts +3085 -0
- package/dist/commonjs/src/auth.d.ts.map +1 -0
- package/dist/commonjs/src/auth.js +72 -0
- package/dist/commonjs/src/auth.js.map +1 -0
- package/dist/commonjs/src/client/adapter.d.ts +18 -0
- package/dist/commonjs/src/client/adapter.d.ts.map +1 -0
- package/dist/commonjs/src/client/adapter.js +211 -0
- package/dist/commonjs/src/client/adapter.js.map +1 -0
- package/dist/commonjs/src/client/createSchema.d.ts +25 -0
- package/dist/commonjs/src/client/createSchema.d.ts.map +1 -0
- package/dist/commonjs/src/client/createSchema.js +103 -0
- package/dist/commonjs/src/client/createSchema.js.map +1 -0
- package/dist/commonjs/src/client/index.d.ts +3310 -0
- package/dist/commonjs/src/client/index.d.ts.map +1 -0
- package/dist/commonjs/src/client/index.js +377 -0
- package/dist/commonjs/src/client/index.js.map +1 -0
- package/dist/commonjs/src/client/plugins/index.d.ts +3 -0
- package/dist/commonjs/src/client/plugins/index.d.ts.map +1 -0
- package/dist/commonjs/src/client/plugins/index.js +3 -0
- package/dist/commonjs/src/client/plugins/index.js.map +1 -0
- package/dist/commonjs/src/component/_generated/api.d.ts +12 -0
- package/dist/commonjs/src/component/_generated/api.d.ts.map +1 -0
- package/dist/commonjs/src/component/_generated/api.js +22 -0
- package/dist/commonjs/src/component/_generated/api.js.map +1 -0
- package/dist/commonjs/src/component/_generated/server.d.ts +64 -0
- package/dist/commonjs/src/component/_generated/server.d.ts.map +1 -0
- package/dist/commonjs/src/component/_generated/server.js +74 -0
- package/dist/commonjs/src/component/_generated/server.js.map +1 -0
- package/dist/commonjs/src/component/adapter.d.ts +355 -0
- package/dist/commonjs/src/component/adapter.d.ts.map +1 -0
- package/dist/commonjs/src/component/adapter.js +573 -0
- package/dist/commonjs/src/component/adapter.js.map +1 -0
- package/dist/commonjs/src/component/adapterTest.d.ts +18 -0
- package/dist/commonjs/src/component/adapterTest.d.ts.map +1 -0
- package/dist/commonjs/src/component/adapterTest.js +75 -0
- package/dist/commonjs/src/component/adapterTest.js.map +1 -0
- package/dist/commonjs/src/component/convex.config.d.ts +3 -0
- package/dist/commonjs/src/component/convex.config.d.ts.map +1 -0
- package/dist/commonjs/src/component/convex.config.js +4 -0
- package/dist/commonjs/src/component/convex.config.js.map +1 -0
- package/dist/commonjs/src/component/schema.d.ts +562 -0
- package/dist/commonjs/src/component/schema.d.ts.map +1 -0
- package/dist/commonjs/src/component/schema.js +217 -0
- package/dist/commonjs/src/component/schema.js.map +1 -0
- package/dist/commonjs/src/nextjs/index.d.ts +10 -0
- package/dist/commonjs/src/nextjs/index.d.ts.map +1 -0
- package/dist/commonjs/src/nextjs/index.js +43 -0
- package/dist/commonjs/src/nextjs/index.js.map +1 -0
- package/dist/commonjs/src/plugins/convex/client.d.ts +9 -0
- package/dist/commonjs/src/plugins/convex/client.d.ts.map +1 -0
- package/dist/commonjs/src/plugins/convex/client.js +7 -0
- package/dist/commonjs/src/plugins/convex/client.js.map +1 -0
- package/dist/commonjs/src/plugins/convex/index.d.ts +415 -0
- package/dist/commonjs/src/plugins/convex/index.d.ts.map +1 -0
- package/dist/commonjs/src/plugins/convex/index.js +354 -0
- package/dist/commonjs/src/plugins/convex/index.js.map +1 -0
- package/dist/commonjs/src/plugins/cross-domain/client.d.ts +132 -0
- package/dist/commonjs/src/plugins/cross-domain/client.d.ts.map +1 -0
- package/dist/commonjs/src/plugins/cross-domain/client.js +176 -0
- package/dist/commonjs/src/plugins/cross-domain/client.js.map +1 -0
- package/dist/commonjs/src/plugins/cross-domain/index.d.ts +83 -0
- package/dist/commonjs/src/plugins/cross-domain/index.d.ts.map +1 -0
- package/dist/commonjs/src/plugins/cross-domain/index.js +153 -0
- package/dist/commonjs/src/plugins/cross-domain/index.js.map +1 -0
- package/dist/commonjs/src/plugins/index.d.ts +3 -0
- package/dist/commonjs/src/plugins/index.d.ts.map +1 -0
- package/dist/commonjs/src/plugins/index.js +3 -0
- package/dist/commonjs/src/plugins/index.js.map +1 -0
- package/dist/commonjs/src/react/client.d.ts +31 -0
- package/dist/commonjs/src/react/client.d.ts.map +1 -0
- package/dist/commonjs/src/react/client.js +96 -0
- package/dist/commonjs/src/react/client.js.map +1 -0
- package/dist/commonjs/src/react/index.d.ts +9 -0
- package/dist/commonjs/src/react/index.d.ts.map +1 -0
- package/dist/commonjs/src/react/index.js +15 -0
- package/dist/commonjs/src/react/index.js.map +1 -0
- package/dist/commonjs/src/react-start/index.d.ts +45 -0
- package/dist/commonjs/src/react-start/index.d.ts.map +1 -0
- package/dist/commonjs/src/react-start/index.js +60 -0
- package/dist/commonjs/src/react-start/index.js.map +1 -0
- package/dist/commonjs/src/utils/index.d.ts +9 -0
- package/dist/commonjs/src/utils/index.d.ts.map +1 -0
- package/dist/commonjs/src/utils/index.js +35 -0
- package/dist/commonjs/src/utils/index.js.map +1 -0
- package/dist/esm/auth.d.ts +4 -0
- package/dist/esm/auth.d.ts.map +1 -0
- package/dist/esm/auth.js +44 -0
- package/dist/esm/auth.js.map +1 -0
- package/dist/esm/client/adapter.d.ts +8 -10
- package/dist/esm/client/adapter.d.ts.map +1 -1
- package/dist/esm/client/adapter.js +48 -32
- package/dist/esm/client/adapter.js.map +1 -1
- package/dist/esm/client/adapterUtils.d.ts +66 -0
- package/dist/esm/client/adapterUtils.d.ts.map +1 -0
- package/dist/esm/client/adapterUtils.js +429 -0
- package/dist/esm/client/adapterUtils.js.map +1 -0
- package/dist/esm/client/createSchema.d.ts +24 -0
- package/dist/esm/client/createSchema.d.ts.map +1 -0
- package/dist/esm/client/createSchema.js +101 -0
- package/dist/esm/client/createSchema.js.map +1 -0
- package/dist/esm/client/index.d.ts +449 -601
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +337 -212
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/component/adapter.d.ts +128 -0
- package/dist/esm/component/adapter.d.ts.map +1 -0
- package/dist/esm/component/adapter.js +5 -0
- package/dist/esm/component/adapter.js.map +1 -0
- package/dist/esm/component/adapterTest.d.ts +3 -5
- package/dist/esm/component/adapterTest.d.ts.map +1 -1
- package/dist/esm/component/adapterTest.js +3 -17
- package/dist/esm/component/adapterTest.js.map +1 -1
- package/dist/esm/component/schema.d.ts +451 -207
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +50 -177
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/component/util.d.ts.map +1 -1
- package/dist/esm/nextjs/index.d.ts +1 -2
- package/dist/esm/nextjs/index.d.ts.map +1 -1
- package/dist/esm/nextjs/index.js +3 -2
- package/dist/esm/nextjs/index.js.map +1 -1
- package/dist/esm/plugins/convex/client.d.ts +2 -5
- package/dist/esm/plugins/convex/client.d.ts.map +1 -1
- package/dist/esm/plugins/convex/client.js.map +1 -1
- package/dist/esm/plugins/convex/index.d.ts +7 -134
- package/dist/esm/plugins/convex/index.d.ts.map +1 -1
- package/dist/esm/plugins/convex/index.js +10 -125
- package/dist/esm/plugins/convex/index.js.map +1 -1
- package/dist/esm/plugins/cross-domain/index.js +2 -2
- package/dist/esm/plugins/cross-domain/index.js.map +1 -1
- package/dist/esm/react-start/index.d.ts +17 -36
- package/dist/esm/react-start/index.d.ts.map +1 -1
- package/dist/esm/react-start/index.js +42 -31
- package/dist/esm/react-start/index.js.map +1 -1
- package/dist/esm/src/auth.d.ts +3085 -0
- package/dist/esm/src/auth.d.ts.map +1 -0
- package/dist/esm/src/auth.js +72 -0
- package/dist/esm/src/auth.js.map +1 -0
- package/dist/esm/src/client/adapter.d.ts +18 -0
- package/dist/esm/src/client/adapter.d.ts.map +1 -0
- package/dist/esm/src/client/adapter.js +211 -0
- package/dist/esm/src/client/adapter.js.map +1 -0
- package/dist/esm/src/client/createSchema.d.ts +25 -0
- package/dist/esm/src/client/createSchema.d.ts.map +1 -0
- package/dist/esm/src/client/createSchema.js +103 -0
- package/dist/esm/src/client/createSchema.js.map +1 -0
- package/dist/esm/src/client/index.d.ts +3310 -0
- package/dist/esm/src/client/index.d.ts.map +1 -0
- package/dist/esm/src/client/index.js +377 -0
- package/dist/esm/src/client/index.js.map +1 -0
- package/dist/esm/src/client/plugins/index.d.ts +3 -0
- package/dist/esm/src/client/plugins/index.d.ts.map +1 -0
- package/dist/esm/src/client/plugins/index.js +3 -0
- package/dist/esm/src/client/plugins/index.js.map +1 -0
- package/dist/esm/src/component/_generated/api.d.ts +12 -0
- package/dist/esm/src/component/_generated/api.d.ts.map +1 -0
- package/dist/esm/src/component/_generated/api.js +22 -0
- package/dist/esm/src/component/_generated/api.js.map +1 -0
- package/dist/esm/src/component/_generated/server.d.ts +64 -0
- package/dist/esm/src/component/_generated/server.d.ts.map +1 -0
- package/dist/esm/src/component/_generated/server.js +74 -0
- package/dist/esm/src/component/_generated/server.js.map +1 -0
- package/dist/esm/src/component/adapter.d.ts +355 -0
- package/dist/esm/src/component/adapter.d.ts.map +1 -0
- package/dist/esm/src/component/adapter.js +573 -0
- package/dist/esm/src/component/adapter.js.map +1 -0
- package/dist/esm/src/component/adapterTest.d.ts +18 -0
- package/dist/esm/src/component/adapterTest.d.ts.map +1 -0
- package/dist/esm/src/component/adapterTest.js +75 -0
- package/dist/esm/src/component/adapterTest.js.map +1 -0
- package/dist/esm/src/component/convex.config.d.ts +3 -0
- package/dist/esm/src/component/convex.config.d.ts.map +1 -0
- package/dist/esm/src/component/convex.config.js +4 -0
- package/dist/esm/src/component/convex.config.js.map +1 -0
- package/dist/esm/src/component/schema.d.ts +562 -0
- package/dist/esm/src/component/schema.d.ts.map +1 -0
- package/dist/esm/src/component/schema.js +217 -0
- package/dist/esm/src/component/schema.js.map +1 -0
- package/dist/esm/src/nextjs/index.d.ts +10 -0
- package/dist/esm/src/nextjs/index.d.ts.map +1 -0
- package/dist/esm/src/nextjs/index.js +43 -0
- package/dist/esm/src/nextjs/index.js.map +1 -0
- package/dist/esm/src/plugins/convex/client.d.ts +9 -0
- package/dist/esm/src/plugins/convex/client.d.ts.map +1 -0
- package/dist/esm/src/plugins/convex/client.js +7 -0
- package/dist/esm/src/plugins/convex/client.js.map +1 -0
- package/dist/esm/src/plugins/convex/index.d.ts +415 -0
- package/dist/esm/src/plugins/convex/index.d.ts.map +1 -0
- package/dist/esm/src/plugins/convex/index.js +354 -0
- package/dist/esm/src/plugins/convex/index.js.map +1 -0
- package/dist/esm/src/plugins/cross-domain/client.d.ts +132 -0
- package/dist/esm/src/plugins/cross-domain/client.d.ts.map +1 -0
- package/dist/esm/src/plugins/cross-domain/client.js +176 -0
- package/dist/esm/src/plugins/cross-domain/client.js.map +1 -0
- package/dist/esm/src/plugins/cross-domain/index.d.ts +83 -0
- package/dist/esm/src/plugins/cross-domain/index.d.ts.map +1 -0
- package/dist/esm/src/plugins/cross-domain/index.js +153 -0
- package/dist/esm/src/plugins/cross-domain/index.js.map +1 -0
- package/dist/esm/src/plugins/index.d.ts +3 -0
- package/dist/esm/src/plugins/index.d.ts.map +1 -0
- package/dist/esm/src/plugins/index.js +3 -0
- package/dist/esm/src/plugins/index.js.map +1 -0
- package/dist/esm/src/react/client.d.ts +31 -0
- package/dist/esm/src/react/client.d.ts.map +1 -0
- package/dist/esm/src/react/client.js +96 -0
- package/dist/esm/src/react/client.js.map +1 -0
- package/dist/esm/src/react/index.d.ts +9 -0
- package/dist/esm/src/react/index.d.ts.map +1 -0
- package/dist/esm/src/react/index.js +15 -0
- package/dist/esm/src/react/index.js.map +1 -0
- package/dist/esm/src/react-start/index.d.ts +45 -0
- package/dist/esm/src/react-start/index.d.ts.map +1 -0
- package/dist/esm/src/react-start/index.js +60 -0
- package/dist/esm/src/react-start/index.js.map +1 -0
- package/dist/esm/src/utils/index.d.ts +9 -0
- package/dist/esm/src/utils/index.d.ts.map +1 -0
- package/dist/esm/src/utils/index.js +35 -0
- package/dist/esm/src/utils/index.js.map +1 -0
- package/package.json +21 -4
- package/src/auth.ts +57 -0
- package/src/client/adapter.test.ts +15 -0
- package/src/client/adapter.ts +83 -58
- package/src/{component/lib.ts → client/adapterUtils.ts} +106 -256
- package/src/client/createSchema.ts +149 -0
- package/src/client/index.ts +558 -317
- package/src/component/_generated/api.d.ts +1711 -547
- package/src/component/adapter.ts +13 -0
- package/src/component/adapterTest.ts +8 -34
- package/src/component/schema.ts +58 -192
- package/src/nextjs/index.ts +5 -5
- package/src/plugins/convex/client.ts +2 -3
- package/src/plugins/convex/index.ts +15 -147
- package/src/plugins/cross-domain/index.ts +2 -2
- package/src/react-start/index.ts +76 -44
- package/dist/commonjs/client/cors.d.ts +0 -77
- package/dist/commonjs/client/cors.d.ts.map +0 -1
- package/dist/commonjs/client/cors.js +0 -297
- package/dist/commonjs/client/cors.js.map +0 -1
- package/dist/commonjs/util.d.ts +0 -2
- package/dist/commonjs/util.d.ts.map +0 -1
- package/dist/commonjs/util.js +0 -8
- package/dist/commonjs/util.js.map +0 -1
- package/dist/esm/client/cors.d.ts +0 -77
- package/dist/esm/client/cors.d.ts.map +0 -1
- package/dist/esm/client/cors.js +0 -297
- package/dist/esm/client/cors.js.map +0 -1
- package/dist/esm/util.d.ts +0 -2
- package/dist/esm/util.d.ts.map +0 -1
- package/dist/esm/util.js +0 -8
- package/dist/esm/util.js.map +0 -1
- package/src/component/util.ts +0 -4
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { mutation, query, QueryCtx } from "../component/_generated/server";
|
|
2
1
|
import { asyncMap } from "convex-helpers";
|
|
3
|
-
import { Infer, v } from "convex/values";
|
|
4
|
-
import { Doc, Id, TableNames } from "../component/_generated/dataModel";
|
|
5
|
-
import schema, { specialFields } from "../component/schema";
|
|
2
|
+
import { GenericId, Infer, v } from "convex/values";
|
|
6
3
|
import {
|
|
4
|
+
DocumentByName,
|
|
5
|
+
GenericDataModel,
|
|
6
|
+
GenericQueryCtx,
|
|
7
7
|
PaginationOptions,
|
|
8
|
-
paginationOptsValidator,
|
|
9
8
|
PaginationResult,
|
|
9
|
+
SchemaDefinition,
|
|
10
|
+
TableNamesInDataModel,
|
|
10
11
|
} from "convex/server";
|
|
11
|
-
import { partial } from "convex-helpers/validators";
|
|
12
12
|
import { stream } from "convex-helpers/server/stream";
|
|
13
13
|
import { mergedStream } from "convex-helpers/server/stream";
|
|
14
14
|
import { stripIndent } from "common-tags";
|
|
15
|
+
import { BetterAuthDbSchema } from "better-auth/db";
|
|
15
16
|
|
|
16
17
|
export const adapterWhereValidator = v.object({
|
|
17
18
|
field: v.string(),
|
|
@@ -52,11 +53,15 @@ export const adapterArgsValidator = v.object({
|
|
|
52
53
|
select: v.optional(v.array(v.string())),
|
|
53
54
|
limit: v.optional(v.number()),
|
|
54
55
|
offset: v.optional(v.number()),
|
|
55
|
-
unique: v.optional(v.boolean()),
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
const isUniqueField = (
|
|
59
|
-
|
|
58
|
+
const isUniqueField = (
|
|
59
|
+
betterAuthSchema: BetterAuthDbSchema,
|
|
60
|
+
model: string,
|
|
61
|
+
field: string
|
|
62
|
+
) => {
|
|
63
|
+
const fields =
|
|
64
|
+
betterAuthSchema[model as keyof typeof betterAuthSchema]["fields"];
|
|
60
65
|
if (!fields) {
|
|
61
66
|
return false;
|
|
62
67
|
}
|
|
@@ -65,38 +70,45 @@ const isUniqueField = (model: TableNames, field: string) => {
|
|
|
65
70
|
.map(([key]) => key)
|
|
66
71
|
.includes(field);
|
|
67
72
|
};
|
|
68
|
-
const hasUniqueFields = (
|
|
73
|
+
export const hasUniqueFields = (
|
|
74
|
+
betterAuthSchema: BetterAuthDbSchema,
|
|
75
|
+
model: string,
|
|
76
|
+
input: Record<string, any>
|
|
77
|
+
) => {
|
|
69
78
|
for (const field of Object.keys(input)) {
|
|
70
|
-
if (isUniqueField(model, field)) {
|
|
79
|
+
if (isUniqueField(betterAuthSchema, model, field)) {
|
|
71
80
|
return true;
|
|
72
81
|
}
|
|
73
82
|
}
|
|
74
83
|
return false;
|
|
75
84
|
};
|
|
76
85
|
|
|
77
|
-
const findIndex = (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
86
|
+
const findIndex = (
|
|
87
|
+
schema: SchemaDefinition<any, any>,
|
|
88
|
+
args: {
|
|
89
|
+
model: string;
|
|
90
|
+
where?: {
|
|
91
|
+
field: string;
|
|
92
|
+
operator?:
|
|
93
|
+
| "lt"
|
|
94
|
+
| "lte"
|
|
95
|
+
| "gt"
|
|
96
|
+
| "gte"
|
|
97
|
+
| "eq"
|
|
98
|
+
| "in"
|
|
99
|
+
| "ne"
|
|
100
|
+
| "contains"
|
|
101
|
+
| "starts_with"
|
|
102
|
+
| "ends_with";
|
|
103
|
+
value: string | number | boolean | null | string[] | number[];
|
|
104
|
+
connector?: "AND" | "OR";
|
|
105
|
+
}[];
|
|
106
|
+
sortBy?: {
|
|
107
|
+
field: string;
|
|
108
|
+
direction: "asc" | "desc";
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
) => {
|
|
100
112
|
if (
|
|
101
113
|
(args.where?.length ?? 0) > 1 &&
|
|
102
114
|
args.where?.some((w) => w.connector === "OR")
|
|
@@ -188,7 +200,7 @@ const findIndex = (args: {
|
|
|
188
200
|
indexDescriptor: "by_creation_time",
|
|
189
201
|
fields: [],
|
|
190
202
|
}
|
|
191
|
-
: indexes.find(({ fields }) => {
|
|
203
|
+
: indexes.find(({ fields }: { fields: string[] }) => {
|
|
192
204
|
const fieldsMatch = indexFields.every(
|
|
193
205
|
(field, idx) => field === fields[idx]
|
|
194
206
|
);
|
|
@@ -220,21 +232,25 @@ const findIndex = (args: {
|
|
|
220
232
|
};
|
|
221
233
|
};
|
|
222
234
|
|
|
223
|
-
const checkUniqueFields = async
|
|
224
|
-
|
|
225
|
-
|
|
235
|
+
export const checkUniqueFields = async <
|
|
236
|
+
Schema extends SchemaDefinition<any, any>,
|
|
237
|
+
>(
|
|
238
|
+
ctx: GenericQueryCtx<GenericDataModel>,
|
|
239
|
+
schema: Schema,
|
|
240
|
+
betterAuthSchema: BetterAuthDbSchema,
|
|
241
|
+
table: string,
|
|
226
242
|
input: Record<string, any>,
|
|
227
|
-
doc?:
|
|
243
|
+
doc?: Record<string, any>
|
|
228
244
|
) => {
|
|
229
|
-
if (!hasUniqueFields(table, input)) {
|
|
245
|
+
if (!hasUniqueFields(betterAuthSchema, table, input)) {
|
|
230
246
|
return;
|
|
231
247
|
}
|
|
232
248
|
for (const field of Object.keys(input)) {
|
|
233
|
-
if (!isUniqueField(table, field)) {
|
|
249
|
+
if (!isUniqueField(betterAuthSchema, table, field)) {
|
|
234
250
|
continue;
|
|
235
251
|
}
|
|
236
252
|
const { index } =
|
|
237
|
-
findIndex({
|
|
253
|
+
findIndex(schema, {
|
|
238
254
|
model: table,
|
|
239
255
|
where: [
|
|
240
256
|
{ field, operator: "eq", value: input[field as keyof typeof input] },
|
|
@@ -256,33 +272,17 @@ const checkUniqueFields = async (
|
|
|
256
272
|
};
|
|
257
273
|
|
|
258
274
|
// This handles basic select (stripping out the other fields if there
|
|
259
|
-
// is a select arg)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
275
|
+
// is a select arg).
|
|
276
|
+
export const selectFields = async <
|
|
277
|
+
T extends TableNamesInDataModel<GenericDataModel>,
|
|
278
|
+
D extends DocumentByName<GenericDataModel, T>,
|
|
279
|
+
>(
|
|
263
280
|
doc: D | null,
|
|
264
281
|
select?: string[]
|
|
265
282
|
) => {
|
|
266
283
|
if (!doc) {
|
|
267
284
|
return null;
|
|
268
285
|
}
|
|
269
|
-
const modelSpecialFields =
|
|
270
|
-
specialFields[doc._table as keyof typeof specialFields];
|
|
271
|
-
const userIdField = modelSpecialFields
|
|
272
|
-
? Object.entries(modelSpecialFields).find(
|
|
273
|
-
([_, field]) => field.references?.model === "user"
|
|
274
|
-
)
|
|
275
|
-
: undefined;
|
|
276
|
-
if (userIdField) {
|
|
277
|
-
const userIdFieldName = userIdField[0] as keyof typeof doc;
|
|
278
|
-
const userId = doc[userIdFieldName];
|
|
279
|
-
if (userId) {
|
|
280
|
-
const user = await ctx.db.get(userId as unknown as Id<"user">);
|
|
281
|
-
if (user) {
|
|
282
|
-
(doc as any)[userIdFieldName] = user.userId;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
286
|
if (!select?.length) {
|
|
287
287
|
return doc;
|
|
288
288
|
}
|
|
@@ -295,8 +295,11 @@ const selectFields = async <T extends TableNames, D extends Doc<T>>(
|
|
|
295
295
|
// Manually filter an individual document by where clauses. This is used to
|
|
296
296
|
// simplify queries that can only return 0 or 1 documents, or "in" clauses that
|
|
297
297
|
// query multiple single documents in parallel.
|
|
298
|
-
const filterByWhere =
|
|
299
|
-
|
|
298
|
+
const filterByWhere = <
|
|
299
|
+
T extends TableNamesInDataModel<GenericDataModel>,
|
|
300
|
+
D extends DocumentByName<GenericDataModel, T>,
|
|
301
|
+
>(
|
|
302
|
+
doc: D | null,
|
|
300
303
|
where?: Infer<typeof adapterWhereValidator>[],
|
|
301
304
|
// Optionally filter which where clauses to apply.
|
|
302
305
|
filterWhere?: (w: Infer<typeof adapterWhereValidator>) => any
|
|
@@ -374,11 +377,13 @@ const filterByWhere = (
|
|
|
374
377
|
};
|
|
375
378
|
|
|
376
379
|
const generateQuery = (
|
|
377
|
-
ctx:
|
|
380
|
+
ctx: GenericQueryCtx<GenericDataModel>,
|
|
381
|
+
schema: SchemaDefinition<any, any>,
|
|
378
382
|
args: Infer<typeof adapterArgsValidator>
|
|
379
383
|
) => {
|
|
380
|
-
const { index, values, boundField, indexFields } =
|
|
381
|
-
|
|
384
|
+
const { index, values, boundField, indexFields } =
|
|
385
|
+
findIndex(schema, args) ?? {};
|
|
386
|
+
const query = stream(ctx.db as any, schema).query(args.model as any);
|
|
382
387
|
const hasValues =
|
|
383
388
|
values?.eq?.length ||
|
|
384
389
|
values?.lt ||
|
|
@@ -443,12 +448,17 @@ const generateQuery = (
|
|
|
443
448
|
// This is the core function for reading from the database, it parses and
|
|
444
449
|
// validates where conditions, selects indexes, and allows the caller to
|
|
445
450
|
// optionally paginate as needed. Every response is a pagination result.
|
|
446
|
-
const paginate = async
|
|
447
|
-
|
|
451
|
+
export const paginate = async <
|
|
452
|
+
Doc extends DocumentByName<GenericDataModel, T>,
|
|
453
|
+
T extends TableNamesInDataModel<GenericDataModel>,
|
|
454
|
+
>(
|
|
455
|
+
ctx: GenericQueryCtx<GenericDataModel>,
|
|
456
|
+
schema: SchemaDefinition<any, any>,
|
|
457
|
+
betterAuthSchema: BetterAuthDbSchema,
|
|
448
458
|
args: Infer<typeof adapterArgsValidator> & {
|
|
449
459
|
paginationOpts: PaginationOptions;
|
|
450
460
|
}
|
|
451
|
-
): Promise<PaginationResult<Doc
|
|
461
|
+
): Promise<PaginationResult<Doc>> => {
|
|
452
462
|
if (args.offset) {
|
|
453
463
|
throw new Error(`offset not supported: ${JSON.stringify(args.offset)}`);
|
|
454
464
|
}
|
|
@@ -473,17 +483,17 @@ const paginate = async (
|
|
|
473
483
|
const uniqueWhere = args.where?.find(
|
|
474
484
|
(w) =>
|
|
475
485
|
(!w.operator || w.operator === "eq") &&
|
|
476
|
-
(isUniqueField(args.model
|
|
486
|
+
(isUniqueField(betterAuthSchema, args.model, w.field) || w.field === "id")
|
|
477
487
|
);
|
|
478
488
|
if (uniqueWhere) {
|
|
479
489
|
const { index } =
|
|
480
|
-
findIndex({
|
|
490
|
+
findIndex(schema, {
|
|
481
491
|
model: args.model,
|
|
482
492
|
where: [uniqueWhere],
|
|
483
493
|
}) || {};
|
|
484
494
|
const doc =
|
|
485
495
|
uniqueWhere.field === "id"
|
|
486
|
-
? await ctx.db.get(uniqueWhere.value as
|
|
496
|
+
? await ctx.db.get(uniqueWhere.value as GenericId<T>)
|
|
487
497
|
: await ctx.db
|
|
488
498
|
.query(args.model as any)
|
|
489
499
|
.withIndex(index?.indexDescriptor as any, (q) =>
|
|
@@ -494,7 +504,7 @@ const paginate = async (
|
|
|
494
504
|
// Apply all other clauses as static filters to our 0 or 1 result.
|
|
495
505
|
if (filterByWhere(doc, args.where, (w) => w !== uniqueWhere)) {
|
|
496
506
|
return {
|
|
497
|
-
page: [await selectFields(
|
|
507
|
+
page: [await selectFields(doc, args.select)].filter(Boolean) as Doc[],
|
|
498
508
|
isDone: true,
|
|
499
509
|
continueCursor: "",
|
|
500
510
|
};
|
|
@@ -525,18 +535,18 @@ const paginate = async (
|
|
|
525
535
|
// For ids, just use asyncMap + .get()
|
|
526
536
|
if (inWhere.field === "id") {
|
|
527
537
|
const docs = await asyncMap(inWhere.value as any[], async (value) => {
|
|
528
|
-
return ctx.db.get(value as
|
|
538
|
+
return ctx.db.get(value as GenericId<T>);
|
|
529
539
|
});
|
|
530
540
|
const filteredDocs = docs
|
|
531
|
-
.flatMap((doc) => doc
|
|
541
|
+
.flatMap((doc) => (doc ? [doc] : []))
|
|
532
542
|
.filter((doc) => filterByWhere(doc, args.where, (w) => w !== inWhere));
|
|
533
543
|
|
|
534
544
|
return {
|
|
535
545
|
page: filteredDocs.sort((a, b) => {
|
|
536
546
|
if (args.sortBy?.field === "createdAt") {
|
|
537
547
|
return args.sortBy.direction === "asc"
|
|
538
|
-
? a._creationTime - b._creationTime
|
|
539
|
-
: b._creationTime - a._creationTime;
|
|
548
|
+
? (a._creationTime as number) - (b._creationTime as number)
|
|
549
|
+
: (b._creationTime as number) - (a._creationTime as number);
|
|
540
550
|
}
|
|
541
551
|
if (args.sortBy) {
|
|
542
552
|
const aValue = a[args.sortBy.field as keyof typeof a];
|
|
@@ -545,21 +555,21 @@ const paginate = async (
|
|
|
545
555
|
return 0;
|
|
546
556
|
}
|
|
547
557
|
return args.sortBy.direction === "asc"
|
|
548
|
-
? aValue > bValue
|
|
558
|
+
? aValue! > bValue!
|
|
549
559
|
? 1
|
|
550
560
|
: -1
|
|
551
|
-
: aValue > bValue
|
|
561
|
+
: aValue! > bValue!
|
|
552
562
|
? -1
|
|
553
563
|
: 1;
|
|
554
564
|
}
|
|
555
565
|
return 0;
|
|
556
|
-
}),
|
|
566
|
+
}) as Doc[],
|
|
557
567
|
isDone: true,
|
|
558
568
|
continueCursor: "",
|
|
559
569
|
};
|
|
560
570
|
}
|
|
561
571
|
const streams = inWhere.value.map((value) => {
|
|
562
|
-
return generateQuery(ctx, {
|
|
572
|
+
return generateQuery(ctx, schema, {
|
|
563
573
|
...args,
|
|
564
574
|
where: args.where?.map((w) => {
|
|
565
575
|
if (w === inWhere) {
|
|
@@ -579,195 +589,35 @@ const paginate = async (
|
|
|
579
589
|
return {
|
|
580
590
|
...result,
|
|
581
591
|
page: await asyncMap(result.page, (doc) =>
|
|
582
|
-
selectFields(
|
|
592
|
+
selectFields(doc, args.select)
|
|
583
593
|
),
|
|
584
594
|
};
|
|
585
595
|
}
|
|
586
596
|
|
|
587
|
-
const query = generateQuery(ctx, args);
|
|
597
|
+
const query = generateQuery(ctx, schema, args);
|
|
588
598
|
const result = await query.paginate(paginationOpts);
|
|
589
599
|
return {
|
|
590
600
|
...result,
|
|
591
|
-
page: await asyncMap(result.page, (doc) =>
|
|
592
|
-
selectFields(ctx, doc, args.select)
|
|
593
|
-
),
|
|
601
|
+
page: await asyncMap(result.page, (doc) => selectFields(doc, args.select)),
|
|
594
602
|
};
|
|
595
603
|
};
|
|
596
604
|
|
|
597
|
-
const listOne = async
|
|
598
|
-
|
|
605
|
+
export const listOne = async <
|
|
606
|
+
Doc extends DocumentByName<GenericDataModel, T>,
|
|
607
|
+
T extends TableNamesInDataModel<GenericDataModel>,
|
|
608
|
+
>(
|
|
609
|
+
ctx: GenericQueryCtx<GenericDataModel>,
|
|
610
|
+
schema: SchemaDefinition<any, any>,
|
|
611
|
+
betterAuthSchema: BetterAuthDbSchema,
|
|
599
612
|
args: Infer<typeof adapterArgsValidator>
|
|
600
|
-
): Promise<Doc
|
|
613
|
+
): Promise<Doc | null> => {
|
|
601
614
|
return (
|
|
602
|
-
await paginate(ctx, {
|
|
615
|
+
await paginate(ctx, schema, betterAuthSchema, {
|
|
603
616
|
...args,
|
|
604
617
|
paginationOpts: {
|
|
605
618
|
numItems: 1,
|
|
606
619
|
cursor: null,
|
|
607
620
|
},
|
|
608
621
|
})
|
|
609
|
-
).page[0];
|
|
622
|
+
).page[0] as Doc | null;
|
|
610
623
|
};
|
|
611
|
-
|
|
612
|
-
export const create = mutation({
|
|
613
|
-
args: {
|
|
614
|
-
input: v.union(
|
|
615
|
-
...Object.entries(schema.tables).map(([model, table]) =>
|
|
616
|
-
v.object({
|
|
617
|
-
model: v.literal(model),
|
|
618
|
-
data: v.object(table.validator.fields),
|
|
619
|
-
})
|
|
620
|
-
)
|
|
621
|
-
),
|
|
622
|
-
},
|
|
623
|
-
handler: async (ctx, args) => {
|
|
624
|
-
await checkUniqueFields(
|
|
625
|
-
ctx,
|
|
626
|
-
args.input.model as TableNames,
|
|
627
|
-
args.input.data
|
|
628
|
-
);
|
|
629
|
-
|
|
630
|
-
const id = await ctx.db.insert(args.input.model as any, args.input.data);
|
|
631
|
-
const doc = await ctx.db.get(id);
|
|
632
|
-
if (!doc) {
|
|
633
|
-
throw new Error(`Failed to create ${args.input.model}`);
|
|
634
|
-
}
|
|
635
|
-
return doc;
|
|
636
|
-
},
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
export const findOne = query({
|
|
640
|
-
args: adapterArgsValidator,
|
|
641
|
-
handler: async (ctx, args) => {
|
|
642
|
-
return listOne(ctx, args);
|
|
643
|
-
},
|
|
644
|
-
});
|
|
645
|
-
|
|
646
|
-
export const findMany = query({
|
|
647
|
-
args: {
|
|
648
|
-
...adapterArgsValidator.fields,
|
|
649
|
-
paginationOpts: paginationOptsValidator,
|
|
650
|
-
},
|
|
651
|
-
handler: async (ctx, args) => {
|
|
652
|
-
return await paginate(ctx, args);
|
|
653
|
-
},
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
export const updateOne = mutation({
|
|
657
|
-
args: {
|
|
658
|
-
input: v.union(
|
|
659
|
-
...Object.entries(schema.tables).map(([model, table]) =>
|
|
660
|
-
v.object({
|
|
661
|
-
model: v.literal(model),
|
|
662
|
-
where: v.optional(v.array(adapterWhereValidator)),
|
|
663
|
-
update: v.object(partial(table.validator.fields)),
|
|
664
|
-
})
|
|
665
|
-
)
|
|
666
|
-
),
|
|
667
|
-
},
|
|
668
|
-
handler: async (ctx, args) => {
|
|
669
|
-
const doc = await listOne(ctx, args.input);
|
|
670
|
-
if (!doc) {
|
|
671
|
-
throw new Error(`Failed to update ${args.input.model}`);
|
|
672
|
-
}
|
|
673
|
-
await checkUniqueFields(
|
|
674
|
-
ctx,
|
|
675
|
-
args.input.model as TableNames,
|
|
676
|
-
args.input.update,
|
|
677
|
-
doc
|
|
678
|
-
);
|
|
679
|
-
await ctx.db.patch(doc._id, args.input.update as any);
|
|
680
|
-
const updatedDoc = await ctx.db.get(doc._id);
|
|
681
|
-
if (!updatedDoc) {
|
|
682
|
-
throw new Error(`Failed to update ${args.input.model}`);
|
|
683
|
-
}
|
|
684
|
-
return updatedDoc;
|
|
685
|
-
},
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
export const updateMany = mutation({
|
|
689
|
-
args: {
|
|
690
|
-
input: v.union(
|
|
691
|
-
...Object.entries(schema.tables).map(([model, table]) =>
|
|
692
|
-
v.object({
|
|
693
|
-
...adapterArgsValidator.fields,
|
|
694
|
-
model: v.literal(model),
|
|
695
|
-
where: v.optional(v.array(adapterWhereValidator)),
|
|
696
|
-
update: v.object(partial(table.validator.fields)),
|
|
697
|
-
paginationOpts: paginationOptsValidator,
|
|
698
|
-
})
|
|
699
|
-
)
|
|
700
|
-
),
|
|
701
|
-
},
|
|
702
|
-
handler: async (ctx, args) => {
|
|
703
|
-
const { page, ...result } = await paginate(ctx, args.input);
|
|
704
|
-
if (args.input.update) {
|
|
705
|
-
if (
|
|
706
|
-
hasUniqueFields(
|
|
707
|
-
args.input.model as TableNames,
|
|
708
|
-
args.input.update ?? {}
|
|
709
|
-
) &&
|
|
710
|
-
page.length > 1
|
|
711
|
-
) {
|
|
712
|
-
throw new Error(
|
|
713
|
-
`Attempted to set unique fields in multiple documents in ${args.input.model} with the same value. Fields: ${Object.keys(args.input.update ?? {}).join(", ")}`
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
await asyncMap(page, async (doc) => {
|
|
717
|
-
await checkUniqueFields(
|
|
718
|
-
ctx,
|
|
719
|
-
args.input.model as TableNames,
|
|
720
|
-
args.input.update ?? {},
|
|
721
|
-
doc
|
|
722
|
-
);
|
|
723
|
-
await ctx.db.patch(doc._id, args.input.update as any);
|
|
724
|
-
});
|
|
725
|
-
}
|
|
726
|
-
return {
|
|
727
|
-
...result,
|
|
728
|
-
count: page.length,
|
|
729
|
-
};
|
|
730
|
-
},
|
|
731
|
-
});
|
|
732
|
-
|
|
733
|
-
export const deleteOne = mutation({
|
|
734
|
-
args: adapterArgsValidator,
|
|
735
|
-
handler: async (ctx, args) => {
|
|
736
|
-
const doc = await listOne(ctx, args);
|
|
737
|
-
if (!doc) {
|
|
738
|
-
return;
|
|
739
|
-
}
|
|
740
|
-
await ctx.db.delete(doc._id);
|
|
741
|
-
return doc;
|
|
742
|
-
},
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
export const deleteMany = mutation({
|
|
746
|
-
args: {
|
|
747
|
-
...adapterArgsValidator.fields,
|
|
748
|
-
paginationOpts: paginationOptsValidator,
|
|
749
|
-
},
|
|
750
|
-
handler: async (ctx, args) => {
|
|
751
|
-
const { page, ...result } = await paginate(ctx, args);
|
|
752
|
-
await asyncMap(page, async (doc) => {
|
|
753
|
-
await ctx.db.delete(doc._id);
|
|
754
|
-
});
|
|
755
|
-
return {
|
|
756
|
-
...result,
|
|
757
|
-
count: page.length,
|
|
758
|
-
};
|
|
759
|
-
},
|
|
760
|
-
});
|
|
761
|
-
|
|
762
|
-
// Get the session via sessionId in jwt claims
|
|
763
|
-
// TODO: this needs a refresh, subquery only necessary for actions
|
|
764
|
-
export const getCurrentSession = query({
|
|
765
|
-
args: {},
|
|
766
|
-
handler: async (ctx) => {
|
|
767
|
-
const identity = await ctx.auth.getUserIdentity();
|
|
768
|
-
if (!identity) {
|
|
769
|
-
return null;
|
|
770
|
-
}
|
|
771
|
-
return ctx.db.get(identity.sessionId as Id<"session">);
|
|
772
|
-
},
|
|
773
|
-
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { BetterAuthDbSchema, type FieldAttribute } from "better-auth/db";
|
|
2
|
+
|
|
3
|
+
// Manually add fields to index on for schema generation,
|
|
4
|
+
// all fields in the schema specialFields are automatically indexed
|
|
5
|
+
export const indexFields = {
|
|
6
|
+
account: ["accountId", ["accountId", "providerId"], ["providerId", "userId"]],
|
|
7
|
+
rateLimit: ["key"],
|
|
8
|
+
session: ["expiresAt", ["expiresAt", "userId"]],
|
|
9
|
+
verification: ["expiresAt", "identifier"],
|
|
10
|
+
user: [["email", "name"], "name", "userId"],
|
|
11
|
+
passkey: ["credentialID"],
|
|
12
|
+
apikey: ["key"],
|
|
13
|
+
member: [["organizationId", "userId"]],
|
|
14
|
+
invitation: [
|
|
15
|
+
["email", "organizationId", "status"],
|
|
16
|
+
["organizationId", "status"],
|
|
17
|
+
],
|
|
18
|
+
oauthConsent: [["clientId", "userId"]],
|
|
19
|
+
ssoProvider: ["organizationId", "domain"],
|
|
20
|
+
subscription: ["stripeSubscriptionId", "stripeCustomerId", "referenceId"],
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Return map of unique, sortable, and reference fields
|
|
24
|
+
const specialFields = (tables: BetterAuthDbSchema) =>
|
|
25
|
+
Object.fromEntries(
|
|
26
|
+
Object.entries(tables)
|
|
27
|
+
.map(([key, table]) => {
|
|
28
|
+
const fields = Object.fromEntries(
|
|
29
|
+
Object.entries(table.fields)
|
|
30
|
+
.map(([fieldKey, field]) => [
|
|
31
|
+
fieldKey,
|
|
32
|
+
{
|
|
33
|
+
...(field.sortable ? { sortable: true } : {}),
|
|
34
|
+
...(field.unique ? { unique: true } : {}),
|
|
35
|
+
...(field.references ? { references: field.references } : {}),
|
|
36
|
+
},
|
|
37
|
+
])
|
|
38
|
+
.filter(([_key, value]) =>
|
|
39
|
+
typeof value === "object" ? Object.keys(value).length > 0 : true
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
return [key, fields];
|
|
43
|
+
})
|
|
44
|
+
.filter(([_key, value]) =>
|
|
45
|
+
typeof value === "object" ? Object.keys(value).length > 0 : true
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const mergedIndexFields = (tables: BetterAuthDbSchema) =>
|
|
50
|
+
Object.fromEntries(
|
|
51
|
+
Object.entries(tables).map(([key]) => {
|
|
52
|
+
const manualIndexes = indexFields[key as keyof typeof indexFields] || [];
|
|
53
|
+
const specialFieldIndexes = Object.keys(
|
|
54
|
+
specialFields(tables)[key as keyof ReturnType<typeof specialFields>] ||
|
|
55
|
+
{}
|
|
56
|
+
).filter(
|
|
57
|
+
(index) =>
|
|
58
|
+
!manualIndexes.some((m) =>
|
|
59
|
+
Array.isArray(m) ? m[0] === index : m === index
|
|
60
|
+
)
|
|
61
|
+
);
|
|
62
|
+
return [key, manualIndexes.concat(specialFieldIndexes)];
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
export const createSchema = async ({
|
|
67
|
+
file,
|
|
68
|
+
tables,
|
|
69
|
+
}: {
|
|
70
|
+
tables: BetterAuthDbSchema;
|
|
71
|
+
file?: string;
|
|
72
|
+
}) => {
|
|
73
|
+
process.env.IS_GENERATING_SCHEMA = "1";
|
|
74
|
+
let code: string = `// This file is auto-generated. Do not edit this file manually.
|
|
75
|
+
// To regenerate the schema, run:
|
|
76
|
+
// \`npx @better-auth/cli generate --output ${file} -y\`
|
|
77
|
+
|
|
78
|
+
import { defineSchema, defineTable } from "convex/server";
|
|
79
|
+
import { v } from "convex/values";
|
|
80
|
+
|
|
81
|
+
export const tables = {
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
for (const tableKey in tables) {
|
|
85
|
+
const table = tables[tableKey]!;
|
|
86
|
+
const modelName = table.modelName;
|
|
87
|
+
|
|
88
|
+
// No id fields in Convex schema
|
|
89
|
+
const fields = Object.fromEntries(
|
|
90
|
+
Object.entries(table.fields).filter(([key]) => key !== "id")
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
function getType(name: string, field: FieldAttribute) {
|
|
94
|
+
const type = field.type as
|
|
95
|
+
| "string"
|
|
96
|
+
| "number"
|
|
97
|
+
| "boolean"
|
|
98
|
+
| "date"
|
|
99
|
+
| `${"string" | "number"}[]`;
|
|
100
|
+
|
|
101
|
+
const typeMap: Record<typeof type, string> = {
|
|
102
|
+
string: `v.string()`,
|
|
103
|
+
boolean: `v.boolean()`,
|
|
104
|
+
number: `v.number()`,
|
|
105
|
+
date: `v.number()`,
|
|
106
|
+
"number[]": `v.array(v.number())`,
|
|
107
|
+
"string[]": `v.array(v.string())`,
|
|
108
|
+
} as const;
|
|
109
|
+
return typeMap[type];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const indexes =
|
|
113
|
+
mergedIndexFields(tables)[
|
|
114
|
+
modelName as keyof typeof mergedIndexFields
|
|
115
|
+
]?.map((index) => {
|
|
116
|
+
const indexArray = Array.isArray(index) ? index.sort() : [index];
|
|
117
|
+
const indexName = indexArray.join("_");
|
|
118
|
+
return `.index("${indexName}", ${JSON.stringify(indexArray)})`;
|
|
119
|
+
}) || [];
|
|
120
|
+
|
|
121
|
+
const schema = `${modelName}: defineTable({
|
|
122
|
+
${Object.keys(fields)
|
|
123
|
+
.map((field) => {
|
|
124
|
+
const attr = fields[field]!;
|
|
125
|
+
const type = getType(field, attr as FieldAttribute);
|
|
126
|
+
const optional = (fieldSchema: string) =>
|
|
127
|
+
attr.required
|
|
128
|
+
? fieldSchema
|
|
129
|
+
: `v.optional(v.union(v.null(), ${fieldSchema}))`;
|
|
130
|
+
return ` ${field}: ${optional(type)},`;
|
|
131
|
+
})
|
|
132
|
+
.join("\n")}
|
|
133
|
+
})${indexes.length > 0 ? `\n ${indexes.join("\n ")}` : ""},\n`;
|
|
134
|
+
code += ` ${schema}`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
code += `};
|
|
138
|
+
|
|
139
|
+
const schema = defineSchema(tables);
|
|
140
|
+
|
|
141
|
+
export default schema;
|
|
142
|
+
`;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
code,
|
|
146
|
+
path: file ?? "./schema.ts",
|
|
147
|
+
overwrite: true,
|
|
148
|
+
};
|
|
149
|
+
};
|