2
0
Files
bot/packages/bot-engine/src/services/logic.ts

100 lines
3.1 KiB
TypeScript
Raw Normal View History

import {
LogicStep,
LogicStepType,
LogicalOperator,
ConditionStep,
Variable,
ComparisonOperators,
2022-01-20 07:21:08 +01:00
SetVariableStep,
RedirectStep,
Comparison,
} from 'models'
import { isDefined, isNotDefined } from 'utils'
2022-01-20 07:21:08 +01:00
import { sanitizeUrl } from './utils'
import { isMathFormula, evaluateExpression, parseVariables } from './variable'
2022-01-20 07:21:08 +01:00
type EdgeId = string
export const executeLogic = (
step: LogicStep,
variables: Variable[],
updateVariableValue: (variableId: string, expression: string) => void
2022-01-20 07:21:08 +01:00
): EdgeId | undefined => {
switch (step.type) {
2022-01-20 07:21:08 +01:00
case LogicStepType.SET_VARIABLE:
return executeSetVariable(step, variables, updateVariableValue)
case LogicStepType.CONDITION:
return executeCondition(step, variables)
case LogicStepType.REDIRECT:
return executeRedirect(step, variables)
}
}
2022-01-20 07:21:08 +01:00
const executeSetVariable = (
step: SetVariableStep,
variables: Variable[],
2022-01-20 07:21:08 +01:00
updateVariableValue: (variableId: string, expression: string) => void
): EdgeId | undefined => {
if (!step.options?.variableId || !step.options.expressionToEvaluate)
return step.outgoingEdgeId
2022-01-20 07:21:08 +01:00
const expression = step.options.expressionToEvaluate
const evaluatedExpression = isMathFormula(expression)
? evaluateExpression(parseVariables(variables)(expression))
2022-01-20 07:21:08 +01:00
: expression
updateVariableValue(step.options.variableId, evaluatedExpression)
return step.outgoingEdgeId
2022-01-20 07:21:08 +01:00
}
const executeCondition = (
step: ConditionStep,
variables: Variable[]
2022-01-20 07:21:08 +01:00
): EdgeId | undefined => {
const { content } = step.items[0]
2022-01-20 07:21:08 +01:00
const isConditionPassed =
content.logicalOperator === LogicalOperator.AND
? content.comparisons.every(executeComparison(variables))
: content.comparisons.some(executeComparison(variables))
return isConditionPassed ? step.items[0].outgoingEdgeId : step.outgoingEdgeId
2022-01-20 07:21:08 +01:00
}
const executeComparison =
(variables: Variable[]) => (comparison: Comparison) => {
if (!comparison?.variableId) return false
const inputValue =
variables.find((v) => v.id === comparison.variableId)?.value ?? ''
const value = parseVariables(variables)(comparison.value)
if (isNotDefined(value)) return false
switch (comparison.comparisonOperator) {
case ComparisonOperators.CONTAINS: {
return inputValue.toString().includes(value.toString())
}
case ComparisonOperators.EQUAL: {
return inputValue.toString() === value.toString()
}
case ComparisonOperators.NOT_EQUAL: {
return inputValue.toString() !== value.toString()
}
case ComparisonOperators.GREATER: {
return parseFloat(inputValue) >= parseFloat(value)
}
case ComparisonOperators.LESS: {
return parseFloat(inputValue) <= parseFloat(value)
}
case ComparisonOperators.IS_SET: {
return isDefined(inputValue) && inputValue.length > 0
}
}
}
2022-01-20 07:21:08 +01:00
const executeRedirect = (
step: RedirectStep,
variables: Variable[]
2022-01-20 07:21:08 +01:00
): EdgeId | undefined => {
if (!step.options?.url) return step.outgoingEdgeId
2022-01-20 07:21:08 +01:00
window.open(
sanitizeUrl(parseVariables(variables)(step.options?.url)),
2022-01-20 07:21:08 +01:00
step.options.isNewTab ? '_blank' : '_self'
)
return step.outgoingEdgeId
2022-01-20 07:21:08 +01:00
}