UNPKG

@forzalabs/remora

Version:

A powerful CLI tool for seamless data translation.

101 lines (100 loc) 4.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Affirm_1 = __importDefault(require("../../core/Affirm")); class RequestExecutorClass { constructor() { /** * Applies the filters, limit, offset and order on the in-memory-data */ this.execute = (data, request) => { (0, Affirm_1.default)(data, 'Invalid data'); (0, Affirm_1.default)(request, 'Invalid request'); (0, Affirm_1.default)(Array.isArray(data), `Invalid data type: should be an array`); if (request.filters) data = this._applyFilters(data, request.filters); if (request.order) data = this._applyOrdering(data, request.order); return data; }; this._applyFilters = (data, filters) => { return data.filter((item) => { return filters.every(filter => this._evaluateFilter(item, filter)); }); }; this._evaluateFilter = (item, filter) => { const evaluate = (baseItem, baseFilter) => { const { member, operator, values } = baseFilter; const value = baseItem[member]; const singleValue = values[0]; switch (operator) { case 'equals': return value === singleValue; case 'notEquals': return value !== singleValue; case 'contains': return typeof value === 'string' && value.includes(singleValue); case 'notContains': return typeof value === 'string' && !value.includes(singleValue); case 'startsWith': return typeof value === 'string' && value.startsWith(singleValue); case 'endsWith': return typeof value === 'string' && value.endsWith(singleValue); case 'greaterThan': return typeof value === 'number' && value > Number(singleValue); case 'greaterThanOrEquals': return typeof value === 'number' && value >= Number(singleValue); case 'lessThan': return typeof value === 'number' && value < Number(singleValue); case 'lessThanOrEquals': return typeof value === 'number' && value <= Number(singleValue); case 'in': return values.includes(value); case 'notIn': return !values.includes(value); case 'between': return values.length === 2 && value >= values[0] && value <= values[1]; case 'notBetween': return values.length === 2 && (value < values[0] || value > values[1]); case 'isNull': return value === null || value === undefined; case 'isNotNull': return value !== null && value !== undefined; case 'true': return value === true; case 'false': return value === false; case 'matches': return typeof value === 'string' && new RegExp(singleValue).test(value); case 'notMatches': return typeof value === 'string' && !new RegExp(singleValue).test(value); default: throw new Error(`Unsupported filter operator: ${operator}`); } }; const { and, or } = filter; const baseResult = evaluate(item, filter); if (and) return baseResult && and.every(subFilter => this._evaluateFilter(item, subFilter)); if (or) return baseResult || or.some(subFilter => this._evaluateFilter(item, subFilter)); else return baseResult; }; this._applyOrdering = (data, order) => { return data.sort((a, b) => { for (const [field, direction] of order) { if (a[field] < b[field]) return direction === 'asc' ? -1 : 1; if (a[field] > b[field]) return direction === 'asc' ? 1 : -1; } return 0; }); }; } } const RequestExecutor = new RequestExecutorClass(); exports.default = RequestExecutor;