⚡ (bot) Improve variables parsing and predictability
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
VariableWithValue,
|
||||
MakeComBlock,
|
||||
PabblyConnectBlock,
|
||||
VariableWithUnknowValue,
|
||||
} from 'models'
|
||||
import { stringify } from 'qs'
|
||||
import { byId, sendRequest } from 'utils'
|
||||
@@ -34,8 +35,8 @@ type IntegrationContext = {
|
||||
resultValues: ResultValues
|
||||
groups: Group[]
|
||||
resultId?: string
|
||||
updateVariables: (variables: VariableWithValue[]) => void
|
||||
updateVariableValue: (variableId: string, value: string | number) => void
|
||||
updateVariables: (variables: VariableWithUnknowValue[]) => void
|
||||
updateVariableValue: (variableId: string, value: unknown) => void
|
||||
onNewLog: (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) => void
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ const executeWebhook = async (
|
||||
details: JSON.stringify(error ?? data, null, 2).substring(0, 1000),
|
||||
})
|
||||
const newVariables = block.options.responseVariableMapping.reduce<
|
||||
VariableWithValue[]
|
||||
VariableWithUnknowValue[]
|
||||
>((newVariables, varMapping) => {
|
||||
if (!varMapping?.bodyPath || !varMapping.variableId) return newVariables
|
||||
const existingVariable = variables.find(byId(varMapping.variableId))
|
||||
@@ -262,13 +263,8 @@ const executeWebhook = async (
|
||||
`return data.${parseVariables(variables)(varMapping?.bodyPath)}`
|
||||
)
|
||||
try {
|
||||
const value = func(data)
|
||||
updateVariableValue(
|
||||
existingVariable?.id,
|
||||
typeof value !== 'number' && typeof value !== 'string'
|
||||
? JSON.stringify(value)
|
||||
: value
|
||||
)
|
||||
const value: unknown = func(data)
|
||||
updateVariableValue(existingVariable?.id, value)
|
||||
return [...newVariables, { ...existingVariable, value }]
|
||||
} catch (err) {
|
||||
return newVariables
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
PublicTypebot,
|
||||
Typebot,
|
||||
Edge,
|
||||
VariableWithValue,
|
||||
VariableWithUnknowValue,
|
||||
} from 'models'
|
||||
import { byId, isDefined, isNotDefined, sendRequest } from 'utils'
|
||||
import { sanitizeUrl } from './utils'
|
||||
@@ -35,8 +35,8 @@ type LogicContext = {
|
||||
typebotId: string
|
||||
}) => void
|
||||
setCurrentTypebotId: (id: string) => void
|
||||
updateVariableValue: (variableId: string, value: string) => void
|
||||
updateVariables: (variables: VariableWithValue[]) => void
|
||||
updateVariableValue: (variableId: string, value: unknown) => void
|
||||
updateVariables: (variables: VariableWithUnknowValue[]) => void
|
||||
injectLinkedTypebot: (typebot: Typebot | PublicTypebot) => LinkedTypebot
|
||||
onNewLog: (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) => void
|
||||
createEdge: (edge: Edge) => void
|
||||
@@ -97,10 +97,8 @@ const executeComparison =
|
||||
if (!comparison?.variableId) return false
|
||||
const inputValue = (
|
||||
variables.find((v) => v.id === comparison.variableId)?.value ?? ''
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
const value = parseVariables(variables)(comparison.value).toString().trim()
|
||||
).trim()
|
||||
const value = parseVariables(variables)(comparison.value).trim()
|
||||
if (isNotDefined(value)) return false
|
||||
switch (comparison.comparisonOperator) {
|
||||
case ComparisonOperators.CONTAINS: {
|
||||
|
||||
@@ -23,30 +23,44 @@ export const parseVariables =
|
||||
if (options.fieldToParse === 'id') return variable.id
|
||||
const { value } = variable
|
||||
if (isNotDefined(value)) return ''
|
||||
if (options.escapeForJson) return jsonParse(value.toString())
|
||||
return value.toString()
|
||||
if (options.escapeForJson) return jsonParse(value)
|
||||
const parsedValue = safeStringify(value)
|
||||
if (!parsedValue) return ''
|
||||
return parsedValue
|
||||
})
|
||||
}
|
||||
|
||||
export const safeStringify = (val: unknown): string | null => {
|
||||
if (isNotDefined(val)) return null
|
||||
if (typeof val === 'string') return val
|
||||
try {
|
||||
return JSON.stringify(val)
|
||||
} catch {
|
||||
console.warn('Failed to safely stringify variable value', val)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const jsonParse = (str: string) =>
|
||||
str
|
||||
.replace(/\n/g, `\\n`)
|
||||
.replace(/"/g, `\\"`)
|
||||
.replace(/\\[^n"]/g, `\\\\ `)
|
||||
|
||||
export const evaluateExpression = (variables: Variable[]) => (str: string) => {
|
||||
const evaluating = parseVariables(variables, { fieldToParse: 'id' })(
|
||||
str.includes('return ') ? str : `return ${str}`
|
||||
)
|
||||
try {
|
||||
const func = Function(...variables.map((v) => v.id), evaluating)
|
||||
const evaluatedResult = func(...variables.map((v) => v.value))
|
||||
return isNotDefined(evaluatedResult) ? '' : evaluatedResult
|
||||
} catch (err) {
|
||||
console.log(`Evaluating: ${evaluating}`, err)
|
||||
return str
|
||||
export const evaluateExpression =
|
||||
(variables: Variable[]) =>
|
||||
(str: string): unknown => {
|
||||
const evaluating = parseVariables(variables, { fieldToParse: 'id' })(
|
||||
str.includes('return ') ? str : `return ${str}`
|
||||
)
|
||||
try {
|
||||
const func = Function(...variables.map((v) => v.id), evaluating)
|
||||
return func(...variables.map((v) => v.value))
|
||||
} catch (err) {
|
||||
console.log(`Evaluating: ${evaluating}`, err)
|
||||
return str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const parseVariablesInObject = (
|
||||
object: { [key: string]: string | number },
|
||||
|
||||
Reference in New Issue
Block a user