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
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 };
}
returnType is typed with only the base table fields, this doenst include the fields that get included from relations. Any clues or pointers ??
2 Replies
Amur
Amur17mo ago
@therealsujje did you manage to solve this?
Suji
SujiOP17mo ago
Nope
Want results from more Discord servers?
Add your server