Improve handling of loop handlebars string replacement
This commit is contained in:
parent
47dcc24491
commit
ef90021b05
|
@ -103,7 +103,7 @@ globals:
|
|||
google:
|
||||
clientId: ""
|
||||
secret: ""
|
||||
automationMaxIterations: "0"
|
||||
automationMaxIterations: "500"
|
||||
|
||||
createSecrets: true # creates an internal API key, JWT secrets and redis password for you
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const { getTable } = require("../api/controllers/table/utils")
|
||||
const { findHBSBlocks } = require("@budibase/string-templates")
|
||||
|
||||
/**
|
||||
* When values are input to the system generally they will be of type string as this is required for template strings.
|
||||
|
@ -74,3 +75,14 @@ exports.getError = err => {
|
|||
}
|
||||
return typeof err !== "string" ? err.toString() : err
|
||||
}
|
||||
|
||||
exports.substituteLoopStep = (hbsString, substitute) => {
|
||||
let blocks = findHBSBlocks(hbsString)
|
||||
for (let block of blocks) {
|
||||
let oldBlock = block
|
||||
block = block.replace(/loop/, substitute)
|
||||
hbsString = hbsString.replace(new RegExp(oldBlock, "g"), block)
|
||||
}
|
||||
|
||||
return hbsString
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ exports.definition = {
|
|||
properties: {
|
||||
items: {
|
||||
customType: "item",
|
||||
description: "the item currently being executed",
|
||||
description: "The item currently being executed",
|
||||
},
|
||||
success: {
|
||||
type: "boolean",
|
||||
|
@ -43,7 +43,7 @@ exports.definition = {
|
|||
descriptions: "The amount of times the block ran",
|
||||
},
|
||||
},
|
||||
required: ["success"],
|
||||
required: ["success, items, iterations"],
|
||||
},
|
||||
},
|
||||
type: "LOGIC",
|
||||
|
|
|
@ -190,5 +190,11 @@ exports.WebhookType = {
|
|||
AUTOMATION: "automation",
|
||||
}
|
||||
|
||||
exports.AutomationErrors = {
|
||||
INCORRECT_TYPE: "INCORRECT_TYPE",
|
||||
MAX_ITERATIONS: "MAX_ITERATIONS_REACHED",
|
||||
FAILURE_CONDITION: "FAILURE_CONDITION_MET",
|
||||
}
|
||||
|
||||
// pass through the list from the auth/core lib
|
||||
exports.ObjectStoreBuckets = ObjectStoreBuckets
|
||||
|
|
|
@ -8,7 +8,7 @@ const { DocumentTypes } = require("../db/utils")
|
|||
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
||||
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
||||
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
||||
|
||||
const { AutomationErrors } = require("../constants")
|
||||
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
||||
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
|
||||
|
||||
|
@ -146,7 +146,7 @@ class Orchestrator {
|
|||
typeof newInput.binding !== "string")
|
||||
) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: "INCORRECT_TYPE",
|
||||
status: AutomationErrors.INCORRECT_TYPE,
|
||||
success: false,
|
||||
})
|
||||
loopSteps = null
|
||||
|
@ -156,27 +156,35 @@ class Orchestrator {
|
|||
|
||||
// The "Loop" binding in the front end is "fake", so replace it here so the context can understand it
|
||||
// Pretty hacky because we need to account for the row object
|
||||
for (let key in originalStepInput) {
|
||||
if (key === "row") {
|
||||
for (let val in originalStepInput["row"]) {
|
||||
originalStepInput["row"][val] = originalStepInput["row"][
|
||||
val
|
||||
].replace(/loop/, `steps.${loopStepNumber}`)
|
||||
}
|
||||
} else {
|
||||
originalStepInput[key] = originalStepInput[key].replace(
|
||||
/loop/,
|
||||
for (let [key, value] of Object.entries(originalStepInput)) {
|
||||
if (typeof value === "object") {
|
||||
for (let [innerKey, innerValue] of Object.entries(
|
||||
originalStepInput[key]
|
||||
)) {
|
||||
if (typeof innerValue === "string") {
|
||||
originalStepInput[key][innerKey] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (typeof value === "string") {
|
||||
originalStepInput[key] = automationUtils.substituteLoopStep(
|
||||
value,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
index === parseInt(env.AUTOMATION_MAX_ITERATIONS) ||
|
||||
index === loopStep.inputs.iterations
|
||||
) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: "MAX_ITERATIONS_REACHED",
|
||||
status: AutomationErrors.MAX_ITERATIONS,
|
||||
success: true,
|
||||
})
|
||||
loopSteps = null
|
||||
|
@ -189,7 +197,7 @@ class Orchestrator {
|
|||
loopStep.inputs.failure
|
||||
) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: "FAILURE_CONDITION_MET",
|
||||
status: AutomationErrors.FAILURE_CONDITION,
|
||||
success: false,
|
||||
})
|
||||
loopSteps = null
|
||||
|
|
Loading…
Reference in New Issue