@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
118 lines (108 loc) • 4.84 kB
text/typescript
import { findIndex } from '../../utils/lang';
import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/matcherTypes';
import { segmentTransform } from './segment';
import { whitelistTransform } from './whitelist';
import { numericTransform } from './unaryNumeric';
import { zeroSinceHH, zeroSinceSS, betweenDateTimeTransform } from '../convertions';
import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData, IDefinitionMatcher, IUnaryNumericMatcherData } from '../../dtos/types';
import { IMatcherDto } from '../types';
/**
* Flat the complex matcherGroup structure into something handy.
*/
export function matchersTransform(matchers: IDefinitionMatcher[]): IMatcherDto[] {
let parsedMatchers = matchers.map(matcher => {
let {
matcherType,
negate,
keySelector,
userDefinedSegmentMatcherData,
userDefinedLargeSegmentMatcherData,
whitelistMatcherData, /* whitelistObject, provided by 'WHITELIST', 'IN_LIST_SEMVER', set and string matchers */
unaryNumericMatcherData,
betweenMatcherData,
dependencyMatcherData,
booleanMatcherData,
stringMatcherData,
betweenStringMatcherData
} = matcher;
let attribute = keySelector && keySelector.attribute;
let type = matcherTypesMapper(matcherType);
// As default input data type we use string (even for ALL_KEYS)
let dataType = matcherDataTypes.STRING;
let value;
if (type === matcherTypes.IN_SEGMENT) {
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
} else if (type === matcherTypes.IN_LARGE_SEGMENT) {
value = segmentTransform(userDefinedLargeSegmentMatcherData as IInLargeSegmentMatcherData);
} else if (type === matcherTypes.EQUAL_TO) {
value = numericTransform(unaryNumericMatcherData as IUnaryNumericMatcherData);
dataType = matcherDataTypes.NUMBER;
if ((unaryNumericMatcherData as IUnaryNumericMatcherData).dataType === 'DATETIME') {
value = zeroSinceHH(value);
dataType = matcherDataTypes.DATETIME;
}
} else if (type === matcherTypes.GREATER_THAN_OR_EQUAL_TO ||
type === matcherTypes.LESS_THAN_OR_EQUAL_TO) {
value = numericTransform(unaryNumericMatcherData as IUnaryNumericMatcherData);
dataType = matcherDataTypes.NUMBER;
if ((unaryNumericMatcherData as IUnaryNumericMatcherData).dataType === 'DATETIME') {
value = zeroSinceSS(value);
dataType = matcherDataTypes.DATETIME;
}
} else if (type === matcherTypes.BETWEEN) {
value = betweenMatcherData as IBetweenMatcherData;
dataType = matcherDataTypes.NUMBER;
if (value.dataType === 'DATETIME') {
value = betweenDateTimeTransform(value);
dataType = matcherDataTypes.DATETIME;
}
} else if (type === matcherTypes.BETWEEN_SEMVER) {
value = betweenStringMatcherData;
} else if (
type === matcherTypes.EQUAL_TO_SET ||
type === matcherTypes.CONTAINS_ANY_OF_SET ||
type === matcherTypes.CONTAINS_ALL_OF_SET ||
type === matcherTypes.PART_OF_SET
) {
value = whitelistTransform(whitelistMatcherData);
dataType = matcherDataTypes.SET;
} else if (
type === matcherTypes.WHITELIST ||
type === matcherTypes.IN_LIST_SEMVER ||
type === matcherTypes.STARTS_WITH ||
type === matcherTypes.ENDS_WITH ||
type === matcherTypes.CONTAINS_STRING
) {
value = whitelistTransform(whitelistMatcherData);
} else if (type === matcherTypes.IN_SPLIT_TREATMENT) {
value = dependencyMatcherData;
dataType = matcherDataTypes.NOT_SPECIFIED;
} else if (type === matcherTypes.EQUAL_TO_BOOLEAN) {
dataType = matcherDataTypes.BOOLEAN;
value = booleanMatcherData;
} else if (
type === matcherTypes.MATCHES_STRING ||
type === matcherTypes.EQUAL_TO_SEMVER ||
type === matcherTypes.GREATER_THAN_OR_EQUAL_TO_SEMVER ||
type === matcherTypes.LESS_THAN_OR_EQUAL_TO_SEMVER
) {
value = stringMatcherData;
} else if (type === matcherTypes.IN_RULE_BASED_SEGMENT) {
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
dataType = matcherDataTypes.NOT_SPECIFIED;
}
return {
attribute, // attribute over we should do the matching, undefined means 'use the key'
negate, // should we negate the result?
type, // which kind of matcher we should evaluate
name: matcherType,// name of the matcher for logging purposes
value, // metadata used for the matching
dataType // runtime input data type
};
});
if (findIndex(parsedMatchers, m => m.type === matcherTypes.UNDEFINED) === -1) {
return parsedMatchers;
} else {
return [];
}
}