74 lines
2.1 KiB
JavaScript
Raw Normal View History

2019-03-13 19:27:18 +01:00
const _ = require('lodash');
const findModelByAssoc = assoc => {
const { models } = assoc.plugin ? strapi.plugins[assoc.plugin] : strapi;
return models[assoc.collection || assoc.model];
};
const isAttribute = (model, field) => _.has(model.attributes, field) || model.primaryKey === field;
2019-03-13 19:27:18 +01:00
const createFilterValidator = model => ({ field }) => {
const fieldParts = field.split('.');
let isValid = true;
let tmpModel = model;
for (let i = 0; i < fieldParts.length; i++) {
const field = fieldParts[i];
const assoc = tmpModel.associations.find(ast => ast.alias === field);
if (assoc) {
tmpModel = findModelByAssoc(assoc);
continue;
}
if (!assoc && (!isAttribute(tmpModel, field) || i !== fieldParts.length - 1)) {
isValid = false;
break;
2019-03-13 19:27:18 +01:00
}
}
2019-03-13 19:27:18 +01:00
return isValid;
2019-03-13 19:27:18 +01:00
};
/**
*
* @param {Object} options - Options
* @param {Object} options.model - The model for which the query will be built
* @param {Object} options.filters - The filters for the query (start, sort, limit, and where clauses)
* @param {Object} options.rest - In case the database layer requires any other params pass them
*/
2019-03-13 19:27:18 +01:00
const buildQuery = ({ model, filters, ...rest }) => {
const validator = createFilterValidator(model);
// Validate query clauses
2019-03-13 19:27:18 +01:00
if (filters.where && Array.isArray(filters.where)) {
const deepFilters = filters.where.filter(({ field }) => field.split('.').length > 1);
if (deepFilters.length > 0) {
strapi.log.warn(
'Deep filtering queries should be used carefully (e.g Can cause performance issues).\nWhen possible build custom routes which will in most case be more optimised.'
);
}
2019-03-13 19:27:18 +01:00
filters.where.forEach(whereClause => {
if (!validator(whereClause)) {
const err = new Error(
`Your filters contain a field '${
2019-03-13 19:27:18 +01:00
whereClause.field
}' that doesn't appear on your model definition nor it's relations`
2019-03-13 19:27:18 +01:00
);
err.status = 400;
throw err;
2019-03-13 19:27:18 +01:00
}
});
}
const orm = strapi.hook[model.orm];
2019-03-13 19:27:18 +01:00
// call the orm's buildQuery implementation
return orm.load().buildQuery({ model, filters, ...rest });
2019-03-13 19:27:18 +01:00
};
module.exports = buildQuery;