Removing the concept of a logic block.
This commit is contained in:
parent
daef4c2d64
commit
458db567ea
|
@ -1,6 +1,5 @@
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const actions = require("../../automations/actions")
|
const actions = require("../../automations/actions")
|
||||||
const logic = require("../../automations/logic")
|
|
||||||
const triggers = require("../../automations/triggers")
|
const triggers = require("../../automations/triggers")
|
||||||
const { getAutomationParams, generateAutomationID } = require("../../db/utils")
|
const { getAutomationParams, generateAutomationID } = require("../../db/utils")
|
||||||
const {
|
const {
|
||||||
|
@ -163,13 +162,8 @@ exports.getTriggerList = async function (ctx) {
|
||||||
ctx.body = triggers.TRIGGER_DEFINITIONS
|
ctx.body = triggers.TRIGGER_DEFINITIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getLogicList = async function (ctx) {
|
|
||||||
ctx.body = logic.LOGIC_DEFINITIONS
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.getDefinitionList = async function (ctx) {
|
module.exports.getDefinitionList = async function (ctx) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
logic: logic.LOGIC_DEFINITIONS,
|
|
||||||
trigger: triggers.TRIGGER_DEFINITIONS,
|
trigger: triggers.TRIGGER_DEFINITIONS,
|
||||||
action: actions.ACTION_DEFINITIONS,
|
action: actions.ACTION_DEFINITIONS,
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,6 @@ router
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
controller.getActionList
|
controller.getActionList
|
||||||
)
|
)
|
||||||
.get(
|
|
||||||
"/api/automations/logic/list",
|
|
||||||
authorized(BUILDER),
|
|
||||||
controller.getLogicList
|
|
||||||
)
|
|
||||||
.get(
|
.get(
|
||||||
"/api/automations/definitions/list",
|
"/api/automations/definitions/list",
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
|
|
|
@ -11,7 +11,6 @@ const MAX_RETRIES = 4
|
||||||
|
|
||||||
let ACTION_DEFINITIONS = {}
|
let ACTION_DEFINITIONS = {}
|
||||||
let TRIGGER_DEFINITIONS = {}
|
let TRIGGER_DEFINITIONS = {}
|
||||||
let LOGIC_DEFINITIONS = {}
|
|
||||||
|
|
||||||
describe("/automations", () => {
|
describe("/automations", () => {
|
||||||
let request = setup.getRequest()
|
let request = setup.getRequest()
|
||||||
|
@ -47,17 +46,6 @@ describe("/automations", () => {
|
||||||
TRIGGER_DEFINITIONS = res.body
|
TRIGGER_DEFINITIONS = res.body
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns a list of definitions for actions", async () => {
|
|
||||||
const res = await request
|
|
||||||
.get(`/api/automations/logic/list`)
|
|
||||||
.set(config.defaultHeaders())
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect(200)
|
|
||||||
|
|
||||||
expect(Object.keys(res.body).length).not.toEqual(0)
|
|
||||||
LOGIC_DEFINITIONS = res.body
|
|
||||||
})
|
|
||||||
|
|
||||||
it("returns all of the definitions in one", async () => {
|
it("returns all of the definitions in one", async () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/api/automations/definitions/list`)
|
.get(`/api/automations/definitions/list`)
|
||||||
|
@ -67,7 +55,6 @@ describe("/automations", () => {
|
||||||
|
|
||||||
expect(Object.keys(res.body.action).length).toBeGreaterThanOrEqual(Object.keys(ACTION_DEFINITIONS).length)
|
expect(Object.keys(res.body.action).length).toBeGreaterThanOrEqual(Object.keys(ACTION_DEFINITIONS).length)
|
||||||
expect(Object.keys(res.body.trigger).length).toEqual(Object.keys(TRIGGER_DEFINITIONS).length)
|
expect(Object.keys(res.body.trigger).length).toEqual(Object.keys(TRIGGER_DEFINITIONS).length)
|
||||||
expect(Object.keys(res.body.logic).length).toEqual(Object.keys(LOGIC_DEFINITIONS).length)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ const discord = require("./steps/discord")
|
||||||
const slack = require("./steps/slack")
|
const slack = require("./steps/slack")
|
||||||
const zapier = require("./steps/zapier")
|
const zapier = require("./steps/zapier")
|
||||||
const integromat = require("./steps/integromat")
|
const integromat = require("./steps/integromat")
|
||||||
|
let filter = require("./steps/filter")
|
||||||
|
let delay = require("./steps/delay")
|
||||||
|
|
||||||
const ACTION_IMPLS = {
|
const ACTION_IMPLS = {
|
||||||
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
||||||
|
@ -22,6 +24,8 @@ const ACTION_IMPLS = {
|
||||||
EXECUTE_BASH: bash.run,
|
EXECUTE_BASH: bash.run,
|
||||||
EXECUTE_QUERY: executeQuery.run,
|
EXECUTE_QUERY: executeQuery.run,
|
||||||
SERVER_LOG: serverLog.run,
|
SERVER_LOG: serverLog.run,
|
||||||
|
DELAY: delay.run,
|
||||||
|
FILTER: filter.run,
|
||||||
// these used to be lowercase step IDs, maintain for backwards compat
|
// these used to be lowercase step IDs, maintain for backwards compat
|
||||||
discord: discord.run,
|
discord: discord.run,
|
||||||
slack: slack.run,
|
slack: slack.run,
|
||||||
|
@ -38,6 +42,8 @@ const ACTION_DEFINITIONS = {
|
||||||
EXECUTE_QUERY: executeQuery.definition,
|
EXECUTE_QUERY: executeQuery.definition,
|
||||||
EXECUTE_BASH: bash.definition,
|
EXECUTE_BASH: bash.definition,
|
||||||
SERVER_LOG: serverLog.definition,
|
SERVER_LOG: serverLog.definition,
|
||||||
|
DELAY: delay.definition,
|
||||||
|
FILTER: filter.definition,
|
||||||
// these used to be lowercase step IDs, maintain for backwards compat
|
// these used to be lowercase step IDs, maintain for backwards compat
|
||||||
discord: discord.definition,
|
discord: discord.definition,
|
||||||
slack: slack.definition,
|
slack: slack.definition,
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
let filter = require("./steps/filter")
|
|
||||||
let delay = require("./steps/delay")
|
|
||||||
|
|
||||||
let LOGIC_IMPLS = {
|
|
||||||
DELAY: delay.run,
|
|
||||||
FILTER: filter.run,
|
|
||||||
}
|
|
||||||
|
|
||||||
let LOGIC_DEFINITIONS = {
|
|
||||||
DELAY: delay.definition,
|
|
||||||
FILTER: filter.definition,
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.getLogic = function (logicName) {
|
|
||||||
if (LOGIC_IMPLS[logicName] != null) {
|
|
||||||
return LOGIC_IMPLS[logicName]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.LOGIC_DEFINITIONS = LOGIC_DEFINITIONS
|
|
|
@ -1,19 +1,19 @@
|
||||||
const LogicConditions = {
|
const FilterConditions = {
|
||||||
EQUAL: "EQUAL",
|
EQUAL: "EQUAL",
|
||||||
NOT_EQUAL: "NOT_EQUAL",
|
NOT_EQUAL: "NOT_EQUAL",
|
||||||
GREATER_THAN: "GREATER_THAN",
|
GREATER_THAN: "GREATER_THAN",
|
||||||
LESS_THAN: "LESS_THAN",
|
LESS_THAN: "LESS_THAN",
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrettyLogicConditions = {
|
const PrettyFilterConditions = {
|
||||||
[LogicConditions.EQUAL]: "Equals",
|
[FilterConditions.EQUAL]: "Equals",
|
||||||
[LogicConditions.NOT_EQUAL]: "Not equals",
|
[FilterConditions.NOT_EQUAL]: "Not equals",
|
||||||
[LogicConditions.GREATER_THAN]: "Greater than",
|
[FilterConditions.GREATER_THAN]: "Greater than",
|
||||||
[LogicConditions.LESS_THAN]: "Less than",
|
[FilterConditions.LESS_THAN]: "Less than",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.LogicConditions = LogicConditions
|
exports.FilterConditions = FilterConditions
|
||||||
exports.PrettyLogicConditions = PrettyLogicConditions
|
exports.PrettyFilterConditions = PrettyFilterConditions
|
||||||
|
|
||||||
exports.definition = {
|
exports.definition = {
|
||||||
name: "Filter",
|
name: "Filter",
|
||||||
|
@ -23,7 +23,7 @@ exports.definition = {
|
||||||
type: "LOGIC",
|
type: "LOGIC",
|
||||||
stepId: "FILTER",
|
stepId: "FILTER",
|
||||||
inputs: {
|
inputs: {
|
||||||
condition: LogicConditions.EQUALS,
|
condition: FilterConditions.EQUALS,
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
inputs: {
|
inputs: {
|
||||||
|
@ -35,8 +35,8 @@ exports.definition = {
|
||||||
condition: {
|
condition: {
|
||||||
type: "string",
|
type: "string",
|
||||||
title: "Condition",
|
title: "Condition",
|
||||||
enum: Object.values(LogicConditions),
|
enum: Object.values(FilterConditions),
|
||||||
pretty: Object.values(PrettyLogicConditions),
|
pretty: Object.values(PrettyFilterConditions),
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
@ -70,16 +70,16 @@ exports.run = async function filter({ inputs }) {
|
||||||
let success = false
|
let success = false
|
||||||
if (typeof field !== "object" && typeof value !== "object") {
|
if (typeof field !== "object" && typeof value !== "object") {
|
||||||
switch (condition) {
|
switch (condition) {
|
||||||
case LogicConditions.EQUAL:
|
case FilterConditions.EQUAL:
|
||||||
success = field === value
|
success = field === value
|
||||||
break
|
break
|
||||||
case LogicConditions.NOT_EQUAL:
|
case FilterConditions.NOT_EQUAL:
|
||||||
success = field !== value
|
success = field !== value
|
||||||
break
|
break
|
||||||
case LogicConditions.GREATER_THAN:
|
case FilterConditions.GREATER_THAN:
|
||||||
success = field > value
|
success = field > value
|
||||||
break
|
break
|
||||||
case LogicConditions.LESS_THAN:
|
case FilterConditions.LESS_THAN:
|
||||||
success = field < value
|
success = field < value
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe("test the delay logic", () => {
|
||||||
it("should be able to run the delay", async () => {
|
it("should be able to run the delay", async () => {
|
||||||
const time = 100
|
const time = 100
|
||||||
const before = Date.now()
|
const before = Date.now()
|
||||||
await setup.runStep(setup.logic.DELAY.stepId, { time: time })
|
await setup.runStep(setup.actions.DELAY.stepId, { time: time })
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
// divide by two just so that test will always pass as long as there was some sort of delay
|
// divide by two just so that test will always pass as long as there was some sort of delay
|
||||||
expect(now - before).toBeGreaterThanOrEqual(time / 2)
|
expect(now - before).toBeGreaterThanOrEqual(time / 2)
|
||||||
|
|
|
@ -1,48 +1,48 @@
|
||||||
const setup = require("./utilities")
|
const setup = require("./utilities")
|
||||||
const { LogicConditions } = require("../steps/filter")
|
const { FilterConditions } = require("../steps/filter")
|
||||||
|
|
||||||
describe("test the filter logic", () => {
|
describe("test the filter logic", () => {
|
||||||
async function checkFilter(field, condition, value, pass = true) {
|
async function checkFilter(field, condition, value, pass = true) {
|
||||||
let res = await setup.runStep(setup.logic.FILTER.stepId,
|
let res = await setup.runStep(setup.actions.FILTER.stepId,
|
||||||
{ field, condition, value }
|
{ field, condition, value }
|
||||||
)
|
)
|
||||||
expect(res.success).toEqual(pass)
|
expect(res.success).toEqual(pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should be able test equality", async () => {
|
it("should be able test equality", async () => {
|
||||||
await checkFilter("hello", LogicConditions.EQUAL, "hello", true)
|
await checkFilter("hello", FilterConditions.EQUAL, "hello", true)
|
||||||
await checkFilter("hello", LogicConditions.EQUAL, "no", false)
|
await checkFilter("hello", FilterConditions.EQUAL, "no", false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to test greater than", async () => {
|
it("should be able to test greater than", async () => {
|
||||||
await checkFilter(10, LogicConditions.GREATER_THAN, 5, true)
|
await checkFilter(10, FilterConditions.GREATER_THAN, 5, true)
|
||||||
await checkFilter(10, LogicConditions.GREATER_THAN, 15, false)
|
await checkFilter(10, FilterConditions.GREATER_THAN, 15, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to test less than", async () => {
|
it("should be able to test less than", async () => {
|
||||||
await checkFilter(5, LogicConditions.LESS_THAN, 10, true)
|
await checkFilter(5, FilterConditions.LESS_THAN, 10, true)
|
||||||
await checkFilter(15, LogicConditions.LESS_THAN, 10, false)
|
await checkFilter(15, FilterConditions.LESS_THAN, 10, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to in-equality", async () => {
|
it("should be able to in-equality", async () => {
|
||||||
await checkFilter("hello", LogicConditions.NOT_EQUAL, "no", true)
|
await checkFilter("hello", FilterConditions.NOT_EQUAL, "no", true)
|
||||||
await checkFilter(10, LogicConditions.NOT_EQUAL, 10, false)
|
await checkFilter(10, FilterConditions.NOT_EQUAL, 10, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("check number coercion", async () => {
|
it("check number coercion", async () => {
|
||||||
await checkFilter("10", LogicConditions.GREATER_THAN, "5", true)
|
await checkFilter("10", FilterConditions.GREATER_THAN, "5", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("check date coercion", async () => {
|
it("check date coercion", async () => {
|
||||||
await checkFilter(
|
await checkFilter(
|
||||||
(new Date()).toISOString(),
|
(new Date()).toISOString(),
|
||||||
LogicConditions.GREATER_THAN,
|
FilterConditions.GREATER_THAN,
|
||||||
(new Date(-10000)).toISOString(),
|
(new Date(-10000)).toISOString(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("check objects always false", async () => {
|
it("check objects always false", async () => {
|
||||||
await checkFilter({}, LogicConditions.EQUAL, {}, false)
|
await checkFilter({}, FilterConditions.EQUAL, {}, false)
|
||||||
})
|
})
|
||||||
})
|
})
|
|
@ -1,6 +1,5 @@
|
||||||
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
||||||
const actions = require("../../actions")
|
const actions = require("../../actions")
|
||||||
const logic = require("../../logic")
|
|
||||||
const emitter = require("../../../events/index")
|
const emitter = require("../../../events/index")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
|
||||||
|
@ -34,16 +33,7 @@ exports.runInProd = async fn => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.runStep = async function runStep(stepId, inputs) {
|
exports.runStep = async function runStep(stepId, inputs) {
|
||||||
let step
|
let step = await actions.getAction(stepId)
|
||||||
if (
|
|
||||||
Object.values(exports.actions)
|
|
||||||
.map(action => action.stepId)
|
|
||||||
.includes(stepId)
|
|
||||||
) {
|
|
||||||
step = await actions.getAction(stepId)
|
|
||||||
} else {
|
|
||||||
step = logic.getLogic(stepId)
|
|
||||||
}
|
|
||||||
expect(step).toBeDefined()
|
expect(step).toBeDefined()
|
||||||
return step({
|
return step({
|
||||||
inputs,
|
inputs,
|
||||||
|
@ -57,4 +47,3 @@ exports.runStep = async function runStep(stepId, inputs) {
|
||||||
exports.apiKey = "test"
|
exports.apiKey = "test"
|
||||||
|
|
||||||
exports.actions = actions.ACTION_DEFINITIONS
|
exports.actions = actions.ACTION_DEFINITIONS
|
||||||
exports.logic = logic.LOGIC_DEFINITIONS
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const actions = require("./actions")
|
const actions = require("./actions")
|
||||||
const logic = require("./logic")
|
|
||||||
const automationUtils = require("./automationUtils")
|
const automationUtils = require("./automationUtils")
|
||||||
const AutomationEmitter = require("../events/AutomationEmitter")
|
const AutomationEmitter = require("../events/AutomationEmitter")
|
||||||
const { processObject } = require("@budibase/string-templates")
|
const { processObject } = require("@budibase/string-templates")
|
||||||
|
@ -8,7 +7,7 @@ const CouchDB = require("../db")
|
||||||
const { DocumentTypes } = require("../db/utils")
|
const { DocumentTypes } = require("../db/utils")
|
||||||
const { doInTenant } = require("@budibase/auth/tenancy")
|
const { doInTenant } = require("@budibase/auth/tenancy")
|
||||||
|
|
||||||
const FILTER_STEP_ID = logic.LOGIC_DEFINITIONS.FILTER.stepId
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The automation orchestrator is a class responsible for executing automations.
|
* The automation orchestrator is a class responsible for executing automations.
|
||||||
|
@ -37,13 +36,8 @@ class Orchestrator {
|
||||||
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)
|
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStepFunctionality(type, stepId) {
|
async getStepFunctionality(stepId) {
|
||||||
let step = null
|
let step = await actions.getAction(stepId)
|
||||||
if (type === "ACTION") {
|
|
||||||
step = await actions.getAction(stepId)
|
|
||||||
} else if (type === "LOGIC") {
|
|
||||||
step = logic.getLogic(stepId)
|
|
||||||
}
|
|
||||||
if (step == null) {
|
if (step == null) {
|
||||||
throw `Cannot find automation step by name ${stepId}`
|
throw `Cannot find automation step by name ${stepId}`
|
||||||
}
|
}
|
||||||
|
@ -73,7 +67,7 @@ class Orchestrator {
|
||||||
let automation = this._automation
|
let automation = this._automation
|
||||||
const app = await this.getApp()
|
const app = await this.getApp()
|
||||||
for (let step of automation.definition.steps) {
|
for (let step of automation.definition.steps) {
|
||||||
let stepFn = await this.getStepFunctionality(step.type, step.stepId)
|
let stepFn = await this.getStepFunctionality(step.stepId)
|
||||||
step.inputs = await processObject(step.inputs, this._context)
|
step.inputs = await processObject(step.inputs, this._context)
|
||||||
step.inputs = automationUtils.cleanInputValues(
|
step.inputs = automationUtils.cleanInputValues(
|
||||||
step.inputs,
|
step.inputs,
|
||||||
|
|
Loading…
Reference in New Issue