"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inOperator = exports.likeOperator = exports.betweenOperator = exports.eqOperator = exports.isArrayWithType = exports.isFilter = exports.convertToFilter = exports.filterConverter = void 0;
var FilterTypes;
(function (FilterTypes) {
    FilterTypes[FilterTypes["eq"] = 0] = "eq";
    FilterTypes[FilterTypes["between"] = 1] = "between";
    FilterTypes[FilterTypes["like"] = 2] = "like";
    FilterTypes[FilterTypes["in"] = 3] = "in";
})(FilterTypes || (FilterTypes = {}));
const isFilterType = (filter) => {
    return typeof filter === 'object'
        && filter.hasOwnProperty('operation')
        && filter.hasOwnProperty('field')
        && (filter.hasOwnProperty('value') || (filter.hasOwnProperty('from') && filter.hasOwnProperty('to')));
};
const isArrayWithType = (value, checkType) => {
    if (value instanceof Array && value.length > 0) {
        return value.every((item) => typeof item === checkType);
    }
    return false;
};
exports.isArrayWithType = isArrayWithType;
const isFilter = (filter) => {
    if (!isFilterType(filter)) {
        return false;
    }
    if ((filter.operation === 'between' && (filter.from === undefined || filter.to === undefined))) {
        return false;
    }
    if (filter.operation === 'in'
        && !isArrayWithType(filter.value, 'number')
        && !isArrayWithType(filter.value, 'string')) {
        return false;
    }
    if (filter.operation === 'like' && typeof filter.value !== 'string') {
        return false;
    }
    if (filter.operation === 'eq'
        && typeof filter.value !== 'string'
        && typeof filter.value !== 'number'
        && typeof filter.value !== 'boolean') {
        return false;
    }
    return filter.operation != undefined
        && filter.operation in FilterTypes;
};
exports.isFilter = isFilter;
const eqOperator = (field, value) => {
    return {
        [field]: value
    };
};
exports.eqOperator = eqOperator;
const betweenOperator = (field, from, to) => {
    return {
        [field]: { $gte: from, $lte: to }
    };
};
exports.betweenOperator = betweenOperator;
const likeOperator = (field, value) => {
    const rgx = (pattern) => new RegExp(`.*${pattern}.*`);
    return {
        [field]: { $regex: rgx(value), $options: "i" }
    };
};
exports.likeOperator = likeOperator;
const inOperator = (field, value) => {
    return {
        [field]: { $in: value }
    };
};
exports.inOperator = inOperator;
const filterConverter = (filter) => {
    const convertedFilters = filter.map(convertToFilter).filter((val) => val);
    if (convertedFilters === null || convertedFilters === void 0 ? void 0 : convertedFilters.length) {
        return {
            $and: convertedFilters
        };
    }
    return null;
};
exports.filterConverter = filterConverter;
const convertToFilter = (data) => {
    if (!isFilter(data)) {
        return null;
    }
    switch (data.operation) {
        case 'eq':
            return eqOperator(data.field, data.value);
        case 'between':
            return betweenOperator(data.field, data.from, data.to);
        case 'like':
            return likeOperator(data.field, data.value);
        case 'in':
            return inOperator(data.field, data.value);
        default:
            break;
    }
};
exports.convertToFilter = convertToFilter;
//# sourceMappingURL=filters.js.map