2019-03-13 19:27:18 +01:00
|
|
|
const _ = require('lodash');
|
|
|
|
|
2019-03-22 12:16:09 +01:00
|
|
|
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('.');
|
2019-03-22 12:16:09 +01:00
|
|
|
|
|
|
|
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-22 12:16:09 +01:00
|
|
|
}
|
2019-03-13 19:27:18 +01:00
|
|
|
|
2019-03-22 12:16:09 +01:00
|
|
|
return isValid;
|
2019-03-13 19:27:18 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const buildQuery = ({ model, filters, ...rest }) => {
|
|
|
|
const validator = createFilterValidator(model);
|
|
|
|
|
|
|
|
if (filters.where && Array.isArray(filters.where)) {
|
|
|
|
filters.where.forEach(whereClause => {
|
|
|
|
if (!validator(whereClause)) {
|
2019-03-22 12:16:09 +01:00
|
|
|
const err = new Error(
|
|
|
|
`Your filters contain a field '${
|
2019-03-13 19:27:18 +01:00
|
|
|
whereClause.field
|
2019-03-22 12:16:09 +01:00
|
|
|
}' that doesn't appear on your model definition nor it's relations`
|
2019-03-13 19:27:18 +01:00
|
|
|
);
|
2019-03-22 12:16:09 +01:00
|
|
|
|
|
|
|
err.status = 400;
|
|
|
|
throw err;
|
2019-03-13 19:27:18 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const hook = strapi.hook[model.orm];
|
|
|
|
|
|
|
|
return hook.load().buildQuery({ model, filters, ...rest });
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = buildQuery;
|