Files
bigcapital/packages/server/src/models/Pagination.ts
2024-08-18 19:38:15 +02:00

69 lines
2.0 KiB
TypeScript

import { Model } from 'objection';
import { castArray, omit, pick } from 'lodash';
import { isEmpty } from 'lodash';
import { ServiceError } from '@/exceptions';
export default class PaginationQueryBuilder extends Model.QueryBuilder {
pagination(page, pageSize) {
return super.page(page, pageSize).runAfter(({ results, total }) => {
return {
results,
pagination: {
total,
page: page + 1,
pageSize,
},
};
});
}
queryAndThrowIfHasRelations = ({
type,
message,
excludeRelations = [],
includedRelations = [],
}) => {
const _excludeRelations = castArray(excludeRelations);
const _includedRelations = castArray(includedRelations);
const model = this.modelClass();
const modelRelations = Object.keys(model.relationMappings).filter(
(relation) =>
[Model.HasManyRelation, Model.HasOneRelation].indexOf(
model.relationMappings[relation]?.relation
) !== -1
);
const relations = model.secureDeleteRelations || modelRelations;
const filteredByIncluded = relations.filter((r) =>
_includedRelations.includes(r)
);
const filteredByExcluded = relations.filter(
(r) => !excludeRelations.includes(r)
);
const filteredRelations = !isEmpty(_includedRelations)
? filteredByIncluded
: !isEmpty(_excludeRelations)
? filteredByExcluded
: relations;
this.runAfter((model, query) => {
const nonEmptyRelations = filteredRelations.filter(
(relation) => !isEmpty(model[relation])
);
if (nonEmptyRelations.length > 0) {
throw new ServiceError(type || 'MODEL_HAS_RELATIONS', { message });
}
return model;
});
return this.onBuild((query) => {
filteredRelations.forEach((relation) => {
query.withGraphFetched(`${relation}(selectId)`).modifiers({
selectId(builder) {
builder.select('id');
},
});
});
});
};
}