Cleanup, prepping for automation history, some refactoring to get rid of concept of builtin.
This commit is contained in:
parent
5cc5bd4533
commit
2531d9a681
|
@ -5,8 +5,8 @@ const triggers = require("../../automations/triggers")
|
||||||
const webhooks = require("./webhook")
|
const webhooks = require("./webhook")
|
||||||
const { getAutomationParams, generateAutomationID } = require("../../db/utils")
|
const { getAutomationParams, generateAutomationID } = require("../../db/utils")
|
||||||
|
|
||||||
const WH_STEP_ID = triggers.BUILTIN_DEFINITIONS.WEBHOOK.stepId
|
const WH_STEP_ID = triggers.TRIGGER_DEFINITIONS.WEBHOOK.stepId
|
||||||
const CRON_STEP_ID = triggers.BUILTIN_DEFINITIONS.CRON.stepId
|
const CRON_STEP_ID = triggers.TRIGGER_DEFINITIONS.CRON.stepId
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
* *
|
* *
|
||||||
|
@ -242,22 +242,22 @@ exports.destroy = async function (ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getActionList = async function (ctx) {
|
exports.getActionList = async function (ctx) {
|
||||||
ctx.body = actions.DEFINITIONS
|
ctx.body = actions.ACTION_DEFINITIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getTriggerList = async function (ctx) {
|
exports.getTriggerList = async function (ctx) {
|
||||||
ctx.body = triggers.BUILTIN_DEFINITIONS
|
ctx.body = triggers.TRIGGER_DEFINITIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getLogicList = async function (ctx) {
|
exports.getLogicList = async function (ctx) {
|
||||||
ctx.body = logic.BUILTIN_DEFINITIONS
|
ctx.body = logic.LOGIC_DEFINITIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getDefinitionList = async function (ctx) {
|
module.exports.getDefinitionList = async function (ctx) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
logic: logic.BUILTIN_DEFINITIONS,
|
logic: logic.LOGIC_DEFINITIONS,
|
||||||
trigger: triggers.BUILTIN_DEFINITIONS,
|
trigger: triggers.TRIGGER_DEFINITIONS,
|
||||||
action: actions.DEFINITIONS,
|
action: actions.ACTION_DEFINITIONS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ describe("/automations", () => {
|
||||||
ACTION_DEFINITIONS = res.body
|
ACTION_DEFINITIONS = res.body
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns a list of definitions for triggers", async () => {
|
it("returns a list of definitions for triggerInfo", async () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/api/automations/trigger/list`)
|
.get(`/api/automations/trigger/list`)
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
|
|
|
@ -13,7 +13,7 @@ const discord = require("./steps/discord")
|
||||||
const zapier = require("./steps/zapier")
|
const zapier = require("./steps/zapier")
|
||||||
const integromat = require("./steps/integromat")
|
const integromat = require("./steps/integromat")
|
||||||
|
|
||||||
const BUILTIN_ACTIONS = {
|
const ACTION_IMPLS = {
|
||||||
SEND_EMAIL: sendgridEmail.run,
|
SEND_EMAIL: sendgridEmail.run,
|
||||||
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
||||||
CREATE_ROW: createRow.run,
|
CREATE_ROW: createRow.run,
|
||||||
|
@ -29,7 +29,7 @@ const BUILTIN_ACTIONS = {
|
||||||
zapier: zapier.run,
|
zapier: zapier.run,
|
||||||
integromat: integromat.run,
|
integromat: integromat.run,
|
||||||
}
|
}
|
||||||
const BUILTIN_DEFINITIONS = {
|
const ACTION_DEFINITIONS = {
|
||||||
SEND_EMAIL: sendgridEmail.definition,
|
SEND_EMAIL: sendgridEmail.definition,
|
||||||
SEND_EMAIL_SMTP: sendSmtpEmail.definition,
|
SEND_EMAIL_SMTP: sendSmtpEmail.definition,
|
||||||
CREATE_ROW: createRow.definition,
|
CREATE_ROW: createRow.definition,
|
||||||
|
@ -47,12 +47,10 @@ const BUILTIN_DEFINITIONS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
module.exports.getAction = async function (actionName) {
|
exports.getAction = async function (actionName) {
|
||||||
if (BUILTIN_ACTIONS[actionName] != null) {
|
if (ACTION_IMPLS[actionName] != null) {
|
||||||
return BUILTIN_ACTIONS[actionName]
|
return ACTION_IMPLS[actionName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// definitions will have downloaded ones added to it, while builtin won't
|
exports.ACTION_DEFINITIONS = ACTION_DEFINITIONS
|
||||||
module.exports.DEFINITIONS = BUILTIN_DEFINITIONS
|
|
||||||
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
let filter = require("./steps/filter")
|
let filter = require("./steps/filter")
|
||||||
let delay = require("./steps/delay")
|
let delay = require("./steps/delay")
|
||||||
|
|
||||||
let BUILTIN_LOGIC = {
|
let LOGIC_IMPLS = {
|
||||||
DELAY: delay.run,
|
DELAY: delay.run,
|
||||||
FILTER: filter.run,
|
FILTER: filter.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
let BUILTIN_DEFINITIONS = {
|
let LOGIC_DEFINITIONS = {
|
||||||
DELAY: delay.definition,
|
DELAY: delay.definition,
|
||||||
FILTER: filter.definition,
|
FILTER: filter.definition,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getLogic = function (logicName) {
|
exports.getLogic = function (logicName) {
|
||||||
if (BUILTIN_LOGIC[logicName] != null) {
|
if (LOGIC_IMPLS[logicName] != null) {
|
||||||
return BUILTIN_LOGIC[logicName]
|
return LOGIC_IMPLS[logicName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|
exports.LOGIC_DEFINITIONS = LOGIC_DEFINITIONS
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const { execSync } = require("child_process")
|
const { execSync } = require("child_process")
|
||||||
const { processStringSync } = require("@budibase/string-templates")
|
const { processStringSync } = require("@budibase/string-templates")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Bash Scripting",
|
name: "Bash Scripting",
|
||||||
tagline: "Execute a bash command",
|
tagline: "Execute a bash command",
|
||||||
icon: "ri-terminal-box-line",
|
icon: "ri-terminal-box-line",
|
||||||
|
@ -32,7 +32,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, context }) {
|
exports.run = async function ({ inputs, context }) {
|
||||||
if (inputs.code == null) {
|
if (inputs.code == null) {
|
||||||
return {
|
return {
|
||||||
stdout: "Budibase bash automation failed: Invalid inputs",
|
stdout: "Budibase bash automation failed: Invalid inputs",
|
||||||
|
|
|
@ -3,7 +3,7 @@ const automationUtils = require("../automationUtils")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const usage = require("../../utilities/usageQuota")
|
const usage = require("../../utilities/usageQuota")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Create Row",
|
name: "Create Row",
|
||||||
tagline: "Create a {{inputs.enriched.table.name}} row",
|
tagline: "Create a {{inputs.enriched.table.name}} row",
|
||||||
icon: "ri-save-3-line",
|
icon: "ri-save-3-line",
|
||||||
|
@ -58,7 +58,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId, apiKey, emitter }) {
|
exports.run = async function ({ inputs, appId, apiKey, emitter }) {
|
||||||
if (inputs.row == null || inputs.row.tableId == null) {
|
if (inputs.row == null || inputs.row.tableId == null) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
let { wait } = require("../../utilities")
|
let { wait } = require("../../utilities")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Delay",
|
name: "Delay",
|
||||||
icon: "ri-time-line",
|
icon: "ri-time-line",
|
||||||
tagline: "Delay for {{inputs.time}} milliseconds",
|
tagline: "Delay for {{inputs.time}} milliseconds",
|
||||||
|
@ -21,6 +21,6 @@ module.exports.definition = {
|
||||||
type: "LOGIC",
|
type: "LOGIC",
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function delay({ inputs }) {
|
exports.run = async function delay({ inputs }) {
|
||||||
await wait(inputs.time)
|
await wait(inputs.time)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ const rowController = require("../../api/controllers/row")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const usage = require("../../utilities/usageQuota")
|
const usage = require("../../utilities/usageQuota")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
description: "Delete a row from your database",
|
description: "Delete a row from your database",
|
||||||
icon: "ri-delete-bin-line",
|
icon: "ri-delete-bin-line",
|
||||||
name: "Delete Row",
|
name: "Delete Row",
|
||||||
|
@ -50,7 +50,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId, apiKey, emitter }) {
|
exports.run = async function ({ inputs, appId, apiKey, emitter }) {
|
||||||
if (inputs.id == null || inputs.revision == null) {
|
if (inputs.id == null || inputs.revision == null) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Discord Message",
|
name: "Discord Message",
|
||||||
tagline: "Send a message to a Discord server",
|
tagline: "Send a message to a Discord server",
|
||||||
description: "Send a message to a Discord server",
|
description: "Send a message to a Discord server",
|
||||||
|
@ -44,7 +44,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
const { url, username, avatar_url, content } = inputs
|
const { url, username, avatar_url, content } = inputs
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const queryController = require("../../api/controllers/query")
|
const queryController = require("../../api/controllers/query")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "External Data Connector",
|
name: "External Data Connector",
|
||||||
tagline: "Execute Data Connector",
|
tagline: "Execute Data Connector",
|
||||||
icon: "ri-database-2-line",
|
icon: "ri-database-2-line",
|
||||||
|
@ -42,7 +42,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId, emitter }) {
|
exports.run = async function ({ inputs, appId, emitter }) {
|
||||||
if (inputs.query == null) {
|
if (inputs.query == null) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const scriptController = require("../../api/controllers/script")
|
const scriptController = require("../../api/controllers/script")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "JS Scripting",
|
name: "JS Scripting",
|
||||||
tagline: "Execute JavaScript Code",
|
tagline: "Execute JavaScript Code",
|
||||||
icon: "ri-terminal-box-line",
|
icon: "ri-terminal-box-line",
|
||||||
|
@ -36,7 +36,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId, context, emitter }) {
|
exports.run = async function ({ inputs, appId, context, emitter }) {
|
||||||
if (inputs.code == null) {
|
if (inputs.code == null) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -12,10 +12,10 @@ const PrettyLogicConditions = {
|
||||||
[LogicConditions.LESS_THAN]: "Less than",
|
[LogicConditions.LESS_THAN]: "Less than",
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.LogicConditions = LogicConditions
|
exports.LogicConditions = LogicConditions
|
||||||
module.exports.PrettyLogicConditions = PrettyLogicConditions
|
exports.PrettyLogicConditions = PrettyLogicConditions
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Filter",
|
name: "Filter",
|
||||||
tagline: "{{inputs.field}} {{inputs.condition}} {{inputs.value}}",
|
tagline: "{{inputs.field}} {{inputs.condition}} {{inputs.value}}",
|
||||||
icon: "ri-git-branch-line",
|
icon: "ri-git-branch-line",
|
||||||
|
@ -57,7 +57,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function filter({ inputs }) {
|
exports.run = async function filter({ inputs }) {
|
||||||
let { field, condition, value } = inputs
|
let { field, condition, value } = inputs
|
||||||
// coerce types so that we can use them
|
// coerce types so that we can use them
|
||||||
if (!isNaN(value) && !isNaN(field)) {
|
if (!isNaN(value) && !isNaN(field)) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Integromat Integration",
|
name: "Integromat Integration",
|
||||||
tagline: "Trigger an Integromat scenario",
|
tagline: "Trigger an Integromat scenario",
|
||||||
description:
|
description:
|
||||||
|
@ -55,7 +55,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
const { url, value1, value2, value3, value4, value5 } = inputs
|
const { url, value1, value2, value3, value4, value5 } = inputs
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
|
|
|
@ -16,7 +16,7 @@ const BODY_REQUESTS = [RequestType.POST, RequestType.PUT, RequestType.PATCH]
|
||||||
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
|
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Outgoing webhook",
|
name: "Outgoing webhook",
|
||||||
tagline: "Send a {{inputs.requestMethod}} request",
|
tagline: "Send a {{inputs.requestMethod}} request",
|
||||||
icon: "ri-send-plane-line",
|
icon: "ri-send-plane-line",
|
||||||
|
@ -70,7 +70,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
let { requestMethod, url, requestBody, headers } = inputs
|
let { requestMethod, url, requestBody, headers } = inputs
|
||||||
if (!url.startsWith("http")) {
|
if (!url.startsWith("http")) {
|
||||||
url = `http://${url}`
|
url = `http://${url}`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { sendSmtpEmail } = require("../../utilities/workerRequests")
|
const { sendSmtpEmail } = require("../../utilities/workerRequests")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
description: "Send an email using SMTP",
|
description: "Send an email using SMTP",
|
||||||
tagline: "Send SMTP email to {{inputs.to}}",
|
tagline: "Send SMTP email to {{inputs.to}}",
|
||||||
icon: "ri-mail-open-line",
|
icon: "ri-mail-open-line",
|
||||||
|
@ -46,7 +46,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
let { to, from, subject, contents } = inputs
|
let { to, from, subject, contents } = inputs
|
||||||
if (!contents) {
|
if (!contents) {
|
||||||
contents = "<h1>No content</h1>"
|
contents = "<h1>No content</h1>"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
description: "Send an email using SendGrid",
|
description: "Send an email using SendGrid",
|
||||||
tagline: "Send email to {{inputs.to}}",
|
tagline: "Send email to {{inputs.to}}",
|
||||||
icon: "ri-mail-open-line",
|
icon: "ri-mail-open-line",
|
||||||
|
@ -48,7 +48,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
const sgMail = require("@sendgrid/mail")
|
const sgMail = require("@sendgrid/mail")
|
||||||
sgMail.setApiKey(inputs.apiKey)
|
sgMail.setApiKey(inputs.apiKey)
|
||||||
const msg = {
|
const msg = {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
|
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Backend log",
|
name: "Backend log",
|
||||||
tagline: "Console log a value in the backend",
|
tagline: "Console log a value in the backend",
|
||||||
icon: "ri-server-line",
|
icon: "ri-server-line",
|
||||||
|
@ -36,6 +36,6 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId }) {
|
exports.run = async function ({ inputs, appId }) {
|
||||||
console.log(`App ${appId} - ${inputs.text}`)
|
console.log(`App ${appId} - ${inputs.text}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const rowController = require("../../api/controllers/row")
|
const rowController = require("../../api/controllers/row")
|
||||||
const automationUtils = require("../automationUtils")
|
const automationUtils = require("../automationUtils")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Update Row",
|
name: "Update Row",
|
||||||
tagline: "Update a {{inputs.enriched.table.name}} row",
|
tagline: "Update a {{inputs.enriched.table.name}} row",
|
||||||
icon: "ri-refresh-line",
|
icon: "ri-refresh-line",
|
||||||
|
@ -53,7 +53,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs, appId, emitter }) {
|
exports.run = async function ({ inputs, appId, emitter }) {
|
||||||
if (inputs.rowId == null || inputs.row == null) {
|
if (inputs.rowId == null || inputs.row == null) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
module.exports.definition = {
|
exports.definition = {
|
||||||
name: "Zapier Webhook",
|
name: "Zapier Webhook",
|
||||||
stepId: "zapier",
|
stepId: "zapier",
|
||||||
type: "ACTION",
|
type: "ACTION",
|
||||||
|
@ -52,7 +52,7 @@ module.exports.definition = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function ({ inputs }) {
|
exports.run = async function ({ inputs }) {
|
||||||
const { url, value1, value2, value3, value4, value5 } = inputs
|
const { url, value1, value2, value3, value4, value5 } = inputs
|
||||||
|
|
||||||
// send the platform to make sure zaps always work, even
|
// send the platform to make sure zaps always work, even
|
||||||
|
|
|
@ -56,5 +56,5 @@ exports.runStep = async function runStep(stepId, inputs) {
|
||||||
|
|
||||||
exports.apiKey = "test"
|
exports.apiKey = "test"
|
||||||
|
|
||||||
exports.actions = actions.BUILTIN_DEFINITIONS
|
exports.actions = actions.ACTION_DEFINITIONS
|
||||||
exports.logic = logic.BUILTIN_DEFINITIONS
|
exports.logic = logic.LOGIC_DEFINITIONS
|
||||||
|
|
|
@ -8,7 +8,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.BUILTIN_DEFINITIONS.FILTER.stepId
|
const FILTER_STEP_ID = logic.LOGIC_DEFINITIONS.FILTER.stepId
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The automation orchestrator is a class responsible for executing automations.
|
* The automation orchestrator is a class responsible for executing automations.
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
exports.definition = {
|
||||||
|
name: "App Action",
|
||||||
|
event: "app:trigger",
|
||||||
|
icon: "ri-window-fill",
|
||||||
|
tagline: "Automation fired from the frontend",
|
||||||
|
description: "Trigger an automation from an action inside your app",
|
||||||
|
stepId: "APP",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
fields: {
|
||||||
|
type: "object",
|
||||||
|
customType: "triggerSchema",
|
||||||
|
title: "Fields",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: [],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
fields: {
|
||||||
|
type: "object",
|
||||||
|
description: "Fields submitted from the app frontend",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["fields"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
exports.defintion = {
|
||||||
|
name: "Cron Trigger",
|
||||||
|
event: "cron:trigger",
|
||||||
|
icon: "ri-timer-line",
|
||||||
|
tagline: "Cron Trigger (<b>{{inputs.cron}}</b>)",
|
||||||
|
description: "Triggers automation on a cron schedule.",
|
||||||
|
stepId: "CRON",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
cron: {
|
||||||
|
type: "string",
|
||||||
|
customType: "cron",
|
||||||
|
title: "Expression",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["cron"],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
timestamp: {
|
||||||
|
type: "number",
|
||||||
|
description: "Timestamp the cron was executed",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["timestamp"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
const app = require("./app")
|
||||||
|
const cron = require("./cron")
|
||||||
|
const rowDeleted = require("./rowDeleted")
|
||||||
|
const rowSaved = require("./rowSaved")
|
||||||
|
const rowUpdated = require("./rowUpdated")
|
||||||
|
const webhook = require("./webhook")
|
||||||
|
|
||||||
|
exports.definitions = {
|
||||||
|
ROW_SAVED: rowSaved.definition,
|
||||||
|
ROW_UPDATED: rowUpdated.definition,
|
||||||
|
ROW_DELETED: rowDeleted.definition,
|
||||||
|
WEBHOOK: webhook.definition,
|
||||||
|
APP: app.definition,
|
||||||
|
CRON: cron.defintion,
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
exports.definition = {
|
||||||
|
name: "Row Deleted",
|
||||||
|
event: "row:delete",
|
||||||
|
icon: "ri-delete-bin-line",
|
||||||
|
tagline: "Row is deleted from {{inputs.enriched.table.name}}",
|
||||||
|
description: "Fired when a row is deleted from your database",
|
||||||
|
stepId: "ROW_DELETED",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
tableId: {
|
||||||
|
type: "string",
|
||||||
|
customType: "table",
|
||||||
|
title: "Table",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["tableId"],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
row: {
|
||||||
|
type: "object",
|
||||||
|
customType: "row",
|
||||||
|
description: "The row that was deleted",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["row"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
exports.definition = {
|
||||||
|
name: "Row Created",
|
||||||
|
event: "row:save",
|
||||||
|
icon: "ri-save-line",
|
||||||
|
tagline: "Row is added to {{inputs.enriched.table.name}}",
|
||||||
|
description: "Fired when a row is added to your database",
|
||||||
|
stepId: "ROW_SAVED",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
tableId: {
|
||||||
|
type: "string",
|
||||||
|
customType: "table",
|
||||||
|
title: "Table",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["tableId"],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
row: {
|
||||||
|
type: "object",
|
||||||
|
customType: "row",
|
||||||
|
description: "The new row that was created",
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: "string",
|
||||||
|
description: "Row ID - can be used for updating",
|
||||||
|
},
|
||||||
|
revision: {
|
||||||
|
type: "string",
|
||||||
|
description: "Revision of row",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["row", "id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
exports.definition = {
|
||||||
|
name: "Row Updated",
|
||||||
|
event: "row:update",
|
||||||
|
icon: "ri-refresh-line",
|
||||||
|
tagline: "Row is updated in {{inputs.enriched.table.name}}",
|
||||||
|
description: "Fired when a row is updated in your database",
|
||||||
|
stepId: "ROW_UPDATED",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
tableId: {
|
||||||
|
type: "string",
|
||||||
|
customType: "table",
|
||||||
|
title: "Table",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["tableId"],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
row: {
|
||||||
|
type: "object",
|
||||||
|
customType: "row",
|
||||||
|
description: "The row that was updated",
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: "string",
|
||||||
|
description: "Row ID - can be used for updating",
|
||||||
|
},
|
||||||
|
revision: {
|
||||||
|
type: "string",
|
||||||
|
description: "Revision of row",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["row", "id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
exports.definition = {
|
||||||
|
name: "Webhook",
|
||||||
|
event: "web:trigger",
|
||||||
|
icon: "ri-global-line",
|
||||||
|
tagline: "Webhook endpoint is hit",
|
||||||
|
description: "Trigger an automation when a HTTP POST webhook is hit",
|
||||||
|
stepId: "WEBHOOK",
|
||||||
|
inputs: {},
|
||||||
|
schema: {
|
||||||
|
inputs: {
|
||||||
|
properties: {
|
||||||
|
schemaUrl: {
|
||||||
|
type: "string",
|
||||||
|
customType: "webhookUrl",
|
||||||
|
title: "Schema URL",
|
||||||
|
},
|
||||||
|
triggerUrl: {
|
||||||
|
type: "string",
|
||||||
|
customType: "webhookUrl",
|
||||||
|
title: "Trigger URL",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["schemaUrl", "triggerUrl"],
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
properties: {
|
||||||
|
body: {
|
||||||
|
type: "object",
|
||||||
|
description: "Body of the request which hit the webhook",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["body"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: "TRIGGER",
|
||||||
|
}
|
|
@ -8,232 +8,12 @@ const { getAutomationParams } = require("../db/utils")
|
||||||
const { coerce } = require("../utilities/rowProcessor")
|
const { coerce } = require("../utilities/rowProcessor")
|
||||||
const { utils } = require("@budibase/auth/redis")
|
const { utils } = require("@budibase/auth/redis")
|
||||||
const { JobQueues } = require("../constants")
|
const { JobQueues } = require("../constants")
|
||||||
const {
|
const { definitions } = require("./triggerInfo")
|
||||||
isExternalTable,
|
|
||||||
breakExternalTableId,
|
|
||||||
} = require("../integrations/utils")
|
|
||||||
const { getExternalTable } = require("../api/controllers/table/utils")
|
|
||||||
|
|
||||||
const { opts } = utils.getRedisOptions()
|
const { opts } = utils.getRedisOptions()
|
||||||
let automationQueue = new Queue(JobQueues.AUTOMATIONS, { redis: opts })
|
let automationQueue = new Queue(JobQueues.AUTOMATIONS, { redis: opts })
|
||||||
|
|
||||||
const FAKE_STRING = "TEST"
|
const TRIGGER_DEFINITIONS = definitions
|
||||||
const FAKE_BOOL = false
|
|
||||||
const FAKE_NUMBER = 1
|
|
||||||
const FAKE_DATETIME = "1970-01-01T00:00:00.000Z"
|
|
||||||
|
|
||||||
const BUILTIN_DEFINITIONS = {
|
|
||||||
ROW_SAVED: {
|
|
||||||
name: "Row Created",
|
|
||||||
event: "row:save",
|
|
||||||
icon: "ri-save-line",
|
|
||||||
tagline: "Row is added to {{inputs.enriched.table.name}}",
|
|
||||||
description: "Fired when a row is added to your database",
|
|
||||||
stepId: "ROW_SAVED",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
tableId: {
|
|
||||||
type: "string",
|
|
||||||
customType: "table",
|
|
||||||
title: "Table",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["tableId"],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
row: {
|
|
||||||
type: "object",
|
|
||||||
customType: "row",
|
|
||||||
description: "The new row that was created",
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: "string",
|
|
||||||
description: "Row ID - can be used for updating",
|
|
||||||
},
|
|
||||||
revision: {
|
|
||||||
type: "string",
|
|
||||||
description: "Revision of row",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["row", "id"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
ROW_UPDATED: {
|
|
||||||
name: "Row Updated",
|
|
||||||
event: "row:update",
|
|
||||||
icon: "ri-refresh-line",
|
|
||||||
tagline: "Row is updated in {{inputs.enriched.table.name}}",
|
|
||||||
description: "Fired when a row is updated in your database",
|
|
||||||
stepId: "ROW_UPDATED",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
tableId: {
|
|
||||||
type: "string",
|
|
||||||
customType: "table",
|
|
||||||
title: "Table",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["tableId"],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
row: {
|
|
||||||
type: "object",
|
|
||||||
customType: "row",
|
|
||||||
description: "The row that was updated",
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: "string",
|
|
||||||
description: "Row ID - can be used for updating",
|
|
||||||
},
|
|
||||||
revision: {
|
|
||||||
type: "string",
|
|
||||||
description: "Revision of row",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["row", "id"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
ROW_DELETED: {
|
|
||||||
name: "Row Deleted",
|
|
||||||
event: "row:delete",
|
|
||||||
icon: "ri-delete-bin-line",
|
|
||||||
tagline: "Row is deleted from {{inputs.enriched.table.name}}",
|
|
||||||
description: "Fired when a row is deleted from your database",
|
|
||||||
stepId: "ROW_DELETED",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
tableId: {
|
|
||||||
type: "string",
|
|
||||||
customType: "table",
|
|
||||||
title: "Table",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["tableId"],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
row: {
|
|
||||||
type: "object",
|
|
||||||
customType: "row",
|
|
||||||
description: "The row that was deleted",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["row"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
WEBHOOK: {
|
|
||||||
name: "Webhook",
|
|
||||||
event: "web:trigger",
|
|
||||||
icon: "ri-global-line",
|
|
||||||
tagline: "Webhook endpoint is hit",
|
|
||||||
description: "Trigger an automation when a HTTP POST webhook is hit",
|
|
||||||
stepId: "WEBHOOK",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
schemaUrl: {
|
|
||||||
type: "string",
|
|
||||||
customType: "webhookUrl",
|
|
||||||
title: "Schema URL",
|
|
||||||
},
|
|
||||||
triggerUrl: {
|
|
||||||
type: "string",
|
|
||||||
customType: "webhookUrl",
|
|
||||||
title: "Trigger URL",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["schemaUrl", "triggerUrl"],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
body: {
|
|
||||||
type: "object",
|
|
||||||
description: "Body of the request which hit the webhook",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["body"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
APP: {
|
|
||||||
name: "App Action",
|
|
||||||
event: "app:trigger",
|
|
||||||
icon: "ri-window-fill",
|
|
||||||
tagline: "Automation fired from the frontend",
|
|
||||||
description: "Trigger an automation from an action inside your app",
|
|
||||||
stepId: "APP",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
fields: {
|
|
||||||
type: "object",
|
|
||||||
customType: "triggerSchema",
|
|
||||||
title: "Fields",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: [],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
fields: {
|
|
||||||
type: "object",
|
|
||||||
description: "Fields submitted from the app frontend",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["fields"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
CRON: {
|
|
||||||
name: "Cron Trigger",
|
|
||||||
event: "cron:trigger",
|
|
||||||
icon: "ri-timer-line",
|
|
||||||
tagline: "Cron Trigger (<b>{{inputs.cron}}</b>)",
|
|
||||||
description: "Triggers automation on a cron schedule.",
|
|
||||||
stepId: "CRON",
|
|
||||||
inputs: {},
|
|
||||||
schema: {
|
|
||||||
inputs: {
|
|
||||||
properties: {
|
|
||||||
cron: {
|
|
||||||
type: "string",
|
|
||||||
customType: "cron",
|
|
||||||
title: "Expression",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["cron"],
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
properties: {
|
|
||||||
timestamp: {
|
|
||||||
type: "number",
|
|
||||||
description: "Timestamp the cron was executed",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ["timestamp"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "TRIGGER",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
async function queueRelevantRowAutomations(event, eventType) {
|
async function queueRelevantRowAutomations(event, eventType) {
|
||||||
if (event.appId == null) {
|
if (event.appId == null) {
|
||||||
|
@ -262,7 +42,7 @@ async function queueRelevantRowAutomations(event, eventType) {
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
automationQueue.add({ automation, event })
|
await automationQueue.add({ automation, event })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,51 +70,8 @@ emitter.on("row:delete", async function (event) {
|
||||||
await queueRelevantRowAutomations(event, "row:delete")
|
await queueRelevantRowAutomations(event, "row:delete")
|
||||||
})
|
})
|
||||||
|
|
||||||
async function fillRowOutput(automation, params) {
|
exports.externalTrigger = async function (automation, params) {
|
||||||
let triggerSchema = automation.definition.trigger
|
|
||||||
let tableId = triggerSchema.inputs.tableId
|
|
||||||
try {
|
|
||||||
let table
|
|
||||||
if (!isExternalTable(tableId)) {
|
|
||||||
const db = new CouchDB(params.appId)
|
|
||||||
table = await db.get(tableId)
|
|
||||||
} else {
|
|
||||||
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
||||||
table = await getExternalTable(params.appId, datasourceId, tableName)
|
|
||||||
}
|
|
||||||
let row = {}
|
|
||||||
for (let schemaKey of Object.keys(table.schema)) {
|
|
||||||
const paramValue = params[schemaKey]
|
|
||||||
let propSchema = table.schema[schemaKey]
|
|
||||||
switch (propSchema.constraints.type) {
|
|
||||||
case "string":
|
|
||||||
row[schemaKey] = paramValue || FAKE_STRING
|
|
||||||
break
|
|
||||||
case "boolean":
|
|
||||||
row[schemaKey] = paramValue || FAKE_BOOL
|
|
||||||
break
|
|
||||||
case "number":
|
|
||||||
row[schemaKey] = paramValue || FAKE_NUMBER
|
|
||||||
break
|
|
||||||
case "datetime":
|
|
||||||
row[schemaKey] = paramValue || FAKE_DATETIME
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params.row = row
|
|
||||||
} catch (err) {
|
|
||||||
/* istanbul ignore next */
|
|
||||||
throw "Failed to find table for trigger"
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.externalTrigger = async function (automation, params) {
|
|
||||||
// TODO: replace this with allowing user in builder to input values in future
|
|
||||||
if (automation.definition != null && automation.definition.trigger != null) {
|
if (automation.definition != null && automation.definition.trigger != null) {
|
||||||
if (automation.definition.trigger.inputs.tableId != null) {
|
|
||||||
params = await fillRowOutput(automation, params)
|
|
||||||
}
|
|
||||||
if (automation.definition.trigger.stepId === "APP") {
|
if (automation.definition.trigger.stepId === "APP") {
|
||||||
// values are likely to be submitted as strings, so we shall convert to correct type
|
// values are likely to be submitted as strings, so we shall convert to correct type
|
||||||
const coercedFields = {}
|
const coercedFields = {}
|
||||||
|
@ -346,13 +83,12 @@ module.exports.externalTrigger = async function (automation, params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
automationQueue.add({ automation, event: params })
|
await automationQueue.add({ automation, event: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getQueues = () => {
|
exports.getQueues = () => {
|
||||||
return [automationQueue]
|
return [automationQueue]
|
||||||
}
|
}
|
||||||
module.exports.fillRowOutput = fillRowOutput
|
exports.automationQueue = automationQueue
|
||||||
module.exports.automationQueue = automationQueue
|
|
||||||
|
|
||||||
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|
exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS
|
||||||
|
|
|
@ -14,7 +14,7 @@ const DOMAIN_MAP = {
|
||||||
views: usageQuota.Properties.VIEW,
|
views: usageQuota.Properties.VIEW,
|
||||||
users: usageQuota.Properties.USER,
|
users: usageQuota.Properties.USER,
|
||||||
// this will not be updated by endpoint calls
|
// this will not be updated by endpoint calls
|
||||||
// instead it will be updated by triggers
|
// instead it will be updated by triggerInfo
|
||||||
automationRuns: usageQuota.Properties.AUTOMATION,
|
automationRuns: usageQuota.Properties.AUTOMATION,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue