Merge remote-tracking branch 'origin/execute-script-v2' into execute-script-v2-frontend
This commit is contained in:
commit
8b04a56dd6
|
@ -103,11 +103,8 @@ describe("/automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Should ensure you can't have a branch as not a last step", async () => {
|
it("Should ensure you can't have a branch as not a last step", async () => {
|
||||||
const automation = createAutomationBuilder({
|
const automation = createAutomationBuilder(config)
|
||||||
name: "String Equality Branching",
|
.onAppAction()
|
||||||
appId: config.getAppId(),
|
|
||||||
})
|
|
||||||
.appAction({ fields: { status: "active" } })
|
|
||||||
.branch({
|
.branch({
|
||||||
activeBranch: {
|
activeBranch: {
|
||||||
steps: stepBuilder =>
|
steps: stepBuilder =>
|
||||||
|
@ -130,11 +127,8 @@ describe("/automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Should check validation on an automation that has a branch step with no children", async () => {
|
it("Should check validation on an automation that has a branch step with no children", async () => {
|
||||||
const automation = createAutomationBuilder({
|
const automation = createAutomationBuilder(config)
|
||||||
name: "String Equality Branching",
|
.onAppAction()
|
||||||
appId: config.getAppId(),
|
|
||||||
})
|
|
||||||
.appAction({ fields: { status: "active" } })
|
|
||||||
.branch({})
|
.branch({})
|
||||||
.serverLog({ text: "Inactive user" })
|
.serverLog({ text: "Inactive user" })
|
||||||
.build()
|
.build()
|
||||||
|
@ -149,11 +143,8 @@ describe("/automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Should check validation on a branch step with empty conditions", async () => {
|
it("Should check validation on a branch step with empty conditions", async () => {
|
||||||
const automation = createAutomationBuilder({
|
const automation = createAutomationBuilder(config)
|
||||||
name: "String Equality Branching",
|
.onAppAction()
|
||||||
appId: config.getAppId(),
|
|
||||||
})
|
|
||||||
.appAction({ fields: { status: "active" } })
|
|
||||||
.branch({
|
.branch({
|
||||||
activeBranch: {
|
activeBranch: {
|
||||||
steps: stepBuilder =>
|
steps: stepBuilder =>
|
||||||
|
@ -173,11 +164,8 @@ describe("/automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Should check validation on an branch that has a condition that is not valid", async () => {
|
it("Should check validation on an branch that has a condition that is not valid", async () => {
|
||||||
const automation = createAutomationBuilder({
|
const automation = createAutomationBuilder(config)
|
||||||
name: "String Equality Branching",
|
.onAppAction()
|
||||||
appId: config.getAppId(),
|
|
||||||
})
|
|
||||||
.appAction({ fields: { status: "active" } })
|
|
||||||
.branch({
|
.branch({
|
||||||
activeBranch: {
|
activeBranch: {
|
||||||
steps: stepBuilder =>
|
steps: stepBuilder =>
|
||||||
|
@ -248,12 +236,8 @@ describe("/automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to access platformUrl, logoUrl and company in the automation", async () => {
|
it("should be able to access platformUrl, logoUrl and company in the automation", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Test Automation",
|
.onAppAction()
|
||||||
appId: config.getAppId(),
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: "{{ settings.url }}",
|
text: "{{ settings.url }}",
|
||||||
})
|
})
|
||||||
|
@ -263,7 +247,7 @@ describe("/automations", () => {
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: "{{ settings.company }}",
|
text: "{{ settings.company }}",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.message).toEndWith("https://example.com")
|
expect(result.steps[0].outputs.message).toEndWith("https://example.com")
|
||||||
expect(result.steps[1].outputs.message).toEndWith(
|
expect(result.steps[1].outputs.message).toEndWith(
|
||||||
|
|
|
@ -24,8 +24,8 @@ describe("Branching automations", () => {
|
||||||
const branch2LogId = "33333333-3333-3333-3333-333333333333"
|
const branch2LogId = "33333333-3333-3333-3333-333333333333"
|
||||||
const branch2Id = "44444444-4444-4444-4444-444444444444"
|
const branch2Id = "44444444-4444-4444-4444-444444444444"
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Starting automation" },
|
{ text: "Starting automation" },
|
||||||
{ stepName: "FirstLog", stepId: firstLogId }
|
{ stepName: "FirstLog", stepId: firstLogId }
|
||||||
|
@ -76,15 +76,15 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[3].outputs.status).toContain("branch1 branch taken")
|
expect(results.steps[3].outputs.status).toContain("branch1 branch taken")
|
||||||
expect(results.steps[4].outputs.message).toContain("Branch 1.1")
|
expect(results.steps[4].outputs.message).toContain("Branch 1.1")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should execute correct branch based on string equality", async () => {
|
it("should execute correct branch based on string equality", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { status: "active" } })
|
.onAppAction()
|
||||||
.branch({
|
.branch({
|
||||||
activeBranch: {
|
activeBranch: {
|
||||||
steps: stepBuilder => stepBuilder.serverLog({ text: "Active user" }),
|
steps: stepBuilder => stepBuilder.serverLog({ text: "Active user" }),
|
||||||
|
@ -100,7 +100,7 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { status: "active" } })
|
||||||
expect(results.steps[0].outputs.status).toContain(
|
expect(results.steps[0].outputs.status).toContain(
|
||||||
"activeBranch branch taken"
|
"activeBranch branch taken"
|
||||||
)
|
)
|
||||||
|
@ -108,8 +108,8 @@ describe("Branching automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle multiple conditions with AND operator", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.branch({
|
.branch({
|
||||||
activeAdminBranch: {
|
activeAdminBranch: {
|
||||||
steps: stepBuilder =>
|
steps: stepBuilder =>
|
||||||
|
@ -130,14 +130,14 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { status: "active", role: "admin" } })
|
||||||
|
|
||||||
expect(results.steps[1].outputs.message).toContain("Active admin user")
|
expect(results.steps[1].outputs.message).toContain("Active admin user")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle multiple conditions with OR operator", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.branch({
|
.branch({
|
||||||
specialBranch: {
|
specialBranch: {
|
||||||
steps: stepBuilder => stepBuilder.serverLog({ text: "Special user" }),
|
steps: stepBuilder => stepBuilder.serverLog({ text: "Special user" }),
|
||||||
|
@ -162,14 +162,14 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { status: "test", role: "user" } })
|
||||||
|
|
||||||
expect(results.steps[1].outputs.message).toContain("Special user")
|
expect(results.steps[1].outputs.message).toContain("Special user")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should stop the branch automation when no conditions are met", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.createRow({ row: { name: "Test", tableId: table._id } })
|
.createRow({ row: { name: "Test", tableId: table._id } })
|
||||||
.branch({
|
.branch({
|
||||||
specialBranch: {
|
specialBranch: {
|
||||||
|
@ -195,7 +195,7 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { status: "test", role: "user" } })
|
||||||
|
|
||||||
expect(results.steps[1].outputs.status).toEqual(
|
expect(results.steps[1].outputs.status).toEqual(
|
||||||
AutomationStatus.NO_CONDITION_MET
|
AutomationStatus.NO_CONDITION_MET
|
||||||
|
@ -204,8 +204,8 @@ describe("Branching automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("evaluate multiple conditions", async () => {
|
it("evaluate multiple conditions", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { test_trigger: true } })
|
.onAppAction()
|
||||||
.serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" })
|
.serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" })
|
||||||
.branch({
|
.branch({
|
||||||
specialBranch: {
|
specialBranch: {
|
||||||
|
@ -239,14 +239,14 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { test_trigger: true } })
|
||||||
|
|
||||||
expect(results.steps[2].outputs.message).toContain("Special user")
|
expect(results.steps[2].outputs.message).toContain("Special user")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("evaluate multiple conditions with interpolated text", async () => {
|
it("evaluate multiple conditions with interpolated text", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { test_trigger: true } })
|
.onAppAction()
|
||||||
.serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" })
|
.serverLog({ text: "Starting automation" }, { stepId: "aN6znRYHG" })
|
||||||
.branch({
|
.branch({
|
||||||
specialBranch: {
|
specialBranch: {
|
||||||
|
@ -276,7 +276,7 @@ describe("Branching automations", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { test_trigger: true } })
|
||||||
|
|
||||||
expect(results.steps[2].outputs.message).toContain("Special user")
|
expect(results.steps[2].outputs.message).toContain("Special user")
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,47 +21,44 @@ describe("Execute Script Automations", () => {
|
||||||
afterAll(setup.afterAll)
|
afterAll(setup.afterAll)
|
||||||
|
|
||||||
it("should execute a basic script and return the result", async () => {
|
it("should execute a basic script and return the result", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Basic Script Execution"
|
||||||
name: "Basic Script Execution",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScriptV2({ code: encodeJS("return 2 + 2") })
|
.executeScriptV2({ code: encodeJS("return 2 + 2") })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual(4)
|
expect(results.steps[0].outputs.value).toEqual(4)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should access bindings from previous steps", async () => {
|
it("should access bindings from previous steps", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Access Bindings"
|
||||||
name: "Access Bindings",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: { data: [1, 2, 3] } })
|
.onAppAction()
|
||||||
.executeScriptV2(
|
.executeScriptV2(
|
||||||
{
|
{
|
||||||
code: encodeJS(`return $("trigger.fields.data").map(x => x * 2)`),
|
code: encodeJS(`return $("trigger.fields.data").map(x => x * 2)`),
|
||||||
},
|
},
|
||||||
{ stepId: "binding-script-step" }
|
{ stepId: "binding-script-step" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { data: [1, 2, 3] } })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual([2, 4, 6])
|
expect(results.steps[0].outputs.value).toEqual([2, 4, 6])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle script execution errors gracefully", async () => {
|
it("should handle script execution errors gracefully", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Handle Script Errors"
|
||||||
name: "Handle Script Errors",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScriptV2({
|
.executeScriptV2({
|
||||||
code: encodeJS("return nonexistentVariable.map(x => x)"),
|
code: encodeJS("return nonexistentVariable.map(x => x)"),
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.response).toContain(
|
expect(results.steps[0].outputs.response).toContain(
|
||||||
"ReferenceError: nonexistentVariable is not defined"
|
"ReferenceError: nonexistentVariable is not defined"
|
||||||
|
@ -70,12 +67,11 @@ describe("Execute Script Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle conditional logic in scripts", async () => {
|
it("should handle conditional logic in scripts", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Conditional Script Logic"
|
||||||
name: "Conditional Script Logic",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: { value: 10 } })
|
.onAppAction()
|
||||||
.executeScriptV2({
|
.executeScriptV2({
|
||||||
code: encodeJS(`
|
code: encodeJS(`
|
||||||
if ($("trigger.fields.value") > 5) {
|
if ($("trigger.fields.value") > 5) {
|
||||||
|
@ -85,18 +81,17 @@ describe("Execute Script Automations", () => {
|
||||||
}
|
}
|
||||||
`),
|
`),
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { value: 10 } })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual("Value is greater than 5")
|
expect(results.steps[0].outputs.value).toEqual("Value is greater than 5")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should use multiple steps and validate script execution", async () => {
|
it("should use multiple steps and validate script execution", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Multi-Step Script Execution"
|
||||||
name: "Multi-Step Script Execution",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Starting multi-step automation" },
|
{ text: "Starting multi-step automation" },
|
||||||
{ stepId: "start-log-step" }
|
{ stepId: "start-log-step" }
|
||||||
|
@ -117,7 +112,7 @@ describe("Execute Script Automations", () => {
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: `Final result is {{ steps.ScriptingStep1.value }}`,
|
text: `Final result is {{ steps.ScriptingStep1.value }}`,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.message).toContain(
|
expect(results.steps[0].outputs.message).toContain(
|
||||||
"Starting multi-step automation"
|
"Starting multi-step automation"
|
||||||
|
@ -128,16 +123,15 @@ describe("Execute Script Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should fail if the code has not been encoded as a handlebars template", async () => {
|
it("should fail if the code has not been encoded as a handlebars template", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Invalid Code Encoding"
|
||||||
name: "Invalid Code Encoding",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScriptV2({
|
.executeScriptV2({
|
||||||
code: "return 2 + 2",
|
code: "return 2 + 2",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.response.message).toEqual(
|
expect(results.steps[0].outputs.response.message).toEqual(
|
||||||
"Expected code to be a {{ js }} template block"
|
"Expected code to be a {{ js }} template block"
|
||||||
|
@ -146,16 +140,15 @@ describe("Execute Script Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("does not process embedded handlebars templates", async () => {
|
it("does not process embedded handlebars templates", async () => {
|
||||||
const builder = createAutomationBuilder({
|
config.name = "Embedded Handlebars"
|
||||||
name: "Embedded Handlebars",
|
const builder = createAutomationBuilder(config)
|
||||||
})
|
|
||||||
|
|
||||||
const results = await builder
|
const results = await builder
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScriptV2({
|
.executeScriptV2({
|
||||||
code: encodeJS(`return "{{ triggers.row.whatever }}"`),
|
code: encodeJS(`return "{{ triggers.row.whatever }}"`),
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual(
|
expect(results.steps[0].outputs.value).toEqual(
|
||||||
"{{ triggers.row.whatever }}"
|
"{{ triggers.row.whatever }}"
|
||||||
|
|
|
@ -29,14 +29,8 @@ describe("Automation Scenarios", () => {
|
||||||
it("should trigger an automation which then creates a row", async () => {
|
it("should trigger an automation which then creates a row", async () => {
|
||||||
const table = await config.api.table.save(basicTable())
|
const table = await config.api.table.save(basicTable())
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.rowUpdated(
|
.onRowUpdated({ tableId: table._id! })
|
||||||
{ tableId: table._id! },
|
|
||||||
{
|
|
||||||
row: { name: "Test", description: "TEST" },
|
|
||||||
id: "1234",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.createRow({
|
.createRow({
|
||||||
row: {
|
row: {
|
||||||
name: "{{trigger.row.name}}",
|
name: "{{trigger.row.name}}",
|
||||||
|
@ -44,7 +38,10 @@ describe("Automation Scenarios", () => {
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({
|
||||||
|
row: { name: "Test", description: "TEST" },
|
||||||
|
id: "1234",
|
||||||
|
})
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(1)
|
expect(results.steps).toHaveLength(1)
|
||||||
|
|
||||||
|
@ -65,12 +62,12 @@ describe("Automation Scenarios", () => {
|
||||||
}
|
}
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(1)
|
expect(results.steps).toHaveLength(1)
|
||||||
expect(results.steps[0].outputs.rows).toHaveLength(2)
|
expect(results.steps[0].outputs.rows).toHaveLength(2)
|
||||||
|
@ -84,8 +81,8 @@ describe("Automation Scenarios", () => {
|
||||||
}
|
}
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
|
@ -96,7 +93,7 @@ describe("Automation Scenarios", () => {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(3)
|
expect(results.steps).toHaveLength(3)
|
||||||
expect(results.steps[1].outputs.success).toBeTruthy()
|
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||||
|
@ -126,8 +123,8 @@ describe("Automation Scenarios", () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.createRow(
|
.createRow(
|
||||||
{
|
{
|
||||||
row: {
|
row: {
|
||||||
|
@ -156,7 +153,7 @@ describe("Automation Scenarios", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "QueryRowsStep" }
|
{ stepName: "QueryRowsStep" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(3)
|
expect(results.steps).toHaveLength(3)
|
||||||
|
|
||||||
|
@ -195,8 +192,8 @@ describe("Automation Scenarios", () => {
|
||||||
}
|
}
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
await config.api.row.save(table._id!, row)
|
await config.api.row.save(table._id!, row)
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -210,7 +207,7 @@ describe("Automation Scenarios", () => {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(3)
|
expect(results.steps).toHaveLength(3)
|
||||||
expect(results.steps[1].outputs.success).toBeTruthy()
|
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||||
|
@ -245,8 +242,8 @@ describe("Automation Scenarios", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should stop an automation if the condition is not met", async () => {
|
it("should stop an automation if the condition is not met", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.createRow({
|
.createRow({
|
||||||
row: {
|
row: {
|
||||||
name: "Equal Test",
|
name: "Equal Test",
|
||||||
|
@ -263,7 +260,7 @@ describe("Automation Scenarios", () => {
|
||||||
value: 20,
|
value: 20,
|
||||||
})
|
})
|
||||||
.serverLog({ text: "Equal condition met" })
|
.serverLog({ text: "Equal condition met" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[2].outputs.success).toBeTrue()
|
expect(results.steps[2].outputs.success).toBeTrue()
|
||||||
expect(results.steps[2].outputs.result).toBeFalse()
|
expect(results.steps[2].outputs.result).toBeFalse()
|
||||||
|
@ -271,8 +268,8 @@ describe("Automation Scenarios", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should continue the automation if the condition is met", async () => {
|
it("should continue the automation if the condition is met", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.createRow({
|
.createRow({
|
||||||
row: {
|
row: {
|
||||||
name: "Not Equal Test",
|
name: "Not Equal Test",
|
||||||
|
@ -289,7 +286,7 @@ describe("Automation Scenarios", () => {
|
||||||
value: 20,
|
value: 20,
|
||||||
})
|
})
|
||||||
.serverLog({ text: "Not Equal condition met" })
|
.serverLog({ text: "Not Equal condition met" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[2].outputs.success).toBeTrue()
|
expect(results.steps[2].outputs.success).toBeTrue()
|
||||||
expect(results.steps[2].outputs.result).toBeTrue()
|
expect(results.steps[2].outputs.result).toBeTrue()
|
||||||
|
@ -338,8 +335,8 @@ describe("Automation Scenarios", () => {
|
||||||
it.each(testCases)(
|
it.each(testCases)(
|
||||||
"should pass the filter when condition is $condition",
|
"should pass the filter when condition is $condition",
|
||||||
async ({ condition, value, rowValue, expectPass }) => {
|
async ({ condition, value, rowValue, expectPass }) => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.createRow({
|
.createRow({
|
||||||
row: {
|
row: {
|
||||||
name: `${condition} Test`,
|
name: `${condition} Test`,
|
||||||
|
@ -358,7 +355,7 @@ describe("Automation Scenarios", () => {
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: `${condition} condition ${expectPass ? "passed" : "failed"}`,
|
text: `${condition} condition ${expectPass ? "passed" : "failed"}`,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[2].outputs.result).toBe(expectPass)
|
expect(results.steps[2].outputs.result).toBe(expectPass)
|
||||||
if (expectPass) {
|
if (expectPass) {
|
||||||
|
@ -373,25 +370,22 @@ describe("Automation Scenarios", () => {
|
||||||
it("Check user is passed through from row trigger", async () => {
|
it("Check user is passed through from row trigger", async () => {
|
||||||
const table = await config.api.table.save(basicTable())
|
const table = await config.api.table.save(basicTable())
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.rowUpdated(
|
.onRowUpdated({ tableId: table._id! })
|
||||||
{ tableId: table._id! },
|
|
||||||
{
|
|
||||||
row: { name: "Test", description: "TEST" },
|
|
||||||
id: "1234",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.serverLog({ text: "{{ [user].[email] }}" })
|
.serverLog({ text: "{{ [user].[email] }}" })
|
||||||
.run()
|
.test({
|
||||||
|
row: { name: "Test", description: "TEST" },
|
||||||
|
id: "1234",
|
||||||
|
})
|
||||||
|
|
||||||
expect(results.steps[0].outputs.message).toContain("example.com")
|
expect(results.steps[0].outputs.message).toContain("example.com")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Check user is passed through from app trigger", async () => {
|
it("Check user is passed through from app trigger", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog({ text: "{{ [user].[email] }}" })
|
.serverLog({ text: "{{ [user].[email] }}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.message).toContain("example.com")
|
expect(results.steps[0].outputs.message).toContain("example.com")
|
||||||
})
|
})
|
||||||
|
@ -460,10 +454,8 @@ if (descriptions.length) {
|
||||||
queryVerb: "read",
|
queryVerb: "read",
|
||||||
})
|
})
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({
|
.onAppAction()
|
||||||
fields: {},
|
|
||||||
})
|
|
||||||
.executeQuery({
|
.executeQuery({
|
||||||
query: {
|
query: {
|
||||||
queryId: query._id!,
|
queryId: query._id!,
|
||||||
|
@ -483,7 +475,7 @@ if (descriptions.length) {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: newTable._id!,
|
tableId: newTable._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(3)
|
expect(results.steps).toHaveLength(3)
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ describe("Execute Bash Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should use trigger data in bash command and pass output to subsequent steps", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.bash(
|
.bash(
|
||||||
{ code: "echo '{{ trigger.fields.command }}'" },
|
{ code: "echo '{{ trigger.fields.command }}'" },
|
||||||
{ stepName: "Echo Command" }
|
{ stepName: "Echo Command" }
|
||||||
|
@ -34,7 +34,7 @@ describe("Execute Bash Automations", () => {
|
||||||
{ text: "Bash output was: {{ steps.[Echo Command].stdout }}" },
|
{ text: "Bash output was: {{ steps.[Echo Command].stdout }}" },
|
||||||
{ stepName: "Log Output" }
|
{ stepName: "Log Output" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { command: "hello world" } })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.stdout).toEqual("hello world\n")
|
expect(result.steps[0].outputs.stdout).toEqual("hello world\n")
|
||||||
expect(result.steps[1].outputs.message).toContain(
|
expect(result.steps[1].outputs.message).toContain(
|
||||||
|
@ -43,8 +43,8 @@ describe("Execute Bash Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should chain multiple bash commands using previous outputs", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.bash(
|
.bash(
|
||||||
{ code: "echo 'initial content' > {{ trigger.fields.filename }}" },
|
{ code: "echo 'initial content' > {{ trigger.fields.filename }}" },
|
||||||
{ stepName: "Create File" }
|
{ stepName: "Create File" }
|
||||||
|
@ -57,15 +57,15 @@ describe("Execute Bash Automations", () => {
|
||||||
{ code: "rm {{ trigger.fields.filename }}" },
|
{ code: "rm {{ trigger.fields.filename }}" },
|
||||||
{ stepName: "Cleanup" }
|
{ stepName: "Cleanup" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { filename: "testfile.txt" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.stdout).toEqual("INITIAL CONTENT\n")
|
expect(result.steps[1].outputs.stdout).toEqual("INITIAL CONTENT\n")
|
||||||
expect(result.steps[1].outputs.success).toEqual(true)
|
expect(result.steps[1].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should integrate bash output with row operations", async () => {
|
it("should integrate bash output with row operations", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -83,7 +83,7 @@ describe("Execute Bash Automations", () => {
|
||||||
{ text: "{{ steps.[Process Row Data].stdout }}" },
|
{ text: "{{ steps.[Process Row Data].stdout }}" },
|
||||||
{ stepName: "Log Result" }
|
{ stepName: "Log Result" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.stdout).toContain(
|
expect(result.steps[1].outputs.stdout).toContain(
|
||||||
"Row data: test row - test description"
|
"Row data: test row - test description"
|
||||||
|
@ -94,8 +94,8 @@ describe("Execute Bash Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle bash output in conditional logic", async () => {
|
it("should handle bash output in conditional logic", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { threshold: "5" } })
|
.onAppAction()
|
||||||
.bash(
|
.bash(
|
||||||
{ code: "echo $(( {{ trigger.fields.threshold }} + 5 ))" },
|
{ code: "echo $(( {{ trigger.fields.threshold }} + 5 ))" },
|
||||||
{ stepName: "Calculate Value" }
|
{ stepName: "Calculate Value" }
|
||||||
|
@ -113,7 +113,7 @@ describe("Execute Bash Automations", () => {
|
||||||
{ text: "Value was {{ steps.[Check Value].value }}" },
|
{ text: "Value was {{ steps.[Check Value].value }}" },
|
||||||
{ stepName: "Log Result" }
|
{ stepName: "Log Result" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { threshold: "5" } })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.stdout).toEqual("10\n")
|
expect(result.steps[0].outputs.stdout).toEqual("10\n")
|
||||||
expect(result.steps[1].outputs.value).toEqual("high")
|
expect(result.steps[1].outputs.value).toEqual("high")
|
||||||
|
@ -121,14 +121,14 @@ describe("Execute Bash Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle null values gracefully", async () => {
|
it("should handle null values gracefully", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.bash(
|
.bash(
|
||||||
// @ts-expect-error - testing null input
|
// @ts-expect-error - testing null input
|
||||||
{ code: null },
|
{ code: null },
|
||||||
{ stepName: "Null Command" }
|
{ stepName: "Null Command" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.stdout).toBe(
|
expect(result.steps[0].outputs.stdout).toBe(
|
||||||
"Budibase bash automation failed: Invalid inputs"
|
"Budibase bash automation failed: Invalid inputs"
|
||||||
|
|
|
@ -40,15 +40,15 @@ describe("test the create row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to run the action", async () => {
|
it("should be able to run the action", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { status: "new" } })
|
.onAppAction()
|
||||||
.serverLog({ text: "Starting create row flow" }, { stepName: "StartLog" })
|
.serverLog({ text: "Starting create row flow" }, { stepName: "StartLog" })
|
||||||
.createRow({ row }, { stepName: "CreateRow" })
|
.createRow({ row }, { stepName: "CreateRow" })
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Row created with ID: {{ stepsByName.CreateRow.row._id }}" },
|
{ text: "Row created with ID: {{ stepsByName.CreateRow.row._id }}" },
|
||||||
{ stepName: "CreationLog" }
|
{ stepName: "CreationLog" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { status: "new" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toBeDefined()
|
expect(result.steps[1].outputs.success).toBeDefined()
|
||||||
expect(result.steps[1].outputs.id).toBeDefined()
|
expect(result.steps[1].outputs.id).toBeDefined()
|
||||||
|
@ -66,8 +66,8 @@ describe("test the create row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return an error (not throw) when bad info provided", async () => {
|
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" } })
|
.onAppAction()
|
||||||
.serverLog({ text: "Starting error test flow" }, { stepName: "StartLog" })
|
.serverLog({ text: "Starting error test flow" }, { stepName: "StartLog" })
|
||||||
.createRow(
|
.createRow(
|
||||||
{
|
{
|
||||||
|
@ -78,14 +78,14 @@ describe("test the create row action", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "CreateRow" }
|
{ stepName: "CreateRow" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { status: "error" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toEqual(false)
|
expect(result.steps[1].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should check invalid inputs return an error", async () => {
|
it("should check invalid inputs return an error", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { status: "invalid" } })
|
.onAppAction()
|
||||||
.serverLog({ text: "Testing invalid input" }, { stepName: "StartLog" })
|
.serverLog({ text: "Testing invalid input" }, { stepName: "StartLog" })
|
||||||
.createRow({ row: {} }, { stepName: "CreateRow" })
|
.createRow({ row: {} }, { stepName: "CreateRow" })
|
||||||
.filter({
|
.filter({
|
||||||
|
@ -97,7 +97,7 @@ describe("test the create row action", () => {
|
||||||
{ text: "This log should not appear" },
|
{ text: "This log should not appear" },
|
||||||
{ stepName: "SkippedLog" }
|
{ stepName: "SkippedLog" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { status: "invalid" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toEqual(false)
|
expect(result.steps[1].outputs.success).toEqual(false)
|
||||||
expect(result.steps.length).toBeLessThan(4)
|
expect(result.steps.length).toBeLessThan(4)
|
||||||
|
@ -122,8 +122,8 @@ describe("test the create row action", () => {
|
||||||
]
|
]
|
||||||
|
|
||||||
attachmentRow.file_attachment = attachmentObject
|
attachmentRow.file_attachment = attachmentObject
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { type: "attachment" } })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Processing attachment upload" },
|
{ text: "Processing attachment upload" },
|
||||||
{ stepName: "StartLog" }
|
{ stepName: "StartLog" }
|
||||||
|
@ -140,7 +140,7 @@ describe("test the create row action", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "UploadLog" }
|
{ stepName: "UploadLog" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { type: "attachment" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toEqual(true)
|
expect(result.steps[1].outputs.success).toEqual(true)
|
||||||
expect(result.steps[1].outputs.row.file_attachment[0]).toHaveProperty("key")
|
expect(result.steps[1].outputs.row.file_attachment[0]).toHaveProperty("key")
|
||||||
|
@ -173,8 +173,8 @@ describe("test the create row action", () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentRow.single_file_attachment = attachmentObject
|
attachmentRow.single_file_attachment = attachmentObject
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { type: "single-attachment" } })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Processing single attachment" },
|
{ text: "Processing single attachment" },
|
||||||
{ stepName: "StartLog" }
|
{ stepName: "StartLog" }
|
||||||
|
@ -209,7 +209,7 @@ describe("test the create row action", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { type: "single-attachment" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toEqual(true)
|
expect(result.steps[1].outputs.success).toEqual(true)
|
||||||
expect(result.steps[1].outputs.row.single_file_attachment).toHaveProperty(
|
expect(result.steps[1].outputs.row.single_file_attachment).toHaveProperty(
|
||||||
|
@ -244,8 +244,8 @@ describe("test the create row action", () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentRow.single_file_attachment = attachmentObject
|
attachmentRow.single_file_attachment = attachmentObject
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { type: "invalid-attachment" } })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Testing invalid attachment keys" },
|
{ text: "Testing invalid attachment keys" },
|
||||||
{ stepName: "StartLog" }
|
{ stepName: "StartLog" }
|
||||||
|
@ -278,7 +278,7 @@ describe("test the create row action", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { type: "invalid-attachment" } })
|
||||||
|
|
||||||
expect(result.steps[1].outputs.success).toEqual(false)
|
expect(result.steps[1].outputs.success).toEqual(false)
|
||||||
expect(result.steps[1].outputs.response).toEqual(
|
expect(result.steps[1].outputs.response).toEqual(
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe("cron automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should initialise the automation timestamp", async () => {
|
it("should initialise the automation timestamp", async () => {
|
||||||
await createAutomationBuilder({ config }).cron({ cron: "* * * * *" }).save()
|
await createAutomationBuilder(config).onCron({ cron: "* * * * *" }).save()
|
||||||
|
|
||||||
tk.travel(Date.now() + oneMinuteInMs)
|
tk.travel(Date.now() + oneMinuteInMs)
|
||||||
await config.publish()
|
await config.publish()
|
||||||
|
|
|
@ -16,10 +16,10 @@ describe("test the delay logic", () => {
|
||||||
const time = 100
|
const time = 100
|
||||||
const before = performance.now()
|
const before = performance.now()
|
||||||
|
|
||||||
await createAutomationBuilder({ config })
|
await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.delay({ time })
|
.delay({ time })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
const now = performance.now()
|
const now = performance.now()
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,14 @@ describe("test the delete row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to run the delete row action", async () => {
|
it("should be able to run the delete row action", async () => {
|
||||||
await createAutomationBuilder({ config })
|
await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.deleteRow({
|
.deleteRow({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
id: row._id!,
|
id: row._id!,
|
||||||
revision: row._rev,
|
revision: row._rev,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
await config.api.row.get(table._id!, row._id!, {
|
await config.api.row.get(table._id!, row._id!, {
|
||||||
status: 404,
|
status: 404,
|
||||||
|
@ -35,23 +35,23 @@ describe("test the delete row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should check invalid inputs return an error", async () => {
|
it("should check invalid inputs return an error", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.deleteRow({ tableId: "", id: "", revision: "" })
|
.deleteRow({ tableId: "", id: "", revision: "" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(false)
|
expect(results.steps[0].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return an error when table doesn't exist", async () => {
|
it("should return an error when table doesn't exist", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.deleteRow({
|
.deleteRow({
|
||||||
tableId: "invalid",
|
tableId: "invalid",
|
||||||
id: "invalid",
|
id: "invalid",
|
||||||
revision: "invalid",
|
revision: "invalid",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(false)
|
expect(results.steps[0].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,14 +19,14 @@ describe("test the outgoing webhook action", () => {
|
||||||
|
|
||||||
it("should be able to run the action", async () => {
|
it("should be able to run the action", async () => {
|
||||||
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.discord({
|
.discord({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
username: "joe_bloggs",
|
username: "joe_bloggs",
|
||||||
content: "Hello, world",
|
content: "Hello, world",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,33 +20,33 @@ describe("Execute Script Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should execute a basic script and return the result", async () => {
|
it("should execute a basic script and return the result", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScript({ code: "return 2 + 2" })
|
.executeScript({ code: "return 2 + 2" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual(4)
|
expect(results.steps[0].outputs.value).toEqual(4)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should access bindings from previous steps", async () => {
|
it("should access bindings from previous steps", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { data: [1, 2, 3] } })
|
.onAppAction()
|
||||||
.executeScript(
|
.executeScript(
|
||||||
{
|
{
|
||||||
code: "return trigger.fields.data.map(x => x * 2)",
|
code: "return trigger.fields.data.map(x => x * 2)",
|
||||||
},
|
},
|
||||||
{ stepId: "binding-script-step" }
|
{ stepId: "binding-script-step" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: { data: [1, 2, 3] } })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual([2, 4, 6])
|
expect(results.steps[0].outputs.value).toEqual([2, 4, 6])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle script execution errors gracefully", async () => {
|
it("should handle script execution errors gracefully", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.executeScript({ code: "return nonexistentVariable.map(x => x)" })
|
.executeScript({ code: "return nonexistentVariable.map(x => x)" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.response).toContain(
|
expect(results.steps[0].outputs.response).toContain(
|
||||||
"ReferenceError: nonexistentVariable is not defined"
|
"ReferenceError: nonexistentVariable is not defined"
|
||||||
|
@ -55,8 +55,8 @@ describe("Execute Script Automations", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle conditional logic in scripts", async () => {
|
it("should handle conditional logic in scripts", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: { value: 10 } })
|
.onAppAction()
|
||||||
.executeScript({
|
.executeScript({
|
||||||
code: `
|
code: `
|
||||||
if (trigger.fields.value > 5) {
|
if (trigger.fields.value > 5) {
|
||||||
|
@ -66,14 +66,14 @@ describe("Execute Script Automations", () => {
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: { value: 10 } })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.value).toEqual("Value is greater than 5")
|
expect(results.steps[0].outputs.value).toEqual("Value is greater than 5")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should use multiple steps and validate script execution", async () => {
|
it("should use multiple steps and validate script execution", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog(
|
.serverLog(
|
||||||
{ text: "Starting multi-step automation" },
|
{ text: "Starting multi-step automation" },
|
||||||
{ stepId: "start-log-step" }
|
{ stepId: "start-log-step" }
|
||||||
|
@ -94,7 +94,7 @@ describe("Execute Script Automations", () => {
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: `Final result is {{ steps.ScriptingStep1.value }}`,
|
text: `Final result is {{ steps.ScriptingStep1.value }}`,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.message).toContain(
|
expect(results.steps[0].outputs.message).toContain(
|
||||||
"Starting multi-step automation"
|
"Starting multi-step automation"
|
||||||
|
|
|
@ -42,10 +42,10 @@ describe("test the filter logic", () => {
|
||||||
[new Date().toISOString(), ">", new Date(-10000).toISOString()],
|
[new Date().toISOString(), ">", new Date(-10000).toISOString()],
|
||||||
]
|
]
|
||||||
it.each(pass)("should pass %p %p %p", async (field, condition, value) => {
|
it.each(pass)("should pass %p %p %p", async (field, condition, value) => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.filter({ field, condition: stringToFilterCondition(condition), value })
|
.filter({ field, condition: stringToFilterCondition(condition), value })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.result).toEqual(true)
|
expect(result.steps[0].outputs.result).toEqual(true)
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
|
@ -60,10 +60,10 @@ describe("test the filter logic", () => {
|
||||||
[{}, "==", {}],
|
[{}, "==", {}],
|
||||||
]
|
]
|
||||||
it.each(fail)("should fail %p %p %p", async (field, condition, value) => {
|
it.each(fail)("should fail %p %p %p", async (field, condition, value) => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.filter({ field, condition: stringToFilterCondition(condition), value })
|
.filter({ field, condition: stringToFilterCondition(condition), value })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.result).toEqual(false)
|
expect(result.steps[0].outputs.result).toEqual(false)
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
|
|
|
@ -72,18 +72,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should run an automation with a trigger, loop, and create row step", async () => {
|
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(
|
.onRowSaved({ tableId: table._id! })
|
||||||
{ tableId: table._id! },
|
|
||||||
{
|
|
||||||
row: {
|
|
||||||
name: "Trigger Row",
|
|
||||||
description: "This row triggers the automation",
|
|
||||||
},
|
|
||||||
id: "1234",
|
|
||||||
revision: "1",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: [1, 2, 3],
|
binding: [1, 2, 3],
|
||||||
|
@ -95,7 +85,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({
|
||||||
|
row: {
|
||||||
|
name: "Trigger Row",
|
||||||
|
description: "This row triggers the automation",
|
||||||
|
},
|
||||||
|
id: "1234",
|
||||||
|
revision: "1",
|
||||||
|
})
|
||||||
|
|
||||||
expect(results.trigger).toBeDefined()
|
expect(results.trigger).toBeDefined()
|
||||||
expect(results.steps).toHaveLength(1)
|
expect(results.steps).toHaveLength(1)
|
||||||
|
@ -115,18 +112,8 @@ 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 () => {
|
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(
|
.onRowSaved({ tableId: table._id! })
|
||||||
{ tableId: table._id! },
|
|
||||||
{
|
|
||||||
row: {
|
|
||||||
name: "Trigger Row",
|
|
||||||
description: "This row triggers the automation",
|
|
||||||
},
|
|
||||||
id: "1234",
|
|
||||||
revision: "1",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
|
@ -136,7 +123,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
.serverLog({ text: "Message {{loop.currentItem}}" })
|
.serverLog({ text: "Message {{loop.currentItem}}" })
|
||||||
.serverLog({ text: "{{steps.1.rows.0._id}}" })
|
.serverLog({ text: "{{steps.1.rows.0._id}}" })
|
||||||
.run()
|
.test({
|
||||||
|
row: {
|
||||||
|
name: "Trigger Row",
|
||||||
|
description: "This row triggers the automation",
|
||||||
|
},
|
||||||
|
id: "1234",
|
||||||
|
revision: "1",
|
||||||
|
})
|
||||||
|
|
||||||
results.steps[1].outputs.items.forEach(
|
results.steps[1].outputs.items.forEach(
|
||||||
(output: ServerLogStepOutputs, index: number) => {
|
(output: ServerLogStepOutputs, index: number) => {
|
||||||
|
@ -151,14 +145,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("if an incorrect type is passed to the loop it should return an error", async () => {
|
it("if an incorrect type is passed to the loop it should return an error", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: "1, 2, 3",
|
binding: "1, 2, 3",
|
||||||
})
|
})
|
||||||
.serverLog({ text: "Message {{loop.currentItem}}" })
|
.serverLog({ text: "Message {{loop.currentItem}}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs).toEqual({
|
expect(results.steps[0].outputs).toEqual({
|
||||||
success: false,
|
success: false,
|
||||||
|
@ -167,15 +161,15 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("ensure the loop stops if the failure condition is reached", async () => {
|
it("ensure the loop stops if the failure condition is reached", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: ["test", "test2", "test3"],
|
binding: ["test", "test2", "test3"],
|
||||||
failure: "test2",
|
failure: "test2",
|
||||||
})
|
})
|
||||||
.serverLog({ text: "Message {{loop.currentItem}}" })
|
.serverLog({ text: "Message {{loop.currentItem}}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs).toEqual(
|
expect(results.steps[0].outputs).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
|
@ -186,8 +180,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("ensure the loop stops if the max iterations are reached", async () => {
|
it("ensure the loop stops if the max iterations are reached", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: ["test", "test2", "test3"],
|
binding: ["test", "test2", "test3"],
|
||||||
|
@ -195,14 +189,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
.serverLog({ text: "{{loop.currentItem}}" })
|
.serverLog({ text: "{{loop.currentItem}}" })
|
||||||
.serverLog({ text: "{{steps.1.iterations}}" })
|
.serverLog({ text: "{{steps.1.iterations}}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.iterations).toBe(2)
|
expect(results.steps[0].outputs.iterations).toBe(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should run an automation with loop and max iterations to ensure context correctness further down the tree", async () => {
|
it("should run an automation with loop and max iterations to ensure context correctness further down the tree", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: ["test", "test2", "test3"],
|
binding: ["test", "test2", "test3"],
|
||||||
|
@ -210,24 +204,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
.serverLog({ text: "{{loop.currentItem}}" })
|
.serverLog({ text: "{{loop.currentItem}}" })
|
||||||
.serverLog({ text: "{{steps.1.iterations}}" })
|
.serverLog({ text: "{{steps.1.iterations}}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[1].outputs.message).toContain("- 2")
|
expect(results.steps[1].outputs.message).toContain("- 2")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should run an automation where a loop is successfully run twice", async () => {
|
it("should run an automation where a loop is successfully run twice", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.rowSaved(
|
.onRowSaved({ tableId: table._id! })
|
||||||
{ tableId: table._id! },
|
|
||||||
{
|
|
||||||
row: {
|
|
||||||
name: "Trigger Row",
|
|
||||||
description: "This row triggers the automation",
|
|
||||||
},
|
|
||||||
id: "1234",
|
|
||||||
revision: "1",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: [1, 2, 3],
|
binding: [1, 2, 3],
|
||||||
|
@ -244,7 +228,14 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
binding: "Message 1,Message 2,Message 3",
|
binding: "Message 1,Message 2,Message 3",
|
||||||
})
|
})
|
||||||
.serverLog({ text: "{{loop.currentItem}}" })
|
.serverLog({ text: "{{loop.currentItem}}" })
|
||||||
.run()
|
.test({
|
||||||
|
row: {
|
||||||
|
name: "Trigger Row",
|
||||||
|
description: "This row triggers the automation",
|
||||||
|
},
|
||||||
|
id: "1234",
|
||||||
|
revision: "1",
|
||||||
|
})
|
||||||
|
|
||||||
expect(results.trigger).toBeDefined()
|
expect(results.trigger).toBeDefined()
|
||||||
expect(results.steps).toHaveLength(2)
|
expect(results.steps).toHaveLength(2)
|
||||||
|
@ -278,8 +269,8 @@ 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 () => {
|
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 })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop({
|
.loop({
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
binding: [1, 2, 3],
|
binding: [1, 2, 3],
|
||||||
|
@ -292,7 +283,7 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
.serverLog({ text: "{{loop.currentItem}}" })
|
.serverLog({ text: "{{loop.currentItem}}" })
|
||||||
.serverLog({ text: "{{steps.3.iterations}}" })
|
.serverLog({ text: "{{steps.3.iterations}}" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
// We want to ensure that bindings are corr
|
// We want to ensure that bindings are corr
|
||||||
expect(results.steps[1].outputs.message).toContain("- 3")
|
expect(results.steps[1].outputs.message).toContain("- 3")
|
||||||
|
@ -300,8 +291,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should use automation names to loop with", async () => {
|
it("should use automation names to loop with", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.loop(
|
.loop(
|
||||||
{
|
{
|
||||||
option: LoopStepType.ARRAY,
|
option: LoopStepType.ARRAY,
|
||||||
|
@ -317,7 +308,7 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
{ text: "{{steps.FirstLoopLog.iterations}}" },
|
{ text: "{{steps.FirstLoopLog.iterations}}" },
|
||||||
{ stepName: "FirstLoopIterationLog" }
|
{ stepName: "FirstLoopIterationLog" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[1].outputs.message).toContain("- 3")
|
expect(results.steps[1].outputs.message).toContain("- 3")
|
||||||
})
|
})
|
||||||
|
@ -352,8 +343,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
|
|
||||||
await config.api.row.bulkImport(table._id!, { rows })
|
await config.api.row.bulkImport(table._id!, { rows })
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
|
@ -373,7 +364,7 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
const expectedRows = [
|
const expectedRows = [
|
||||||
{ name: "Updated Row 1", value: 1 },
|
{ name: "Updated Row 1", value: 1 },
|
||||||
|
@ -432,8 +423,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
|
|
||||||
await config.api.row.bulkImport(table._id!, { rows })
|
await config.api.row.bulkImport(table._id!, { rows })
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -456,7 +447,7 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
const expectedRows = [
|
const expectedRows = [
|
||||||
{ name: "Updated Row 1", value: 1 },
|
{ name: "Updated Row 1", value: 1 },
|
||||||
|
@ -515,8 +506,8 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
|
|
||||||
await config.api.row.bulkImport(table._id!, { rows })
|
await config.api.row.bulkImport(table._id!, { rows })
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
|
@ -531,7 +522,7 @@ describe("Attempt to run a basic loop automation", () => {
|
||||||
.queryRows({
|
.queryRows({
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps).toHaveLength(3)
|
expect(results.steps).toHaveLength(3)
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,13 @@ describe("test the outgoing webhook action", () => {
|
||||||
|
|
||||||
it("should be able to run the action", async () => {
|
it("should be able to run the action", async () => {
|
||||||
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.make({
|
.make({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: null,
|
body: null,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
|
@ -46,26 +46,26 @@ describe("test the outgoing webhook action", () => {
|
||||||
.post("/", payload)
|
.post("/", payload)
|
||||||
.reply(200, { foo: "bar" })
|
.reply(200, { foo: "bar" })
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.make({
|
.make({
|
||||||
body: { value: JSON.stringify(payload) },
|
body: { value: JSON.stringify(payload) },
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return a 400 if the JSON payload string is malformed", async () => {
|
it("should return a 400 if the JSON payload string is malformed", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.make({
|
.make({
|
||||||
body: { value: "{ invalid json }" },
|
body: { value: "{ invalid json }" },
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.httpStatus).toEqual(400)
|
expect(result.steps[0].outputs.httpStatus).toEqual(400)
|
||||||
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
||||||
|
|
|
@ -20,14 +20,14 @@ describe("test the outgoing webhook action", () => {
|
||||||
|
|
||||||
it("should be able to run the action and default to 'get'", async () => {
|
it("should be able to run the action and default to 'get'", async () => {
|
||||||
nock("http://www.example.com/").get("/").reply(200, { foo: "bar" })
|
nock("http://www.example.com/").get("/").reply(200, { foo: "bar" })
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.n8n({
|
.n8n({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: { test: "IGNORE_ME" },
|
body: { test: "IGNORE_ME" },
|
||||||
authorization: "",
|
authorization: "",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response).toEqual({ foo: "bar" })
|
expect(result.steps[0].outputs.response).toEqual({ foo: "bar" })
|
||||||
expect(result.steps[0].outputs.httpStatus).toEqual(200)
|
expect(result.steps[0].outputs.httpStatus).toEqual(200)
|
||||||
|
@ -39,29 +39,29 @@ describe("test the outgoing webhook action", () => {
|
||||||
.post("/", { name: "Adam", age: 9 })
|
.post("/", { name: "Adam", age: 9 })
|
||||||
.reply(200)
|
.reply(200)
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.n8n({
|
.n8n({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: { value: JSON.stringify({ name: "Adam", age: 9 }) },
|
body: { value: JSON.stringify({ name: "Adam", age: 9 }) },
|
||||||
method: HttpMethod.POST,
|
method: HttpMethod.POST,
|
||||||
authorization: "",
|
authorization: "",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return a 400 if the JSON payload string is malformed", async () => {
|
it("should return a 400 if the JSON payload string is malformed", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.n8n({
|
.n8n({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: { value: "{ value1 1 }" },
|
body: { value: "{ value1 1 }" },
|
||||||
method: HttpMethod.POST,
|
method: HttpMethod.POST,
|
||||||
authorization: "",
|
authorization: "",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.httpStatus).toEqual(400)
|
expect(result.steps[0].outputs.httpStatus).toEqual(400)
|
||||||
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
||||||
|
@ -73,15 +73,15 @@ describe("test the outgoing webhook action", () => {
|
||||||
.head("/", body => body === "")
|
.head("/", body => body === "")
|
||||||
.reply(200)
|
.reply(200)
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.n8n({
|
.n8n({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
method: HttpMethod.HEAD,
|
method: HttpMethod.HEAD,
|
||||||
body: { test: "IGNORE_ME" },
|
body: { test: "IGNORE_ME" },
|
||||||
authorization: "",
|
authorization: "",
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,10 +57,10 @@ describe("test the openai action", () => {
|
||||||
// means it goes through the "legacy" path which requires you to set your
|
// means it goes through the "legacy" path which requires you to set your
|
||||||
// own API key. We don't count this against your quota.
|
// own API key. We don't count this against your quota.
|
||||||
const result = await expectAIUsage(0, () =>
|
const result = await expectAIUsage(0, () =>
|
||||||
createAutomationBuilder({ config })
|
createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI })
|
.openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response).toEqual("This is a test")
|
expect(result.steps[0].outputs.response).toEqual("This is a test")
|
||||||
|
@ -69,10 +69,10 @@ describe("test the openai action", () => {
|
||||||
|
|
||||||
it("should present the correct error message when a prompt is not provided", async () => {
|
it("should present the correct error message when a prompt is not provided", async () => {
|
||||||
const result = await expectAIUsage(0, () =>
|
const result = await expectAIUsage(0, () =>
|
||||||
createAutomationBuilder({ config })
|
createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.openai({ prompt: "", model: Model.GPT_4O_MINI })
|
.openai({ prompt: "", model: Model.GPT_4O_MINI })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response).toEqual(
|
expect(result.steps[0].outputs.response).toEqual(
|
||||||
|
@ -85,10 +85,10 @@ describe("test the openai action", () => {
|
||||||
mockChatGPTError()
|
mockChatGPTError()
|
||||||
|
|
||||||
const result = await expectAIUsage(0, () =>
|
const result = await expectAIUsage(0, () =>
|
||||||
createAutomationBuilder({ config })
|
createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI })
|
.openai({ prompt: "Hello, world", model: Model.GPT_4O_MINI })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response).toEqual(
|
expect(result.steps[0].outputs.response).toEqual(
|
||||||
|
@ -108,10 +108,10 @@ describe("test the openai action", () => {
|
||||||
// calculation we use to approximate cost. This uses Budibase's OpenAI API
|
// calculation we use to approximate cost. This uses Budibase's OpenAI API
|
||||||
// key, so we charge users for it.
|
// key, so we charge users for it.
|
||||||
const result = await expectAIUsage(14, () =>
|
const result = await expectAIUsage(14, () =>
|
||||||
createAutomationBuilder({ config })
|
createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.openai({ model: Model.GPT_4O_MINI, prompt: "Hello, world" })
|
.openai({ model: Model.GPT_4O_MINI, prompt: "Hello, world" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response).toEqual("This is a test")
|
expect(result.steps[0].outputs.response).toEqual("This is a test")
|
||||||
|
|
|
@ -23,15 +23,15 @@ describe("test the outgoing webhook action", () => {
|
||||||
.post("/", { a: 1 })
|
.post("/", { a: 1 })
|
||||||
.reply(200, { foo: "bar" })
|
.reply(200, { foo: "bar" })
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.outgoingWebhook({
|
.outgoingWebhook({
|
||||||
requestMethod: RequestType.POST,
|
requestMethod: RequestType.POST,
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
requestBody: JSON.stringify({ a: 1 }),
|
requestBody: JSON.stringify({ a: 1 }),
|
||||||
headers: {},
|
headers: {},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
expect(result.steps[0].outputs.httpStatus).toEqual(200)
|
expect(result.steps[0].outputs.httpStatus).toEqual(200)
|
||||||
|
@ -39,15 +39,15 @@ describe("test the outgoing webhook action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return an error if something goes wrong in fetch", async () => {
|
it("should return an error if something goes wrong in fetch", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.outgoingWebhook({
|
.outgoingWebhook({
|
||||||
requestMethod: RequestType.GET,
|
requestMethod: RequestType.GET,
|
||||||
url: "www.invalid.com",
|
url: "www.invalid.com",
|
||||||
requestBody: "",
|
requestBody: "",
|
||||||
headers: {},
|
headers: {},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
expect(result.steps[0].outputs.success).toEqual(false)
|
expect(result.steps[0].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,11 +28,8 @@ describe("Test a query step automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to run the query step", async () => {
|
it("should be able to run the query step", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Basic Query Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -47,7 +44,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query All Rows" }
|
{ stepName: "Query All Rows" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
|
@ -56,11 +53,8 @@ describe("Test a query step automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Returns all rows when onEmptyFilter has no value and no filters are passed", async () => {
|
it("Returns all rows when onEmptyFilter has no value and no filters are passed", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Empty Filter Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -71,7 +65,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query With Empty Filter" }
|
{ stepName: "Query With Empty Filter" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
|
@ -80,11 +74,8 @@ describe("Test a query step automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Returns no rows when onEmptyFilter is RETURN_NONE and theres no filters", async () => {
|
it("Returns no rows when onEmptyFilter is RETURN_NONE and theres no filters", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Return None Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -97,7 +88,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query With Return None" }
|
{ stepName: "Query With Return None" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
|
@ -105,11 +96,8 @@ describe("Test a query step automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Returns no rows when onEmptyFilters RETURN_NONE and a filter is passed with a null value", async () => {
|
it("Returns no rows when onEmptyFilters RETURN_NONE and a filter is passed with a null value", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Null Filter Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -126,7 +114,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query With Null Filter" }
|
{ stepName: "Query With Null Filter" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
|
@ -134,11 +122,8 @@ describe("Test a query step automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Returns rows when onEmptyFilter is RETURN_ALL and no filter is passed", async () => {
|
it("Returns rows when onEmptyFilter is RETURN_ALL and no filter is passed", async () => {
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Return All Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -150,7 +135,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query With Return All" }
|
{ stepName: "Query With Return All" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
|
@ -165,11 +150,8 @@ describe("Test a query step automation", () => {
|
||||||
await config.api.row.save(tableWithSpaces._id!, {
|
await config.api.row.save(tableWithSpaces._id!, {
|
||||||
name: NAME,
|
name: NAME,
|
||||||
})
|
})
|
||||||
const result = await createAutomationBuilder({
|
const result = await createAutomationBuilder(config)
|
||||||
name: "Return All Test",
|
.onAppAction()
|
||||||
config,
|
|
||||||
})
|
|
||||||
.appAction({ fields: {} })
|
|
||||||
.queryRows(
|
.queryRows(
|
||||||
{
|
{
|
||||||
tableId: tableWithSpaces._id!,
|
tableId: tableWithSpaces._id!,
|
||||||
|
@ -178,7 +160,7 @@ describe("Test a query step automation", () => {
|
||||||
},
|
},
|
||||||
{ stepName: "Query table with spaces" }
|
{ stepName: "Query table with spaces" }
|
||||||
)
|
)
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
expect(result.steps[0].outputs.rows).toBeDefined()
|
expect(result.steps[0].outputs.rows).toBeDefined()
|
||||||
expect(result.steps[0].outputs.rows.length).toBe(1)
|
expect(result.steps[0].outputs.rows.length).toBe(1)
|
||||||
|
|
|
@ -13,10 +13,10 @@ describe("test the server log action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to log the text", async () => {
|
it("should be able to log the text", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog({ text: "Hello World" })
|
.serverLog({ text: "Hello World" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
expect(result.steps[0].outputs.message).toEqual(
|
expect(result.steps[0].outputs.message).toEqual(
|
||||||
`App ${config.getAppId()} - Hello World`
|
`App ${config.getAppId()} - Hello World`
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,27 +17,27 @@ describe("Test triggering an automation from another automation", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should trigger an other server log automation", async () => {
|
it("should trigger an other server log automation", async () => {
|
||||||
const automation = await createAutomationBuilder({ config })
|
const { automation } = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.serverLog({ text: "Hello World" })
|
.serverLog({ text: "Hello World" })
|
||||||
.save()
|
.save()
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.triggerAutomationRun({
|
.triggerAutomationRun({
|
||||||
automation: {
|
automation: {
|
||||||
automationId: automation._id!,
|
automationId: automation._id!,
|
||||||
},
|
},
|
||||||
timeout: env.getDefaults().AUTOMATION_THREAD_TIMEOUT,
|
timeout: env.getDefaults().AUTOMATION_THREAD_TIMEOUT,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(true)
|
expect(result.steps[0].outputs.success).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should fail gracefully if the automation id is incorrect", async () => {
|
it("should fail gracefully if the automation id is incorrect", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.triggerAutomationRun({
|
.triggerAutomationRun({
|
||||||
automation: {
|
automation: {
|
||||||
// @ts-expect-error - incorrect on purpose
|
// @ts-expect-error - incorrect on purpose
|
||||||
|
@ -45,7 +45,7 @@ describe("Test triggering an automation from another automation", () => {
|
||||||
},
|
},
|
||||||
timeout: env.getDefaults().AUTOMATION_THREAD_TIMEOUT,
|
timeout: env.getDefaults().AUTOMATION_THREAD_TIMEOUT,
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toBe(false)
|
expect(result.steps[0].outputs.success).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
|
@ -30,8 +30,8 @@ describe("test the update row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to run the update row action", async () => {
|
it("should be able to run the update row action", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.updateRow({
|
.updateRow({
|
||||||
rowId: row._id!,
|
rowId: row._id!,
|
||||||
row: {
|
row: {
|
||||||
|
@ -41,7 +41,7 @@ describe("test the update row action", () => {
|
||||||
},
|
},
|
||||||
meta: {},
|
meta: {},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(true)
|
expect(results.steps[0].outputs.success).toEqual(true)
|
||||||
const updatedRow = await config.api.row.get(
|
const updatedRow = await config.api.row.get(
|
||||||
|
@ -53,23 +53,23 @@ describe("test the update row action", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should check invalid inputs return an error", async () => {
|
it("should check invalid inputs return an error", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.updateRow({ meta: {}, row: {}, rowId: "" })
|
.updateRow({ meta: {}, row: {}, rowId: "" })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(false)
|
expect(results.steps[0].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return an error when table doesn't exist", async () => {
|
it("should return an error when table doesn't exist", async () => {
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.updateRow({
|
.updateRow({
|
||||||
row: { _id: "invalid" },
|
row: { _id: "invalid" },
|
||||||
rowId: "invalid",
|
rowId: "invalid",
|
||||||
meta: {},
|
meta: {},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(false)
|
expect(results.steps[0].outputs.success).toEqual(false)
|
||||||
})
|
})
|
||||||
|
@ -106,8 +106,8 @@ describe("test the update row action", () => {
|
||||||
user2: [{ _id: user2._id }],
|
user2: [{ _id: user2._id }],
|
||||||
})
|
})
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.updateRow({
|
.updateRow({
|
||||||
rowId: row._id!,
|
rowId: row._id!,
|
||||||
row: {
|
row: {
|
||||||
|
@ -119,7 +119,7 @@ describe("test the update row action", () => {
|
||||||
},
|
},
|
||||||
meta: {},
|
meta: {},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(true)
|
expect(results.steps[0].outputs.success).toEqual(true)
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ describe("test the update row action", () => {
|
||||||
user2: [{ _id: user2._id }],
|
user2: [{ _id: user2._id }],
|
||||||
})
|
})
|
||||||
|
|
||||||
const results = await createAutomationBuilder({ config })
|
const results = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.updateRow({
|
.updateRow({
|
||||||
rowId: row._id!,
|
rowId: row._id!,
|
||||||
row: {
|
row: {
|
||||||
|
@ -179,7 +179,7 @@ describe("test the update row action", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(results.steps[0].outputs.success).toEqual(true)
|
expect(results.steps[0].outputs.success).toEqual(true)
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,10 @@ describe("test the outgoing webhook action", () => {
|
||||||
it("should be able to run the action", async () => {
|
it("should be able to run the action", async () => {
|
||||||
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
nock("http://www.example.com/").post("/").reply(200, { foo: "bar" })
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.zapier({ url: "http://www.example.com", body: null })
|
.zapier({ url: "http://www.example.com", body: null })
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
|
@ -44,26 +44,26 @@ describe("test the outgoing webhook action", () => {
|
||||||
.post("/", { ...payload, platform: "budibase" })
|
.post("/", { ...payload, platform: "budibase" })
|
||||||
.reply(200, { foo: "bar" })
|
.reply(200, { foo: "bar" })
|
||||||
|
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.zapier({
|
.zapier({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: { value: JSON.stringify(payload) },
|
body: { value: JSON.stringify(payload) },
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
expect(result.steps[0].outputs.response.foo).toEqual("bar")
|
||||||
expect(result.steps[0].outputs.success).toEqual(true)
|
expect(result.steps[0].outputs.success).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return a 400 if the JSON payload string is malformed", async () => {
|
it("should return a 400 if the JSON payload string is malformed", async () => {
|
||||||
const result = await createAutomationBuilder({ config })
|
const result = await createAutomationBuilder(config)
|
||||||
.appAction({ fields: {} })
|
.onAppAction()
|
||||||
.zapier({
|
.zapier({
|
||||||
url: "http://www.example.com",
|
url: "http://www.example.com",
|
||||||
body: { value: "{ invalid json }" },
|
body: { value: "{ invalid json }" },
|
||||||
})
|
})
|
||||||
.run()
|
.test({ fields: {} })
|
||||||
|
|
||||||
expect(result.steps[0].outputs.success).toEqual(false)
|
expect(result.steps[0].outputs.success).toEqual(false)
|
||||||
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
expect(result.steps[0].outputs.response).toEqual("Invalid payload JSON")
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Job } from "bull"
|
||||||
describe("cron trigger", () => {
|
describe("cron trigger", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeAll(async () => {
|
||||||
await config.init()
|
await config.init()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ describe("cron trigger", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
await createAutomationBuilder({ config })
|
await createAutomationBuilder(config)
|
||||||
.cron({ cron: "* * * * *" })
|
.onCron({ cron: "* * * * *" })
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: "Hello, world!",
|
text: "Hello, world!",
|
||||||
})
|
})
|
||||||
|
@ -44,8 +44,8 @@ describe("cron trigger", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should fail if the cron expression is invalid", async () => {
|
it("should fail if the cron expression is invalid", async () => {
|
||||||
await createAutomationBuilder({ config })
|
await createAutomationBuilder(config)
|
||||||
.cron({ cron: "* * * * * *" })
|
.onCron({ cron: "* * * * * *" })
|
||||||
.serverLog({
|
.serverLog({
|
||||||
text: "Hello, world!",
|
text: "Hello, world!",
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as automation from "../../index"
|
|
||||||
import { Table, Webhook, WebhookActionType } from "@budibase/types"
|
import { Table, Webhook, WebhookActionType } from "@budibase/types"
|
||||||
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
||||||
import { mocks } from "@budibase/backend-core/tests"
|
import { mocks } from "@budibase/backend-core/tests"
|
||||||
|
@ -12,8 +11,8 @@ describe("Branching automations", () => {
|
||||||
let webhook: Webhook
|
let webhook: Webhook
|
||||||
|
|
||||||
async function createWebhookAutomation() {
|
async function createWebhookAutomation() {
|
||||||
const automation = await createAutomationBuilder({ config })
|
const { automation } = await createAutomationBuilder(config)
|
||||||
.webhook({ body: { parameter: "string" } })
|
.onWebhook({ body: { parameter: "string" } })
|
||||||
.createRow({
|
.createRow({
|
||||||
row: { tableId: table._id!, name: "{{ trigger.parameter }}" },
|
row: { tableId: table._id!, name: "{{ trigger.parameter }}" },
|
||||||
})
|
})
|
||||||
|
@ -37,7 +36,6 @@ describe("Branching automations", () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await automation.init()
|
|
||||||
await config.init()
|
await config.init()
|
||||||
table = await config.createTable()
|
table = await config.createTable()
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,8 +2,6 @@ import { v4 as uuidv4 } from "uuid"
|
||||||
import { BUILTIN_ACTION_DEFINITIONS } from "../../actions"
|
import { BUILTIN_ACTION_DEFINITIONS } from "../../actions"
|
||||||
import { TRIGGER_DEFINITIONS } from "../../triggers"
|
import { TRIGGER_DEFINITIONS } from "../../triggers"
|
||||||
import {
|
import {
|
||||||
AppActionTriggerInputs,
|
|
||||||
AppActionTriggerOutputs,
|
|
||||||
Automation,
|
Automation,
|
||||||
AutomationActionStepId,
|
AutomationActionStepId,
|
||||||
AutomationResults,
|
AutomationResults,
|
||||||
|
@ -12,57 +10,19 @@ import {
|
||||||
AutomationTrigger,
|
AutomationTrigger,
|
||||||
AutomationTriggerDefinition,
|
AutomationTriggerDefinition,
|
||||||
AutomationTriggerInputs,
|
AutomationTriggerInputs,
|
||||||
|
AutomationTriggerOutputs,
|
||||||
AutomationTriggerStepId,
|
AutomationTriggerStepId,
|
||||||
BashStepInputs,
|
|
||||||
Branch,
|
|
||||||
BranchStepInputs,
|
BranchStepInputs,
|
||||||
CollectStepInputs,
|
|
||||||
CreateRowStepInputs,
|
|
||||||
CronTriggerInputs,
|
|
||||||
CronTriggerOutputs,
|
|
||||||
DelayStepInputs,
|
|
||||||
DeleteRowStepInputs,
|
|
||||||
DiscordStepInputs,
|
|
||||||
ExecuteQueryStepInputs,
|
|
||||||
ExecuteScriptStepInputs,
|
|
||||||
FilterStepInputs,
|
|
||||||
isDidNotTriggerResponse,
|
isDidNotTriggerResponse,
|
||||||
LoopStepInputs,
|
|
||||||
MakeIntegrationInputs,
|
|
||||||
n8nStepInputs,
|
|
||||||
OpenAIStepInputs,
|
|
||||||
OutgoingWebhookStepInputs,
|
|
||||||
QueryRowsStepInputs,
|
|
||||||
RowCreatedTriggerInputs,
|
|
||||||
RowCreatedTriggerOutputs,
|
|
||||||
RowDeletedTriggerInputs,
|
|
||||||
RowDeletedTriggerOutputs,
|
|
||||||
RowUpdatedTriggerInputs,
|
|
||||||
RowUpdatedTriggerOutputs,
|
|
||||||
SearchFilters,
|
SearchFilters,
|
||||||
ServerLogStepInputs,
|
|
||||||
SmtpEmailStepInputs,
|
|
||||||
TestAutomationRequest,
|
TestAutomationRequest,
|
||||||
TriggerAutomationStepInputs,
|
|
||||||
UpdateRowStepInputs,
|
|
||||||
WebhookTriggerInputs,
|
|
||||||
WebhookTriggerOutputs,
|
|
||||||
ZapierStepInputs,
|
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
||||||
import * as setup from "../utilities"
|
|
||||||
import { automations } from "@budibase/shared-core"
|
import { automations } from "@budibase/shared-core"
|
||||||
|
|
||||||
type TriggerOutputs =
|
type StepBuilderFunction = <TStep extends AutomationTriggerStepId>(
|
||||||
| RowCreatedTriggerOutputs
|
stepBuilder: BranchStepBuilder<TStep>
|
||||||
| RowUpdatedTriggerOutputs
|
) => void
|
||||||
| RowDeletedTriggerOutputs
|
|
||||||
| AppActionTriggerOutputs
|
|
||||||
| WebhookTriggerOutputs
|
|
||||||
| CronTriggerOutputs
|
|
||||||
| undefined
|
|
||||||
|
|
||||||
type StepBuilderFunction = (stepBuilder: StepBuilder) => void
|
|
||||||
|
|
||||||
type BranchConfig = {
|
type BranchConfig = {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
@ -71,311 +31,108 @@ type BranchConfig = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseStepBuilder {
|
class TriggerBuilder {
|
||||||
protected steps: AutomationStep[] = []
|
private readonly config: TestConfiguration
|
||||||
protected stepNames: { [key: string]: string } = {}
|
|
||||||
|
|
||||||
protected step<TStep extends AutomationActionStepId>(
|
constructor(config: TestConfiguration) {
|
||||||
stepId: TStep,
|
this.config = config
|
||||||
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
|
||||||
inputs: AutomationStepInputs<TStep>,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected trigger<
|
||||||
|
TStep extends AutomationTriggerStepId,
|
||||||
|
TInput = AutomationTriggerInputs<TStep>
|
||||||
|
>(stepId: TStep) {
|
||||||
|
return (inputs: TInput) => {
|
||||||
|
const definition: AutomationTriggerDefinition =
|
||||||
|
TRIGGER_DEFINITIONS[stepId]
|
||||||
|
const trigger: AutomationTrigger = {
|
||||||
|
...definition,
|
||||||
|
stepId,
|
||||||
|
inputs: (inputs || {}) as any,
|
||||||
|
id: uuidv4(),
|
||||||
|
}
|
||||||
|
return new StepBuilder<TStep>(this.config, trigger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAppAction = this.trigger(AutomationTriggerStepId.APP)
|
||||||
|
|
||||||
|
onRowSaved = this.trigger(AutomationTriggerStepId.ROW_SAVED)
|
||||||
|
onRowUpdated = this.trigger(AutomationTriggerStepId.ROW_UPDATED)
|
||||||
|
onRowDeleted = this.trigger(AutomationTriggerStepId.ROW_DELETED)
|
||||||
|
onWebhook = this.trigger(AutomationTriggerStepId.WEBHOOK)
|
||||||
|
onCron = this.trigger(AutomationTriggerStepId.CRON)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BranchStepBuilder<TStep extends AutomationTriggerStepId> {
|
||||||
|
protected readonly steps: AutomationStep[] = []
|
||||||
|
protected readonly stepNames: { [key: string]: string } = {}
|
||||||
|
|
||||||
|
protected step<TStep extends AutomationActionStepId>(stepId: TStep) {
|
||||||
|
return (
|
||||||
|
inputs: AutomationStepInputs<TStep>,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createRow = this.step(AutomationActionStepId.CREATE_ROW)
|
||||||
|
updateRow = this.step(AutomationActionStepId.UPDATE_ROW)
|
||||||
|
deleteRow = this.step(AutomationActionStepId.DELETE_ROW)
|
||||||
|
sendSmtpEmail = this.step(AutomationActionStepId.SEND_EMAIL_SMTP)
|
||||||
|
executeQuery = this.step(AutomationActionStepId.EXECUTE_QUERY)
|
||||||
|
queryRows = this.step(AutomationActionStepId.QUERY_ROWS)
|
||||||
|
loop = this.step(AutomationActionStepId.LOOP)
|
||||||
|
serverLog = this.step(AutomationActionStepId.SERVER_LOG)
|
||||||
|
executeScript = this.step(AutomationActionStepId.EXECUTE_SCRIPT)
|
||||||
|
executeScriptV2 = this.step(AutomationActionStepId.EXECUTE_SCRIPT_V2)
|
||||||
|
filter = this.step(AutomationActionStepId.FILTER)
|
||||||
|
bash = this.step(AutomationActionStepId.EXECUTE_BASH)
|
||||||
|
openai = this.step(AutomationActionStepId.OPENAI)
|
||||||
|
collect = this.step(AutomationActionStepId.COLLECT)
|
||||||
|
zapier = this.step(AutomationActionStepId.zapier)
|
||||||
|
triggerAutomationRun = this.step(
|
||||||
|
AutomationActionStepId.TRIGGER_AUTOMATION_RUN
|
||||||
|
)
|
||||||
|
outgoingWebhook = this.step(AutomationActionStepId.OUTGOING_WEBHOOK)
|
||||||
|
n8n = this.step(AutomationActionStepId.n8n)
|
||||||
|
make = this.step(AutomationActionStepId.integromat)
|
||||||
|
discord = this.step(AutomationActionStepId.discord)
|
||||||
|
delay = this.step(AutomationActionStepId.DELAY)
|
||||||
|
|
||||||
protected addBranchStep(branchConfig: BranchConfig): void {
|
protected addBranchStep(branchConfig: BranchConfig): void {
|
||||||
const branchStepInputs: BranchStepInputs = {
|
const inputs: BranchStepInputs = {
|
||||||
branches: [] as Branch[],
|
branches: [],
|
||||||
children: {},
|
children: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.entries(branchConfig).forEach(([key, branch]) => {
|
for (const [name, branch] of Object.entries(branchConfig)) {
|
||||||
const stepBuilder = new StepBuilder()
|
const builder = new BranchStepBuilder<TStep>()
|
||||||
branch.steps(stepBuilder)
|
branch.steps(builder)
|
||||||
let branchId = uuidv4()
|
let id = uuidv4()
|
||||||
branchStepInputs.branches.push({
|
inputs.branches.push({ name, condition: branch.condition, id })
|
||||||
name: key,
|
inputs.children![id] = builder.steps
|
||||||
condition: branch.condition,
|
}
|
||||||
id: branchId,
|
|
||||||
})
|
this.steps.push({
|
||||||
branchStepInputs.children![branchId] = stepBuilder.build()
|
|
||||||
})
|
|
||||||
const branchStep: AutomationStep = {
|
|
||||||
...automations.steps.branch.definition,
|
...automations.steps.branch.definition,
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
stepId: AutomationActionStepId.BRANCH,
|
stepId: AutomationActionStepId.BRANCH,
|
||||||
inputs: branchStepInputs,
|
|
||||||
}
|
|
||||||
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,
|
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use `executeScriptV2` instead
|
|
||||||
*/
|
|
||||||
executeScript(
|
|
||||||
input: ExecuteScriptStepInputs,
|
|
||||||
opts?: { stepName?: string; stepId?: string }
|
|
||||||
): this {
|
|
||||||
return this.step(
|
|
||||||
AutomationActionStepId.EXECUTE_SCRIPT,
|
|
||||||
BUILTIN_ACTION_DEFINITIONS.EXECUTE_SCRIPT,
|
|
||||||
input,
|
|
||||||
opts
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
executeScriptV2(
|
|
||||||
input: ExecuteScriptStepInputs,
|
|
||||||
opts?: { stepName?: string; stepId?: string }
|
|
||||||
): this {
|
|
||||||
return this.step(
|
|
||||||
AutomationActionStepId.EXECUTE_SCRIPT_V2,
|
|
||||||
BUILTIN_ACTION_DEFINITIONS.EXECUTE_SCRIPT_V2,
|
|
||||||
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 {
|
|
||||||
build(): AutomationStep[] {
|
|
||||||
return this.steps
|
|
||||||
}
|
}
|
||||||
|
|
||||||
branch(branchConfig: BranchConfig): this {
|
branch(branchConfig: BranchConfig): this {
|
||||||
|
@ -384,160 +141,77 @@ class StepBuilder extends BaseStepBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutomationBuilder extends BaseStepBuilder {
|
class StepBuilder<
|
||||||
private automationConfig: Automation
|
TStep extends AutomationTriggerStepId
|
||||||
private config: TestConfiguration
|
> extends BranchStepBuilder<TStep> {
|
||||||
private triggerOutputs: TriggerOutputs
|
private readonly config: TestConfiguration
|
||||||
private triggerSet = false
|
private readonly trigger: AutomationTrigger
|
||||||
|
private _name: string | undefined = undefined
|
||||||
|
|
||||||
constructor(
|
constructor(config: TestConfiguration, trigger: AutomationTrigger) {
|
||||||
options: { name?: string; appId?: string; config?: TestConfiguration } = {}
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.config = options.config || setup.getConfig()
|
this.config = config
|
||||||
this.automationConfig = {
|
this.trigger = trigger
|
||||||
name: options.name || `Test Automation ${uuidv4()}`,
|
|
||||||
definition: {
|
|
||||||
steps: [],
|
|
||||||
trigger: {} as AutomationTrigger,
|
|
||||||
stepNames: {},
|
|
||||||
},
|
|
||||||
type: "automation",
|
|
||||||
appId: options.appId ?? this.config.getAppId(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRIGGERS
|
name(n: string): this {
|
||||||
rowSaved(inputs: RowCreatedTriggerInputs, outputs: RowCreatedTriggerOutputs) {
|
this._name = n
|
||||||
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<TStep extends AutomationTriggerStepId>(
|
|
||||||
triggerSchema: AutomationTriggerDefinition,
|
|
||||||
stepId: TStep,
|
|
||||||
inputs?: AutomationTriggerInputs<TStep>,
|
|
||||||
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
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
branch(branchConfig: BranchConfig): this {
|
|
||||||
this.addBranchStep(branchConfig)
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
build(): Automation {
|
build(): Automation {
|
||||||
this.automationConfig.definition.steps = this.steps
|
const name = this._name || `Test Automation ${uuidv4()}`
|
||||||
this.automationConfig.definition.stepNames = this.stepNames
|
return {
|
||||||
return this.automationConfig
|
name,
|
||||||
|
definition: {
|
||||||
|
steps: this.steps,
|
||||||
|
trigger: this.trigger,
|
||||||
|
stepNames: this.stepNames,
|
||||||
|
},
|
||||||
|
type: "automation",
|
||||||
|
appId: this.config.getAppId(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async save() {
|
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())
|
const { automation } = await this.config.api.automation.post(this.build())
|
||||||
return automation
|
return new AutomationRunner<TStep>(this.config, automation)
|
||||||
}
|
}
|
||||||
|
|
||||||
async run() {
|
async test(triggerOutput: AutomationTriggerOutputs<TStep>) {
|
||||||
const automation = await this.save()
|
const runner = await this.save()
|
||||||
|
return await runner.test(triggerOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AutomationRunner<TStep extends AutomationTriggerStepId> {
|
||||||
|
private readonly config: TestConfiguration
|
||||||
|
readonly automation: Automation
|
||||||
|
|
||||||
|
constructor(config: TestConfiguration, automation: Automation) {
|
||||||
|
this.config = config
|
||||||
|
this.automation = automation
|
||||||
|
}
|
||||||
|
|
||||||
|
async test(triggerOutput: AutomationTriggerOutputs<TStep>) {
|
||||||
const response = await this.config.api.automation.test(
|
const response = await this.config.api.automation.test(
|
||||||
automation._id!,
|
this.automation._id!,
|
||||||
this.triggerOutputs as TestAutomationRequest
|
// TODO: figure out why this cast is needed.
|
||||||
|
triggerOutput as TestAutomationRequest
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isDidNotTriggerResponse(response)) {
|
if (isDidNotTriggerResponse(response)) {
|
||||||
throw new Error(response.message)
|
throw new Error(response.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
const results: AutomationResults = response as AutomationResults
|
const results: AutomationResults = response as AutomationResults
|
||||||
|
// Remove the trigger step from the response.
|
||||||
results.steps.shift()
|
results.steps.shift()
|
||||||
return {
|
|
||||||
trigger: results.trigger,
|
return response
|
||||||
steps: results.steps,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAutomationBuilder(options?: {
|
export function createAutomationBuilder(config: TestConfiguration) {
|
||||||
name?: string
|
return new TriggerBuilder(config)
|
||||||
appId?: string
|
|
||||||
config?: TestConfiguration
|
|
||||||
}) {
|
|
||||||
return new AutomationBuilder(options)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ export default class TestConfiguration {
|
||||||
request?: supertest.SuperTest<supertest.Test>
|
request?: supertest.SuperTest<supertest.Test>
|
||||||
started: boolean
|
started: boolean
|
||||||
appId?: string
|
appId?: string
|
||||||
|
name?: string
|
||||||
allApps: App[]
|
allApps: App[]
|
||||||
app?: App
|
app?: App
|
||||||
prodApp?: App
|
prodApp?: App
|
||||||
|
|
|
@ -217,10 +217,8 @@ export function basicAutomation(opts?: DeepPartial<Automation>): Automation {
|
||||||
icon: "test",
|
icon: "test",
|
||||||
description: "test",
|
description: "test",
|
||||||
type: AutomationStepType.TRIGGER,
|
type: AutomationStepType.TRIGGER,
|
||||||
|
inputs: {},
|
||||||
id: "test",
|
id: "test",
|
||||||
inputs: {
|
|
||||||
fields: {},
|
|
||||||
},
|
|
||||||
schema: {
|
schema: {
|
||||||
inputs: {
|
inputs: {
|
||||||
properties: {},
|
properties: {},
|
||||||
|
|
|
@ -254,10 +254,6 @@ export type OutgoingWebhookStepInputs = {
|
||||||
headers: string | Record<string, string>
|
headers: string | Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AppActionTriggerInputs = {
|
|
||||||
fields: object
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AppActionTriggerOutputs = {
|
export type AppActionTriggerOutputs = {
|
||||||
fields: object
|
fields: object
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,18 @@ import {
|
||||||
OpenAIStepInputs,
|
OpenAIStepInputs,
|
||||||
OpenAIStepOutputs,
|
OpenAIStepOutputs,
|
||||||
LoopStepInputs,
|
LoopStepInputs,
|
||||||
AppActionTriggerInputs,
|
|
||||||
CronTriggerInputs,
|
CronTriggerInputs,
|
||||||
RowUpdatedTriggerInputs,
|
RowUpdatedTriggerInputs,
|
||||||
RowCreatedTriggerInputs,
|
RowCreatedTriggerInputs,
|
||||||
RowDeletedTriggerInputs,
|
RowDeletedTriggerInputs,
|
||||||
BranchStepInputs,
|
BranchStepInputs,
|
||||||
BaseAutomationOutputs,
|
BaseAutomationOutputs,
|
||||||
|
AppActionTriggerOutputs,
|
||||||
|
CronTriggerOutputs,
|
||||||
|
RowDeletedTriggerOutputs,
|
||||||
|
RowCreatedTriggerOutputs,
|
||||||
|
RowUpdatedTriggerOutputs,
|
||||||
|
WebhookTriggerOutputs,
|
||||||
} from "./StepInputsOutputs"
|
} from "./StepInputsOutputs"
|
||||||
|
|
||||||
export type ActionImplementations<T extends Hosting> = {
|
export type ActionImplementations<T extends Hosting> = {
|
||||||
|
@ -337,7 +342,7 @@ export type AutomationTriggerDefinition = Omit<
|
||||||
|
|
||||||
export type AutomationTriggerInputs<T extends AutomationTriggerStepId> =
|
export type AutomationTriggerInputs<T extends AutomationTriggerStepId> =
|
||||||
T extends AutomationTriggerStepId.APP
|
T extends AutomationTriggerStepId.APP
|
||||||
? AppActionTriggerInputs
|
? void | Record<string, any>
|
||||||
: T extends AutomationTriggerStepId.CRON
|
: T extends AutomationTriggerStepId.CRON
|
||||||
? CronTriggerInputs
|
? CronTriggerInputs
|
||||||
: T extends AutomationTriggerStepId.ROW_ACTION
|
: T extends AutomationTriggerStepId.ROW_ACTION
|
||||||
|
@ -352,6 +357,23 @@ export type AutomationTriggerInputs<T extends AutomationTriggerStepId> =
|
||||||
? Record<string, any>
|
? Record<string, any>
|
||||||
: never
|
: never
|
||||||
|
|
||||||
|
export type AutomationTriggerOutputs<T extends AutomationTriggerStepId> =
|
||||||
|
T extends AutomationTriggerStepId.APP
|
||||||
|
? AppActionTriggerOutputs
|
||||||
|
: T extends AutomationTriggerStepId.CRON
|
||||||
|
? CronTriggerOutputs
|
||||||
|
: T extends AutomationTriggerStepId.ROW_ACTION
|
||||||
|
? Record<string, any>
|
||||||
|
: 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<
|
export interface AutomationTriggerSchema<
|
||||||
TTrigger extends AutomationTriggerStepId
|
TTrigger extends AutomationTriggerStepId
|
||||||
> extends AutomationStepSchemaBase {
|
> extends AutomationStepSchemaBase {
|
||||||
|
|
Loading…
Reference in New Issue