diff --git a/packages/server/src/automations/tests/loop.spec.ts b/packages/server/src/automations/tests/loop.spec.ts index 70b771c445..68ab694c5d 100644 --- a/packages/server/src/automations/tests/loop.spec.ts +++ b/packages/server/src/automations/tests/loop.spec.ts @@ -44,4 +44,12 @@ describe("Attempt to run a basic loop automation", () => { }) expect(resp.steps[2].outputs.iterations).toBe(3) }) + + it("test a loop with a binding that returns an integer", async () => { + const resp = await runLoop({ + option: LoopStepType.ARRAY, + binding: "{{ 1 }}", + }) + expect(resp.steps[2].outputs.iterations).toBe(1) + }) }) diff --git a/packages/server/src/automations/triggers.ts b/packages/server/src/automations/triggers.ts index 17a33e4394..08e3199a11 100644 --- a/packages/server/src/automations/triggers.ts +++ b/packages/server/src/automations/triggers.ts @@ -9,7 +9,7 @@ import * as utils from "./utils" import env from "../environment" import { context, db as dbCore } from "@budibase/backend-core" import { Automation, Row, AutomationData, AutomationJob } from "@budibase/types" -import { executeSynchronously } from "../threads/automation" +import { executeInThread } from "../threads/automation" export const TRIGGER_DEFINITIONS = definitions const JOB_OPTS = { @@ -117,8 +117,7 @@ export async function externalTrigger( appId: context.getAppId(), automation, } - const job = { data } as AutomationJob - return executeSynchronously(job) + return executeInThread({ data } as AutomationJob) } else { return automationQueue.add(data, JOB_OPTS) } diff --git a/packages/server/src/threads/automation.ts b/packages/server/src/threads/automation.ts index 56d9280f31..a828af5d19 100644 --- a/packages/server/src/threads/automation.ts +++ b/packages/server/src/threads/automation.ts @@ -43,20 +43,18 @@ const CRON_STEP_ID = triggerDefs.CRON.stepId const STOPPED_STATUS = { success: true, status: AutomationStatus.STOPPED } function getLoopIterations(loopStep: LoopStep) { - let binding = loopStep.inputs.binding + const binding = loopStep.inputs.binding if (!binding) { return 0 } try { - if (typeof binding === "string") { - binding = JSON.parse(binding) + const json = typeof binding === "string" ? JSON.parse(binding) : binding + if (Array.isArray(json)) { + return json.length } } catch (err) { // ignore error - wasn't able to parse } - if (Array.isArray(binding)) { - return binding.length - } if (typeof binding === "string") { return automationUtils.stringSplit(binding).length } @@ -614,7 +612,7 @@ export function execute(job: Job, callback: WorkerCallback) { }) } -export function executeSynchronously(job: Job) { +export async function executeInThread(job: Job) { const appId = job.data.event.appId if (!appId) { throw new Error("Unable to execute, event doesn't contain app ID.") @@ -626,10 +624,10 @@ export function executeSynchronously(job: Job) { }, job.data.event.timeout || 12000) }) - return context.doInAppContext(appId, async () => { + return await context.doInAppContext(appId, async () => { const envVars = await sdkUtils.getEnvironmentVariables() // put into automation thread for whole context - return context.doInEnvironmentContext(envVars, async () => { + return await context.doInEnvironmentContext(envVars, async () => { const automationOrchestrator = new Orchestrator(job) return await Promise.race([ automationOrchestrator.execute(),