67 lines
2.0 KiB
JavaScript
67 lines
2.0 KiB
JavaScript
import * as sift from 'sift';
|
|
import qs from 'qs';
|
|
import { AbilityBuilder, Ability } from '@casl/ability';
|
|
import { pick, isNil, isObject } from 'lodash/fp';
|
|
|
|
const allowedOperations = [
|
|
'$or',
|
|
'$and',
|
|
'$eq',
|
|
'$ne',
|
|
'$in',
|
|
'$nin',
|
|
'$lt',
|
|
'$lte',
|
|
'$gt',
|
|
'$gte',
|
|
'$exists',
|
|
'$elemMatch'
|
|
];
|
|
const operations = pick(allowedOperations, sift);
|
|
const conditionsMatcher = (conditions)=>{
|
|
return sift.createQueryTester(conditions, {
|
|
operations
|
|
});
|
|
};
|
|
const buildParametrizedAction = ({ name, params })=>{
|
|
return `${name}?${qs.stringify(params)}`;
|
|
};
|
|
/**
|
|
* Casl Ability Builder.
|
|
*/ const caslAbilityBuilder = ()=>{
|
|
const { can, build, ...rest } = new AbilityBuilder(Ability);
|
|
return {
|
|
can (permission) {
|
|
const { action, subject, properties = {}, condition } = permission;
|
|
const { fields } = properties;
|
|
const caslAction = typeof action === 'string' ? action : buildParametrizedAction(action);
|
|
return can(caslAction, isNil(subject) ? 'all' : subject, fields, isObject(condition) ? condition : undefined);
|
|
},
|
|
buildParametrizedAction ({ name, params }) {
|
|
return `${name}?${qs.stringify(params)}`;
|
|
},
|
|
build () {
|
|
const ability = build({
|
|
conditionsMatcher
|
|
});
|
|
function decorateCan(originalCan) {
|
|
return function(...args) {
|
|
const [action, ...rest] = args;
|
|
const caslAction = typeof action === 'string' ? action : buildParametrizedAction(action);
|
|
// Call the original `can` method
|
|
return originalCan.apply(ability, [
|
|
caslAction,
|
|
...rest
|
|
]);
|
|
};
|
|
}
|
|
ability.can = decorateCan(ability.can);
|
|
return ability;
|
|
},
|
|
...rest
|
|
};
|
|
};
|
|
|
|
export { caslAbilityBuilder };
|
|
//# sourceMappingURL=casl-ability.mjs.map
|