@maximai/maxim-js
Version:
Maxim AI JS SDK. Visit https://getmaxim.ai for more info.
135 lines • 5.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseIncomingQuery = parseIncomingQuery;
exports.findBestMatch = findBestMatch;
exports.findAllMatches = findAllMatches;
function parseIncomingQuery(incomingQuery) {
if (incomingQuery.trim().length === 0) {
return [];
}
const operators = ["!=", ">=", "<=", ">", "<", "includes", "does not include", "="];
return incomingQuery.split(",").map((condition) => {
for (let op of operators) {
if (condition.includes(op)) {
let [field, value] = condition.split(op).map((s) => s.trim());
const operator = op;
let exactMatch = false;
if (field.startsWith("!!")) {
exactMatch = true;
field = field.slice(2);
}
if (!isNaN(Number(value))) {
return { field, value: Number(value), operator, exactMatch };
}
return { field: field, value, operator, exactMatch };
}
}
throw new Error(`Unsupported operator found in condition "${condition}"`);
});
}
function evaluateRuleGroup(ruleGroup, incomingQueryRules) {
const matchedRules = [];
const matchResults = ruleGroup.rules.map((rule) => {
if ("combinator" in rule) {
return evaluateRuleGroup(rule, incomingQueryRules);
}
else {
return incomingQueryRules.some((incomingRule) => {
const conditionMet = (fieldRule, fieldIncomingRule) => {
if (typeof fieldRule.value !== typeof fieldIncomingRule.value) {
if (typeof fieldRule.value === "number") {
fieldIncomingRule.value = Number(fieldIncomingRule.value);
}
else if (typeof fieldRule.value === "boolean") {
fieldIncomingRule.value = Boolean(fieldIncomingRule.value);
}
else if (typeof fieldRule.value === "string") {
fieldIncomingRule.value = String(fieldIncomingRule.value);
}
}
switch (fieldRule.operator) {
case "=":
return fieldRule.value === fieldIncomingRule.value;
case "!=":
return fieldRule.value !== fieldIncomingRule.value;
case ">":
return fieldRule.value > fieldIncomingRule.value;
case "<":
return fieldRule.value < fieldIncomingRule.value;
case ">=":
return fieldRule.value >= fieldIncomingRule.value;
case "<=":
return fieldRule.value <= fieldIncomingRule.value;
case "includes":
return fieldRule.value.includes(fieldIncomingRule.value);
case "does not include":
return !fieldRule.value.includes(fieldIncomingRule.value);
}
return false;
};
const result = rule.field === incomingRule.field && conditionMet(rule, incomingRule);
if (result) {
matchedRules.push(incomingRule);
}
return result;
});
}
});
const exactMatches = incomingQueryRules.every((rule) => {
if (!rule.exactMatch) {
return true;
}
if (matchedRules.includes(rule)) {
return true;
}
return false;
});
if (!exactMatches) {
return false;
}
if (ruleGroup.combinator === "AND") {
return matchResults.every(Boolean);
}
else {
return matchResults.some(Boolean);
}
}
function findBestMatch(objects, incomingQuery) {
let bestMatch = null;
let maxMatchCount = 0;
const incomingQueryRules = parseIncomingQuery(incomingQuery.query);
for (const object of objects) {
const isMatch = evaluateRuleGroup(object.query, incomingQueryRules);
if (isMatch) {
if (incomingQuery.exactMatch) {
if (incomingQueryRules.length !== object.query.rules.length) {
continue;
}
}
const matchCount = object.query.rules.length;
if (matchCount > maxMatchCount) {
maxMatchCount = matchCount;
bestMatch = object;
}
}
}
return bestMatch;
}
function findAllMatches(objects, incomingQuery) {
let bestMatch = null;
const matches = [];
const incomingQueryRules = parseIncomingQuery(incomingQuery.query);
for (const object of objects) {
const isMatch = evaluateRuleGroup(object.query, incomingQueryRules);
if (isMatch) {
if (incomingQuery.exactMatch) {
if (incomingQueryRules.length !== object.query.rules.length) {
continue;
}
}
matches.push(object);
}
}
return matches;
}
//# sourceMappingURL=filterObjects.js.map