map-transform
Version:
Map and transform objects with mapping definitions
86 lines • 3.27 kB
JavaScript
import mapAny from 'map-any';
import { pathGetter } from '../operations/getSet.js';
import { defToDataMapper } from '../utils/definitionHelpers.js';
import { goForward } from '../utils/stateHelpers.js';
import xor from '../utils/xor.js';
import { unescapeValue } from '../utils/escape.js';
import { isDate } from '../utils/is.js';
const not = (comparer) => (value, match) => !comparer(value, match);
const compareArrayOrValue = (comparer) => (value, match) => Array.isArray(value)
? value.some((value) => comparer(value, match))
: comparer(value, match);
const isNumeric = (value) => typeof value === 'number';
function prepareValue(value) {
if (isDate(value)) {
return value.getTime();
}
else {
return value;
}
}
const compareArrayOrValueNumeric = (comparer) => compareArrayOrValue((value, match) => isNumeric(value) && isNumeric(match) && comparer(value, match));
const compareEqual = compareArrayOrValue((value, match) => value === match);
const compareIn = (value, match) => Array.isArray(match)
? match.some((item) => compareEqual(value, item))
: compareEqual(value, match);
const exists = (value) => value !== undefined;
function getGtLtComparer(operator) {
switch (operator) {
case '>':
return (value, match) => value > match;
case '>=':
return (value, match) => value >= match;
case '<':
return (value, match) => value < match;
case '<=':
return (value, match) => value <= match;
}
}
function createComparer(operator) {
switch (operator) {
case '=':
return compareEqual;
case '!=':
return not(compareEqual);
case 'in':
return compareIn;
case 'exists':
return exists;
case '>':
case '>=':
case '<':
case '<=':
return compareArrayOrValueNumeric(getGtLtComparer(operator));
default:
return (_value, _match) => false;
}
}
const transformer = function compare({ path = '.', operator = '=', match, value, matchPath, valuePath, not = false, }) {
match = match === undefined ? value : match;
matchPath = matchPath ?? valuePath;
return (options) => {
const realMatchValue = mapAny(unescapeValue, match);
const comparer = createComparer(operator);
const getMatch = typeof matchPath === 'string'
? pathGetter(matchPath)
: () => realMatchValue;
if (typeof path === 'string' || !path) {
const getValue = pathGetter(path);
return (data, state) => {
const value = prepareValue(getValue(data, state));
const match = prepareValue(getMatch(data, state));
return xor(comparer(value, match), not);
};
}
else {
const getValue = defToDataMapper(path, options);
return async (data, state) => {
const value = prepareValue(await getValue(data, goForward(state)));
const match = prepareValue(getMatch(data, state));
return xor(comparer(value, match), not);
};
}
};
};
export default transformer;
//# sourceMappingURL=compare.js.map