@convex-dev/better-auth 0.7.0-alpha.12 → 0.7.0-alpha.3
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 +1 -10
- package/dist/commonjs/client/adapter.d.ts.map +1 -1
- package/dist/commonjs/client/adapter.js +192 -183
- package/dist/commonjs/client/adapter.js.map +1 -1
- package/dist/commonjs/client/index.d.ts +179 -238
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +67 -60
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/component/lib.d.ts +548 -218
- package/dist/commonjs/component/lib.d.ts.map +1 -1
- package/dist/commonjs/component/lib.js +286 -315
- package/dist/commonjs/component/lib.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +28 -90
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +18 -76
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/component/util.d.ts +86 -148
- package/dist/commonjs/component/util.d.ts.map +1 -1
- package/dist/commonjs/nextjs/index.d.ts.map +1 -1
- package/dist/commonjs/nextjs/index.js +0 -3
- package/dist/commonjs/nextjs/index.js.map +1 -1
- package/dist/commonjs/plugins/convex/index.d.ts +11 -14
- package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
- package/dist/commonjs/plugins/convex/index.js +4 -10
- package/dist/commonjs/plugins/convex/index.js.map +1 -1
- package/dist/commonjs/plugins/cross-domain/client.d.ts +1 -1
- package/dist/commonjs/plugins/cross-domain/index.d.ts +3 -5
- package/dist/commonjs/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/commonjs/plugins/cross-domain/index.js +5 -19
- package/dist/commonjs/plugins/cross-domain/index.js.map +1 -1
- package/dist/commonjs/react/client.d.ts +1 -1
- package/dist/commonjs/react/client.d.ts.map +1 -1
- package/dist/commonjs/react/client.js +9 -3
- package/dist/commonjs/react/client.js.map +1 -1
- package/dist/commonjs/react-start/index.d.ts +3 -37
- package/dist/commonjs/react-start/index.d.ts.map +1 -1
- package/dist/commonjs/react-start/index.js +4 -20
- package/dist/commonjs/react-start/index.js.map +1 -1
- package/dist/esm/client/adapter.d.ts +1 -10
- package/dist/esm/client/adapter.d.ts.map +1 -1
- package/dist/esm/client/adapter.js +192 -183
- package/dist/esm/client/adapter.js.map +1 -1
- package/dist/esm/client/index.d.ts +179 -238
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +67 -60
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/component/lib.d.ts +548 -218
- package/dist/esm/component/lib.d.ts.map +1 -1
- package/dist/esm/component/lib.js +286 -315
- package/dist/esm/component/lib.js.map +1 -1
- package/dist/esm/component/schema.d.ts +28 -90
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +18 -76
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/component/util.d.ts +86 -148
- package/dist/esm/component/util.d.ts.map +1 -1
- package/dist/esm/nextjs/index.d.ts.map +1 -1
- package/dist/esm/nextjs/index.js +0 -3
- package/dist/esm/nextjs/index.js.map +1 -1
- package/dist/esm/plugins/convex/index.d.ts +11 -14
- package/dist/esm/plugins/convex/index.d.ts.map +1 -1
- package/dist/esm/plugins/convex/index.js +4 -10
- package/dist/esm/plugins/convex/index.js.map +1 -1
- package/dist/esm/plugins/cross-domain/client.d.ts +1 -1
- package/dist/esm/plugins/cross-domain/index.d.ts +3 -5
- package/dist/esm/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/esm/plugins/cross-domain/index.js +5 -19
- package/dist/esm/plugins/cross-domain/index.js.map +1 -1
- package/dist/esm/react/client.d.ts +1 -1
- package/dist/esm/react/client.d.ts.map +1 -1
- package/dist/esm/react/client.js +9 -3
- package/dist/esm/react/client.js.map +1 -1
- package/dist/esm/react-start/index.d.ts +3 -37
- package/dist/esm/react-start/index.d.ts.map +1 -1
- package/dist/esm/react-start/index.js +4 -20
- package/dist/esm/react-start/index.js.map +1 -1
- package/package.json +5 -20
- package/src/client/adapter.ts +195 -191
- package/src/client/cors.ts +425 -0
- package/src/client/index.ts +80 -61
- package/src/component/_generated/api.d.ts +149 -605
- package/src/component/lib.ts +335 -444
- package/src/component/schema.ts +19 -81
- package/src/nextjs/index.ts +0 -3
- package/src/plugins/convex/index.ts +4 -12
- package/src/plugins/cross-domain/index.ts +5 -19
- package/src/react/client.tsx +11 -5
- package/src/react-start/index.ts +6 -33
- package/dist/commonjs/component/adapterTest.d.ts +0 -19
- package/dist/commonjs/component/adapterTest.d.ts.map +0 -1
- package/dist/commonjs/component/adapterTest.js +0 -82
- package/dist/commonjs/component/adapterTest.js.map +0 -1
- package/dist/commonjs/utils/index.d.ts +0 -2
- package/dist/commonjs/utils/index.d.ts.map +0 -1
- package/dist/commonjs/utils/index.js +0 -8
- package/dist/commonjs/utils/index.js.map +0 -1
- package/dist/esm/component/adapterTest.d.ts +0 -19
- package/dist/esm/component/adapterTest.d.ts.map +0 -1
- package/dist/esm/component/adapterTest.js +0 -82
- package/dist/esm/component/adapterTest.js.map +0 -1
- package/dist/esm/utils/index.d.ts +0 -2
- package/dist/esm/utils/index.d.ts.map +0 -1
- package/dist/esm/utils/index.js +0 -8
- package/dist/esm/utils/index.js.map +0 -1
- package/src/client/adapter.test.ts +0 -144
- package/src/component/adapterTest.ts +0 -141
- package/src/react-start/vite-env.d.ts +0 -2
- /package/src/{utils/index.ts → util.ts} +0 -0
|
@@ -1,380 +1,351 @@
|
|
|
1
|
-
import { mutation, query } from "../component/_generated/server";
|
|
1
|
+
import { action, mutation, query, } from "../component/_generated/server";
|
|
2
2
|
import { asyncMap } from "convex-helpers";
|
|
3
3
|
import { v } from "convex/values";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import { api } from "../component/_generated/api";
|
|
5
|
+
import schema from "../component/schema";
|
|
6
|
+
import { paginationOptsValidator } from "convex/server";
|
|
6
7
|
import { paginator } from "convex-helpers/server/pagination";
|
|
7
8
|
import { partial } from "convex-helpers/validators";
|
|
8
|
-
export const
|
|
9
|
-
field: v.string(),
|
|
10
|
-
operator: v.optional(v.union(v.literal("lt"), v.literal("lte"), v.literal("gt"), v.literal("gte"), v.literal("eq"), v.literal("in"), v.literal("ne"), v.literal("contains"), v.literal("starts_with"), v.literal("ends_with"))),
|
|
11
|
-
value: v.union(v.string(), v.number(), v.boolean(), v.array(v.string()), v.array(v.number()), v.null()),
|
|
12
|
-
connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
|
|
13
|
-
});
|
|
14
|
-
export const adapterArgsValidator = v.object({
|
|
15
|
-
model: v.string(),
|
|
16
|
-
where: v.optional(v.array(adapterWhereValidator)),
|
|
17
|
-
sortBy: v.optional(v.object({
|
|
18
|
-
field: v.string(),
|
|
19
|
-
direction: v.union(v.literal("asc"), v.literal("desc")),
|
|
20
|
-
})),
|
|
21
|
-
select: v.optional(v.array(v.string())),
|
|
22
|
-
limit: v.optional(v.number()),
|
|
23
|
-
unique: v.optional(v.boolean()),
|
|
24
|
-
});
|
|
25
|
-
const getUniqueFields = (table, input) => {
|
|
26
|
-
const fields = specialFields[table];
|
|
27
|
-
if (!fields) {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
return Object.entries(fields)
|
|
31
|
-
.filter(([key, value]) => value.unique && Object.keys(input).includes(key))
|
|
32
|
-
.map(([key]) => key);
|
|
33
|
-
};
|
|
34
|
-
const checkUniqueFields = async (ctx, table, input, doc) => {
|
|
35
|
-
const uniqueFields = getUniqueFields(table, input);
|
|
36
|
-
if (!uniqueFields.length) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
for (const field of uniqueFields) {
|
|
40
|
-
const existingDoc = await ctx.db
|
|
41
|
-
.query(table)
|
|
42
|
-
.withIndex(field, (q) => q.eq(field, input[field]))
|
|
43
|
-
.unique();
|
|
44
|
-
if (existingDoc && existingDoc._id !== doc?._id) {
|
|
45
|
-
throw new Error(`${table} ${field} already exists`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const findIndex = async (args) => {
|
|
50
|
-
if (!args.where && !args.sortBy) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (args.where?.some((w) => w.field === "id")) {
|
|
54
|
-
throw new Error("id is not a valid index field");
|
|
55
|
-
}
|
|
56
|
-
if (args.where?.some((w) => w.connector && w.connector !== "AND")) {
|
|
57
|
-
throw new Error(`OR connector not supported: ${JSON.stringify(args.where)}`);
|
|
58
|
-
}
|
|
59
|
-
if (args.where?.some((w) => w.operator &&
|
|
60
|
-
!["lt", "lte", "gt", "gte", "eq", "in"].includes(w.operator))) {
|
|
61
|
-
throw new Error(`where clause not supported: ${JSON.stringify(args.where)}`);
|
|
62
|
-
}
|
|
63
|
-
const lowerBounds = args.where?.filter((w) => w.operator === "lt" || w.operator === "lte") ??
|
|
64
|
-
[];
|
|
65
|
-
if (lowerBounds.length > 1) {
|
|
66
|
-
throw new Error(`cannot have more than one lower bound where clause: ${JSON.stringify(args.where)}`);
|
|
67
|
-
}
|
|
68
|
-
const upperBounds = args.where?.filter((w) => w.operator === "gt" || w.operator === "gte") ??
|
|
69
|
-
[];
|
|
70
|
-
if (upperBounds.length > 1) {
|
|
71
|
-
throw new Error(`cannot have more than one upper bound where clause: ${JSON.stringify(args.where)}`);
|
|
72
|
-
}
|
|
73
|
-
const lowerBound = lowerBounds[0];
|
|
74
|
-
const upperBound = upperBounds[0];
|
|
75
|
-
if (lowerBound && upperBound && lowerBound.field !== upperBound.field) {
|
|
76
|
-
throw new Error(`lower bound and upper bound must have the same field: ${JSON.stringify(args.where)}`);
|
|
77
|
-
}
|
|
78
|
-
const boundField = lowerBound?.field || upperBound?.field;
|
|
79
|
-
if (boundField &&
|
|
80
|
-
args.where?.some((w) => w.field === boundField && w !== lowerBound && w !== upperBound)) {
|
|
81
|
-
throw new Error(`too many where clauses on the bound field: ${JSON.stringify(args.where)}`);
|
|
82
|
-
}
|
|
83
|
-
const indexFields = args.where
|
|
84
|
-
?.filter((w) => !w.operator || w.operator === "eq")
|
|
85
|
-
.sort((a, b) => {
|
|
86
|
-
return a.field.localeCompare(b.field);
|
|
87
|
-
})
|
|
88
|
-
.map((w) => [w.field, w.value]) ?? [];
|
|
89
|
-
if (!indexFields?.length && !boundField && !args.sortBy) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const indexes = schema.tables[args.model][" indexes"]();
|
|
93
|
-
const sortField = args.sortBy?.field;
|
|
94
|
-
// We internally use _creationTime in place of Better Auth's createdAt
|
|
95
|
-
const indexName = indexFields
|
|
96
|
-
.map(([field]) => field)
|
|
97
|
-
.join("_")
|
|
98
|
-
.concat(boundField && boundField !== "createdAt"
|
|
99
|
-
? `${indexFields.length ? "_" : ""}${boundField}`
|
|
100
|
-
: "")
|
|
101
|
-
.concat(sortField && sortField !== "createdAt" && boundField !== sortField
|
|
102
|
-
? `${indexFields.length || boundField ? "_" : ""}${sortField}`
|
|
103
|
-
: "");
|
|
104
|
-
if (!indexName && !boundField && !sortField) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
// Use the built in creationTime index if bounding or sorting by createdAt
|
|
108
|
-
// with no other fields
|
|
109
|
-
const index = !indexName
|
|
110
|
-
? {
|
|
111
|
-
indexDescriptor: "by_creation_time",
|
|
112
|
-
fields: [],
|
|
113
|
-
}
|
|
114
|
-
: indexes.find(({ indexDescriptor }) => {
|
|
115
|
-
return boundField === "createdAt" || sortField === "createdAt"
|
|
116
|
-
? indexDescriptor === indexName
|
|
117
|
-
: indexDescriptor.startsWith(indexName);
|
|
118
|
-
});
|
|
119
|
-
if (!index) {
|
|
120
|
-
throw new Error(`Index ${indexName} not found for table ${args.model}`);
|
|
121
|
-
}
|
|
9
|
+
export const transformInput = (model, data) => {
|
|
122
10
|
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
values: {
|
|
130
|
-
eq: indexFields.map(([, value]) => value),
|
|
131
|
-
lt: lowerBound?.operator === "lt" ? lowerBound.value : undefined,
|
|
132
|
-
lte: lowerBound?.operator === "lte" ? lowerBound.value : undefined,
|
|
133
|
-
gt: upperBound?.operator === "gt" ? upperBound.value : undefined,
|
|
134
|
-
gte: upperBound?.operator === "gte" ? upperBound.value : undefined,
|
|
135
|
-
},
|
|
11
|
+
...Object.fromEntries(Object.entries(data).map(([key, value]) => {
|
|
12
|
+
if (value instanceof Date) {
|
|
13
|
+
return [key, value.getTime()];
|
|
14
|
+
}
|
|
15
|
+
return [key, value];
|
|
16
|
+
})),
|
|
136
17
|
};
|
|
137
18
|
};
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
if (!select?.length) {
|
|
143
|
-
return doc;
|
|
144
|
-
}
|
|
145
|
-
return select.reduce((acc, field) => {
|
|
146
|
-
acc[field] = doc[field];
|
|
147
|
-
return acc;
|
|
148
|
-
}, {});
|
|
19
|
+
export const transformOutput = ({ _id, _creationTime, ...data }, _model) => {
|
|
20
|
+
// Provide the expected id field, but it can be overwritten if
|
|
21
|
+
// the model has an id field
|
|
22
|
+
return { id: _id, ...data };
|
|
149
23
|
};
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
24
|
+
// Get the session via sessionId in jwt claims
|
|
25
|
+
export const getCurrentSession = query({
|
|
26
|
+
args: {},
|
|
27
|
+
handler: async (ctx) => {
|
|
28
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
29
|
+
if (!identity) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return ctx.db.get(identity.sessionId);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
export const getByHelper = async (ctx, args) => {
|
|
36
|
+
if (args.field === "id") {
|
|
37
|
+
return ctx.db.get(args.value);
|
|
163
38
|
}
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
values?.lte ||
|
|
169
|
-
values?.gt ||
|
|
170
|
-
values?.gte;
|
|
171
|
-
const indexedQuery = index && index.indexDescriptor !== "by_creation_time"
|
|
172
|
-
? query.withIndex(index.indexDescriptor, hasValues
|
|
173
|
-
? (q) => {
|
|
174
|
-
for (const [idx, value] of (values?.eq ?? []).entries()) {
|
|
175
|
-
q = q.eq(index.fields[idx], value);
|
|
176
|
-
}
|
|
177
|
-
if (values?.lt) {
|
|
178
|
-
q = q.lt(boundField, values.lt);
|
|
179
|
-
}
|
|
180
|
-
if (values?.lte) {
|
|
181
|
-
q = q.lte(boundField, values.lte);
|
|
182
|
-
}
|
|
183
|
-
if (values?.gt) {
|
|
184
|
-
q = q.gt(boundField, values.gt);
|
|
185
|
-
}
|
|
186
|
-
if (values?.gte) {
|
|
187
|
-
q = q.gte(boundField, values.gte);
|
|
188
|
-
}
|
|
189
|
-
return q;
|
|
190
|
-
}
|
|
191
|
-
: undefined)
|
|
192
|
-
: query;
|
|
193
|
-
const orderedQuery = args.sortBy
|
|
194
|
-
? indexedQuery.order(args.sortBy.direction === "asc" ? "asc" : "desc")
|
|
195
|
-
: indexedQuery;
|
|
196
|
-
const result = await orderedQuery.paginate(args.paginationOpts);
|
|
197
|
-
return {
|
|
198
|
-
...result,
|
|
199
|
-
page: result.page.map((doc) => selectFields(doc, args.select)),
|
|
200
|
-
};
|
|
39
|
+
const query = ctx.db
|
|
40
|
+
.query(args.table)
|
|
41
|
+
.withIndex(args.field, (q) => q.eq(args.field, args.value));
|
|
42
|
+
return args.unique ? await query.unique() : await query.first();
|
|
201
43
|
};
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
cursor: null,
|
|
208
|
-
},
|
|
209
|
-
})).page[0];
|
|
44
|
+
export const getByArgsValidator = {
|
|
45
|
+
table: v.string(),
|
|
46
|
+
field: v.string(),
|
|
47
|
+
unique: v.optional(v.boolean()),
|
|
48
|
+
value: v.union(v.string(), v.number(), v.boolean(), v.array(v.string()), v.array(v.number()), v.null()),
|
|
210
49
|
};
|
|
50
|
+
// Generic functions
|
|
51
|
+
export const getByQuery = query({
|
|
52
|
+
args: getByArgsValidator,
|
|
53
|
+
handler: async (ctx, args) => {
|
|
54
|
+
const doc = await getByHelper(ctx, args);
|
|
55
|
+
if (!doc) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
return transformOutput(doc, args.table);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
export { getByQuery as getBy };
|
|
211
62
|
export const create = mutation({
|
|
212
|
-
args: {
|
|
213
|
-
input: v.union(...Object.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
data: v.object(table.validator.fields),
|
|
63
|
+
args: v.object({
|
|
64
|
+
input: v.union(...Object.values(schema.tables).map((table) => v.object({
|
|
65
|
+
table: v.string(),
|
|
66
|
+
...table.validator.fields,
|
|
217
67
|
}))),
|
|
218
|
-
},
|
|
68
|
+
}),
|
|
219
69
|
handler: async (ctx, args) => {
|
|
220
|
-
|
|
221
|
-
const id = await ctx.db.insert(
|
|
70
|
+
const { table, ...input } = args.input;
|
|
71
|
+
const id = await ctx.db.insert(table, {
|
|
72
|
+
...input,
|
|
73
|
+
});
|
|
222
74
|
const doc = await ctx.db.get(id);
|
|
223
75
|
if (!doc) {
|
|
224
|
-
throw new Error(`Failed to create ${
|
|
76
|
+
throw new Error(`Failed to create ${table}`);
|
|
77
|
+
}
|
|
78
|
+
return transformOutput(doc, table);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
export const updateArgsInputValidator = (table) => {
|
|
82
|
+
return v.object({
|
|
83
|
+
table: v.literal(table),
|
|
84
|
+
where: v.object({ field: v.string(), value: getByArgsValidator.value }),
|
|
85
|
+
value: v.record(v.string(), v.any()),
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const updateArgsValidator = {
|
|
89
|
+
input: v.union(updateArgsInputValidator("account"), updateArgsInputValidator("session"), updateArgsInputValidator("verification"), updateArgsInputValidator("user")),
|
|
90
|
+
};
|
|
91
|
+
export const update = mutation({
|
|
92
|
+
args: updateArgsValidator,
|
|
93
|
+
handler: async (ctx, args) => {
|
|
94
|
+
const { table, where, value } = args.input;
|
|
95
|
+
const doc = where.field === "id"
|
|
96
|
+
? await ctx.db.get(where.value)
|
|
97
|
+
: await getByHelper(ctx, { table, ...where });
|
|
98
|
+
if (!doc) {
|
|
99
|
+
throw new Error(`Failed to update ${table}`);
|
|
100
|
+
}
|
|
101
|
+
await ctx.db.patch(doc._id, value);
|
|
102
|
+
const updatedDoc = await ctx.db.get(doc._id);
|
|
103
|
+
if (!updatedDoc) {
|
|
104
|
+
throw new Error(`Failed to update ${table}`);
|
|
105
|
+
}
|
|
106
|
+
return transformOutput(updatedDoc, table);
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
export const deleteBy = mutation({
|
|
110
|
+
args: getByArgsValidator,
|
|
111
|
+
handler: async (ctx, args) => {
|
|
112
|
+
const doc = await getByHelper(ctx, args);
|
|
113
|
+
if (!doc) {
|
|
114
|
+
return;
|
|
225
115
|
}
|
|
116
|
+
await ctx.db.delete(doc._id);
|
|
117
|
+
// onDeleteUser requires userId from the doc,
|
|
118
|
+
// so just return the whole thing
|
|
226
119
|
return doc;
|
|
227
120
|
},
|
|
228
121
|
});
|
|
229
|
-
|
|
230
|
-
|
|
122
|
+
// Single purpose functions
|
|
123
|
+
export const getAccountsByUserId = query({
|
|
124
|
+
args: { userId: v.string(), limit: v.optional(v.number()) },
|
|
231
125
|
handler: async (ctx, args) => {
|
|
232
|
-
|
|
126
|
+
const query = ctx.db
|
|
127
|
+
.query("account")
|
|
128
|
+
.withIndex("userId", (q) => q.eq("userId", args.userId));
|
|
129
|
+
const docs = args.limit
|
|
130
|
+
? await query.take(args.limit)
|
|
131
|
+
: await query.collect();
|
|
132
|
+
return docs.map((doc) => transformOutput(doc, "account"));
|
|
233
133
|
},
|
|
234
134
|
});
|
|
235
|
-
export const
|
|
135
|
+
export const getSessionsByUserId = query({
|
|
136
|
+
args: { userId: v.string(), limit: v.optional(v.number()) },
|
|
137
|
+
handler: async (ctx, args) => {
|
|
138
|
+
const query = ctx.db
|
|
139
|
+
.query("session")
|
|
140
|
+
.withIndex("userId", (q) => q.eq("userId", args.userId));
|
|
141
|
+
const docs = args.limit
|
|
142
|
+
? await query.take(args.limit)
|
|
143
|
+
: await query.collect();
|
|
144
|
+
return docs.map((doc) => transformOutput(doc, "session"));
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
export const getJwks = query({
|
|
236
148
|
args: {
|
|
237
|
-
|
|
238
|
-
paginationOpts: paginationOptsValidator,
|
|
149
|
+
limit: v.optional(v.number()),
|
|
239
150
|
},
|
|
240
151
|
handler: async (ctx, args) => {
|
|
241
|
-
|
|
152
|
+
const query = ctx.db.query("jwks");
|
|
153
|
+
const docs = args.limit
|
|
154
|
+
? await query.take(args.limit)
|
|
155
|
+
: await query.collect();
|
|
156
|
+
return docs.map((doc) => transformOutput(doc, "jwks"));
|
|
242
157
|
},
|
|
243
158
|
});
|
|
244
|
-
export const
|
|
159
|
+
export const listVerificationsByIdentifier = query({
|
|
245
160
|
args: {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
]))),
|
|
253
|
-
}))),
|
|
161
|
+
identifier: v.string(),
|
|
162
|
+
sortBy: v.optional(v.object({
|
|
163
|
+
field: v.string(),
|
|
164
|
+
direction: v.union(v.literal("asc"), v.literal("desc")),
|
|
165
|
+
})),
|
|
166
|
+
limit: v.optional(v.number()),
|
|
254
167
|
},
|
|
255
168
|
handler: async (ctx, args) => {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
throw new Error(`Failed to update ${args.input.model}`);
|
|
169
|
+
if (args.sortBy && args.sortBy.field !== "createdAt") {
|
|
170
|
+
throw new Error(`Unsupported sortBy field: ${args.sortBy.field}`);
|
|
259
171
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
172
|
+
const query = ctx.db
|
|
173
|
+
.query("verification")
|
|
174
|
+
.withIndex("identifier", (q) => q.eq("identifier", args.identifier))
|
|
175
|
+
.order(args.sortBy?.field === "createdAt" && args.sortBy?.direction
|
|
176
|
+
? args.sortBy.direction
|
|
177
|
+
: "asc");
|
|
178
|
+
const docs = args.limit
|
|
179
|
+
? await query.take(args.limit)
|
|
180
|
+
: await query.collect();
|
|
181
|
+
return docs.map((doc) => transformOutput(doc, "verification"));
|
|
267
182
|
},
|
|
268
183
|
});
|
|
269
|
-
export const
|
|
184
|
+
export const deleteOldVerificationsPage = mutation({
|
|
270
185
|
args: {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
paginationOpts: paginationOptsValidator,
|
|
186
|
+
currentTimestamp: v.number(),
|
|
187
|
+
paginationOpts: v.optional(paginationOptsValidator),
|
|
274
188
|
},
|
|
275
189
|
handler: async (ctx, args) => {
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (uniqueFields.length && page.length > 1) {
|
|
280
|
-
throw new Error(`Attempted to set unique fields in multiple documents in ${args.model} with the same value. Fields: ${uniqueFields.join(", ")}`);
|
|
281
|
-
}
|
|
282
|
-
await asyncMap(page, async (doc) => {
|
|
283
|
-
await checkUniqueFields(ctx, args.model, args.update ?? {}, doc);
|
|
284
|
-
await ctx.db.patch(doc._id, args.update);
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
return {
|
|
288
|
-
...result,
|
|
289
|
-
count: page.length,
|
|
190
|
+
const paginationOpts = args.paginationOpts ?? {
|
|
191
|
+
numItems: 500,
|
|
192
|
+
cursor: null,
|
|
290
193
|
};
|
|
194
|
+
const { page, ...result } = await paginator(ctx.db, schema)
|
|
195
|
+
.query("verification")
|
|
196
|
+
.withIndex("expiresAt", (q) => q.lt("expiresAt", args.currentTimestamp))
|
|
197
|
+
.paginate(paginationOpts);
|
|
198
|
+
await asyncMap(page, async (doc) => {
|
|
199
|
+
await ctx.db.delete(doc._id);
|
|
200
|
+
});
|
|
201
|
+
return { ...result, count: page.length };
|
|
291
202
|
},
|
|
292
203
|
});
|
|
293
|
-
export const
|
|
294
|
-
args:
|
|
204
|
+
export const deleteOldVerifications = action({
|
|
205
|
+
args: {
|
|
206
|
+
currentTimestamp: v.number(),
|
|
207
|
+
},
|
|
295
208
|
handler: async (ctx, args) => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
209
|
+
let count = 0;
|
|
210
|
+
let cursor = null;
|
|
211
|
+
let isDone = false;
|
|
212
|
+
do {
|
|
213
|
+
const result = await ctx.runMutation(api.lib.deleteOldVerificationsPage, {
|
|
214
|
+
currentTimestamp: args.currentTimestamp,
|
|
215
|
+
paginationOpts: {
|
|
216
|
+
numItems: 500,
|
|
217
|
+
cursor,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
count += result.count;
|
|
221
|
+
cursor =
|
|
222
|
+
result.pageStatus &&
|
|
223
|
+
result.splitCursor &&
|
|
224
|
+
["SplitRecommended", "SplitRequired"].includes(result.pageStatus)
|
|
225
|
+
? result.splitCursor
|
|
226
|
+
: result.continueCursor;
|
|
227
|
+
isDone = result.isDone;
|
|
228
|
+
} while (!isDone);
|
|
229
|
+
return count;
|
|
302
230
|
},
|
|
303
231
|
});
|
|
304
|
-
export const
|
|
232
|
+
export const deleteExpiredSessions = mutation({
|
|
305
233
|
args: {
|
|
306
|
-
|
|
307
|
-
|
|
234
|
+
userId: v.string(),
|
|
235
|
+
expiresAt: v.number(),
|
|
308
236
|
},
|
|
309
237
|
handler: async (ctx, args) => {
|
|
310
|
-
const
|
|
311
|
-
|
|
238
|
+
const docs = await ctx.db
|
|
239
|
+
.query("session")
|
|
240
|
+
.withIndex("userId_expiresAt", (q) => q.eq("userId", args.userId).lt("expiresAt", args.expiresAt))
|
|
241
|
+
.collect();
|
|
242
|
+
await asyncMap(docs, async (doc) => {
|
|
312
243
|
await ctx.db.delete(doc._id);
|
|
313
244
|
});
|
|
314
|
-
return
|
|
315
|
-
|
|
316
|
-
|
|
245
|
+
return docs.length;
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
export const deleteAllForUserPage = mutation({
|
|
249
|
+
args: {
|
|
250
|
+
table: v.string(),
|
|
251
|
+
userId: v.string(),
|
|
252
|
+
paginationOpts: v.optional(paginationOptsValidator),
|
|
253
|
+
},
|
|
254
|
+
handler: async (ctx, args) => {
|
|
255
|
+
const paginationOpts = args.paginationOpts ?? {
|
|
256
|
+
numItems: 500,
|
|
257
|
+
cursor: null,
|
|
317
258
|
};
|
|
259
|
+
const { page, ...result } = await paginator(ctx.db, schema)
|
|
260
|
+
.query(args.table)
|
|
261
|
+
.withIndex("userId", (q) => q.eq("userId", args.userId))
|
|
262
|
+
.paginate(paginationOpts);
|
|
263
|
+
await asyncMap(page, async (doc) => {
|
|
264
|
+
await ctx.db.delete(doc._id);
|
|
265
|
+
});
|
|
266
|
+
return { ...result, count: page.length };
|
|
318
267
|
},
|
|
319
268
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
269
|
+
export const deleteAllForUser = action({
|
|
270
|
+
args: {
|
|
271
|
+
table: v.string(),
|
|
272
|
+
userId: v.string(),
|
|
273
|
+
},
|
|
274
|
+
handler: async (ctx, args) => {
|
|
275
|
+
let count = 0;
|
|
276
|
+
let cursor = null;
|
|
277
|
+
let isDone = false;
|
|
278
|
+
do {
|
|
279
|
+
const result = await ctx.runMutation(api.lib.deleteAllForUserPage, {
|
|
280
|
+
table: args.table,
|
|
281
|
+
userId: args.userId,
|
|
282
|
+
paginationOpts: {
|
|
283
|
+
numItems: 500,
|
|
284
|
+
cursor,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
count += result.count;
|
|
288
|
+
cursor =
|
|
289
|
+
result.pageStatus &&
|
|
290
|
+
result.splitCursor &&
|
|
291
|
+
["SplitRecommended", "SplitRequired"].includes(result.pageStatus)
|
|
292
|
+
? result.splitCursor
|
|
293
|
+
: result.continueCursor;
|
|
294
|
+
isDone = result.isDone;
|
|
295
|
+
} while (!isDone);
|
|
296
|
+
return count;
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
export const getAccountByAccountIdAndProviderId = query({
|
|
300
|
+
args: { accountId: v.string(), providerId: v.string() },
|
|
301
|
+
handler: async (ctx, args) => {
|
|
302
|
+
const doc = await ctx.db
|
|
303
|
+
.query("account")
|
|
304
|
+
.withIndex("providerId_accountId", (q) => q.eq("providerId", args.providerId).eq("accountId", args.accountId))
|
|
305
|
+
.unique();
|
|
306
|
+
if (!doc) {
|
|
307
|
+
return;
|
|
328
308
|
}
|
|
329
|
-
return
|
|
309
|
+
return transformOutput(doc, "account");
|
|
330
310
|
},
|
|
331
311
|
});
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
312
|
+
export const updateUserProviderAccounts = mutation({
|
|
313
|
+
args: {
|
|
314
|
+
userId: v.string(),
|
|
315
|
+
providerId: v.string(),
|
|
316
|
+
update: v.object(partial(schema.tables.account.validator.fields)),
|
|
317
|
+
},
|
|
335
318
|
handler: async (ctx, args) => {
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
319
|
+
const docs = await ctx.db
|
|
320
|
+
.query("account")
|
|
321
|
+
.withIndex("userId_providerId", (q) => q.eq("userId", args.userId).eq("providerId", args.providerId))
|
|
322
|
+
.collect();
|
|
323
|
+
if (docs.length === 0) {
|
|
324
|
+
return 0;
|
|
339
325
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const query = ctx.db
|
|
345
|
-
.query(args.model)
|
|
346
|
-
.withIndex(where.field, (q) => q.eq(where.field, value));
|
|
347
|
-
if (args.limit) {
|
|
348
|
-
return await query.take(args.limit);
|
|
349
|
-
}
|
|
350
|
-
return await query.collect();
|
|
351
|
-
}))
|
|
352
|
-
.flat()
|
|
353
|
-
.filter(Boolean);
|
|
326
|
+
await asyncMap(docs, async (doc) => {
|
|
327
|
+
await ctx.db.patch(doc._id, args.update);
|
|
328
|
+
});
|
|
329
|
+
return docs.length;
|
|
354
330
|
},
|
|
355
331
|
});
|
|
356
|
-
export const
|
|
332
|
+
export const updateTwoFactor = mutation({
|
|
357
333
|
args: {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
field: v.literal("token"),
|
|
361
|
-
values: v.array(v.string()),
|
|
362
|
-
})),
|
|
334
|
+
userId: v.string(),
|
|
335
|
+
update: v.object(partial(schema.tables.twoFactor.validator.fields)),
|
|
363
336
|
},
|
|
364
337
|
handler: async (ctx, args) => {
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
await ctx.db.delete(doc._id);
|
|
375
|
-
return doc;
|
|
338
|
+
const docs = await ctx.db
|
|
339
|
+
.query("twoFactor")
|
|
340
|
+
.withIndex("userId", (q) => q.eq("userId", args.userId))
|
|
341
|
+
.collect();
|
|
342
|
+
if (docs.length === 0) {
|
|
343
|
+
return 0;
|
|
344
|
+
}
|
|
345
|
+
await asyncMap(docs, async (doc) => {
|
|
346
|
+
await ctx.db.patch(doc._id, args.update);
|
|
376
347
|
});
|
|
377
|
-
return docs.
|
|
348
|
+
return docs.length;
|
|
378
349
|
},
|
|
379
350
|
});
|
|
380
351
|
//# sourceMappingURL=lib.js.map
|