Fixing an issue where HBS statements couldn't be used for passing arrays through to a looping action in automations.
This commit is contained in:
parent
e7bb4a1fb7
commit
637ce41b3f
|
@ -208,5 +208,10 @@ exports.AutomationErrors = {
|
||||||
FAILURE_CONDITION: "FAILURE_CONDITION_MET",
|
FAILURE_CONDITION: "FAILURE_CONDITION_MET",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.LoopStepTypes = {
|
||||||
|
ARRAY: "Array",
|
||||||
|
STRING: "String",
|
||||||
|
}
|
||||||
|
|
||||||
// pass through the list from the auth/core lib
|
// pass through the list from the auth/core lib
|
||||||
exports.ObjectStoreBuckets = ObjectStoreBuckets
|
exports.ObjectStoreBuckets = ObjectStoreBuckets
|
||||||
|
|
|
@ -8,7 +8,7 @@ const { DocumentTypes } = require("../db/utils")
|
||||||
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
||||||
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
||||||
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
||||||
const { AutomationErrors } = require("../constants")
|
const { AutomationErrors, LoopStepTypes } = require("../constants")
|
||||||
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
||||||
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
|
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
|
||||||
|
|
||||||
|
@ -17,6 +17,41 @@ const STOPPED_STATUS = { success: false, status: "STOPPED" }
|
||||||
const { cloneDeep } = require("lodash/fp")
|
const { cloneDeep } = require("lodash/fp")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
|
|
||||||
|
function typecastForLooping(loopStep, input) {
|
||||||
|
if (!input || !input.binding) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const isArray = Array.isArray(input.binding),
|
||||||
|
isString = typeof input.binding === "string"
|
||||||
|
try {
|
||||||
|
switch (loopStep.inputs.option) {
|
||||||
|
case LoopStepTypes.ARRAY:
|
||||||
|
if (isString) {
|
||||||
|
return JSON.parse(input.binding)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case LoopStepTypes.STRING:
|
||||||
|
if (isArray) {
|
||||||
|
return input.binding.join(",")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error("Unable to cast to correct type")
|
||||||
|
}
|
||||||
|
return input.binding
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoopIterations(loopStep, input) {
|
||||||
|
const binding = typecastForLooping(loopStep, input)
|
||||||
|
if (!loopStep || !binding) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return Array.isArray(binding)
|
||||||
|
? binding.length
|
||||||
|
: automationUtils.stringSplit(binding).length
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The automation orchestrator is a class responsible for executing automations.
|
* The automation orchestrator is a class responsible for executing automations.
|
||||||
* It handles the context of the automation and makes sure each step gets the correct
|
* It handles the context of the automation and makes sure each step gets the correct
|
||||||
|
@ -107,7 +142,9 @@ class Orchestrator {
|
||||||
let loopSteps = []
|
let loopSteps = []
|
||||||
for (let step of automation.definition.steps) {
|
for (let step of automation.definition.steps) {
|
||||||
stepCount++
|
stepCount++
|
||||||
let input
|
let input,
|
||||||
|
iterations = 1,
|
||||||
|
iterationCount = 0
|
||||||
if (step.stepId === LOOP_STEP_ID) {
|
if (step.stepId === LOOP_STEP_ID) {
|
||||||
loopStep = step
|
loopStep = step
|
||||||
loopStepNumber = stepCount
|
loopStepNumber = stepCount
|
||||||
|
@ -116,13 +153,9 @@ class Orchestrator {
|
||||||
|
|
||||||
if (loopStep) {
|
if (loopStep) {
|
||||||
input = await processObject(loopStep.inputs, this._context)
|
input = await processObject(loopStep.inputs, this._context)
|
||||||
|
iterations = getLoopIterations(loopStep, input)
|
||||||
}
|
}
|
||||||
let iterations = loopStep
|
|
||||||
? Array.isArray(input.binding)
|
|
||||||
? input.binding.length
|
|
||||||
: automationUtils.stringSplit(input.binding).length
|
|
||||||
: 1
|
|
||||||
let iterationCount = 0
|
|
||||||
for (let index = 0; index < iterations; index++) {
|
for (let index = 0; index < iterations; index++) {
|
||||||
let originalStepInput = cloneDeep(step.inputs)
|
let originalStepInput = cloneDeep(step.inputs)
|
||||||
|
|
||||||
|
@ -132,18 +165,11 @@ class Orchestrator {
|
||||||
loopStep.inputs,
|
loopStep.inputs,
|
||||||
cloneDeep(this._context)
|
cloneDeep(this._context)
|
||||||
)
|
)
|
||||||
newInput = automationUtils.cleanInputValues(
|
|
||||||
newInput,
|
|
||||||
loopStep.schema.inputs
|
|
||||||
)
|
|
||||||
|
|
||||||
let tempOutput = { items: loopSteps, iterations: iterationCount }
|
let tempOutput = { items: loopSteps, iterations: iterationCount }
|
||||||
if (
|
try {
|
||||||
(loopStep.inputs.option === "Array" &&
|
newInput.binding = typecastForLooping(loopStep, newInput)
|
||||||
!Array.isArray(newInput.binding)) ||
|
} catch (err) {
|
||||||
(loopStep.inputs.option === "String" &&
|
|
||||||
typeof newInput.binding !== "string")
|
|
||||||
) {
|
|
||||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||||
status: AutomationErrors.INCORRECT_TYPE,
|
status: AutomationErrors.INCORRECT_TYPE,
|
||||||
success: false,
|
success: false,
|
||||||
|
@ -205,21 +231,13 @@ class Orchestrator {
|
||||||
}
|
}
|
||||||
|
|
||||||
let isFailure = false
|
let isFailure = false
|
||||||
if (
|
const currentItem = this._context.steps[loopStepNumber]?.currentItem
|
||||||
typeof this._context.steps[loopStepNumber]?.currentItem === "object"
|
if (currentItem && typeof currentItem === "object") {
|
||||||
) {
|
isFailure = Object.keys(currentItem).some(value => {
|
||||||
isFailure = Object.keys(
|
return currentItem[value] === loopStep.inputs.failure
|
||||||
this._context.steps[loopStepNumber].currentItem
|
|
||||||
).some(value => {
|
|
||||||
return (
|
|
||||||
this._context.steps[loopStepNumber].currentItem[value] ===
|
|
||||||
loopStep.inputs.failure
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
isFailure =
|
isFailure = currentItem && currentItem === loopStep.inputs.failure
|
||||||
this._context.steps[loopStepNumber]?.currentItem ===
|
|
||||||
loopStep.inputs.failure
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFailure) {
|
if (isFailure) {
|
||||||
|
|
|
@ -1014,10 +1014,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@budibase/backend-core@1.0.147":
|
"@budibase/backend-core@1.0.150":
|
||||||
version "1.0.147"
|
version "1.0.150"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.147.tgz#fc93a803e97e304170b33bd28b4f5deda32bec18"
|
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.150.tgz#a48beb1e38f5e3e09473235fd2b7f35a05a15342"
|
||||||
integrity sha512-0GcF9G/tTAsko9g352MB8K3EtMTVb7v7Av6RdsYyKBdVtOD42HKFzSOD0n/RQUL4v70YByiu99zJAB6z1m1Pcg==
|
integrity sha512-ceQVPnypKFurQMJgghky+MxtiF3x4b7rIzYhXv6Y+QfIb7IdY6wvv9o+dD3GPwNZJCRFSFizPR4YLBXdL+2+yw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@techpass/passport-openidconnect" "^0.3.0"
|
"@techpass/passport-openidconnect" "^0.3.0"
|
||||||
aws-sdk "^2.901.0"
|
aws-sdk "^2.901.0"
|
||||||
|
@ -1091,12 +1091,12 @@
|
||||||
svelte-flatpickr "^3.2.3"
|
svelte-flatpickr "^3.2.3"
|
||||||
svelte-portal "^1.0.0"
|
svelte-portal "^1.0.0"
|
||||||
|
|
||||||
"@budibase/pro@1.0.147":
|
"@budibase/pro@1.0.150":
|
||||||
version "1.0.147"
|
version "1.0.150"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.147.tgz#c1ec9d92ffaa40285a83c57ddbec1f32802cd9a1"
|
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.150.tgz#06384561b67130bb2a93f0119921bd35d2be245c"
|
||||||
integrity sha512-e4im6Byqeeit/QFHkVhVdRmgIlJJY/W06cQrOuiG/1ngO4PGnXeJqtjQjHVfvchD5Xi3y1MgQ4AtH2Bzb5LEhw==
|
integrity sha512-Wlam8b5nhSeuNEj5Bb3ro1DKGX81mxxsjKMmxT4rbTqZrzuHSlTkxJ59IvUQqKuyp+cqfP6Rq/i4UXrhK0cg9Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/backend-core" "1.0.147"
|
"@budibase/backend-core" "1.0.150"
|
||||||
node-fetch "^2.6.1"
|
node-fetch "^2.6.1"
|
||||||
|
|
||||||
"@budibase/standard-components@^0.9.139":
|
"@budibase/standard-components@^0.9.139":
|
||||||
|
|
|
@ -293,10 +293,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@budibase/backend-core@1.0.147":
|
"@budibase/backend-core@1.0.150":
|
||||||
version "1.0.147"
|
version "1.0.150"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.147.tgz#fc93a803e97e304170b33bd28b4f5deda32bec18"
|
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.150.tgz#a48beb1e38f5e3e09473235fd2b7f35a05a15342"
|
||||||
integrity sha512-0GcF9G/tTAsko9g352MB8K3EtMTVb7v7Av6RdsYyKBdVtOD42HKFzSOD0n/RQUL4v70YByiu99zJAB6z1m1Pcg==
|
integrity sha512-ceQVPnypKFurQMJgghky+MxtiF3x4b7rIzYhXv6Y+QfIb7IdY6wvv9o+dD3GPwNZJCRFSFizPR4YLBXdL+2+yw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@techpass/passport-openidconnect" "^0.3.0"
|
"@techpass/passport-openidconnect" "^0.3.0"
|
||||||
aws-sdk "^2.901.0"
|
aws-sdk "^2.901.0"
|
||||||
|
@ -321,12 +321,12 @@
|
||||||
uuid "^8.3.2"
|
uuid "^8.3.2"
|
||||||
zlib "^1.0.5"
|
zlib "^1.0.5"
|
||||||
|
|
||||||
"@budibase/pro@1.0.147":
|
"@budibase/pro@1.0.150":
|
||||||
version "1.0.147"
|
version "1.0.150"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.147.tgz#c1ec9d92ffaa40285a83c57ddbec1f32802cd9a1"
|
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.150.tgz#06384561b67130bb2a93f0119921bd35d2be245c"
|
||||||
integrity sha512-e4im6Byqeeit/QFHkVhVdRmgIlJJY/W06cQrOuiG/1ngO4PGnXeJqtjQjHVfvchD5Xi3y1MgQ4AtH2Bzb5LEhw==
|
integrity sha512-Wlam8b5nhSeuNEj5Bb3ro1DKGX81mxxsjKMmxT4rbTqZrzuHSlTkxJ59IvUQqKuyp+cqfP6Rq/i4UXrhK0cg9Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/backend-core" "1.0.147"
|
"@budibase/backend-core" "1.0.150"
|
||||||
node-fetch "^2.6.1"
|
node-fetch "^2.6.1"
|
||||||
|
|
||||||
"@cspotcode/source-map-consumer@0.8.0":
|
"@cspotcode/source-map-consumer@0.8.0":
|
||||||
|
|
Loading…
Reference in New Issue