Add mongo support

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-06-25 21:13:53 +02:00
parent 82316bbf3a
commit 6776a3ce46
2 changed files with 50 additions and 12 deletions

View File

@ -304,12 +304,6 @@ describe('Role', () => {
}, },
]; ];
const defaultPermissions = [ const defaultPermissions = [
{
action: 'plugins::upload.settings.read',
conditions: [],
fields: null,
subject: null,
},
{ {
action: 'plugins::upload.assets.create', action: 'plugins::upload.assets.create',
conditions: [], conditions: [],

View File

@ -62,6 +62,20 @@ const buildSearchOr = (model, query) => {
return searchOr; return searchOr;
}; };
const BOOLEAN_OPERATORS = ['or'];
const hasDeepFilters = (whereClauses = []) => {
return (
whereClauses.filter(({ field, operator, value }) => {
if (BOOLEAN_OPERATORS.includes(operator)) {
return value.filter(hasDeepFilters).length > 0;
}
return field.split('.').length > 1;
}).length > 0
);
};
/** /**
* Build a mongo query * Build a mongo query
* @param {Object} options - Query options * @param {Object} options - Query options
@ -77,10 +91,9 @@ const buildQuery = ({
populate = [], populate = [],
aggregate = false, aggregate = false,
} = {}) => { } = {}) => {
const deepFilters = (filters.where || []).filter(({ field }) => field.split('.').length > 1);
const search = buildSearchOr(model, searchParam); const search = buildSearchOr(model, searchParam);
if (deepFilters.length === 0 && aggregate === false) { if (!hasDeepFilters(filters.where) && aggregate === false) {
return buildSimpleQuery({ model, filters, search, populate }); return buildSimpleQuery({ model, filters, search, populate });
} }
@ -246,9 +259,7 @@ const computePopulatedPaths = ({ model, populate = [], where = [] }) => {
}) })
.reduce((acc, paths) => acc.concat(paths), []); .reduce((acc, paths) => acc.concat(paths), []);
const castedWherePaths = where const castedWherePaths = recursiveCastedWherePaths(where, { model });
.map(({ field }) => findModelPath({ rootModel: model, path: field }))
.filter(path => !!path);
return { return {
populatePaths: pathsToTree(castedPopulatePaths), populatePaths: pathsToTree(castedPopulatePaths),
@ -256,6 +267,18 @@ const computePopulatedPaths = ({ model, populate = [], where = [] }) => {
}; };
}; };
const recursiveCastedWherePaths = (whereClauses, { model }) => {
const paths = whereClauses.map(({ field, operator, value }) => {
if (BOOLEAN_OPERATORS.includes(operator)) {
return value.map(where => recursiveCastedWherePaths(where, { model }));
}
return findModelPath({ rootModel: model, path: field });
});
return _.flattenDeep(paths).filter(path => !!path);
};
/** /**
* Builds an object based on paths: * Builds an object based on paths:
* [ * [
@ -436,7 +459,7 @@ const formatValue = value => utils.valueToId(value);
* @param {*} options.value - Where clause alue * @param {*} options.value - Where clause alue
*/ */
const buildWhereClause = ({ field, operator, value }) => { const buildWhereClause = ({ field, operator, value }) => {
if (Array.isArray(value) && !['in', 'nin'].includes(operator)) { if (Array.isArray(value) && !['or', 'in', 'nin'].includes(operator)) {
return { return {
$or: value.map(val => buildWhereClause({ field, operator, value: val })), $or: value.map(val => buildWhereClause({ field, operator, value: val })),
}; };
@ -445,6 +468,19 @@ const buildWhereClause = ({ field, operator, value }) => {
const val = formatValue(value); const val = formatValue(value);
switch (operator) { switch (operator) {
case 'or': {
return {
$or: value.map(orClause => {
if (Array.isArray(orClause)) {
return {
$and: orClause.map(buildWhereClause),
};
} else {
return buildWhereClause(orClause);
}
}),
};
}
case 'eq': case 'eq':
return { [field]: val }; return { [field]: val };
case 'ne': case 'ne':
@ -513,6 +549,14 @@ const buildWhereClause = ({ field, operator, value }) => {
* @param {*} whereClause.value - Where clause alue * @param {*} whereClause.value - Where clause alue
*/ */
const formatWhereClause = (model, { field, operator, value }) => { const formatWhereClause = (model, { field, operator, value }) => {
if (BOOLEAN_OPERATORS.includes(operator)) {
return {
field,
operator,
value: value.map(v => v.map(whereClause => formatWhereClause(model, whereClause))),
};
}
const { assoc, model: assocModel } = getAssociationFromFieldKey(model, field); const { assoc, model: assocModel } = getAssociationFromFieldKey(model, field);
const shouldFieldBeSuffixed = const shouldFieldBeSuffixed =