@botonic/plugin-flow-builder 0.50.2 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-evaluators.d.ts +15 -0
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-evaluators.js +71 -0
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-evaluators.js.map +1 -0
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-resolver.d.ts +9 -0
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-resolver.js +58 -0
- package/lib/cjs/content-fields/custom-conditional/custom-conditional-v2-resolver.js.map +1 -0
- package/lib/cjs/content-fields/custom-conditional/flow-custom-condition-v2.d.ts +17 -0
- package/lib/cjs/content-fields/custom-conditional/flow-custom-condition-v2.js +79 -0
- package/lib/cjs/content-fields/custom-conditional/flow-custom-condition-v2.js.map +1 -0
- package/lib/cjs/content-fields/flow-custom-conditional.js +1 -0
- package/lib/cjs/content-fields/flow-custom-conditional.js.map +1 -1
- package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.d.ts +56 -0
- package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.js +36 -0
- package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/index.d.ts +1 -0
- package/lib/cjs/content-fields/hubtype-fields/index.js +1 -0
- package/lib/cjs/content-fields/hubtype-fields/index.js.map +1 -1
- package/lib/cjs/content-fields/hubtype-fields/node-types.d.ts +2 -1
- package/lib/cjs/content-fields/hubtype-fields/node-types.js +1 -0
- package/lib/cjs/content-fields/hubtype-fields/node-types.js.map +1 -1
- package/lib/cjs/content-fields/hubtype-fields/nodes.d.ts +2 -1
- package/lib/cjs/content-fields/index.d.ts +3 -2
- package/lib/cjs/content-fields/index.js +3 -1
- package/lib/cjs/content-fields/index.js.map +1 -1
- package/lib/cjs/flow-factory.js +2 -0
- package/lib/cjs/flow-factory.js.map +1 -1
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-evaluators.d.ts +15 -0
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-evaluators.js +71 -0
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-evaluators.js.map +1 -0
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-resolver.d.ts +9 -0
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-resolver.js +58 -0
- package/lib/esm/content-fields/custom-conditional/custom-conditional-v2-resolver.js.map +1 -0
- package/lib/esm/content-fields/custom-conditional/flow-custom-condition-v2.d.ts +17 -0
- package/lib/esm/content-fields/custom-conditional/flow-custom-condition-v2.js +79 -0
- package/lib/esm/content-fields/custom-conditional/flow-custom-condition-v2.js.map +1 -0
- package/lib/esm/content-fields/flow-custom-conditional.js +1 -0
- package/lib/esm/content-fields/flow-custom-conditional.js.map +1 -1
- package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.d.ts +56 -0
- package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.js +36 -0
- package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/index.d.ts +1 -0
- package/lib/esm/content-fields/hubtype-fields/index.js +1 -0
- package/lib/esm/content-fields/hubtype-fields/index.js.map +1 -1
- package/lib/esm/content-fields/hubtype-fields/node-types.d.ts +2 -1
- package/lib/esm/content-fields/hubtype-fields/node-types.js +1 -0
- package/lib/esm/content-fields/hubtype-fields/node-types.js.map +1 -1
- package/lib/esm/content-fields/hubtype-fields/nodes.d.ts +2 -1
- package/lib/esm/content-fields/index.d.ts +3 -2
- package/lib/esm/content-fields/index.js +3 -1
- package/lib/esm/content-fields/index.js.map +1 -1
- package/lib/esm/flow-factory.js +2 -0
- package/lib/esm/flow-factory.js.map +1 -1
- package/package.json +2 -2
- package/src/content-fields/custom-conditional/custom-conditional-v2-evaluators.ts +124 -0
- package/src/content-fields/custom-conditional/custom-conditional-v2-resolver.ts +92 -0
- package/src/content-fields/custom-conditional/flow-custom-condition-v2.tsx +136 -0
- package/src/content-fields/flow-custom-conditional.tsx +1 -0
- package/src/content-fields/hubtype-fields/custom-conditional-v2.ts +68 -0
- package/src/content-fields/hubtype-fields/index.ts +1 -0
- package/src/content-fields/hubtype-fields/node-types.ts +1 -0
- package/src/content-fields/hubtype-fields/nodes.ts +2 -0
- package/src/content-fields/index.ts +3 -0
- package/src/flow-factory.ts +7 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BooleanConditionOperator,
|
|
3
|
+
type HtBooleanCondition,
|
|
4
|
+
type HtNumberCondition,
|
|
5
|
+
type HtStringCondition,
|
|
6
|
+
NumberConditionOperator,
|
|
7
|
+
StringConditionOperator,
|
|
8
|
+
} from '../hubtype-fields'
|
|
9
|
+
|
|
10
|
+
type StringEvaluator = (variable: string, value: string) => boolean
|
|
11
|
+
|
|
12
|
+
type NumberEvaluator = (
|
|
13
|
+
variable: number,
|
|
14
|
+
value: number,
|
|
15
|
+
condition: HtNumberCondition
|
|
16
|
+
) => boolean
|
|
17
|
+
|
|
18
|
+
type BooleanEvaluator = (variable: boolean) => boolean
|
|
19
|
+
|
|
20
|
+
export function getMinAndMax(condition: HtNumberCondition): {
|
|
21
|
+
min: number
|
|
22
|
+
max: number
|
|
23
|
+
} {
|
|
24
|
+
if (condition.min !== undefined && condition.max !== undefined) {
|
|
25
|
+
return { min: condition.min, max: condition.max }
|
|
26
|
+
}
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Min or max not found for number condition ${condition.operator}`
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const STRING_CONDITION_EVALUATORS: Record<
|
|
33
|
+
StringConditionOperator,
|
|
34
|
+
StringEvaluator
|
|
35
|
+
> = {
|
|
36
|
+
[StringConditionOperator.Contains]: (variable, value) =>
|
|
37
|
+
variable.includes(value),
|
|
38
|
+
[StringConditionOperator.NotContains]: (variable, value) =>
|
|
39
|
+
!variable.includes(value),
|
|
40
|
+
[StringConditionOperator.EqualsTo]: (variable, value) => variable === value,
|
|
41
|
+
[StringConditionOperator.NotEqualsTo]: (variable, value) =>
|
|
42
|
+
variable !== value,
|
|
43
|
+
[StringConditionOperator.StartsWith]: (variable, value) =>
|
|
44
|
+
variable.startsWith(value),
|
|
45
|
+
[StringConditionOperator.NotStartsWith]: (variable, value) =>
|
|
46
|
+
!variable.startsWith(value),
|
|
47
|
+
[StringConditionOperator.EndsWith]: (variable, value) =>
|
|
48
|
+
variable.endsWith(value),
|
|
49
|
+
[StringConditionOperator.NotEndsWith]: (variable, value) =>
|
|
50
|
+
!variable.endsWith(value),
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const NUMBER_CONDITION_EVALUATORS: Record<
|
|
54
|
+
NumberConditionOperator,
|
|
55
|
+
NumberEvaluator
|
|
56
|
+
> = {
|
|
57
|
+
[NumberConditionOperator.EqualsTo]: (variable, value) => variable === value,
|
|
58
|
+
[NumberConditionOperator.NotEqualsTo]: (variable, value) =>
|
|
59
|
+
variable !== value,
|
|
60
|
+
[NumberConditionOperator.GreaterThan]: (variable, value) => variable > value,
|
|
61
|
+
[NumberConditionOperator.LessThan]: (variable, value) => variable < value,
|
|
62
|
+
[NumberConditionOperator.GreaterThanOrEqualTo]: (variable, value) =>
|
|
63
|
+
variable >= value,
|
|
64
|
+
[NumberConditionOperator.LessThanOrEqualTo]: (variable, value) =>
|
|
65
|
+
variable <= value,
|
|
66
|
+
[NumberConditionOperator.Between]: (variable, _value, condition) => {
|
|
67
|
+
const { min, max } = getMinAndMax(condition)
|
|
68
|
+
return variable >= min && variable <= max
|
|
69
|
+
},
|
|
70
|
+
[NumberConditionOperator.NotBetween]: (variable, _value, condition) => {
|
|
71
|
+
const { min, max } = getMinAndMax(condition)
|
|
72
|
+
return variable < min || variable > max
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const BOOLEAN_CONDITION_EVALUATORS: Record<
|
|
77
|
+
BooleanConditionOperator,
|
|
78
|
+
BooleanEvaluator
|
|
79
|
+
> = {
|
|
80
|
+
[BooleanConditionOperator.IsTruthy]: variable => !!variable,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function evaluateStringCondition(
|
|
84
|
+
variable: string,
|
|
85
|
+
condition: HtStringCondition
|
|
86
|
+
): boolean {
|
|
87
|
+
if (condition.value === undefined) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Value not found for string condition ${condition.operator}`
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
const evaluator = STRING_CONDITION_EVALUATORS[condition.operator]
|
|
93
|
+
if (!evaluator) {
|
|
94
|
+
throw new Error(`Invalid string condition operator ${condition.operator}`)
|
|
95
|
+
}
|
|
96
|
+
return evaluator(variable, condition.value)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function evaluateNumberCondition(
|
|
100
|
+
variable: number,
|
|
101
|
+
condition: HtNumberCondition
|
|
102
|
+
): boolean {
|
|
103
|
+
if (condition.value === undefined) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Value not found for number condition ${condition.operator}`
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
const evaluator = NUMBER_CONDITION_EVALUATORS[condition.operator]
|
|
109
|
+
if (!evaluator) {
|
|
110
|
+
throw new Error(`Invalid number condition operator ${condition.operator}`)
|
|
111
|
+
}
|
|
112
|
+
return evaluator(variable, condition.value, condition)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function evaluateBooleanCondition(
|
|
116
|
+
variable: boolean,
|
|
117
|
+
condition: HtBooleanCondition
|
|
118
|
+
): boolean {
|
|
119
|
+
const evaluator = BOOLEAN_CONDITION_EVALUATORS[condition.operator]
|
|
120
|
+
if (!evaluator) {
|
|
121
|
+
throw new Error(`Invalid boolean condition operator ${condition.operator}`)
|
|
122
|
+
}
|
|
123
|
+
return evaluator(variable)
|
|
124
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type HtCondition,
|
|
3
|
+
type HtNodeLink,
|
|
4
|
+
type HtNumberCondition,
|
|
5
|
+
type HtStringCondition,
|
|
6
|
+
NumberConditionOperator,
|
|
7
|
+
VariableFormat,
|
|
8
|
+
} from '../hubtype-fields'
|
|
9
|
+
|
|
10
|
+
export type ConditionMatch = {
|
|
11
|
+
customResult: string
|
|
12
|
+
target: HtNodeLink
|
|
13
|
+
operator: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getConditionCustomResult(
|
|
17
|
+
condition: HtCondition,
|
|
18
|
+
variableFormat: VariableFormat
|
|
19
|
+
): string {
|
|
20
|
+
switch (variableFormat) {
|
|
21
|
+
case VariableFormat.String:
|
|
22
|
+
return String((condition as HtStringCondition).value)
|
|
23
|
+
case VariableFormat.Number:
|
|
24
|
+
return getNumberConditionCustomResult(condition as HtNumberCondition)
|
|
25
|
+
case VariableFormat.Boolean:
|
|
26
|
+
// Only reached after evaluateBooleanCondition succeeds; today that is isTruthy → 'true'
|
|
27
|
+
return 'true'
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Invalid variable format ${variableFormat}`)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getNumberConditionCustomResult(condition: HtNumberCondition): string {
|
|
34
|
+
const numberCondition = condition as HtNumberCondition
|
|
35
|
+
if (
|
|
36
|
+
numberCondition.operator === NumberConditionOperator.Between ||
|
|
37
|
+
numberCondition.operator === NumberConditionOperator.NotBetween
|
|
38
|
+
) {
|
|
39
|
+
return `min: ${numberCondition.min} - max: ${numberCondition.max}`
|
|
40
|
+
}
|
|
41
|
+
return String(numberCondition.value)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function findLastMatchingCondition<T extends HtCondition>(
|
|
45
|
+
conditions: T[],
|
|
46
|
+
variable: unknown,
|
|
47
|
+
variableFormat: VariableFormat,
|
|
48
|
+
evaluate: (variable: unknown, condition: T) => boolean
|
|
49
|
+
): ConditionMatch | undefined {
|
|
50
|
+
let lastMatch: ConditionMatch | undefined
|
|
51
|
+
|
|
52
|
+
for (const condition of conditions) {
|
|
53
|
+
if (!evaluate(variable, condition)) {
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!condition.target) {
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
lastMatch = {
|
|
62
|
+
customResult: getConditionCustomResult(condition, variableFormat),
|
|
63
|
+
target: condition.target,
|
|
64
|
+
operator: condition.operator,
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return lastMatch
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function resolveWithDefaultTarget(
|
|
72
|
+
match: ConditionMatch | undefined,
|
|
73
|
+
defaultTarget: HtNodeLink,
|
|
74
|
+
nodeCode: string,
|
|
75
|
+
defaultCustomResult: string = 'default'
|
|
76
|
+
): ConditionMatch {
|
|
77
|
+
if (match) {
|
|
78
|
+
return match
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!defaultTarget) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Default target not found for custom condition node ${nodeCode}`
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
customResult: defaultCustomResult,
|
|
89
|
+
target: defaultTarget,
|
|
90
|
+
operator: '',
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BotContext,
|
|
3
|
+
EventAction,
|
|
4
|
+
type EventConditionalCustom,
|
|
5
|
+
} from '@botonic/core'
|
|
6
|
+
import {
|
|
7
|
+
getCommonFlowContentEventArgsForContentId,
|
|
8
|
+
trackEvent,
|
|
9
|
+
} from '../../tracking'
|
|
10
|
+
import { ContentFieldsBase } from '../content-fields-base'
|
|
11
|
+
import {
|
|
12
|
+
type HtBooleanCondition,
|
|
13
|
+
type HtCondition,
|
|
14
|
+
type HtCustomConditionalV2Node,
|
|
15
|
+
type HtNodeLink,
|
|
16
|
+
type HtNumberCondition,
|
|
17
|
+
type HtStringCondition,
|
|
18
|
+
VariableFormat,
|
|
19
|
+
} from '../hubtype-fields'
|
|
20
|
+
import {
|
|
21
|
+
evaluateBooleanCondition,
|
|
22
|
+
evaluateNumberCondition,
|
|
23
|
+
evaluateStringCondition,
|
|
24
|
+
} from './custom-conditional-v2-evaluators'
|
|
25
|
+
import {
|
|
26
|
+
type ConditionMatch,
|
|
27
|
+
findLastMatchingCondition,
|
|
28
|
+
resolveWithDefaultTarget,
|
|
29
|
+
} from './custom-conditional-v2-resolver'
|
|
30
|
+
|
|
31
|
+
export class FlowCustomConditionalV2 extends ContentFieldsBase {
|
|
32
|
+
public variableFormat: VariableFormat
|
|
33
|
+
public keyPath: string
|
|
34
|
+
public conditions: HtCondition[]
|
|
35
|
+
public defaultTarget: HtNodeLink
|
|
36
|
+
public customResult = ''
|
|
37
|
+
public resolvedOperator = ''
|
|
38
|
+
|
|
39
|
+
static fromHubtypeCMS(
|
|
40
|
+
component: HtCustomConditionalV2Node,
|
|
41
|
+
botContext: BotContext
|
|
42
|
+
): FlowCustomConditionalV2 {
|
|
43
|
+
const newCustomConditionalV2 = new FlowCustomConditionalV2(component.id)
|
|
44
|
+
newCustomConditionalV2.code = component.code
|
|
45
|
+
newCustomConditionalV2.variableFormat = component.content.type
|
|
46
|
+
newCustomConditionalV2.keyPath = component.content.key_path
|
|
47
|
+
newCustomConditionalV2.conditions = component.content.conditions
|
|
48
|
+
newCustomConditionalV2.defaultTarget = component.content.default_target
|
|
49
|
+
newCustomConditionalV2.setFollowUp(botContext)
|
|
50
|
+
|
|
51
|
+
return newCustomConditionalV2
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private setFollowUp(botContext: BotContext): void {
|
|
55
|
+
const botVariable = this.getValueFromKeyPath(botContext, this.keyPath)
|
|
56
|
+
const resolved = this.evaluateConditions(botVariable)
|
|
57
|
+
|
|
58
|
+
this.customResult = resolved.customResult
|
|
59
|
+
this.resolvedOperator = resolved.operator
|
|
60
|
+
this.followUp = resolved.target
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private evaluateConditions(botVariable: unknown): ConditionMatch {
|
|
64
|
+
switch (this.variableFormat) {
|
|
65
|
+
case VariableFormat.String: {
|
|
66
|
+
const match = findLastMatchingCondition(
|
|
67
|
+
this.conditions as HtStringCondition[],
|
|
68
|
+
botVariable,
|
|
69
|
+
this.variableFormat,
|
|
70
|
+
(variable, condition) =>
|
|
71
|
+
evaluateStringCondition(variable as string, condition)
|
|
72
|
+
)
|
|
73
|
+
return resolveWithDefaultTarget(match, this.defaultTarget, this.code)
|
|
74
|
+
}
|
|
75
|
+
case VariableFormat.Number: {
|
|
76
|
+
const match = findLastMatchingCondition(
|
|
77
|
+
this.conditions as HtNumberCondition[],
|
|
78
|
+
botVariable,
|
|
79
|
+
this.variableFormat,
|
|
80
|
+
(variable, condition) =>
|
|
81
|
+
evaluateNumberCondition(variable as number, condition)
|
|
82
|
+
)
|
|
83
|
+
return resolveWithDefaultTarget(match, this.defaultTarget, this.code)
|
|
84
|
+
}
|
|
85
|
+
case VariableFormat.Boolean: {
|
|
86
|
+
const match = findLastMatchingCondition(
|
|
87
|
+
this.conditions as HtBooleanCondition[],
|
|
88
|
+
botVariable,
|
|
89
|
+
this.variableFormat,
|
|
90
|
+
(variable, condition) =>
|
|
91
|
+
evaluateBooleanCondition(variable as boolean, condition)
|
|
92
|
+
)
|
|
93
|
+
return resolveWithDefaultTarget(
|
|
94
|
+
match,
|
|
95
|
+
this.defaultTarget,
|
|
96
|
+
this.code,
|
|
97
|
+
'false'
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
default:
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Invalid variable format ${this.variableFormat} for custom condition node ${this.code}`
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async trackFlow(botContext: BotContext): Promise<void> {
|
|
108
|
+
const { flowThreadId, flowId, flowName, flowNodeId, flowNodeContentId } =
|
|
109
|
+
getCommonFlowContentEventArgsForContentId(botContext, this.id)
|
|
110
|
+
|
|
111
|
+
const eventCustomConditional: EventConditionalCustom = {
|
|
112
|
+
action: EventAction.ConditionalCustom,
|
|
113
|
+
flowThreadId,
|
|
114
|
+
flowId,
|
|
115
|
+
flowName,
|
|
116
|
+
flowNodeId,
|
|
117
|
+
flowNodeContentId,
|
|
118
|
+
flowNodeIsMeaningful: false,
|
|
119
|
+
conditionalVariable: this.customResult,
|
|
120
|
+
variableFormat: this.variableFormat,
|
|
121
|
+
operator: this.resolvedOperator,
|
|
122
|
+
}
|
|
123
|
+
const { action, ...eventArgs } = eventCustomConditional
|
|
124
|
+
await trackEvent(botContext, action, eventArgs)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async processContent(botContext: BotContext): Promise<void> {
|
|
128
|
+
await this.filterContent(botContext, this)
|
|
129
|
+
await this.trackFlow(botContext)
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
toBotonic() {
|
|
134
|
+
return <></>
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -101,6 +101,7 @@ export class FlowCustomConditional extends ContentFieldsBase {
|
|
|
101
101
|
flowNodeIsMeaningful: false,
|
|
102
102
|
conditionalVariable: this.customResult.toString(),
|
|
103
103
|
variableFormat: this.variableFormat,
|
|
104
|
+
operator: '',
|
|
104
105
|
}
|
|
105
106
|
const { action, ...eventArgs } = eventCustomConditional
|
|
106
107
|
await trackEvent(botContext, action, eventArgs)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { HtBaseNode, HtNodeLink } from './common'
|
|
2
|
+
import type { HtNodeWithContentType } from './node-types'
|
|
3
|
+
|
|
4
|
+
export enum VariableFormat {
|
|
5
|
+
Boolean = 'boolean',
|
|
6
|
+
Number = 'number',
|
|
7
|
+
String = 'string',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export enum StringConditionOperator {
|
|
11
|
+
Contains = 'contains',
|
|
12
|
+
NotContains = 'notContains',
|
|
13
|
+
EqualsTo = 'equalsTo',
|
|
14
|
+
NotEqualsTo = 'notEqualsTo',
|
|
15
|
+
StartsWith = 'startsWith',
|
|
16
|
+
NotStartsWith = 'notStartsWith',
|
|
17
|
+
EndsWith = 'endsWith',
|
|
18
|
+
NotEndsWith = 'notEndsWith',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HtStringCondition {
|
|
22
|
+
operator: StringConditionOperator
|
|
23
|
+
value?: string
|
|
24
|
+
target?: HtNodeLink
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export enum NumberConditionOperator {
|
|
28
|
+
EqualsTo = 'equalsTo',
|
|
29
|
+
NotEqualsTo = 'notEqualsTo',
|
|
30
|
+
GreaterThan = 'greaterThan',
|
|
31
|
+
LessThan = 'lessThan',
|
|
32
|
+
GreaterThanOrEqualTo = 'greaterThanOrEqualTo',
|
|
33
|
+
LessThanOrEqualTo = 'lessThanOrEqualTo',
|
|
34
|
+
Between = 'between',
|
|
35
|
+
NotBetween = 'notBetween',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface HtNumberCondition {
|
|
39
|
+
operator: NumberConditionOperator
|
|
40
|
+
value?: number
|
|
41
|
+
min?: number
|
|
42
|
+
max?: number
|
|
43
|
+
target?: HtNodeLink
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export enum BooleanConditionOperator {
|
|
47
|
+
IsTruthy = 'isTruthy',
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface HtBooleanCondition {
|
|
51
|
+
operator: BooleanConditionOperator
|
|
52
|
+
target?: HtNodeLink
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type HtCondition =
|
|
56
|
+
| HtStringCondition
|
|
57
|
+
| HtNumberCondition
|
|
58
|
+
| HtBooleanCondition
|
|
59
|
+
|
|
60
|
+
export interface HtCustomConditionalV2Node extends HtBaseNode {
|
|
61
|
+
type: HtNodeWithContentType.CUSTOM_CONDITION
|
|
62
|
+
content: {
|
|
63
|
+
type: VariableFormat
|
|
64
|
+
key_path: string
|
|
65
|
+
conditions: HtCondition[]
|
|
66
|
+
default_target: HtNodeLink
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { HtAiAgentRouterNode } from './ai-agent-router'
|
|
|
3
3
|
import type { HtBotActionNode } from './bot-action'
|
|
4
4
|
import type { HtCaptureUserInputNode } from './capture-user-input'
|
|
5
5
|
import type { HtCarouselNode } from './carousel'
|
|
6
|
+
import type { HtCustomConditionalV2Node } from './custom-conditional-v2'
|
|
6
7
|
// import { HtChannelConditionalNode } from './channel-conditional'
|
|
7
8
|
// import { HtCountryConditionalNode } from './country-conditional'
|
|
8
9
|
// import { HtCustomConditionalNode } from './custom-conditional'
|
|
@@ -46,6 +47,7 @@ export type HtNodeWithContent =
|
|
|
46
47
|
| HtGoToFlow
|
|
47
48
|
| HtWhatsappTemplateNode
|
|
48
49
|
| HtCaptureUserInputNode
|
|
50
|
+
| HtCustomConditionalV2Node
|
|
49
51
|
// | HtChannelConditionalNode
|
|
50
52
|
// | HtCountryConditionalNode
|
|
51
53
|
// | HtCustomConditionalNode
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FlowCustomConditionalV2 } from './custom-conditional/flow-custom-condition-v2'
|
|
1
2
|
import { FlowAiAgent } from './flow-ai-agent'
|
|
2
3
|
import { FlowAiAgentRouter } from './flow-ai-agent-router'
|
|
3
4
|
import { FlowBotAction } from './flow-bot-action'
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
FlowWhatsappButtonList,
|
|
45
46
|
FlowWhatsappCtaUrlButtonNode,
|
|
46
47
|
FlowWhatsappTemplate,
|
|
48
|
+
FlowCustomConditionalV2,
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export type FlowContent =
|
|
@@ -66,5 +68,6 @@ export type FlowContent =
|
|
|
66
68
|
| FlowGoToFlow
|
|
67
69
|
| FlowCaptureUserInput
|
|
68
70
|
| FlowAiAgentRouter
|
|
71
|
+
| FlowCustomConditionalV2
|
|
69
72
|
|
|
70
73
|
export { DISABLED_MEMORY_LENGTH }
|
package/src/flow-factory.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type FlowContent,
|
|
11
11
|
FlowCountryConditional,
|
|
12
12
|
FlowCustomConditional,
|
|
13
|
+
FlowCustomConditionalV2,
|
|
13
14
|
FlowGoToFlow,
|
|
14
15
|
FlowHandoff,
|
|
15
16
|
FlowImage,
|
|
@@ -102,6 +103,12 @@ export class FlowFactory {
|
|
|
102
103
|
case HtNodeWithContentType.CAPTURE_USER_INPUT:
|
|
103
104
|
return FlowCaptureUserInput.fromHubtypeCMS(hubtypeContent)
|
|
104
105
|
|
|
106
|
+
case HtNodeWithContentType.CUSTOM_CONDITION:
|
|
107
|
+
return FlowCustomConditionalV2.fromHubtypeCMS(
|
|
108
|
+
hubtypeContent,
|
|
109
|
+
this.botContext
|
|
110
|
+
)
|
|
111
|
+
|
|
105
112
|
default:
|
|
106
113
|
return undefined
|
|
107
114
|
}
|