Liferay.Loader.define("segments-web@2.0.29/js/utils/odata.es", ['module', 'exports', 'require', 'segments-web$odata-v4-parser', './constants.es', './utils.es'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.buildQueryString = buildQueryString;
    exports.translateQueryToCriteria = translateQueryToCriteria;

    var _odataV4Parser = require("segments-web$odata-v4-parser");

    var _constants = require("./constants.es");

    var _utils = require("./utils.es");

    var _oDataV4ParserNameMap;

    function _toConsumableArray(arr) {
      return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
    }

    function _nonIterableSpread() {
      throw new TypeError("Invalid attempt to spread non-iterable instance");
    }

    function _iterableToArray(iter) {
      if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
    }

    function _arrayWithoutHoles(arr) {
      if (Array.isArray(arr)) {
        for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
          arr2[i] = arr[i];
        }return arr2;
      }
    }

    function ownKeys(object, enumerableOnly) {
      var keys = Object.keys(object);if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });keys.push.apply(keys, symbols);
      }return keys;
    }

    function _objectSpread(target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {
          ownKeys(Object(source), true).forEach(function (key) {
            _defineProperty(target, key, source[key]);
          });
        } else if (Object.getOwnPropertyDescriptors) {
          Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
        } else {
          ownKeys(Object(source)).forEach(function (key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
          });
        }
      }return target;
    }

    function _defineProperty(obj, key, value) {
      if (key in obj) {
        Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
      } else {
        obj[key] = value;
      }return obj;
    }

    var EXPRESSION_TYPES = {
      AND: 'AndExpression',
      BOOL_PAREN: 'BoolParenExpression',
      COMMON: 'CommonExpression',
      EQUALS: 'EqualsExpression',
      FIRST_MEMBER: 'FirstMemberExpression',
      GREATER_OR_EQUALS: 'GreaterOrEqualsExpression',
      GREATER_THAN: 'GreaterThanExpression',
      LESSER_OR_EQUALS: 'LesserOrEqualsExpression',
      LESSER_THAN: 'LesserThanExpression',
      MEMBER: 'MemberExpression',
      METHOD_CALL: 'MethodCallExpression',
      NOT: 'NotExpression',
      OR: 'OrExpression',
      PAREN: 'ParenExpression',
      PROPERTY_PATH: 'PropertyPathExpression'
    };

    var OPERATORS = _objectSpread(_objectSpread({}, _constants.FUNCTIONAL_OPERATORS), _constants.RELATIONAL_OPERATORS);
    /**
     * Maps Odata-v4-parser generated AST expression names to internally used
     * constants.
     */

    var oDataV4ParserNameMap = (_oDataV4ParserNameMap = {}, _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.AND, _constants.CONJUNCTIONS.AND), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.BOOL_PAREN, _constants.GROUP), _defineProperty(_oDataV4ParserNameMap, "contains", OPERATORS.CONTAINS), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.EQUALS, OPERATORS.EQ), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.GREATER_OR_EQUALS, OPERATORS.GE), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.GREATER_THAN, OPERATORS.GT), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.LESSER_OR_EQUALS, OPERATORS.LE), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.LESSER_THAN, OPERATORS.LT), _defineProperty(_oDataV4ParserNameMap, EXPRESSION_TYPES.OR, _constants.CONJUNCTIONS.OR), _oDataV4ParserNameMap);
    /**
     * Wraps a node in a grouping node.
     * @param {object} oDataASTNode
     * @param {string} prevConjunction
     * @returns Object representing the grouping
     */

    function addNewGroup(_ref) {
      var oDataASTNode = _ref.oDataASTNode,
          prevConjunction = _ref.prevConjunction;
      return {
        lastNodeWasGroup: false,
        oDataASTNode: {
          type: EXPRESSION_TYPES.BOOL_PAREN,
          value: oDataASTNode
        },
        prevConjunction: prevConjunction
      };
    }
    /**
     * Gets the type of the property from the property name.
     * @param {string} propertyName The property name to find.
     * @param {array} properties The list of defined properties to search in.
     * @returns {string} The property type.
     */

    var getTypeByPropertyName = function getTypeByPropertyName(propertyName, properties) {
      var type = null;

      if (propertyName && properties) {
        var property = properties.find(function (property) {
          return property.name === propertyName;
        });
        type = property ? property.type : null;
      }

      return type;
    };
    /**
     * Decides whether to add quotes to value.
     * @param {boolean | string} value
     * @param {boolean | date | number | string} type
     * @returns {string}
     */

    function valueParser(value, type) {
      var parsedValue;

      switch (type) {
        case _constants.PROPERTY_TYPES.BOOLEAN:
        case _constants.PROPERTY_TYPES.DATE:
        case _constants.PROPERTY_TYPES.DATE_TIME:
        case _constants.PROPERTY_TYPES.INTEGER:
        case _constants.PROPERTY_TYPES.DOUBLE:
          parsedValue = value;
          break;

        case _constants.PROPERTY_TYPES.COLLECTION:
        case _constants.PROPERTY_TYPES.STRING:
        default:
          parsedValue = "'".concat(value, "'");
          break;
      }

      return parsedValue;
    }
    /**
     * Recursively traverses the criteria object to build an oData filter query
     * string. Properties is required to parse the correctly with or without quotes
     * and formatting the query differently for certain types like collection.
     * @param {object} criteria The criteria object.
     * @param {string} queryConjunction The conjunction name value to be used in the
     * query.
     * @param {array} properties The list of property objects. See
     * ContributorBuilder for valid property object shape.
     * @returns An OData query string built from the criteria object.
     */

    function buildQueryString(criteria, queryConjunction, properties) {
      return criteria.filter(Boolean).reduce(function (queryString, criterion, index) {
        var conjunctionName = criterion.conjunctionName,
            items = criterion.items,
            operatorName = criterion.operatorName,
            propertyName = criterion.propertyName,
            value = criterion.value;

        if (index > 0) {
          queryString = queryString.concat(" ".concat(queryConjunction, " "));
        }

        if (conjunctionName) {
          queryString = queryString.concat("(".concat(buildQueryString(items, conjunctionName, properties), ")"));
        } else {
          var type = criterion.type || getTypeByPropertyName(propertyName, properties);
          var parsedValue = valueParser(value, type);

          if (isValueType(_constants.RELATIONAL_OPERATORS, operatorName)) {
            if (type === _constants.PROPERTY_TYPES.COLLECTION) {
              queryString = queryString.concat("".concat(propertyName, "/any(c:c ").concat(operatorName, " ").concat(parsedValue, ")"));
            } else {
              queryString = queryString.concat("".concat(propertyName, " ").concat(operatorName, " ").concat(parsedValue));
            }
          } else if (isValueType(_constants.FUNCTIONAL_OPERATORS, operatorName)) {
            if (type === _constants.PROPERTY_TYPES.COLLECTION) {
              queryString = queryString.concat("".concat(propertyName, "/any(c:").concat(operatorName, "(c, ").concat(parsedValue, "))"));
            } else {
              queryString = queryString.concat("".concat(operatorName, "(").concat(propertyName, ", ").concat(parsedValue, ")"));
            }
          } else if (isValueType(_constants.NOT_OPERATORS, operatorName)) {
            var baseOperator = operatorName.replace(/not-/g, '');
            // Not is wrapped in a group to simplify AST parsing.

            queryString = queryString.concat("(not (".concat(buildQueryString([{
              operatorName: baseOperator,
              propertyName: propertyName,
              type: type,
              value: value
            }], conjunctionName, properties), "))"));
          }
        }

        return queryString;
      }, '');
    }
    /**
     * Prepares odata query by encoding special characters in string values.
     * @param {string} queryString The odata query.
     * @returns {string} The encoded odata query.
     */

    function encodeQueryString(queryString) {
      return queryString.split(' ').reduce(function (query, queryPartial) {
        var formattedPartial = queryPartial.startsWith("'") ? encodeURIComponent(queryPartial) : queryPartial;
        return "".concat(query, " ").concat(formattedPartial);
      });
    }
    /**
     * Removes both single `'` and double `"` quotes from a string as well as decode
     * special characters.
     * @param {string} criterionValue The string to remove quotes and decode.
     * @returns {string} The decoded string without quotes.
     */

    function formatCriterionValue(criterionValue) {
      return decodeURIComponent(criterionValue).replace(/['"]+/g, '');
    }
    /**
     * Gets the internal name of a child expression from the oDataV4Parser name.
     * @param {object} oDataASTNode
     * @returns String value of the internal name.
     */

    function getChildExpressionName(oDataASTNode) {
      return getExpressionName(oDataASTNode.value);
    }
    /**
     * Gets the conjunction of the group or returns AND as a default.
     * @param {object} oDataASTNode
     * @returns The conjunction name for a group or, if not available, AND.
     */

    function getConjunctionForGroup(oDataASTNode) {
      var childExpressionName = getChildExpressionName(oDataASTNode);
      return isValueType(_constants.CONJUNCTIONS, childExpressionName) ? childExpressionName : _constants.CONJUNCTIONS.AND;
    }
    /**
     * Gets the internal name of an expression from the oDataV4Parser name.
     * @param {object} oDataASTNode
     * @returns String value of the internal name
     */

    function getExpressionName(oDataASTNode) {
      var type = oDataASTNode.type;
      var returnValue = oDataV4ParserNameMap[type];

      if (type == EXPRESSION_TYPES.METHOD_CALL) {
        returnValue = oDataASTNode.value.method;
      }

      return returnValue;
    }

    function getFunctionName(oDataASTNode) {
      return oDataV4ParserNameMap[oDataASTNode.value.method];
    }
    /**
     * Returns the next expression in the syntax tree that is not a grouping.
     * @param {object} oDataASTNode
     * @returns String value of the internal name of the next expression.
     */

    var getNextNonGroupExpression = function getNextNonGroupExpression(oDataASTNode) {
      var returnValue;

      if (oDataASTNode.value.type === EXPRESSION_TYPES.BOOL_PAREN) {
        returnValue = getNextNonGroupExpression(oDataASTNode.value);
      } else {
        returnValue = oDataASTNode.value.left ? oDataASTNode.value.left : oDataASTNode.value;
      }

      return returnValue;
    };
    /**
     * Returns the next expression in the syntax tree that is not a grouping.
     * Also ignoring Common, Paren, Member, and FirstMember expressions for property
     * path expression types like `cookies/any(c:c eq 'key=value')` since the
     * expressions' value are the same for a collection query.
     * @param {object} oDataASTNode
     * @returns String value of the internal name of the next expression.
     */

    var getNextOperatorExpression = function getNextOperatorExpression(oDataASTNode) {
      var returnValue;
      var nextNode = oDataASTNode.value.left ? oDataASTNode.value.left : oDataASTNode.value;
      var type = nextNode.type;

      if (type === EXPRESSION_TYPES.BOOL_PAREN || type === EXPRESSION_TYPES.AND || type === EXPRESSION_TYPES.OR || type === EXPRESSION_TYPES.COMMON || type === EXPRESSION_TYPES.FIRST_MEMBER || type === EXPRESSION_TYPES.MEMBER || type === EXPRESSION_TYPES.PAREN) {
        returnValue = getNextOperatorExpression(nextNode);
      } else {
        returnValue = nextNode;
      }

      return returnValue;
    };
    /**
     * Checks if a grouping has different conjunctions (e.g. (x AND y OR z)).
     * @param {boolean} lastNodeWasGroup
     * @param {object} oDataASTNode
     * @param {string} prevConjunction
     * @returns boolean of whether a grouping has different conjunctions.
     */

    function hasDifferentConjunctions(_ref2) {
      var lastNodeWasGroup = _ref2.lastNodeWasGroup,
          oDataASTNode = _ref2.oDataASTNode,
          prevConjunction = _ref2.prevConjunction;
      return prevConjunction !== oDataASTNode.type && !lastNodeWasGroup;
    }
    /**
     * Checks if the criteria is a group by checking if it has an `items` property.
     * @param {object} criteria
     */

    function isCriteriaGroup(criteria) {
      return !!criteria.items;
    }
    /**
     * Checks if the value is a certain type.
     * @param {object} types A map of supported types.
     * @param {*} value The value to validate.
     * @returns {boolean}
     */

    function isValueType(types, value) {
      return Object.values(types).includes(value);
    }
    /**
     * Checks if the group is needed; It is unnecessary when there are multiple
     * groupings in a row, when the conjunction directly outside the group is the
     * same as the one inside or there is no conjunction within a grouping.
     * @param {boolean} lastNodeWasGroup
     * @param {object} oDataASTNode
     * @param {string} prevConjunction
     * @returns a boolean of whether a group is necessary.
     */

    function isRedundantGroup(_ref3) {
      var lastNodeWasGroup = _ref3.lastNodeWasGroup,
          oDataASTNode = _ref3.oDataASTNode,
          prevConjunction = _ref3.prevConjunction;
      var nextNodeExpressionName = getExpressionName(getNextNonGroupExpression(oDataASTNode));
      return lastNodeWasGroup || oDataV4ParserNameMap[prevConjunction] === nextNodeExpressionName || !isValueType(_constants.CONJUNCTIONS, nextNodeExpressionName);
    }
    /**
     * Removes a grouping node and returns the child node
     * @param {object} oDataASTNode
     * @param {string} prevConjunction
     * @returns Object representing the operation inside the grouping
     */

    function skipGroup(_ref4) {
      var oDataASTNode = _ref4.oDataASTNode,
          prevConjunction = _ref4.prevConjunction;
      return {
        lastNodeWasGroup: true,
        oDataASTNode: oDataASTNode.value,
        prevConjunction: prevConjunction
      };
    }
    /**
     * Converts an OData filter query string to an object that can be used by the
     * criteria builder
     * @param {string} queryString
     * @returns {object} Criteria representation of the query string
     */

    function translateQueryToCriteria(queryString) {
      var criteria;

      try {
        if (queryString === '()') {
          throw 'queryString is ()';
        }

        var oDataASTNode = (0, _odataV4Parser.filter)(encodeQueryString(queryString));
        var criteriaArray = toCriteria({
          oDataASTNode: oDataASTNode
        });
        criteria = isCriteriaGroup(criteriaArray[0]) ? criteriaArray[0] : wrapInCriteriaGroup(criteriaArray);
      } catch (e) {
        criteria = null;
      }

      return criteria;
    }
    /**
     * Recursively transforms the AST generated by the odata-v4-parser library into
     * a shape the criteria builder expects. Returns an array so that left and right
     * arguments can be concatenated together.
     * @param {object} context
     * @param {object} context.oDataASTNode
     * @returns Criterion representation of an AST expression node in an array
     */

    function toCriteria(context) {
      var oDataASTNode = context.oDataASTNode;
      var expressionName = getExpressionName(oDataASTNode);
      var criterion;

      if (oDataASTNode.type === EXPRESSION_TYPES.NOT) {
        criterion = transformNotNode(context);
      } else if (oDataASTNode.type === EXPRESSION_TYPES.COMMON) {
        criterion = transformCommonNode(context);
      } else if (oDataASTNode.type === EXPRESSION_TYPES.METHOD_CALL) {
        criterion = transformFunctionalNode(context);
      } else if (isValueType(_constants.RELATIONAL_OPERATORS, expressionName)) {
        criterion = transformOperatorNode(context);
      } else if (isValueType(_constants.CONJUNCTIONS, expressionName)) {
        criterion = transformConjunctionNode(context);
      } else if (expressionName === _constants.GROUP) {
        criterion = transformGroupNode(context);
      }

      return criterion;
    }
    /**
     * Transform an operator expression node into a criterion for the criteria
     * builder.
     * @param {object} oDataASTNode
     * @returns An array containing the object representation of a collection
     * criterion.
     */

    function transformCommonNode(_ref5) {
      var oDataASTNode = _ref5.oDataASTNode;
      var nextNodeExpression = getNextOperatorExpression(oDataASTNode);
      var anyExpression = nextNodeExpression.value.next.value;
      var methodExpression = anyExpression.value.predicate.value;
      var methodExpressionName = getExpressionName(methodExpression);
      var value;

      if (methodExpressionName == OPERATORS.CONTAINS) {
        value = formatCriterionValue(methodExpression.value.parameters[1].raw);
      } else if (methodExpressionName == OPERATORS.EQ) {
        value = formatCriterionValue(methodExpression.value.right.raw);
      }

      return [{
        operatorName: methodExpressionName,
        propertyName: nextNodeExpression.value.current.raw,
        value: value
      }];
    }
    /**
     * Transforms conjunction expression node into a criterion for the criteria
     * builder. If it comes across a grouping sharing an AND and OR conjunction, it
     * will add a new grouping so the criteria builder doesn't require a user to
     * know operator precedence.
     * @param {object} context
     * @param {object} context.oDataASTNode
     * @returns an array containing the concatenated left and right values of a
     * conjunction expression or a new grouping.
     */

    function transformConjunctionNode(context) {
      var oDataASTNode = context.oDataASTNode;
      var conjunctionType = oDataASTNode.type;
      var nextNode = oDataASTNode.value;
      return hasDifferentConjunctions(context) ? toCriteria(addNewGroup(context)) : [].concat(_toConsumableArray(toCriteria({
        oDataASTNode: nextNode.left,
        prevConjunction: conjunctionType
      })), _toConsumableArray(toCriteria({
        oDataASTNode: nextNode.right,
        prevConjunction: conjunctionType
      })));
    }
    /**
     * Transform a function expression node into a criterion for the criteria
     * builder.
     * @param {object} oDataASTNode
     * @returns an array containing the object representation of an operator
     * criterion
     */

    function transformFunctionalNode(_ref6) {
      var oDataASTNode = _ref6.oDataASTNode;
      return [{
        operatorName: getFunctionName(oDataASTNode),
        propertyName: oDataASTNode.value.parameters[0].raw,
        value: formatCriterionValue(oDataASTNode.value.parameters[1].raw)
      }];
    }
    /**
     * Transforms a group expression node into a criterion for the criteria
     * builder. If it comes across a grouping that is redundant (doesn't provide
     * readability improvements, superfluous to order of operations), it will remove
     * it.
     * @param {object} context
     * @param {object} context.oDataASTNode
     * @param {string} context.prevConjunction
     * @returns Criterion representation of an AST expression node in an array
     */

    function transformGroupNode(context) {
      var oDataASTNode = context.oDataASTNode,
          prevConjunction = context.prevConjunction;
      return isRedundantGroup(context) ? toCriteria(skipGroup(context)) : [{
        conjunctionName: getConjunctionForGroup(oDataASTNode),
        groupId: (0, _utils.generateGroupId)(),
        items: toCriteria({
          lastNodeWasGroup: true,
          oDataASTNode: oDataASTNode.value,
          prevConjunction: prevConjunction
        })
      }];
    }
    /**
     * Transform an operator expression node into a criterion for the criteria
     * builder.
     * @param {object} oDataASTNode
     * @returns an array containing the object representation of an operator
     * criterion
     */

    function transformNotNode(_ref7) {
      var oDataASTNode = _ref7.oDataASTNode;
      var nextNodeExpression = getNextOperatorExpression(oDataASTNode);
      var nextNodeExpressionName = getExpressionName(nextNodeExpression);
      var returnValue;

      if (nextNodeExpressionName == OPERATORS.CONTAINS) {
        returnValue = [{
          operatorName: _constants.NOT_OPERATORS.NOT_CONTAINS,
          propertyName: nextNodeExpression.value.parameters[0].raw,
          value: formatCriterionValue(nextNodeExpression.value.parameters[1].raw)
        }];
      } else if (nextNodeExpressionName == OPERATORS.EQ) {
        returnValue = [{
          operatorName: _constants.NOT_OPERATORS.NOT_EQ,
          propertyName: nextNodeExpression.value.left.raw,
          value: formatCriterionValue(nextNodeExpression.value.right.raw)
        }];
      } else if (nextNodeExpression.type == EXPRESSION_TYPES.PROPERTY_PATH) {
        var anyExpression = nextNodeExpression.value.next.value;
        var methodExpression = anyExpression.value.predicate.value;
        var methodExpressionName = getExpressionName(methodExpression);

        if (methodExpressionName == OPERATORS.CONTAINS) {
          returnValue = [{
            operatorName: _constants.NOT_OPERATORS.NOT_CONTAINS,
            propertyName: nextNodeExpression.value.current.raw,
            value: formatCriterionValue(methodExpression.value.parameters[1].raw)
          }];
        } else if (methodExpressionName == OPERATORS.EQ) {
          returnValue = [{
            operatorName: _constants.NOT_OPERATORS.NOT_EQ,
            propertyName: nextNodeExpression.value.current.raw,
            value: formatCriterionValue(methodExpression.value.right.raw)
          }];
        }
      }

      return returnValue;
    }
    /**
     * Transform an operator expression node into a criterion for the criteria
     * builder.
     * @param {object} oDataASTNode
     * @returns an array containing the object representation of an operator
     * criterion
     */

    function transformOperatorNode(_ref8) {
      var oDataASTNode = _ref8.oDataASTNode;
      return [{
        operatorName: getExpressionName(oDataASTNode),
        propertyName: oDataASTNode.value.left.raw,
        value: formatCriterionValue(oDataASTNode.value.right.raw)
      }];
    }
    /**
     * Wraps the criteria items in a criteria group.
     * @param {array} criteriaArray The list of criterion.
     */

    function wrapInCriteriaGroup(criteriaArray) {
      return {
        conjunctionName: _constants.CONJUNCTIONS.AND,
        groupId: (0, _utils.generateGroupId)(),
        items: criteriaArray
      };
    }
    //# sourceMappingURL=odata.es.js.map
  }
});
//# sourceMappingURL=odata.es.js.map