Infer return type for relational query with pagination
I have created a function that can paginate data for relational queries, problem is i cant figure out how to make to include the relations that are passed into the inferred return type
returnType is typed with only the base table fields, this doenst include the fields that get included from relations. Any clues or pointers ??
async paginatedQuery<
ReturnType extends drizzleOrm.InferModel<Table>,
Table extends AnyPgTable,
>(
table: Table,
{
limit,
page,
where,
takeAll,
with: queryWith,
}: {
limit: number;
page: number;
where?: drizzleOrm.SQL;
takeAll?: boolean;
// eslint-disable-next-line @typescript-eslint/ban-types
with?: object;
},
) {
const tableNameSymbol = Object.getOwnPropertySymbols(table).find(
(value) => value.description === 'Name',
);
const tableName = table[tableNameSymbol!].toString().toLowerCase();
const count = await (where?.queryChunks.length === 0
? this.db
.select({ count: sql<number>`count(*)`.mapWith(Number) })
.from(table)
: this.db
.select({ count: sql<number>`count(*)`.mapWith(Number) })
.from(table)
.where(where));
const offset = (page - 1) * limit;
const data: ReturnType[] = await this.db.query[tableName].findMany({
...(queryWith && { with: queryWith }),
...(where?.queryChunks.length !== 0 && { where }),
...(!takeAll && { limit, offset: offset <= 0 ? 0 : offset }),
});
const meta: IPageMeta = {
currentPage: page,
isLastPage: page * limit >= count[0].count,
isFirstPage: page === 1,
nextPage: page * limit >= count[0].count ? null : page + 1,
previousPage: page - 1 === 0 ? null : page - 1,
pageCount: Math.ceil(count[0].count / limit),
};
return { data, meta };
}
async paginatedQuery<
ReturnType extends drizzleOrm.InferModel<Table>,
Table extends AnyPgTable,
>(
table: Table,
{
limit,
page,
where,
takeAll,
with: queryWith,
}: {
limit: number;
page: number;
where?: drizzleOrm.SQL;
takeAll?: boolean;
// eslint-disable-next-line @typescript-eslint/ban-types
with?: object;
},
) {
const tableNameSymbol = Object.getOwnPropertySymbols(table).find(
(value) => value.description === 'Name',
);
const tableName = table[tableNameSymbol!].toString().toLowerCase();
const count = await (where?.queryChunks.length === 0
? this.db
.select({ count: sql<number>`count(*)`.mapWith(Number) })
.from(table)
: this.db
.select({ count: sql<number>`count(*)`.mapWith(Number) })
.from(table)
.where(where));
const offset = (page - 1) * limit;
const data: ReturnType[] = await this.db.query[tableName].findMany({
...(queryWith && { with: queryWith }),
...(where?.queryChunks.length !== 0 && { where }),
...(!takeAll && { limit, offset: offset <= 0 ? 0 : offset }),
});
const meta: IPageMeta = {
currentPage: page,
isLastPage: page * limit >= count[0].count,
isFirstPage: page === 1,
nextPage: page * limit >= count[0].count ? null : page + 1,
previousPage: page - 1 === 0 ? null : page - 1,
pageCount: Math.ceil(count[0].count / limit),
};
return { data, meta };
}
2 Replies