prisma-criteria
Version:
Parses, validates, and creates a criteria object that can be passed to the Prisma "findMany" method to query a list of resources matching the given filters, pagination and order.
58 lines • 3.33 kB
JavaScript
import { isValidationOk } from './shared/validation.util.js';
import { validateOrder } from './order-validation.js';
import { processUserInputFilters } from './filters/index.js';
import { stringToNumber } from './shared/string-to-number.util.js';
import { PRISMA_LOGIC_OPERATORS } from './filters/validation/consts.js';
export function createPrismaCriteria(userInputCriteria, criteriaOptions) {
const { filters: defaultFilters, orderBy: defaultOrderBy, pagination: defaultPagination } = criteriaOptions.defaults ?? {};
if (defaultPagination && defaultPagination.pageSize < 1)
throw new Error('The minimium page size is "1".');
if (defaultPagination && defaultPagination.pageNumber < 1)
throw new Error('The minimium page number is "1".');
if (criteriaOptions.rules.allowedFieldsToOrderBy.length > 1)
throw new Error('You can only order by one field (for now).');
const onlyStringUserInputs = Object.fromEntries(Object.entries(userInputCriteria)
.filter(entry => typeof entry[1] === 'string'));
const processedUserInputFilters = processUserInputFilters(onlyStringUserInputs.filters, criteriaOptions.rules.allowedFilters);
const mixedFiltersProvidedByUserAndDefaultFilters = (Object.values(PRISMA_LOGIC_OPERATORS)).reduce((acc, logicOperator) => {
const isPresentInDefaultFilters = Object.hasOwn(defaultFilters ?? {}, logicOperator);
const isPresentInProcessedFilters = Object.hasOwn(processedUserInputFilters, logicOperator);
if (!isPresentInDefaultFilters && !isPresentInProcessedFilters)
return acc;
return {
...acc,
[logicOperator]: [
...(isPresentInDefaultFilters ? defaultFilters[logicOperator] : []),
...(isPresentInProcessedFilters ? processedUserInputFilters[logicOperator] : [])
]
};
}, {});
// TODO --- improve this
const thereAreFilters = Object
.values(mixedFiltersProvidedByUserAndDefaultFilters)
.some((logicOperatorFilters) => logicOperatorFilters.length > 0);
let orderBy = defaultOrderBy;
const validationOfUsersInputOrderBy = validateOrder(onlyStringUserInputs.orderBy, onlyStringUserInputs.orderDir, criteriaOptions.rules.allowedFieldsToOrderBy);
if (isValidationOk(validationOfUsersInputOrderBy))
orderBy = validationOfUsersInputOrderBy.ok.orderBy;
let skip = defaultPagination ? defaultPagination.pageNumber - 1 : undefined;
const validationOfUsersInputPageNumber = stringToNumber(onlyStringUserInputs.pageNumber);
if (isValidationOk(validationOfUsersInputPageNumber) &&
validationOfUsersInputPageNumber.ok > 0)
skip = validationOfUsersInputPageNumber.ok - 1;
let take = defaultPagination?.pageSize;
const validationOfUsersInputPageSize = stringToNumber(onlyStringUserInputs.pageSize);
if (isValidationOk(validationOfUsersInputPageSize) &&
validationOfUsersInputPageSize.ok > 0) {
take = Math.min(validationOfUsersInputPageSize.ok, criteriaOptions.rules.pageSizeMax);
}
return {
where: !thereAreFilters && userInputCriteria.filters?.length
? { OR: [] }
: mixedFiltersProvidedByUserAndDefaultFilters,
orderBy,
skip,
take
};
}
//# sourceMappingURL=index.js.map