@botonic/plugin-flow-builder 0.50.2-alpha.0 → 0.51.0-alpha.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.
Files changed (58) hide show
  1. package/lib/cjs/content-fields/custom-conditional-v2-evaluators.d.ts +15 -0
  2. package/lib/cjs/content-fields/custom-conditional-v2-evaluators.js +71 -0
  3. package/lib/cjs/content-fields/custom-conditional-v2-evaluators.js.map +1 -0
  4. package/lib/cjs/content-fields/custom-conditional-v2-resolver.d.ts +8 -0
  5. package/lib/cjs/content-fields/custom-conditional-v2-resolver.js +48 -0
  6. package/lib/cjs/content-fields/custom-conditional-v2-resolver.js.map +1 -0
  7. package/lib/cjs/content-fields/flow-custom-condition-v2.d.ts +16 -0
  8. package/lib/cjs/content-fields/flow-custom-condition-v2.js +76 -0
  9. package/lib/cjs/content-fields/flow-custom-condition-v2.js.map +1 -0
  10. package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.d.ts +56 -0
  11. package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.js +36 -0
  12. package/lib/cjs/content-fields/hubtype-fields/custom-conditional-v2.js.map +1 -0
  13. package/lib/cjs/content-fields/hubtype-fields/index.d.ts +1 -0
  14. package/lib/cjs/content-fields/hubtype-fields/index.js +1 -0
  15. package/lib/cjs/content-fields/hubtype-fields/index.js.map +1 -1
  16. package/lib/cjs/content-fields/hubtype-fields/node-types.d.ts +2 -1
  17. package/lib/cjs/content-fields/hubtype-fields/node-types.js +1 -0
  18. package/lib/cjs/content-fields/hubtype-fields/node-types.js.map +1 -1
  19. package/lib/cjs/content-fields/hubtype-fields/nodes.d.ts +2 -1
  20. package/lib/cjs/content-fields/index.d.ts +3 -2
  21. package/lib/cjs/content-fields/index.js +3 -1
  22. package/lib/cjs/content-fields/index.js.map +1 -1
  23. package/lib/cjs/flow-factory.js +2 -0
  24. package/lib/cjs/flow-factory.js.map +1 -1
  25. package/lib/esm/content-fields/custom-conditional-v2-evaluators.d.ts +15 -0
  26. package/lib/esm/content-fields/custom-conditional-v2-evaluators.js +71 -0
  27. package/lib/esm/content-fields/custom-conditional-v2-evaluators.js.map +1 -0
  28. package/lib/esm/content-fields/custom-conditional-v2-resolver.d.ts +8 -0
  29. package/lib/esm/content-fields/custom-conditional-v2-resolver.js +48 -0
  30. package/lib/esm/content-fields/custom-conditional-v2-resolver.js.map +1 -0
  31. package/lib/esm/content-fields/flow-custom-condition-v2.d.ts +16 -0
  32. package/lib/esm/content-fields/flow-custom-condition-v2.js +76 -0
  33. package/lib/esm/content-fields/flow-custom-condition-v2.js.map +1 -0
  34. package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.d.ts +56 -0
  35. package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.js +36 -0
  36. package/lib/esm/content-fields/hubtype-fields/custom-conditional-v2.js.map +1 -0
  37. package/lib/esm/content-fields/hubtype-fields/index.d.ts +1 -0
  38. package/lib/esm/content-fields/hubtype-fields/index.js +1 -0
  39. package/lib/esm/content-fields/hubtype-fields/index.js.map +1 -1
  40. package/lib/esm/content-fields/hubtype-fields/node-types.d.ts +2 -1
  41. package/lib/esm/content-fields/hubtype-fields/node-types.js +1 -0
  42. package/lib/esm/content-fields/hubtype-fields/node-types.js.map +1 -1
  43. package/lib/esm/content-fields/hubtype-fields/nodes.d.ts +2 -1
  44. package/lib/esm/content-fields/index.d.ts +3 -2
  45. package/lib/esm/content-fields/index.js +3 -1
  46. package/lib/esm/content-fields/index.js.map +1 -1
  47. package/lib/esm/flow-factory.js +2 -0
  48. package/lib/esm/flow-factory.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/content-fields/custom-conditional-v2-evaluators.ts +124 -0
  51. package/src/content-fields/custom-conditional-v2-resolver.ts +77 -0
  52. package/src/content-fields/flow-custom-condition-v2.tsx +133 -0
  53. package/src/content-fields/hubtype-fields/custom-conditional-v2.ts +68 -0
  54. package/src/content-fields/hubtype-fields/index.ts +1 -0
  55. package/src/content-fields/hubtype-fields/node-types.ts +1 -0
  56. package/src/content-fields/hubtype-fields/nodes.ts +2 -0
  57. package/src/content-fields/index.ts +3 -0
  58. package/src/flow-factory.ts +7 -0
@@ -0,0 +1,133 @@
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
+ evaluateBooleanCondition,
13
+ evaluateNumberCondition,
14
+ evaluateStringCondition,
15
+ } from './custom-conditional-v2-evaluators'
16
+ import {
17
+ type ConditionMatch,
18
+ findLastMatchingCondition,
19
+ resolveWithDefaultTarget,
20
+ } from './custom-conditional-v2-resolver'
21
+ import {
22
+ type HtBooleanCondition,
23
+ type HtCondition,
24
+ type HtCustomConditionalV2Node,
25
+ type HtNodeLink,
26
+ type HtNumberCondition,
27
+ type HtStringCondition,
28
+ VariableFormat,
29
+ } from './hubtype-fields'
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
+
38
+ static fromHubtypeCMS(
39
+ component: HtCustomConditionalV2Node,
40
+ botContext: BotContext
41
+ ): FlowCustomConditionalV2 {
42
+ const newCustomConditionalV2 = new FlowCustomConditionalV2(component.id)
43
+ newCustomConditionalV2.code = component.code
44
+ newCustomConditionalV2.variableFormat = component.content.type
45
+ newCustomConditionalV2.keyPath = component.content.key_path
46
+ newCustomConditionalV2.conditions = component.content.conditions
47
+ newCustomConditionalV2.defaultTarget = component.content.default_target
48
+ newCustomConditionalV2.setFollowUp(botContext)
49
+
50
+ return newCustomConditionalV2
51
+ }
52
+
53
+ private setFollowUp(botContext: BotContext): void {
54
+ const botVariable = this.getValueFromKeyPath(botContext, this.keyPath)
55
+ const resolved = this.evaluateConditions(botVariable)
56
+
57
+ this.customResult = resolved.customResult
58
+ this.followUp = resolved.target
59
+ }
60
+
61
+ private evaluateConditions(botVariable: unknown): ConditionMatch {
62
+ switch (this.variableFormat) {
63
+ case VariableFormat.String: {
64
+ const match = findLastMatchingCondition(
65
+ this.conditions as HtStringCondition[],
66
+ botVariable,
67
+ this.variableFormat,
68
+ (variable, condition) =>
69
+ evaluateStringCondition(variable as string, condition)
70
+ )
71
+ return resolveWithDefaultTarget(match, this.defaultTarget, this.code)
72
+ }
73
+ case VariableFormat.Number: {
74
+ const match = findLastMatchingCondition(
75
+ this.conditions as HtNumberCondition[],
76
+ botVariable,
77
+ this.variableFormat,
78
+ (variable, condition) =>
79
+ evaluateNumberCondition(variable as number, condition)
80
+ )
81
+ return resolveWithDefaultTarget(match, this.defaultTarget, this.code)
82
+ }
83
+ case VariableFormat.Boolean: {
84
+ const match = findLastMatchingCondition(
85
+ this.conditions as HtBooleanCondition[],
86
+ botVariable,
87
+ this.variableFormat,
88
+ (variable, condition) =>
89
+ evaluateBooleanCondition(variable as boolean, condition)
90
+ )
91
+ return resolveWithDefaultTarget(
92
+ match,
93
+ this.defaultTarget,
94
+ this.code,
95
+ 'false'
96
+ )
97
+ }
98
+ default:
99
+ throw new Error(
100
+ `Invalid variable format ${this.variableFormat} for custom condition node ${this.code}`
101
+ )
102
+ }
103
+ }
104
+
105
+ async trackFlow(botContext: BotContext): Promise<void> {
106
+ const { flowThreadId, flowId, flowName, flowNodeId, flowNodeContentId } =
107
+ getCommonFlowContentEventArgsForContentId(botContext, this.id)
108
+
109
+ const eventCustomConditional: EventConditionalCustom = {
110
+ action: EventAction.ConditionalCustom,
111
+ flowThreadId,
112
+ flowId,
113
+ flowName,
114
+ flowNodeId,
115
+ flowNodeContentId,
116
+ flowNodeIsMeaningful: false,
117
+ conditionalVariable: this.customResult,
118
+ variableFormat: this.variableFormat,
119
+ }
120
+ const { action, ...eventArgs } = eventCustomConditional
121
+ await trackEvent(botContext, action, eventArgs)
122
+ }
123
+
124
+ async processContent(botContext: BotContext): Promise<void> {
125
+ await this.filterContent(botContext, this)
126
+ await this.trackFlow(botContext)
127
+ return
128
+ }
129
+
130
+ toBotonic() {
131
+ return <></>
132
+ }
133
+ }
@@ -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
+ }
@@ -5,6 +5,7 @@ export * from './button'
5
5
  export * from './capture-user-input'
6
6
  export * from './carousel'
7
7
  export * from './common'
8
+ export * from './custom-conditional-v2'
8
9
  export * from './fallback'
9
10
  export * from './function'
10
11
  export * from './go-to-flow'
@@ -19,6 +19,7 @@ export enum HtNodeWithContentType {
19
19
  WEBVIEW = 'webview',
20
20
  GO_TO_FLOW = 'go-to-flow',
21
21
  CAPTURE_USER_INPUT = 'capture-user-input',
22
+ CUSTOM_CONDITION = 'custom-condition',
22
23
  }
23
24
 
24
25
  export enum HtNodeWithoutContentType {
@@ -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
@@ -5,6 +5,7 @@ import { FlowCaptureUserInput } from './flow-capture-user-input'
5
5
  import { FlowCarousel } from './flow-carousel'
6
6
  import { FlowChannelConditional } from './flow-channel-conditional'
7
7
  import { FlowCountryConditional } from './flow-country-conditional'
8
+ import { FlowCustomConditionalV2 } from './flow-custom-condition-v2'
8
9
  import { FlowCustomConditional } from './flow-custom-conditional'
9
10
  import { FlowGoToFlow } from './flow-go-to-flow'
10
11
  import { FlowHandoff } from './flow-handoff'
@@ -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 }
@@ -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
  }