diff --git a/packages/server/src/api/routes/tests/automation.spec.ts b/packages/server/src/api/routes/tests/automation.spec.ts index 94517db67a..5b451eef4a 100644 --- a/packages/server/src/api/routes/tests/automation.spec.ts +++ b/packages/server/src/api/routes/tests/automation.spec.ts @@ -107,10 +107,7 @@ describe("/automations", () => { }) it("Should ensure you can't have a branch as not a last step", async () => { - const automation = createAutomationBuilder({ - name: "String Equality Branching", - appId: config.getAppId(), - }) + const automation = createAutomationBuilder(config) .appAction({ fields: { status: "active" } }) .branch({ activeBranch: { @@ -134,10 +131,7 @@ describe("/automations", () => { }) it("Should check validation on an automation that has a branch step with no children", async () => { - const automation = createAutomationBuilder({ - name: "String Equality Branching", - appId: config.getAppId(), - }) + const automation = createAutomationBuilder(config) .appAction({ fields: { status: "active" } }) .branch({}) .serverLog({ text: "Inactive user" }) @@ -153,10 +147,7 @@ describe("/automations", () => { }) it("Should check validation on a branch step with empty conditions", async () => { - const automation = createAutomationBuilder({ - name: "String Equality Branching", - appId: config.getAppId(), - }) + const automation = createAutomationBuilder(config) .appAction({ fields: { status: "active" } }) .branch({ activeBranch: { @@ -177,10 +168,7 @@ describe("/automations", () => { }) it("Should check validation on an branch that has a condition that is not valid", async () => { - const automation = createAutomationBuilder({ - name: "String Equality Branching", - appId: config.getAppId(), - }) + const automation = createAutomationBuilder(config) .appAction({ fields: { status: "active" } }) .branch({ activeBranch: { @@ -252,12 +240,7 @@ describe("/automations", () => { }) it("should be able to access platformUrl, logoUrl and company in the automation", async () => { - const result = await createAutomationBuilder({ - name: "Test Automation", - appId: config.getAppId(), - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .serverLog({ text: "{{ settings.url }}", }) diff --git a/packages/server/src/automations/tests/branching.spec.ts b/packages/server/src/automations/tests/branching.spec.ts index 1a514e0537..d9fad543f6 100644 --- a/packages/server/src/automations/tests/branching.spec.ts +++ b/packages/server/src/automations/tests/branching.spec.ts @@ -24,8 +24,7 @@ describe("Branching automations", () => { const branch2LogId = "33333333-3333-3333-3333-333333333333" const branch2Id = "44444444-4444-4444-4444-444444444444" - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .serverLog( { text: "Starting automation" }, { stepName: "FirstLog", stepId: firstLogId } @@ -83,7 +82,7 @@ describe("Branching automations", () => { }) it("should execute correct branch based on string equality", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { status: "active" } }) .branch({ activeBranch: { @@ -108,7 +107,7 @@ describe("Branching automations", () => { }) it("should handle multiple conditions with AND operator", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { status: "active", role: "admin" } }) .branch({ activeAdminBranch: { @@ -136,7 +135,7 @@ describe("Branching automations", () => { }) it("should handle multiple conditions with OR operator", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { status: "test", role: "user" } }) .branch({ specialBranch: { @@ -168,7 +167,7 @@ describe("Branching automations", () => { }) it("should stop the branch automation when no conditions are met", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { status: "test", role: "user" } }) .createRow({ row: { name: "Test", tableId: table._id } }) .branch({ @@ -204,7 +203,7 @@ describe("Branching automations", () => { }) it("evaluate multiple conditions", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { test_trigger: true } }) .serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" }) .branch({ @@ -245,7 +244,7 @@ describe("Branching automations", () => { }) it("evaluate multiple conditions with interpolated text", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { test_trigger: true } }) .serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" }) .branch({ diff --git a/packages/server/src/automations/tests/scenarios.spec.ts b/packages/server/src/automations/tests/scenarios.spec.ts index 8d6e051ce2..2c13b7c019 100644 --- a/packages/server/src/automations/tests/scenarios.spec.ts +++ b/packages/server/src/automations/tests/scenarios.spec.ts @@ -29,7 +29,7 @@ describe("Automation Scenarios", () => { it("should trigger an automation which then creates a row", async () => { const table = await config.api.table.save(basicTable()) - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .rowUpdated( { tableId: table._id! }, { @@ -65,8 +65,7 @@ describe("Automation Scenarios", () => { } await config.api.row.save(table._id!, row) await config.api.row.save(table._id!, row) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows({ tableId: table._id!, }) @@ -84,8 +83,7 @@ describe("Automation Scenarios", () => { } await config.api.row.save(table._id!, row) await config.api.row.save(table._id!, row) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows({ tableId: table._id!, }) @@ -126,8 +124,7 @@ describe("Automation Scenarios", () => { }, }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .createRow( { row: { @@ -195,8 +192,7 @@ describe("Automation Scenarios", () => { } await config.api.row.save(table._id!, row) await config.api.row.save(table._id!, row) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -245,8 +241,7 @@ describe("Automation Scenarios", () => { }) it("should stop an automation if the condition is not met", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .createRow({ row: { name: "Equal Test", @@ -271,8 +266,7 @@ describe("Automation Scenarios", () => { }) it("should continue the automation if the condition is met", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .createRow({ row: { name: "Not Equal Test", @@ -338,8 +332,7 @@ describe("Automation Scenarios", () => { it.each(testCases)( "should pass the filter when condition is $condition", async ({ condition, value, rowValue, expectPass }) => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .createRow({ row: { name: `${condition} Test`, @@ -373,7 +366,7 @@ describe("Automation Scenarios", () => { it("Check user is passed through from row trigger", async () => { const table = await config.api.table.save(basicTable()) - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .rowUpdated( { tableId: table._id! }, { @@ -388,8 +381,7 @@ describe("Automation Scenarios", () => { }) it("Check user is passed through from app trigger", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .serverLog({ text: "{{ [user].[email] }}" }) .run() @@ -460,7 +452,7 @@ if (descriptions.length) { queryVerb: "read", }) - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: {}, }) diff --git a/packages/server/src/automations/tests/steps/bash.spec.ts b/packages/server/src/automations/tests/steps/bash.spec.ts index ef10f9b568..9b797f9479 100644 --- a/packages/server/src/automations/tests/steps/bash.spec.ts +++ b/packages/server/src/automations/tests/steps/bash.spec.ts @@ -24,7 +24,7 @@ describe("Execute Bash Automations", () => { }) it("should use trigger data in bash command and pass output to subsequent steps", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { command: "hello world" } }) .bash( { code: "echo '{{ trigger.fields.command }}'" }, @@ -43,7 +43,7 @@ describe("Execute Bash Automations", () => { }) it("should chain multiple bash commands using previous outputs", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { filename: "testfile.txt" } }) .bash( { code: "echo 'initial content' > {{ trigger.fields.filename }}" }, @@ -64,8 +64,7 @@ describe("Execute Bash Automations", () => { }) it("should integrate bash output with row operations", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -94,7 +93,7 @@ describe("Execute Bash Automations", () => { }) it("should handle bash output in conditional logic", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { threshold: "5" } }) .bash( { code: "echo $(( {{ trigger.fields.threshold }} + 5 ))" }, @@ -121,8 +120,7 @@ describe("Execute Bash Automations", () => { }) it("should handle null values gracefully", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .bash( // @ts-expect-error - testing null input { code: null }, diff --git a/packages/server/src/automations/tests/steps/createRow.spec.ts b/packages/server/src/automations/tests/steps/createRow.spec.ts index 5b86556ae3..4456550cb3 100644 --- a/packages/server/src/automations/tests/steps/createRow.spec.ts +++ b/packages/server/src/automations/tests/steps/createRow.spec.ts @@ -40,7 +40,7 @@ describe("test the create row action", () => { }) it("should be able to run the action", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { status: "new" } }) .serverLog({ text: "Starting create row flow" }, { stepName: "StartLog" }) .createRow({ row }, { stepName: "CreateRow" }) @@ -66,7 +66,7 @@ describe("test the create row action", () => { }) it("should return an error (not throw) when bad info provided", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { status: "error" } }) .serverLog({ text: "Starting error test flow" }, { stepName: "StartLog" }) .createRow( @@ -84,7 +84,7 @@ describe("test the create row action", () => { }) it("should check invalid inputs return an error", async () => { - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { status: "invalid" } }) .serverLog({ text: "Testing invalid input" }, { stepName: "StartLog" }) .createRow({ row: {} }, { stepName: "CreateRow" }) @@ -122,7 +122,7 @@ describe("test the create row action", () => { ] attachmentRow.file_attachment = attachmentObject - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { type: "attachment" } }) .serverLog( { text: "Processing attachment upload" }, @@ -173,7 +173,7 @@ describe("test the create row action", () => { } attachmentRow.single_file_attachment = attachmentObject - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { type: "single-attachment" } }) .serverLog( { text: "Processing single attachment" }, @@ -244,7 +244,7 @@ describe("test the create row action", () => { } attachmentRow.single_file_attachment = attachmentObject - const result = await createAutomationBuilder({ config }) + const result = await createAutomationBuilder(config) .appAction({ fields: { type: "invalid-attachment" } }) .serverLog( { text: "Testing invalid attachment keys" }, diff --git a/packages/server/src/automations/tests/steps/cron-automations.spec.ts b/packages/server/src/automations/tests/steps/cron-automations.spec.ts index 6a82ac1cde..ed0729bd38 100644 --- a/packages/server/src/automations/tests/steps/cron-automations.spec.ts +++ b/packages/server/src/automations/tests/steps/cron-automations.spec.ts @@ -27,7 +27,7 @@ describe("cron automations", () => { }) it("should initialise the automation timestamp", async () => { - await createAutomationBuilder({ config }).cron({ cron: "* * * * *" }).save() + await createAutomationBuilder(config).cron({ cron: "* * * * *" }).save() tk.travel(Date.now() + oneMinuteInMs) await config.publish() diff --git a/packages/server/src/automations/tests/steps/delay.spec.ts b/packages/server/src/automations/tests/steps/delay.spec.ts index a9e97b502f..9dc6470f5a 100644 --- a/packages/server/src/automations/tests/steps/delay.spec.ts +++ b/packages/server/src/automations/tests/steps/delay.spec.ts @@ -16,10 +16,7 @@ describe("test the delay logic", () => { const time = 100 const before = performance.now() - await createAutomationBuilder({ config }) - .appAction({ fields: {} }) - .delay({ time }) - .run() + await createAutomationBuilder(config).delay({ time }).run() const now = performance.now() diff --git a/packages/server/src/automations/tests/steps/deleteRow.spec.ts b/packages/server/src/automations/tests/steps/deleteRow.spec.ts index 1815edb4d3..ee8c9b329f 100644 --- a/packages/server/src/automations/tests/steps/deleteRow.spec.ts +++ b/packages/server/src/automations/tests/steps/deleteRow.spec.ts @@ -20,8 +20,7 @@ describe("test the delete row action", () => { }) it("should be able to run the delete row action", async () => { - await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + await createAutomationBuilder(config) .deleteRow({ tableId: table._id!, id: row._id!, @@ -35,8 +34,7 @@ describe("test the delete row action", () => { }) it("should check invalid inputs return an error", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .deleteRow({ tableId: "", id: "", revision: "" }) .run() @@ -44,8 +42,7 @@ describe("test the delete row action", () => { }) it("should return an error when table doesn't exist", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .deleteRow({ tableId: "invalid", id: "invalid", diff --git a/packages/server/src/automations/tests/steps/discord.spec.ts b/packages/server/src/automations/tests/steps/discord.spec.ts index 5dc9c1088a..361b3517f3 100644 --- a/packages/server/src/automations/tests/steps/discord.spec.ts +++ b/packages/server/src/automations/tests/steps/discord.spec.ts @@ -19,8 +19,7 @@ describe("test the outgoing webhook action", () => { it("should be able to run the action", async () => { nock("http://www.example.com/").post("/").reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .discord({ url: "http://www.example.com", username: "joe_bloggs", diff --git a/packages/server/src/automations/tests/steps/executeScript.spec.ts b/packages/server/src/automations/tests/steps/executeScript.spec.ts index 4470b8e760..e2bea9d0c1 100644 --- a/packages/server/src/automations/tests/steps/executeScript.spec.ts +++ b/packages/server/src/automations/tests/steps/executeScript.spec.ts @@ -20,8 +20,7 @@ describe("Execute Script Automations", () => { }) it("should execute a basic script and return the result", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .executeScript({ code: "return 2 + 2" }) .run() @@ -29,7 +28,7 @@ describe("Execute Script Automations", () => { }) it("should access bindings from previous steps", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { data: [1, 2, 3] } }) .executeScript( { @@ -43,8 +42,7 @@ describe("Execute Script Automations", () => { }) it("should handle script execution errors gracefully", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .executeScript({ code: "return nonexistentVariable.map(x => x)" }) .run() @@ -55,7 +53,7 @@ describe("Execute Script Automations", () => { }) it("should handle conditional logic in scripts", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: { value: 10 } }) .executeScript({ code: ` @@ -72,7 +70,7 @@ describe("Execute Script Automations", () => { }) it("should use multiple steps and validate script execution", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .appAction({ fields: {} }) .serverLog( { text: "Starting multi-step automation" }, diff --git a/packages/server/src/automations/tests/steps/filter.spec.ts b/packages/server/src/automations/tests/steps/filter.spec.ts index b0943f3fa8..51af262aff 100644 --- a/packages/server/src/automations/tests/steps/filter.spec.ts +++ b/packages/server/src/automations/tests/steps/filter.spec.ts @@ -42,8 +42,7 @@ describe("test the filter logic", () => { [new Date().toISOString(), ">", new Date(-10000).toISOString()], ] it.each(pass)("should pass %p %p %p", async (field, condition, value) => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .filter({ field, condition: stringToFilterCondition(condition), value }) .run() @@ -60,8 +59,7 @@ describe("test the filter logic", () => { [{}, "==", {}], ] it.each(fail)("should fail %p %p %p", async (field, condition, value) => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .filter({ field, condition: stringToFilterCondition(condition), value }) .run() diff --git a/packages/server/src/automations/tests/steps/loop.spec.ts b/packages/server/src/automations/tests/steps/loop.spec.ts index af174c33ca..ba74bf6778 100644 --- a/packages/server/src/automations/tests/steps/loop.spec.ts +++ b/packages/server/src/automations/tests/steps/loop.spec.ts @@ -72,7 +72,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should run an automation with a trigger, loop, and create row step", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .rowSaved( { tableId: table._id! }, { @@ -115,7 +115,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should run an automation where a loop step is between two normal steps to ensure context correctness", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .rowSaved( { tableId: table._id! }, { @@ -151,8 +151,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("if an incorrect type is passed to the loop it should return an error", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop({ option: LoopStepType.ARRAY, binding: "1, 2, 3", @@ -167,8 +166,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("ensure the loop stops if the failure condition is reached", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop({ option: LoopStepType.ARRAY, binding: ["test", "test2", "test3"], @@ -186,8 +184,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("ensure the loop stops if the max iterations are reached", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop({ option: LoopStepType.ARRAY, binding: ["test", "test2", "test3"], @@ -201,8 +198,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should run an automation with loop and max iterations to ensure context correctness further down the tree", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop({ option: LoopStepType.ARRAY, binding: ["test", "test2", "test3"], @@ -216,7 +212,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should run an automation where a loop is successfully run twice", async () => { - const results = await createAutomationBuilder({ config }) + const results = await createAutomationBuilder(config) .rowSaved( { tableId: table._id! }, { @@ -278,8 +274,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should run an automation where a loop is used twice to ensure context correctness further down the tree", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop({ option: LoopStepType.ARRAY, binding: [1, 2, 3], @@ -300,8 +295,7 @@ describe("Attempt to run a basic loop automation", () => { }) it("should use automation names to loop with", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .loop( { option: LoopStepType.ARRAY, @@ -352,8 +346,7 @@ describe("Attempt to run a basic loop automation", () => { await config.api.row.bulkImport(table._id!, { rows }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows({ tableId: table._id!, }) @@ -432,8 +425,7 @@ describe("Attempt to run a basic loop automation", () => { await config.api.row.bulkImport(table._id!, { rows }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -515,8 +507,7 @@ describe("Attempt to run a basic loop automation", () => { await config.api.row.bulkImport(table._id!, { rows }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .queryRows({ tableId: table._id!, }) diff --git a/packages/server/src/automations/tests/steps/make.spec.ts b/packages/server/src/automations/tests/steps/make.spec.ts index 8ba5d3f8b7..2d118d943f 100644 --- a/packages/server/src/automations/tests/steps/make.spec.ts +++ b/packages/server/src/automations/tests/steps/make.spec.ts @@ -19,8 +19,7 @@ describe("test the outgoing webhook action", () => { it("should be able to run the action", async () => { nock("http://www.example.com/").post("/").reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .make({ url: "http://www.example.com", body: null, @@ -46,8 +45,7 @@ describe("test the outgoing webhook action", () => { .post("/", payload) .reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .make({ body: { value: JSON.stringify(payload) }, url: "http://www.example.com", @@ -59,8 +57,7 @@ describe("test the outgoing webhook action", () => { }) it("should return a 400 if the JSON payload string is malformed", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .make({ body: { value: "{ invalid json }" }, url: "http://www.example.com", diff --git a/packages/server/src/automations/tests/steps/n8n.spec.ts b/packages/server/src/automations/tests/steps/n8n.spec.ts index 4427ea33e0..d3efb1aaeb 100644 --- a/packages/server/src/automations/tests/steps/n8n.spec.ts +++ b/packages/server/src/automations/tests/steps/n8n.spec.ts @@ -20,8 +20,7 @@ describe("test the outgoing webhook action", () => { it("should be able to run the action and default to 'get'", async () => { nock("http://www.example.com/").get("/").reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .n8n({ url: "http://www.example.com", body: { test: "IGNORE_ME" }, @@ -39,8 +38,7 @@ describe("test the outgoing webhook action", () => { .post("/", { name: "Adam", age: 9 }) .reply(200) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .n8n({ url: "http://www.example.com", body: { value: JSON.stringify({ name: "Adam", age: 9 }) }, @@ -53,8 +51,7 @@ describe("test the outgoing webhook action", () => { }) it("should return a 400 if the JSON payload string is malformed", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .n8n({ url: "http://www.example.com", body: { value: "{ value1 1 }" }, @@ -73,8 +70,7 @@ describe("test the outgoing webhook action", () => { .head("/", body => body === "") .reply(200) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .n8n({ url: "http://www.example.com", method: HttpMethod.HEAD, diff --git a/packages/server/src/automations/tests/steps/openai.spec.ts b/packages/server/src/automations/tests/steps/openai.spec.ts index 3030b3db39..4fbf0aa6d6 100644 --- a/packages/server/src/automations/tests/steps/openai.spec.ts +++ b/packages/server/src/automations/tests/steps/openai.spec.ts @@ -57,8 +57,7 @@ describe("test the openai action", () => { // means it goes through the "legacy" path which requires you to set your // own API key. We don't count this against your quota. const result = await expectAIUsage(0, () => - createAutomationBuilder({ config }) - .appAction({ fields: {} }) + createAutomationBuilder(config) .openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI }) .run() ) @@ -69,8 +68,7 @@ describe("test the openai action", () => { it("should present the correct error message when a prompt is not provided", async () => { const result = await expectAIUsage(0, () => - createAutomationBuilder({ config }) - .appAction({ fields: {} }) + createAutomationBuilder(config) .openai({ prompt: "", model: Model.GPT_4O_MINI }) .run() ) @@ -85,8 +83,7 @@ describe("test the openai action", () => { mockChatGPTError() const result = await expectAIUsage(0, () => - createAutomationBuilder({ config }) - .appAction({ fields: {} }) + createAutomationBuilder(config) .openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI }) .run() ) @@ -108,8 +105,7 @@ describe("test the openai action", () => { // calculation we use to approximate cost. This uses Budibase's OpenAI API // key, so we charge users for it. const result = await expectAIUsage(14, () => - createAutomationBuilder({ config }) - .appAction({ fields: {} }) + createAutomationBuilder(config) .openai({ model: Model.GPT_4O_MINI, prompt: "Hello, world" }) .run() ) diff --git a/packages/server/src/automations/tests/steps/outgoingWebhook.spec.ts b/packages/server/src/automations/tests/steps/outgoingWebhook.spec.ts index b1ff5aa264..b1d13c6917 100644 --- a/packages/server/src/automations/tests/steps/outgoingWebhook.spec.ts +++ b/packages/server/src/automations/tests/steps/outgoingWebhook.spec.ts @@ -23,8 +23,7 @@ describe("test the outgoing webhook action", () => { .post("/", { a: 1 }) .reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .outgoingWebhook({ requestMethod: RequestType.POST, url: "http://www.example.com", @@ -39,8 +38,7 @@ describe("test the outgoing webhook action", () => { }) it("should return an error if something goes wrong in fetch", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .outgoingWebhook({ requestMethod: RequestType.GET, url: "www.invalid.com", diff --git a/packages/server/src/automations/tests/steps/queryRows.spec.ts b/packages/server/src/automations/tests/steps/queryRows.spec.ts index 0030e7fc61..9cda9c94c0 100644 --- a/packages/server/src/automations/tests/steps/queryRows.spec.ts +++ b/packages/server/src/automations/tests/steps/queryRows.spec.ts @@ -28,11 +28,7 @@ describe("Test a query step automation", () => { }) it("should be able to run the query step", async () => { - const result = await createAutomationBuilder({ - name: "Basic Query Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -56,11 +52,7 @@ describe("Test a query step automation", () => { }) it("Returns all rows when onEmptyFilter has no value and no filters are passed", async () => { - const result = await createAutomationBuilder({ - name: "Empty Filter Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -80,11 +72,7 @@ describe("Test a query step automation", () => { }) it("Returns no rows when onEmptyFilter is RETURN_NONE and theres no filters", async () => { - const result = await createAutomationBuilder({ - name: "Return None Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -105,11 +93,7 @@ describe("Test a query step automation", () => { }) it("Returns no rows when onEmptyFilters RETURN_NONE and a filter is passed with a null value", async () => { - const result = await createAutomationBuilder({ - name: "Null Filter Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -134,11 +118,7 @@ describe("Test a query step automation", () => { }) it("Returns rows when onEmptyFilter is RETURN_ALL and no filter is passed", async () => { - const result = await createAutomationBuilder({ - name: "Return All Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: table._id!, @@ -165,11 +145,7 @@ describe("Test a query step automation", () => { await config.api.row.save(tableWithSpaces._id!, { name: NAME, }) - const result = await createAutomationBuilder({ - name: "Return All Test", - config, - }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .queryRows( { tableId: tableWithSpaces._id!, diff --git a/packages/server/src/automations/tests/steps/serverLog.spec.ts b/packages/server/src/automations/tests/steps/serverLog.spec.ts index 556f7b174c..44a9f068b1 100644 --- a/packages/server/src/automations/tests/steps/serverLog.spec.ts +++ b/packages/server/src/automations/tests/steps/serverLog.spec.ts @@ -13,8 +13,7 @@ describe("test the server log action", () => { }) it("should be able to log the text", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .serverLog({ text: "Hello World" }) .run() expect(result.steps[0].outputs.message).toEqual( diff --git a/packages/server/src/automations/tests/steps/triggerAutomationRun.spec.ts b/packages/server/src/automations/tests/steps/triggerAutomationRun.spec.ts index 674f2386c1..ef851bc047 100644 --- a/packages/server/src/automations/tests/steps/triggerAutomationRun.spec.ts +++ b/packages/server/src/automations/tests/steps/triggerAutomationRun.spec.ts @@ -17,13 +17,11 @@ describe("Test triggering an automation from another automation", () => { }) it("should trigger an other server log automation", async () => { - const automation = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const automation = await createAutomationBuilder(config) .serverLog({ text: "Hello World" }) .save() - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .triggerAutomationRun({ automation: { automationId: automation._id!, @@ -36,8 +34,7 @@ describe("Test triggering an automation from another automation", () => { }) it("should fail gracefully if the automation id is incorrect", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .triggerAutomationRun({ automation: { // @ts-expect-error - incorrect on purpose diff --git a/packages/server/src/automations/tests/steps/updateRow.spec.ts b/packages/server/src/automations/tests/steps/updateRow.spec.ts index 79fed5f613..32c7b90446 100644 --- a/packages/server/src/automations/tests/steps/updateRow.spec.ts +++ b/packages/server/src/automations/tests/steps/updateRow.spec.ts @@ -30,8 +30,7 @@ describe("test the update row action", () => { }) it("should be able to run the update row action", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .updateRow({ rowId: row._id!, row: { @@ -53,8 +52,7 @@ describe("test the update row action", () => { }) it("should check invalid inputs return an error", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .updateRow({ meta: {}, row: {}, rowId: "" }) .run() @@ -62,8 +60,7 @@ describe("test the update row action", () => { }) it("should return an error when table doesn't exist", async () => { - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .updateRow({ row: { _id: "invalid" }, rowId: "invalid", @@ -106,8 +103,7 @@ describe("test the update row action", () => { user2: [{ _id: user2._id }], }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .updateRow({ rowId: row._id!, row: { @@ -160,8 +156,7 @@ describe("test the update row action", () => { user2: [{ _id: user2._id }], }) - const results = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const results = await createAutomationBuilder(config) .updateRow({ rowId: row._id!, row: { diff --git a/packages/server/src/automations/tests/steps/zapier.spec.ts b/packages/server/src/automations/tests/steps/zapier.spec.ts index 17a0a7c7bf..e897083d18 100644 --- a/packages/server/src/automations/tests/steps/zapier.spec.ts +++ b/packages/server/src/automations/tests/steps/zapier.spec.ts @@ -20,8 +20,7 @@ describe("test the outgoing webhook action", () => { it("should be able to run the action", async () => { nock("http://www.example.com/").post("/").reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .zapier({ url: "http://www.example.com", body: null }) .run() @@ -44,8 +43,7 @@ describe("test the outgoing webhook action", () => { .post("/", { ...payload, platform: "budibase" }) .reply(200, { foo: "bar" }) - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .zapier({ url: "http://www.example.com", body: { value: JSON.stringify(payload) }, @@ -57,8 +55,7 @@ describe("test the outgoing webhook action", () => { }) it("should return a 400 if the JSON payload string is malformed", async () => { - const result = await createAutomationBuilder({ config }) - .appAction({ fields: {} }) + const result = await createAutomationBuilder(config) .zapier({ url: "http://www.example.com", body: { value: "{ invalid json }" }, diff --git a/packages/server/src/automations/tests/triggers/cron.spec.ts b/packages/server/src/automations/tests/triggers/cron.spec.ts index 956f054ca4..84fe90c314 100644 --- a/packages/server/src/automations/tests/triggers/cron.spec.ts +++ b/packages/server/src/automations/tests/triggers/cron.spec.ts @@ -6,7 +6,7 @@ import { Job } from "bull" describe("cron trigger", () => { const config = new TestConfiguration() - beforeEach(async () => { + beforeAll(async () => { await config.init() }) @@ -24,7 +24,7 @@ describe("cron trigger", () => { }) }) - await createAutomationBuilder({ config }) + await createAutomationBuilder(config) .cron({ cron: "* * * * *" }) .serverLog({ text: "Hello, world!", @@ -44,7 +44,7 @@ describe("cron trigger", () => { }) it("should fail if the cron expression is invalid", async () => { - await createAutomationBuilder({ config }) + await createAutomationBuilder(config) .cron({ cron: "* * * * * *" }) .serverLog({ text: "Hello, world!", diff --git a/packages/server/src/automations/tests/triggers/webhook.spec.ts b/packages/server/src/automations/tests/triggers/webhook.spec.ts index 2e0df5de49..61fab1e891 100644 --- a/packages/server/src/automations/tests/triggers/webhook.spec.ts +++ b/packages/server/src/automations/tests/triggers/webhook.spec.ts @@ -1,4 +1,3 @@ -import * as automation from "../../index" import { Table, Webhook, WebhookActionType } from "@budibase/types" import { createAutomationBuilder } from "../utilities/AutomationTestBuilder" import { mocks } from "@budibase/backend-core/tests" @@ -12,7 +11,7 @@ describe("Branching automations", () => { let webhook: Webhook async function createWebhookAutomation() { - const automation = await createAutomationBuilder({ config }) + const automation = await createAutomationBuilder(config) .webhook({ fields: { parameter: "string" } }) .createRow({ row: { tableId: table._id!, name: "{{ trigger.parameter }}" }, @@ -37,7 +36,6 @@ describe("Branching automations", () => { } beforeEach(async () => { - await automation.init() await config.init() table = await config.createTable() }) diff --git a/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts b/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts index 74e0ae87fb..16a049c556 100644 --- a/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts +++ b/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts @@ -2,51 +2,24 @@ import { v4 as uuidv4 } from "uuid" import { BUILTIN_ACTION_DEFINITIONS } from "../../actions" import { TRIGGER_DEFINITIONS } from "../../triggers" import { - AppActionTriggerInputs, AppActionTriggerOutputs, Automation, AutomationActionStepId, AutomationStep, AutomationStepInputs, AutomationTrigger, - AutomationTriggerDefinition, AutomationTriggerInputs, + AutomationTriggerOutputs, AutomationTriggerStepId, - BashStepInputs, - Branch, BranchStepInputs, - CollectStepInputs, - CreateRowStepInputs, - CronTriggerInputs, CronTriggerOutputs, - DelayStepInputs, - DeleteRowStepInputs, - DiscordStepInputs, - ExecuteQueryStepInputs, - ExecuteScriptStepInputs, - FilterStepInputs, isDidNotTriggerResponse, - LoopStepInputs, - MakeIntegrationInputs, - n8nStepInputs, - OpenAIStepInputs, - OutgoingWebhookStepInputs, - QueryRowsStepInputs, - RowCreatedTriggerInputs, RowCreatedTriggerOutputs, - RowDeletedTriggerInputs, RowDeletedTriggerOutputs, - RowUpdatedTriggerInputs, RowUpdatedTriggerOutputs, SearchFilters, - ServerLogStepInputs, - SmtpEmailStepInputs, TestAutomationRequest, - TriggerAutomationStepInputs, - UpdateRowStepInputs, - WebhookTriggerInputs, WebhookTriggerOutputs, - ZapierStepInputs, } from "@budibase/types" import TestConfiguration from "../../../tests/utilities/TestConfiguration" import * as setup from "../utilities" @@ -74,28 +47,53 @@ class BaseStepBuilder { protected steps: AutomationStep[] = [] protected stepNames: { [key: string]: string } = {} - protected step( - stepId: TStep, - stepSchema: Omit, - inputs: AutomationStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - const id = opts?.stepId || uuidv4() - this.steps.push({ - ...stepSchema, - inputs: inputs as any, - id, - stepId, - name: opts?.stepName || stepSchema.name, - }) - if (opts?.stepName) { - this.stepNames[id] = opts.stepName + protected createStepFn(stepId: TStep) { + return ( + inputs: AutomationStepInputs, + opts?: { stepName?: string; stepId?: string } + ) => { + const schema = BUILTIN_ACTION_DEFINITIONS[stepId] + const id = opts?.stepId || uuidv4() + this.steps.push({ + ...schema, + inputs: inputs as any, + id, + stepId, + name: opts?.stepName || schema.name, + }) + if (opts?.stepName) { + this.stepNames[id] = opts.stepName + } + return this } - return this } + + createRow = this.createStepFn(AutomationActionStepId.CREATE_ROW) + updateRow = this.createStepFn(AutomationActionStepId.UPDATE_ROW) + deleteRow = this.createStepFn(AutomationActionStepId.DELETE_ROW) + sendSmtpEmail = this.createStepFn(AutomationActionStepId.SEND_EMAIL_SMTP) + executeQuery = this.createStepFn(AutomationActionStepId.EXECUTE_QUERY) + queryRows = this.createStepFn(AutomationActionStepId.QUERY_ROWS) + loop = this.createStepFn(AutomationActionStepId.LOOP) + serverLog = this.createStepFn(AutomationActionStepId.SERVER_LOG) + executeScript = this.createStepFn(AutomationActionStepId.EXECUTE_SCRIPT) + filter = this.createStepFn(AutomationActionStepId.FILTER) + bash = this.createStepFn(AutomationActionStepId.EXECUTE_BASH) + openai = this.createStepFn(AutomationActionStepId.OPENAI) + collect = this.createStepFn(AutomationActionStepId.COLLECT) + zapier = this.createStepFn(AutomationActionStepId.zapier) + triggerAutomationRun = this.createStepFn( + AutomationActionStepId.TRIGGER_AUTOMATION_RUN + ) + outgoingWebhook = this.createStepFn(AutomationActionStepId.OUTGOING_WEBHOOK) + n8n = this.createStepFn(AutomationActionStepId.n8n) + make = this.createStepFn(AutomationActionStepId.integromat) + discord = this.createStepFn(AutomationActionStepId.discord) + delay = this.createStepFn(AutomationActionStepId.DELAY) + protected addBranchStep(branchConfig: BranchConfig): void { const branchStepInputs: BranchStepInputs = { - branches: [] as Branch[], + branches: [], children: {}, } @@ -118,243 +116,6 @@ class BaseStepBuilder { } this.steps.push(branchStep) } - - // STEPS - createRow( - inputs: CreateRowStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.CREATE_ROW, - BUILTIN_ACTION_DEFINITIONS.CREATE_ROW, - inputs, - opts - ) - } - - updateRow( - inputs: UpdateRowStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.UPDATE_ROW, - BUILTIN_ACTION_DEFINITIONS.UPDATE_ROW, - inputs, - opts - ) - } - - deleteRow( - inputs: DeleteRowStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.DELETE_ROW, - BUILTIN_ACTION_DEFINITIONS.DELETE_ROW, - inputs, - opts - ) - } - - sendSmtpEmail( - inputs: SmtpEmailStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.SEND_EMAIL_SMTP, - BUILTIN_ACTION_DEFINITIONS.SEND_EMAIL_SMTP, - inputs, - opts - ) - } - - executeQuery( - inputs: ExecuteQueryStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.EXECUTE_QUERY, - BUILTIN_ACTION_DEFINITIONS.EXECUTE_QUERY, - inputs, - opts - ) - } - - queryRows( - inputs: QueryRowsStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.QUERY_ROWS, - BUILTIN_ACTION_DEFINITIONS.QUERY_ROWS, - inputs, - opts - ) - } - - loop( - inputs: LoopStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.LOOP, - BUILTIN_ACTION_DEFINITIONS.LOOP, - inputs, - opts - ) - } - - serverLog( - input: ServerLogStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.SERVER_LOG, - BUILTIN_ACTION_DEFINITIONS.SERVER_LOG, - input, - opts - ) - } - - executeScript( - input: ExecuteScriptStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.EXECUTE_SCRIPT, - BUILTIN_ACTION_DEFINITIONS.EXECUTE_SCRIPT, - input, - opts - ) - } - - filter(input: FilterStepInputs): this { - return this.step( - AutomationActionStepId.FILTER, - BUILTIN_ACTION_DEFINITIONS.FILTER, - input - ) - } - - bash( - input: BashStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.EXECUTE_BASH, - BUILTIN_ACTION_DEFINITIONS.EXECUTE_BASH, - input, - opts - ) - } - - openai( - input: OpenAIStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.OPENAI, - BUILTIN_ACTION_DEFINITIONS.OPENAI, - input, - opts - ) - } - - collect( - input: CollectStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.COLLECT, - BUILTIN_ACTION_DEFINITIONS.COLLECT, - input, - opts - ) - } - - zapier( - input: ZapierStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.zapier, - BUILTIN_ACTION_DEFINITIONS.zapier, - input, - opts - ) - } - - triggerAutomationRun( - input: TriggerAutomationStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.TRIGGER_AUTOMATION_RUN, - BUILTIN_ACTION_DEFINITIONS.TRIGGER_AUTOMATION_RUN, - input, - opts - ) - } - - outgoingWebhook( - input: OutgoingWebhookStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.OUTGOING_WEBHOOK, - BUILTIN_ACTION_DEFINITIONS.OUTGOING_WEBHOOK, - input, - opts - ) - } - - n8n( - input: n8nStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.n8n, - BUILTIN_ACTION_DEFINITIONS.n8n, - input, - opts - ) - } - - make( - input: MakeIntegrationInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.integromat, - BUILTIN_ACTION_DEFINITIONS.integromat, - input, - opts - ) - } - - discord( - input: DiscordStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.discord, - BUILTIN_ACTION_DEFINITIONS.discord, - input, - opts - ) - } - - delay( - input: DelayStepInputs, - opts?: { stepName?: string; stepId?: string } - ): this { - return this.step( - AutomationActionStepId.DELAY, - BUILTIN_ACTION_DEFINITIONS.DELAY, - input, - opts - ) - } } class StepBuilder extends BaseStepBuilder { @@ -374,111 +135,79 @@ class AutomationBuilder extends BaseStepBuilder { private triggerOutputs: TriggerOutputs private triggerSet = false - constructor( - options: { name?: string; appId?: string; config?: TestConfiguration } = {} - ) { + constructor(config?: TestConfiguration) { super() - this.config = options.config || setup.getConfig() + this.config = config || setup.getConfig() + this.triggerOutputs = { fields: {} } this.automationConfig = { - name: options.name || `Test Automation ${uuidv4()}`, + name: `Test Automation ${uuidv4()}`, definition: { steps: [], - trigger: {} as AutomationTrigger, + trigger: { + ...TRIGGER_DEFINITIONS[AutomationTriggerStepId.APP], + stepId: AutomationTriggerStepId.APP, + inputs: this.triggerOutputs, + id: uuidv4(), + }, stepNames: {}, }, type: "automation", - appId: options.appId ?? this.config.getAppId(), + appId: this.config.getAppId(), } } - // TRIGGERS - rowSaved(inputs: RowCreatedTriggerInputs, outputs: RowCreatedTriggerOutputs) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.ROW_SAVED, - AutomationTriggerStepId.ROW_SAVED, - inputs, - outputs - ) - } - - rowUpdated( - inputs: RowUpdatedTriggerInputs, - outputs: RowUpdatedTriggerOutputs - ) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.ROW_UPDATED, - AutomationTriggerStepId.ROW_UPDATED, - inputs, - outputs - ) - } - - rowDeleted( - inputs: RowDeletedTriggerInputs, - outputs: RowDeletedTriggerOutputs - ) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.ROW_DELETED, - AutomationTriggerStepId.ROW_DELETED, - inputs, - outputs - ) - } - - appAction(outputs: AppActionTriggerOutputs, inputs?: AppActionTriggerInputs) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.APP, - AutomationTriggerStepId.APP, - inputs, - outputs - ) - } - - webhook(outputs: WebhookTriggerOutputs, inputs?: WebhookTriggerInputs) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.WEBHOOK, - AutomationTriggerStepId.WEBHOOK, - inputs, - outputs - ) - } - - cron(inputs: CronTriggerInputs, outputs?: CronTriggerOutputs) { - this.triggerOutputs = outputs - return this.trigger( - TRIGGER_DEFINITIONS.CRON, - AutomationTriggerStepId.CRON, - inputs, - outputs - ) - } - - private trigger( - triggerSchema: AutomationTriggerDefinition, - stepId: TStep, - inputs?: AutomationTriggerInputs, - outputs?: TriggerOutputs - ): this { - if (this.triggerSet) { - throw new Error("Only one trigger can be set for an automation.") - } - this.automationConfig.definition.trigger = { - ...triggerSchema, - stepId, - inputs: inputs || ({} as any), - id: uuidv4(), - } - this.triggerOutputs = outputs - this.triggerSet = true - + name(n: string): this { + this.automationConfig.name = n return this } + protected triggerInputOutput< + TStep extends AutomationTriggerStepId, + TInput = AutomationTriggerInputs, + TOutput = AutomationTriggerOutputs + >(stepId: TStep) { + return (inputs: TInput, outputs?: TOutput) => { + if (this.triggerSet) { + throw new Error("Only one trigger can be set for an automation.") + } + this.triggerOutputs = outputs as TriggerOutputs | undefined + this.automationConfig.definition.trigger = { + ...TRIGGER_DEFINITIONS[stepId], + stepId, + inputs, + id: uuidv4(), + } as AutomationTrigger + this.triggerSet = true + return this + } + } + + protected triggerOutputOnly< + TStep extends AutomationTriggerStepId, + TOutput = AutomationTriggerOutputs + >(stepId: TStep) { + return (outputs: TOutput) => { + this.triggerOutputs = outputs as TriggerOutputs + this.automationConfig.definition.trigger = { + ...TRIGGER_DEFINITIONS[stepId], + stepId, + id: uuidv4(), + } as AutomationTrigger + this.triggerSet = true + return this + } + } + + // The input and output for appAction is identical, and we only ever seem to + // set the output, so we're ignoring the input for now. + appAction = this.triggerOutputOnly(AutomationTriggerStepId.APP) + + rowSaved = this.triggerInputOutput(AutomationTriggerStepId.ROW_SAVED) + rowUpdated = this.triggerInputOutput(AutomationTriggerStepId.ROW_UPDATED) + rowDeleted = this.triggerInputOutput(AutomationTriggerStepId.ROW_DELETED) + webhook = this.triggerInputOutput(AutomationTriggerStepId.WEBHOOK) + cron = this.triggerInputOutput(AutomationTriggerStepId.CRON) + branch(branchConfig: BranchConfig): this { this.addBranchStep(branchConfig) return this @@ -491,9 +220,6 @@ class AutomationBuilder extends BaseStepBuilder { } async save() { - if (!Object.keys(this.automationConfig.definition.trigger).length) { - throw new Error("Please add a trigger to this automation test") - } this.automationConfig.definition.steps = this.steps const { automation } = await this.config.api.automation.post(this.build()) return automation @@ -518,10 +244,6 @@ class AutomationBuilder extends BaseStepBuilder { } } -export function createAutomationBuilder(options?: { - name?: string - appId?: string - config?: TestConfiguration -}) { - return new AutomationBuilder(options) +export function createAutomationBuilder(config: TestConfiguration) { + return new AutomationBuilder(config) } diff --git a/packages/types/src/documents/app/automation/schema.ts b/packages/types/src/documents/app/automation/schema.ts index 84bfebf6bf..952397b511 100644 --- a/packages/types/src/documents/app/automation/schema.ts +++ b/packages/types/src/documents/app/automation/schema.ts @@ -52,6 +52,12 @@ import { RowDeletedTriggerInputs, BranchStepInputs, BaseAutomationOutputs, + AppActionTriggerOutputs, + CronTriggerOutputs, + RowDeletedTriggerOutputs, + RowCreatedTriggerOutputs, + RowUpdatedTriggerOutputs, + WebhookTriggerOutputs, } from "./StepInputsOutputs" export type ActionImplementations = { @@ -341,6 +347,23 @@ export type AutomationTriggerInputs = ? Record : never +export type AutomationTriggerOutputs = + T extends AutomationTriggerStepId.APP + ? AppActionTriggerOutputs + : T extends AutomationTriggerStepId.CRON + ? CronTriggerOutputs + : T extends AutomationTriggerStepId.ROW_ACTION + ? Record + : T extends AutomationTriggerStepId.ROW_DELETED + ? RowDeletedTriggerOutputs + : T extends AutomationTriggerStepId.ROW_SAVED + ? RowCreatedTriggerOutputs + : T extends AutomationTriggerStepId.ROW_UPDATED + ? RowUpdatedTriggerOutputs + : T extends AutomationTriggerStepId.WEBHOOK + ? WebhookTriggerOutputs + : never + export interface AutomationTriggerSchema< TTrigger extends AutomationTriggerStepId > extends AutomationStepSchemaBase {