lib/transform/canonical.js
function evalFilter(filters, results, pos = {value: 0}) {
  const key = Object.keys(filters)[0];

  if (['and', 'or', 'not'].indexOf(key) === -1 || filters._isLeaf) {
    pos.value++;
    return results[pos.value - 1];
  }

  if (key === 'not') {
    return !evalFilter(filters[key], results, pos);
  }

  return filters[key].reduce((p, c) => {
    const r = evalFilter(c, results, pos);

    if (p === null) {
      return r;
    }

    return key === 'and' ? p && r : p || r;
  }, null);
}
function evalFilter(filters, results, pos = {value: 0}) {
  const key = Object.keys(filters)[0];

  if (['and', 'or', 'not'].indexOf(key) === -1 || filters._isLeaf) {
    pos.value++;
    return results[pos.value - 1];
  }

  if (key === 'not') {
    return !evalFilter(filters[key], results, pos);
  }

  return filters[key].reduce((p, c) => {
    const r = evalFilter(c, results, pos);

    if (p === null) {
      return r;
    }

    return key === 'and' ? p && r : p || r;
  }, null);
}
function evalFilter ( filters , results , pos = { value : 0 } ) { const key = Object . keys ( filters ) [ 0 ] ; if ( [ 'and' , 'or' , 'not' ] . indexOf ( key ) === - 1 || filters . _isLeaf ) { pos . value ++ ; return results [ pos . value - 1 ] ; } if ( key === 'not' ) { return ! evalFilter ( filters [ key ] , results , pos ) ; } return filters [ key ] . reduce ( ( p , c ) => { const r = evalFilter ( c , results , pos ) ; if ( p === null ) { return r ; } return key === 'and' ? p && r : p || r ; } , null ) ; }
Given a boolean array containing the conditions results, returns
a boolean indicating the whole filter result

@param {object} filters
@param {Array} results - condition results, contains booleans
@param {object} [pos] - current condition position
@returns {boolean}
Given a boolean array containing the conditions results returns a boolean indicating the whole filter result