Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions src/client/adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,9 @@ const NORMAL_DISABLED_TESTS = [
// convex-id-generation:
// Convex controls generated IDs at write time.
"create - should use generateId if provided",
// offset-unsupported:
// Convex adapter rejects offset pagination.
// joins-unsupported:
// Better Auth experimental joins are not supported by the Convex adapter.
"findMany - should be able to perform a complex limited join",
"findMany - should find many models with limit and offset",
"findMany - should find many models with offset",
"findMany - should find many models with sortBy and limit and offset",
"findMany - should find many models with sortBy and limit and offset and where",
"findMany - should find many models with sortBy and offset",
"findMany - should find many with both one-to-one and one-to-many joins",
"findMany - should find many with join and offset",
"findMany - should find many with join, where, limit, and offset",
Expand Down
20 changes: 11 additions & 9 deletions src/client/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,11 @@ export const convexAdapter = <
});
},
findMany: async (data): Promise<any[]> => {
if (data.offset) {
throw new Error("offset not supported");
}
// The component paginates by cursor and has no offset support;
// fetch offset + limit docs and drop the first `offset` here.
const offset = data.offset ?? 0;
const fetchLimit =
data.limit !== undefined ? data.limit + offset : undefined;

if (data.where?.some((w) => w.connector === "OR")) {
// Always fetch full docs for OR unions so we can dedupe
Expand All @@ -321,12 +323,13 @@ export const convexAdapter = <
async ({ paginationOpts }) => {
return await ctx.runQuery(api.adapter.findMany, {
...queryData,
offset: undefined,
model: data.model as TableNames,
where: parseWhere(w),
paginationOpts,
});
},
{ limit: data.limit }
{ limit: fetchLimit }
)
);
let docs = dedupeDocsById(results.flatMap((r) => r.docs));
Expand All @@ -336,24 +339,23 @@ export const convexAdapter = <
data.sortBy.direction,
]);
}
if (data.limit !== undefined) {
docs = docs.slice(0, data.limit);
}
docs = docs.slice(offset, fetchLimit);
return docs.map((doc) => selectDocFields(doc, data.select));
}

const result = await handlePagination(
async ({ paginationOpts }) => {
return await ctx.runQuery(api.adapter.findMany, {
...data,
offset: undefined,
model: data.model as TableNames,
where: parseWhere(data.where),
paginationOpts,
});
},
{ limit: data.limit }
{ limit: fetchLimit }
);
return result.docs;
return offset ? result.docs.slice(offset) : result.docs;
},
count: async (data) => {
// Yes, count is just findMany returning a number.
Expand Down
26 changes: 26 additions & 0 deletions src/test/adapter-factory/convex-custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,32 @@ export const convexCustomTestSuite = createTestSuite(
).toEqual(user);
},

"should apply offset to OR unions": async () => {
const users = [];
for (const letter of ["a", "b", "c", "d"]) {
users.push(
await adapter.create({
model: "user",
data: {
name: "offset-user",
email: `${letter}@offset-or.test`,
},
}),
);
}
const page = await adapter.findMany({
model: "user",
where: [
{ field: "name", value: "offset-user", connector: "OR" },
{ field: "email", value: "none@offset-or.test", connector: "OR" },
],
sortBy: { field: "email", direction: "asc" },
limit: 2,
offset: 1,
});
expect(page).toEqual([users[1], users[2]]);
},

"should update and count each match only once for overlapping OR clauses":
async () => {
const foo = await adapter.create({
Expand Down
3 changes: 3 additions & 0 deletions src/test/adapter-factory/profile-additional-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const ADDITIONAL_FIELDS_NORMAL_TESTS = [
"deleteMany - should delete many models with numeric values",
"findMany - should find many models with sortBy",
"findMany - should find many models with sortBy and limit",
"findMany - should find many models with sortBy and limit and offset",
"findMany - should find many models with sortBy and limit and offset and where",
"findMany - should find many models with sortBy and offset",
"findMany - should find many with join and sortBy",
"findOne - should find a model with additional fields",
] as const;
Expand Down