diff --git a/packages/backend-core/src/plugin/utils.ts b/packages/backend-core/src/plugin/utils.ts index 7b62248bb5..8e71685279 100644 --- a/packages/backend-core/src/plugin/utils.ts +++ b/packages/backend-core/src/plugin/utils.ts @@ -1,4 +1,12 @@ -import { DatasourceFieldType, QueryType, PluginType } from "@budibase/types" +import { + DatasourceFieldType, + QueryType, + PluginType, + AutomationStepType, + AutomationStepIdArray, + AutomationIOType, + AutomationCustomIOType, +} from "@budibase/types" import joi from "joi" const DATASOURCE_TYPES = [ @@ -19,7 +27,7 @@ function runJoi(validator: joi.Schema, schema: any) { function validateComponent(schema: any) { const validator = joi.object({ - type: joi.string().allow("component").required(), + type: joi.string().allow(PluginType.COMPONENT).required(), metadata: joi.object().unknown(true).required(), hash: joi.string().optional(), version: joi.string().optional(), @@ -53,7 +61,7 @@ function validateDatasource(schema: any) { .required() const validator = joi.object({ - type: joi.string().allow("datasource").required(), + type: joi.string().allow(PluginType.DATASOURCE).required(), metadata: joi.object().unknown(true).required(), hash: joi.string().optional(), version: joi.string().optional(), @@ -82,6 +90,55 @@ function validateDatasource(schema: any) { runJoi(validator, schema) } +function validateAutomation(schema: any) { + const basePropsValidator = joi.object({ + type: joi + .string() + .allow(...Object.values(AutomationIOType)) + .required(), + customType: joi.string().allow(...Object.values(AutomationCustomIOType)), + title: joi.string(), + description: joi.string(), + enum: joi.array().items(joi.string()), + pretty: joi.array().items(joi.string()), + }) + const stepSchemaValidator = joi + .object({ + properties: basePropsValidator, + required: joi.array().items(joi.string()), + }) + .concat(basePropsValidator) + .required() + const validator = joi.object({ + type: joi.string().allow(PluginType.AUTOMATION).required(), + metadata: joi.object().unknown(true).required(), + hash: joi.string().optional(), + version: joi.string().optional(), + schema: joi.object({ + name: joi.string().required(), + tagline: joi.string().required(), + icon: joi.string().required(), + description: joi.string().required(), + type: joi + .string() + .allow(AutomationStepType.ACTION, AutomationStepType.LOGIC) + .required(), + stepId: joi + .string() + .disallow(...AutomationStepIdArray) + .required(), + inputs: joi.object().optional(), + schema: joi + .object({ + inputs: stepSchemaValidator, + outputs: stepSchemaValidator, + }) + .required(), + }), + }) + runJoi(validator, schema) +} + export function validate(schema: any) { switch (schema?.type) { case PluginType.COMPONENT: @@ -90,6 +147,9 @@ export function validate(schema: any) { case PluginType.DATASOURCE: validateDatasource(schema) break + case PluginType.AUTOMATION: + validateAutomation(schema) + break default: throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`) } diff --git a/packages/server/src/automations/steps/bash.ts b/packages/server/src/automations/steps/bash.ts index e6deb8c38f..b653095338 100644 --- a/packages/server/src/automations/steps/bash.ts +++ b/packages/server/src/automations/steps/bash.ts @@ -4,8 +4,11 @@ import * as automationUtils from "../automationUtils" import environment from "../../environment" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -13,7 +16,7 @@ export const definition: AutomationStepSchema = { tagline: "Execute a bash command", icon: "JourneyEvent", description: "Run a bash script", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.EXECUTE_BASH, inputs: {}, @@ -21,8 +24,8 @@ export const definition: AutomationStepSchema = { inputs: { properties: { code: { - type: "string", - customType: "code", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.CODE, title: "Code", }, }, @@ -31,11 +34,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { stdout: { - type: "string", + type: AutomationIOType.STRING, description: "Standard output of your bash command or script", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the command was successful", }, }, diff --git a/packages/server/src/automations/steps/createRow.ts b/packages/server/src/automations/steps/createRow.ts index d529127360..dac929f1ee 100644 --- a/packages/server/src/automations/steps/createRow.ts +++ b/packages/server/src/automations/steps/createRow.ts @@ -3,8 +3,11 @@ import { cleanUpRow, getError } from "../automationUtils" import { buildCtx } from "./utils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,7 +15,7 @@ export const definition: AutomationStepSchema = { tagline: "Create a {{inputs.enriched.table.name}} row", icon: "TableRowAddBottom", description: "Add a row to your database", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.CREATE_ROW, inputs: {}, @@ -20,14 +23,14 @@ export const definition: AutomationStepSchema = { inputs: { properties: { row: { - type: "object", + type: AutomationIOType.OBJECT, properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, }, }, - customType: "row", + customType: AutomationCustomIOType.ROW, title: "Table", required: ["tableId"], }, @@ -37,24 +40,24 @@ export const definition: AutomationStepSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The new row", }, response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The response from the table", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the row creation was successful", }, id: { - type: "string", + type: AutomationIOType.STRING, description: "The identifier of the new row", }, revision: { - type: "string", + type: AutomationIOType.STRING, description: "The revision of the new row", }, }, diff --git a/packages/server/src/automations/steps/delay.ts b/packages/server/src/automations/steps/delay.ts index 58ca383ac1..9eeebb1667 100644 --- a/packages/server/src/automations/steps/delay.ts +++ b/packages/server/src/automations/steps/delay.ts @@ -3,6 +3,7 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -33,7 +34,7 @@ export const definition: AutomationStepSchema = { required: ["success"], }, }, - type: "LOGIC", + type: AutomationStepType.LOGIC, } export async function run({ inputs }: AutomationStepInput) { diff --git a/packages/server/src/automations/steps/deleteRow.ts b/packages/server/src/automations/steps/deleteRow.ts index 540d95b94d..86c7703491 100644 --- a/packages/server/src/automations/steps/deleteRow.ts +++ b/packages/server/src/automations/steps/deleteRow.ts @@ -3,8 +3,11 @@ import { buildCtx } from "./utils" import { getError } from "../automationUtils" import { AutomationActionStepId, - AutomationStepSchema, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, + AutomationIOType, + AutomationCustomIOType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,7 +15,7 @@ export const definition: AutomationStepSchema = { icon: "TableRowRemoveCenter", name: "Delete Row", tagline: "Delete a {{inputs.enriched.table.name}} row", - type: "ACTION", + type: AutomationStepType.ACTION, stepId: AutomationActionStepId.DELETE_ROW, internal: true, inputs: {}, @@ -20,12 +23,12 @@ export const definition: AutomationStepSchema = { inputs: { properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, title: "Table", }, id: { - type: "string", + type: AutomationIOType.STRING, title: "Row ID", }, }, @@ -34,16 +37,16 @@ export const definition: AutomationStepSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The deleted row", }, response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The response from the table", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the deletion was successful", }, }, diff --git a/packages/server/src/automations/steps/discord.ts b/packages/server/src/automations/steps/discord.ts index 5d7487ed3b..c46220c3b2 100644 --- a/packages/server/src/automations/steps/discord.ts +++ b/packages/server/src/automations/steps/discord.ts @@ -4,6 +4,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" const DEFAULT_USERNAME = "Budibase Automate" @@ -15,26 +17,26 @@ export const definition: AutomationStepSchema = { description: "Send a message to a Discord server", icon: "ri-discord-line", stepId: AutomationActionStepId.discord, - type: "ACTION", + type: AutomationStepType.ACTION, internal: false, inputs: {}, schema: { inputs: { properties: { url: { - type: "string", + type: AutomationIOType.STRING, title: "Discord Webhook URL", }, username: { - type: "string", + type: AutomationIOType.STRING, title: "Bot Name", }, avatar_url: { - type: "string", + type: AutomationIOType.STRING, title: "Bot Avatar URL", }, content: { - type: "string", + type: AutomationIOType.STRING, title: "Message", }, }, @@ -43,15 +45,15 @@ export const definition: AutomationStepSchema = { outputs: { properties: { httpStatus: { - type: "number", + type: AutomationIOType.NUMBER, description: "The HTTP status code of the request", }, response: { - type: "string", + type: AutomationIOType.STRING, description: "The response from the Discord Webhook", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the message sent successfully", }, }, diff --git a/packages/server/src/automations/steps/executeQuery.ts b/packages/server/src/automations/steps/executeQuery.ts index 72fb69b96c..5edc300264 100644 --- a/packages/server/src/automations/steps/executeQuery.ts +++ b/packages/server/src/automations/steps/executeQuery.ts @@ -3,8 +3,11 @@ import { buildCtx } from "./utils" import * as automationUtils from "../automationUtils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,7 +15,7 @@ export const definition: AutomationStepSchema = { tagline: "Execute Data Connector", icon: "Data", description: "Execute a query in an external data connector", - type: "ACTION", + type: AutomationStepType.ACTION, stepId: AutomationActionStepId.EXECUTE_QUERY, internal: true, inputs: {}, @@ -20,14 +23,14 @@ export const definition: AutomationStepSchema = { inputs: { properties: { query: { - type: "object", + type: AutomationIOType.OBJECT, properties: { queryId: { - type: "string", - customType: "query", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.QUERY, }, }, - customType: "queryParams", + customType: AutomationCustomIOType.QUERY_PARAMS, title: "Parameters", required: ["queryId"], }, @@ -37,16 +40,16 @@ export const definition: AutomationStepSchema = { outputs: { properties: { response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The response from the datasource execution", }, info: { - type: "object", + type: AutomationIOType.OBJECT, description: "Some query types may return extra data, like headers from a REST query", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, }, diff --git a/packages/server/src/automations/steps/executeScript.ts b/packages/server/src/automations/steps/executeScript.ts index 84bdb0e2d5..ac43deb5ac 100644 --- a/packages/server/src/automations/steps/executeScript.ts +++ b/packages/server/src/automations/steps/executeScript.ts @@ -3,8 +3,11 @@ import { buildCtx } from "./utils" import * as automationUtils from "../automationUtils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,7 +15,7 @@ export const definition: AutomationStepSchema = { tagline: "Execute JavaScript Code", icon: "Code", description: "Run a piece of JavaScript code in your automation", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.EXECUTE_SCRIPT, inputs: {}, @@ -20,8 +23,8 @@ export const definition: AutomationStepSchema = { inputs: { properties: { code: { - type: "string", - customType: "code", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.CODE, title: "Code", }, }, @@ -30,11 +33,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { value: { - type: "string", + type: AutomationIOType.STRING, description: "The result of the return statement", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, }, diff --git a/packages/server/src/automations/steps/filter.ts b/packages/server/src/automations/steps/filter.ts index 18914ddca6..c7ab4210ec 100644 --- a/packages/server/src/automations/steps/filter.ts +++ b/packages/server/src/automations/steps/filter.ts @@ -2,6 +2,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" export const FilterConditions = { @@ -24,7 +26,7 @@ export const definition: AutomationStepSchema = { icon: "Branch2", description: "Conditionally halt automations which do not meet certain conditions", - type: "LOGIC", + type: AutomationStepType.LOGIC, internal: true, stepId: AutomationActionStepId.FILTER, inputs: { @@ -34,17 +36,17 @@ export const definition: AutomationStepSchema = { inputs: { properties: { field: { - type: "string", + type: AutomationIOType.STRING, title: "Reference Value", }, condition: { - type: "string", + type: AutomationIOType.STRING, title: "Condition", enum: Object.values(FilterConditions), pretty: Object.values(PrettyFilterConditions), }, value: { - type: "string", + type: AutomationIOType.STRING, title: "Comparison Value", }, }, @@ -53,11 +55,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, result: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the logic block passed", }, }, diff --git a/packages/server/src/automations/steps/integromat.ts b/packages/server/src/automations/steps/integromat.ts index 811c0a3d91..d7c78a6dd8 100644 --- a/packages/server/src/automations/steps/integromat.ts +++ b/packages/server/src/automations/steps/integromat.ts @@ -4,6 +4,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -13,34 +15,34 @@ export const definition: AutomationStepSchema = { "Performs a webhook call to Integromat and gets the response (if configured)", icon: "ri-shut-down-line", stepId: AutomationActionStepId.integromat, - type: "ACTION", + type: AutomationStepType.ACTION, internal: false, inputs: {}, schema: { inputs: { properties: { url: { - type: "string", + type: AutomationIOType.STRING, title: "Webhook URL", }, value1: { - type: "string", + type: AutomationIOType.STRING, title: "Input Value 1", }, value2: { - type: "string", + type: AutomationIOType.STRING, title: "Input Value 2", }, value3: { - type: "string", + type: AutomationIOType.STRING, title: "Input Value 3", }, value4: { - type: "string", + type: AutomationIOType.STRING, title: "Input Value 4", }, value5: { - type: "string", + type: AutomationIOType.STRING, title: "Input Value 5", }, }, @@ -49,15 +51,15 @@ export const definition: AutomationStepSchema = { outputs: { properties: { success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether call was successful", }, httpStatus: { - type: "number", + type: AutomationIOType.NUMBER, description: "The HTTP status code returned", }, response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The webhook response - this can have properties", }, }, diff --git a/packages/server/src/automations/steps/loop.ts b/packages/server/src/automations/steps/loop.ts index 72087ae357..fdbec83f2e 100644 --- a/packages/server/src/automations/steps/loop.ts +++ b/packages/server/src/automations/steps/loop.ts @@ -1,4 +1,10 @@ -import { AutomationActionStepId, AutomationStepSchema } from "@budibase/types" +import { + AutomationActionStepId, + AutomationCustomIOType, + AutomationIOType, + AutomationStepSchema, + AutomationStepType, +} from "@budibase/types" export const definition: AutomationStepSchema = { name: "Looping", @@ -12,19 +18,19 @@ export const definition: AutomationStepSchema = { inputs: { properties: { option: { - customType: "loopOption", + customType: AutomationCustomIOType.LOOP_OPTION, title: "Input type", }, binding: { - type: "string", + type: AutomationIOType.STRING, title: "Binding / Value", }, iterations: { - type: "number", + type: AutomationIOType.NUMBER, title: "Max loop iterations", }, failure: { - type: "string", + type: AutomationIOType.STRING, title: "Failure Condition", }, }, @@ -33,20 +39,20 @@ export const definition: AutomationStepSchema = { outputs: { properties: { items: { - customType: "item", + customType: AutomationCustomIOType.ITEM, description: "The item currently being executed", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the message loop was successfully", }, iterations: { - type: "number", - descriptions: "The amount of times the block ran", + type: AutomationIOType.NUMBER, + description: "The amount of times the block ran", }, }, required: ["success", "items", "iterations"], }, }, - type: "LOGIC", + type: AutomationStepType.LOGIC, } diff --git a/packages/server/src/automations/steps/outgoingWebhook.ts b/packages/server/src/automations/steps/outgoingWebhook.ts index ea1ffeb339..f174935195 100644 --- a/packages/server/src/automations/steps/outgoingWebhook.ts +++ b/packages/server/src/automations/steps/outgoingWebhook.ts @@ -3,8 +3,11 @@ import { getFetchResponse } from "./utils" import * as automationUtils from "../automationUtils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" enum RequestType { @@ -27,7 +30,7 @@ export const definition: AutomationStepSchema = { tagline: "Send a {{inputs.requestMethod}} request", icon: "Send", description: "Send a request of specified method to a URL", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.OUTGOING_WEBHOOK, inputs: { @@ -40,23 +43,23 @@ export const definition: AutomationStepSchema = { inputs: { properties: { requestMethod: { - type: "string", + type: AutomationIOType.STRING, enum: Object.values(RequestType), title: "Request method", }, url: { - type: "string", + type: AutomationIOType.STRING, title: "URL", }, requestBody: { - type: "string", + type: AutomationIOType.STRING, title: "JSON Body", - customType: "wide", + customType: AutomationCustomIOType.WIDE, }, headers: { - type: "string", + type: AutomationIOType.STRING, title: "Headers", - customType: "wide", + customType: AutomationCustomIOType.WIDE, }, }, required: ["requestMethod", "url"], @@ -64,15 +67,15 @@ export const definition: AutomationStepSchema = { outputs: { properties: { response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The response from the webhook", }, httpStatus: { - type: "number", + type: AutomationIOType.NUMBER, description: "The HTTP status code returned", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, }, diff --git a/packages/server/src/automations/steps/queryRows.ts b/packages/server/src/automations/steps/queryRows.ts index 6de518e931..1d7e8a419e 100644 --- a/packages/server/src/automations/steps/queryRows.ts +++ b/packages/server/src/automations/steps/queryRows.ts @@ -5,8 +5,11 @@ import { buildCtx } from "./utils" import * as automationUtils from "../automationUtils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, SearchFilters, Table, } from "@budibase/types" @@ -36,7 +39,7 @@ export const definition: AutomationStepSchema = { icon: "Search", name: "Query rows", tagline: "Query rows from {{inputs.enriched.table.name}} table", - type: "ACTION", + type: AutomationStepType.ACTION, stepId: AutomationActionStepId.QUERY_ROWS, internal: true, inputs: {}, @@ -44,35 +47,35 @@ export const definition: AutomationStepSchema = { inputs: { properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, title: "Table", }, filters: { - type: "object", - customType: "filters", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.FILTERS, title: "Filtering", }, sortColumn: { - type: "string", + type: AutomationIOType.STRING, title: "Sort Column", - customType: "column", + customType: AutomationCustomIOType.COLUMN, }, sortOrder: { - type: "string", + type: AutomationIOType.STRING, title: "Sort Order", enum: Object.values(SortOrder), pretty: Object.values(SortOrderPretty), }, limit: { - type: "number", + type: AutomationIOType.NUMBER, title: "Limit", - customType: "queryLimit", + customType: AutomationCustomIOType.QUERY_LIMIT, }, onEmptyFilter: { pretty: Object.values(EmptyFilterOptionPretty), enum: Object.values(EmptyFilterOption), - type: "string", + type: AutomationIOType.STRING, title: "When Filter Empty", }, }, @@ -81,12 +84,12 @@ export const definition: AutomationStepSchema = { outputs: { properties: { rows: { - type: "array", - customType: "rows", + type: AutomationIOType.ARRAY, + customType: AutomationCustomIOType.ROWS, description: "The rows that were found", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the query was successful", }, }, diff --git a/packages/server/src/automations/steps/sendSmtpEmail.ts b/packages/server/src/automations/steps/sendSmtpEmail.ts index 67516c803d..c4af9aeaa9 100644 --- a/packages/server/src/automations/steps/sendSmtpEmail.ts +++ b/packages/server/src/automations/steps/sendSmtpEmail.ts @@ -4,6 +4,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -11,7 +13,7 @@ export const definition: AutomationStepSchema = { tagline: "Send SMTP email to {{inputs.to}}", icon: "Email", name: "Send Email (SMTP)", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.SEND_EMAIL_SMTP, inputs: {}, @@ -19,27 +21,27 @@ export const definition: AutomationStepSchema = { inputs: { properties: { to: { - type: "string", + type: AutomationIOType.STRING, title: "Send To", }, from: { - type: "string", + type: AutomationIOType.STRING, title: "Send From", }, cc: { - type: "string", + type: AutomationIOType.STRING, title: "CC", }, bcc: { - type: "string", + type: AutomationIOType.STRING, title: "BCC", }, subject: { - type: "string", + type: AutomationIOType.STRING, title: "Email Subject", }, contents: { - type: "string", + type: AutomationIOType.STRING, title: "HTML Contents", }, }, @@ -48,11 +50,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the email was sent", }, response: { - type: "object", + type: AutomationIOType.OBJECT, description: "A response from the email client, this may be an error", }, }, diff --git a/packages/server/src/automations/steps/serverLog.ts b/packages/server/src/automations/steps/serverLog.ts index bb2f49ede8..382f7d4efc 100644 --- a/packages/server/src/automations/steps/serverLog.ts +++ b/packages/server/src/automations/steps/serverLog.ts @@ -2,6 +2,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" /** @@ -15,7 +17,7 @@ export const definition: AutomationStepSchema = { tagline: "Console log a value in the backend", icon: "Monitoring", description: "Logs the given text to the server (using console.log)", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.SERVER_LOG, inputs: { @@ -25,7 +27,7 @@ export const definition: AutomationStepSchema = { inputs: { properties: { text: { - type: "string", + type: AutomationIOType.STRING, title: "Log", }, }, @@ -34,11 +36,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, message: { - type: "string", + type: AutomationIOType.STRING, description: "What was output", }, }, diff --git a/packages/server/src/automations/steps/slack.ts b/packages/server/src/automations/steps/slack.ts index 0c9320a699..21ee6ed742 100644 --- a/packages/server/src/automations/steps/slack.ts +++ b/packages/server/src/automations/steps/slack.ts @@ -4,6 +4,8 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,18 +14,18 @@ export const definition: AutomationStepSchema = { description: "Send a message to Slack", icon: "ri-slack-line", stepId: AutomationActionStepId.slack, - type: "ACTION", + type: AutomationStepType.ACTION, internal: false, inputs: {}, schema: { inputs: { properties: { url: { - type: "string", + type: AutomationIOType.STRING, title: "Incoming Webhook URL", }, text: { - type: "string", + type: AutomationIOType.STRING, title: "Message", }, }, @@ -32,15 +34,15 @@ export const definition: AutomationStepSchema = { outputs: { properties: { httpStatus: { - type: "number", + type: AutomationIOType.NUMBER, description: "The HTTP status code of the request", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the message sent successfully", }, response: { - type: "string", + type: AutomationIOType.STRING, description: "The response from the Slack Webhook", }, }, diff --git a/packages/server/src/automations/steps/updateRow.ts b/packages/server/src/automations/steps/updateRow.ts index 9e905a0706..96ab1d1642 100644 --- a/packages/server/src/automations/steps/updateRow.ts +++ b/packages/server/src/automations/steps/updateRow.ts @@ -3,8 +3,11 @@ import * as automationUtils from "../automationUtils" import { buildCtx } from "./utils" import { AutomationActionStepId, - AutomationStepSchema, + AutomationCustomIOType, + AutomationIOType, AutomationStepInput, + AutomationStepSchema, + AutomationStepType, } from "@budibase/types" export const definition: AutomationStepSchema = { @@ -12,7 +15,7 @@ export const definition: AutomationStepSchema = { tagline: "Update a {{inputs.enriched.table.name}} row", icon: "Refresh", description: "Update a row in your database", - type: "ACTION", + type: AutomationStepType.ACTION, internal: true, stepId: AutomationActionStepId.UPDATE_ROW, inputs: {}, @@ -20,16 +23,16 @@ export const definition: AutomationStepSchema = { inputs: { properties: { meta: { - type: "object", + type: AutomationIOType.OBJECT, title: "Field settings", }, row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, title: "Table", }, rowId: { - type: "string", + type: AutomationIOType.STRING, title: "Row ID", }, }, @@ -38,24 +41,24 @@ export const definition: AutomationStepSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The updated row", }, response: { - type: "object", + type: AutomationIOType.OBJECT, description: "The response from the table", }, success: { - type: "boolean", + type: AutomationIOType.BOOLEAN, description: "Whether the action was successful", }, id: { - type: "string", + type: AutomationIOType.STRING, description: "The identifier of the updated row", }, revision: { - type: "string", + type: AutomationIOType.STRING, description: "The revision of the updated row", }, }, diff --git a/packages/server/src/automations/steps/zapier.ts b/packages/server/src/automations/steps/zapier.ts index 90068e685d..75a21deaae 100644 --- a/packages/server/src/automations/steps/zapier.ts +++ b/packages/server/src/automations/steps/zapier.ts @@ -4,12 +4,14 @@ import { AutomationActionStepId, AutomationStepSchema, AutomationStepInput, + AutomationStepType, + AutomationIOType, } from "@budibase/types" export const definition: AutomationStepSchema = { name: "Zapier Webhook", stepId: AutomationActionStepId.zapier, - type: "ACTION", + type: AutomationStepType.ACTION, internal: false, description: "Trigger a Zapier Zap via webhooks", tagline: "Trigger a Zapier Zap", @@ -19,27 +21,27 @@ export const definition: AutomationStepSchema = { inputs: { properties: { url: { - type: "string", + type: AutomationIOType.STRING, title: "Webhook URL", }, value1: { - type: "string", + type: AutomationIOType.STRING, title: "Payload Value 1", }, value2: { - type: "string", + type: AutomationIOType.STRING, title: "Payload Value 2", }, value3: { - type: "string", + type: AutomationIOType.STRING, title: "Payload Value 3", }, value4: { - type: "string", + type: AutomationIOType.STRING, title: "Payload Value 4", }, value5: { - type: "string", + type: AutomationIOType.STRING, title: "Payload Value 5", }, }, @@ -48,11 +50,11 @@ export const definition: AutomationStepSchema = { outputs: { properties: { httpStatus: { - type: "number", + type: AutomationIOType.NUMBER, description: "The HTTP status code of the request", }, response: { - type: "string", + type: AutomationIOType.STRING, description: "The response from Zapier", }, }, diff --git a/packages/server/src/automations/triggerInfo/app.ts b/packages/server/src/automations/triggerInfo/app.ts index fca9acaef8..abc1463f1a 100644 --- a/packages/server/src/automations/triggerInfo/app.ts +++ b/packages/server/src/automations/triggerInfo/app.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { fields: { - type: "object", - customType: "triggerSchema", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.TRIGGER_SCHEMA, title: "Fields", }, }, @@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { fields: { - type: "object", + type: AutomationIOType.OBJECT, description: "Fields submitted from the app frontend", - customType: "triggerSchema", + customType: AutomationCustomIOType.TRIGGER_SCHEMA, }, }, required: ["fields"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/server/src/automations/triggerInfo/cron.ts b/packages/server/src/automations/triggerInfo/cron.ts index 91b41f7243..1c47aeaeec 100644 --- a/packages/server/src/automations/triggerInfo/cron.ts +++ b/packages/server/src/automations/triggerInfo/cron.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { cron: { - type: "string", - customType: "cron", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.CRON, title: "Expression", }, }, @@ -25,12 +28,12 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { timestamp: { - type: "number", + type: AutomationIOType.NUMBER, description: "Timestamp the cron was executed", }, }, required: ["timestamp"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/server/src/automations/triggerInfo/rowDeleted.ts b/packages/server/src/automations/triggerInfo/rowDeleted.ts index de4a1b0412..e1014f3dbc 100644 --- a/packages/server/src/automations/triggerInfo/rowDeleted.ts +++ b/packages/server/src/automations/triggerInfo/rowDeleted.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, title: "Table", }, }, @@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The row that was deleted", }, }, required: ["row"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/server/src/automations/triggerInfo/rowSaved.ts b/packages/server/src/automations/triggerInfo/rowSaved.ts index c1dde25eef..faa32ef96e 100644 --- a/packages/server/src/automations/triggerInfo/rowSaved.ts +++ b/packages/server/src/automations/triggerInfo/rowSaved.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, title: "Table", }, }, @@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The new row that was created", }, id: { - type: "string", + type: AutomationIOType.STRING, description: "Row ID - can be used for updating", }, revision: { - type: "string", + type: AutomationIOType.STRING, description: "Revision of row", }, }, required: ["row", "id"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/server/src/automations/triggerInfo/rowUpdated.ts b/packages/server/src/automations/triggerInfo/rowUpdated.ts index 1bc8811d54..5e60015808 100644 --- a/packages/server/src/automations/triggerInfo/rowUpdated.ts +++ b/packages/server/src/automations/triggerInfo/rowUpdated.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { tableId: { - type: "string", - customType: "table", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.TABLE, title: "Table", }, }, @@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { row: { - type: "object", - customType: "row", + type: AutomationIOType.OBJECT, + customType: AutomationCustomIOType.ROW, description: "The row that was updated", }, id: { - type: "string", + type: AutomationIOType.STRING, description: "Row ID - can be used for updating", }, revision: { - type: "string", + type: AutomationIOType.STRING, description: "Revision of row", }, }, required: ["row", "id"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/server/src/automations/triggerInfo/webhook.ts b/packages/server/src/automations/triggerInfo/webhook.ts index 906967a02a..310dd66b41 100644 --- a/packages/server/src/automations/triggerInfo/webhook.ts +++ b/packages/server/src/automations/triggerInfo/webhook.ts @@ -1,4 +1,7 @@ import { + AutomationCustomIOType, + AutomationIOType, + AutomationStepType, AutomationTriggerSchema, AutomationTriggerStepId, } from "@budibase/types" @@ -15,13 +18,13 @@ export const definition: AutomationTriggerSchema = { inputs: { properties: { schemaUrl: { - type: "string", - customType: "webhookUrl", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.WEBHOOK_URL, title: "Schema URL", }, triggerUrl: { - type: "string", - customType: "webhookUrl", + type: AutomationIOType.STRING, + customType: AutomationCustomIOType.WEBHOOK_URL, title: "Trigger URL", }, }, @@ -30,12 +33,12 @@ export const definition: AutomationTriggerSchema = { outputs: { properties: { body: { - type: "object", + type: AutomationIOType.OBJECT, description: "Body of the request which hit the webhook", }, }, required: ["body"], }, }, - type: "TRIGGER", + type: AutomationStepType.TRIGGER, } diff --git a/packages/types/src/documents/app/automation.ts b/packages/types/src/documents/app/automation.ts index 0c431b1f93..bf95fdbc1f 100644 --- a/packages/types/src/documents/app/automation.ts +++ b/packages/types/src/documents/app/automation.ts @@ -1,6 +1,32 @@ import { Document } from "../document" import { EventEmitter } from "events" +export enum AutomationIOType { + OBJECT = "object", + STRING = "string", + BOOLEAN = "boolean", + NUMBER = "number", + ARRAY = "array", +} + +export enum AutomationCustomIOType { + TABLE = "table", + ROW = "row", + ROWS = "rows", + WIDE = "wide", + QUERY = "query", + QUERY_PARAMS = "queryParams", + QUERY_LIMIT = "queryLimit", + LOOP_OPTION = "loopOption", + ITEM = "item", + CODE = "code", + FILTERS = "filters", + COLUMN = "column", + TRIGGER_SCHEMA = "triggerSchema", + CRON = "cron", + WEBHOOK_URL = "webhookUrl", +} + export enum AutomationTriggerStepId { ROW_SAVED = "ROW_SAVED", ROW_UPDATED = "ROW_UPDATED", @@ -10,6 +36,12 @@ export enum AutomationTriggerStepId { CRON = "CRON", } +export enum AutomationStepType { + LOGIC = "LOGIC", + ACTION = "ACTION", + TRIGGER = "TRIGGER", +} + export enum AutomationActionStepId { SEND_EMAIL_SMTP = "SEND_EMAIL_SMTP", CREATE_ROW = "CREATE_ROW", @@ -31,6 +63,11 @@ export enum AutomationActionStepId { integromat = "integromat", } +export const AutomationStepIdArray = [ + ...Object.values(AutomationActionStepId), + ...Object.values(AutomationTriggerStepId), +] + export interface Automation extends Document { definition: { steps: AutomationStep[] @@ -41,12 +78,32 @@ export interface Automation extends Document { name: string } +interface BaseIOStructure { + type?: AutomationIOType + customType?: AutomationCustomIOType + title?: string + description?: string + enum?: string[] + pretty?: string[] + properties?: { + [key: string]: BaseIOStructure + } + required?: string[] +} + +interface InputOutputBlock { + properties: { + [key: string]: BaseIOStructure + } + required?: string[] +} + export interface AutomationStepSchema { name: string tagline: string icon: string description: string - type: string + type: AutomationStepType internal?: boolean deprecated?: boolean stepId: AutomationTriggerStepId | AutomationActionStepId @@ -55,13 +112,8 @@ export interface AutomationStepSchema { [key: string]: any } schema: { - inputs: { - [key: string]: any - } - outputs: { - [key: string]: any - } - required?: string[] + inputs: InputOutputBlock + outputs: InputOutputBlock } } diff --git a/packages/types/src/documents/global/plugin.ts b/packages/types/src/documents/global/plugin.ts index 17a8426d85..dd96bc20db 100644 --- a/packages/types/src/documents/global/plugin.ts +++ b/packages/types/src/documents/global/plugin.ts @@ -3,6 +3,7 @@ import { Document } from "../document" export enum PluginType { DATASOURCE = "datasource", COMPONENT = "component", + AUTOMATION = "automation", } export enum PluginSource {