import { JSONPath } from 'jsonpath-plus' ; import { applyOperation , Operation , deepClone } from 'fast-json-patch' ; import { GROUPS_CONFIGURATION } from '../constants' ; type UserGroupsObject = { [ key ] : boolean ; } ; type FilterableObject = { aclExpression : string ; } ; const userGroupsObjectBuilder = ( userGroups ) => { const userGroupsObject = { } ; for ( const userGroup of userGroups ) { userGroupsObject [ userGroup ] = true ; } return userGroupsObject ; } ; const buildPluginFunction = ( plugin ) => { return new Function ( GROUPS_CONFIGURATION . function . key , `return !!(${ plugin . aclExpression })` ) ; } ; const evaluatePluginExpression = ( userGroupsObject ) => { return ( plugin ) => { const expressionEvaluationFunction = buildPluginFunction ( plugin ) ; return expressionEvaluationFunction ( userGroupsObject ) ; } ; } ; const jsonPathCallback = ( valuesToAvoid , expressionEvaluator ) => ( payload , payloadType , fullPayload ) => { if ( ! expressionEvaluator ( fullPayload . value ) ) { valuesToAvoid . push ( payload ) ; } } ; const patchCreator = ( valueToAvoid ) : Operation => ( { op : 'remove' , path : valueToAvoid , } ) ; export const aclExpressionEvaluator = ( jsonToFilter , userGroups ) => { const clonedJsonToFilter = deepClone ( jsonToFilter ) ; const userGroupsObject = userGroupsObjectBuilder ( userGroups ) ; const expressionEvaluator = evaluatePluginExpression ( userGroupsObject ) ; const valuesToAvoid = [ ] ; const pathCallback = jsonPathCallback ( valuesToAvoid , expressionEvaluator ) ; do { valuesToAvoid . splice ( 0 ) ; JSONPath ( { path : '$..aclExpression^' , json : clonedJsonToFilter , resultType : 'pointer' , callback : pathCallback } ) ; const [ patchToApply ] = valuesToAvoid ; patchToApply && applyOperation ( clonedJsonToFilter , patchCreator ( patchToApply ) ) ; } while ( valuesToAvoid . length !== 0 ) ; return clonedJsonToFilter ; } ;