@budibase/server 1.0.105-alpha.2 → 1.0.105-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builder/assets/{index.ea3718aa.css → index.b7e0672d.css} +2 -2
- package/builder/assets/{index.3197fef1.js → index.fb599536.js} +153 -153
- package/builder/index.html +2 -2
- package/coverage/clover.xml +204 -124
- package/coverage/coverage-final.json +8 -7
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +1 -1
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +5 -5
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/utils/index.html +1 -1
- package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +13 -4
- package/coverage/lcov-report/automations/automationUtils.js.html +45 -9
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +18 -18
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +20 -5
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +230 -0
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/automations/utils.js.html +2 -2
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +22 -4
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/client.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +44 -44
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +1 -1
- package/coverage/lcov-report/middleware/currentapp.js.html +55 -10
- package/coverage/lcov-report/middleware/index.html +16 -16
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/threads/automation.js.html +531 -45
- package/coverage/lcov-report/threads/index.html +20 -20
- package/coverage/lcov-report/threads/index.js.html +1 -1
- package/coverage/lcov-report/threads/query.js.html +1 -1
- package/coverage/lcov-report/threads/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +1 -1
- package/coverage/lcov-report/utilities/index.html +1 -1
- package/coverage/lcov-report/utilities/index.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +1 -1
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +385 -243
- package/dist/api/controllers/static/templates/BudibaseApp.svelte +3 -0
- package/dist/api/controllers/table/bulkFormula.js +2 -1
- package/dist/automations/actions.js +3 -0
- package/dist/automations/automationUtils.js +10 -0
- package/dist/automations/steps/loop.js +51 -0
- package/dist/constants/index.js +5 -0
- package/dist/environment.js +1 -0
- package/dist/middleware/currentapp.js +15 -1
- package/dist/package.json +5 -5
- package/dist/threads/automation.js +149 -27
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/api/controllers/static/templates/BudibaseApp.svelte +3 -0
- package/src/api/controllers/table/bulkFormula.js +1 -1
- package/src/automations/actions.js +3 -0
- package/src/automations/automationUtils.js +12 -0
- package/src/automations/steps/loop.js +50 -0
- package/src/constants/index.js +6 -0
- package/src/environment.js +1 -0
- package/src/middleware/currentapp.js +16 -1
- package/src/threads/automation.js +196 -34
|
@@ -24,6 +24,7 @@ function isStaticFormula(column) {
|
|
|
24
24
|
* in the formula.
|
|
25
25
|
*/
|
|
26
26
|
function getFormulaThatUseColumn(table, columnNames) {
|
|
27
|
+
var _a;
|
|
27
28
|
let formula = [];
|
|
28
29
|
columnNames = Array.isArray(columnNames) ? columnNames : [columnNames];
|
|
29
30
|
for (let column of Object.values(table.schema)) {
|
|
@@ -31,7 +32,7 @@ function getFormulaThatUseColumn(table, columnNames) {
|
|
|
31
32
|
if (!isStaticFormula(column)) {
|
|
32
33
|
continue;
|
|
33
34
|
}
|
|
34
|
-
if (!doesContainStrings(column.formula, columnNames)) {
|
|
35
|
+
if (!doesContainStrings((_a = column === null || column === void 0 ? void 0 : column.formula) !== null && _a !== void 0 ? _a : "", columnNames)) {
|
|
35
36
|
continue;
|
|
36
37
|
}
|
|
37
38
|
formula.push(column.name);
|
|
@@ -23,6 +23,7 @@ const integromat = require("./steps/integromat");
|
|
|
23
23
|
let filter = require("./steps/filter");
|
|
24
24
|
let delay = require("./steps/delay");
|
|
25
25
|
let queryRow = require("./steps/queryRows");
|
|
26
|
+
let loop = require("./steps/loop");
|
|
26
27
|
const env = require("../environment");
|
|
27
28
|
const ACTION_IMPLS = {
|
|
28
29
|
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
|
@@ -36,6 +37,7 @@ const ACTION_IMPLS = {
|
|
|
36
37
|
DELAY: delay.run,
|
|
37
38
|
FILTER: filter.run,
|
|
38
39
|
QUERY_ROWS: queryRow.run,
|
|
40
|
+
LOOP: loop.run,
|
|
39
41
|
// these used to be lowercase step IDs, maintain for backwards compat
|
|
40
42
|
discord: discord.run,
|
|
41
43
|
slack: slack.run,
|
|
@@ -54,6 +56,7 @@ const ACTION_DEFINITIONS = {
|
|
|
54
56
|
DELAY: delay.definition,
|
|
55
57
|
FILTER: filter.definition,
|
|
56
58
|
QUERY_ROWS: queryRow.definition,
|
|
59
|
+
LOOP: loop.definition,
|
|
57
60
|
// these used to be lowercase step IDs, maintain for backwards compat
|
|
58
61
|
discord: discord.definition,
|
|
59
62
|
slack: slack.definition,
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
const { getTable } = require("../api/controllers/table/utils");
|
|
12
|
+
const { findHBSBlocks } = require("@budibase/string-templates");
|
|
12
13
|
/**
|
|
13
14
|
* When values are input to the system generally they will be of type string as this is required for template strings.
|
|
14
15
|
* This can generate some odd scenarios as the Schema of the automation requires a number but the builder might supply
|
|
@@ -79,3 +80,12 @@ exports.getError = err => {
|
|
|
79
80
|
}
|
|
80
81
|
return typeof err !== "string" ? err.toString() : err;
|
|
81
82
|
};
|
|
83
|
+
exports.substituteLoopStep = (hbsString, substitute) => {
|
|
84
|
+
let blocks = findHBSBlocks(hbsString);
|
|
85
|
+
for (let block of blocks) {
|
|
86
|
+
let oldBlock = block;
|
|
87
|
+
block = block.replace(/loop/, substitute);
|
|
88
|
+
hbsString = hbsString.replace(new RegExp(oldBlock, "g"), block);
|
|
89
|
+
}
|
|
90
|
+
return hbsString;
|
|
91
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.definition = {
|
|
3
|
+
name: "Looping",
|
|
4
|
+
icon: "Reuse",
|
|
5
|
+
tagline: "Loop the block",
|
|
6
|
+
description: "Loop",
|
|
7
|
+
stepId: "LOOP",
|
|
8
|
+
internal: true,
|
|
9
|
+
inputs: {},
|
|
10
|
+
schema: {
|
|
11
|
+
inputs: {
|
|
12
|
+
properties: {
|
|
13
|
+
option: {
|
|
14
|
+
customType: "loopOption",
|
|
15
|
+
title: "Input type",
|
|
16
|
+
},
|
|
17
|
+
binding: {
|
|
18
|
+
type: "string",
|
|
19
|
+
title: "Binding / Value",
|
|
20
|
+
},
|
|
21
|
+
iterations: {
|
|
22
|
+
type: "number",
|
|
23
|
+
title: "Max loop iterations",
|
|
24
|
+
},
|
|
25
|
+
failure: {
|
|
26
|
+
type: "string",
|
|
27
|
+
title: "Failure Condition",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
required: ["type", "value", "iterations", "failure"],
|
|
31
|
+
},
|
|
32
|
+
outputs: {
|
|
33
|
+
properties: {
|
|
34
|
+
items: {
|
|
35
|
+
customType: "item",
|
|
36
|
+
description: "The item currently being executed",
|
|
37
|
+
},
|
|
38
|
+
success: {
|
|
39
|
+
type: "boolean",
|
|
40
|
+
description: "Whether the message loop was successfully",
|
|
41
|
+
},
|
|
42
|
+
iterations: {
|
|
43
|
+
type: "number",
|
|
44
|
+
descriptions: "The amount of times the block ran",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
required: ["success", "items", "iterations"],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
type: "LOGIC",
|
|
51
|
+
};
|
package/dist/constants/index.js
CHANGED
|
@@ -169,5 +169,10 @@ exports.BuildSchemaErrors = {
|
|
|
169
169
|
exports.WebhookType = {
|
|
170
170
|
AUTOMATION: "automation",
|
|
171
171
|
};
|
|
172
|
+
exports.AutomationErrors = {
|
|
173
|
+
INCORRECT_TYPE: "INCORRECT_TYPE",
|
|
174
|
+
MAX_ITERATIONS: "MAX_ITERATIONS_REACHED",
|
|
175
|
+
FAILURE_CONDITION: "FAILURE_CONDITION_MET",
|
|
176
|
+
};
|
|
172
177
|
// pass through the list from the auth/core lib
|
|
173
178
|
exports.ObjectStoreBuckets = ObjectStoreBuckets;
|
package/dist/environment.js
CHANGED
|
@@ -51,6 +51,7 @@ module.exports = {
|
|
|
51
51
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
52
52
|
AUTOMATION_DIRECTORY: process.env.AUTOMATION_DIRECTORY,
|
|
53
53
|
AUTOMATION_BUCKET: process.env.AUTOMATION_BUCKET,
|
|
54
|
+
AUTOMATION_MAX_ITERATIONS: process.env.AUTOMATION_MAX_ITERATIONS,
|
|
54
55
|
SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,
|
|
55
56
|
DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,
|
|
56
57
|
POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
const { getAppIdFromCtx, setCookie, getCookie, clearCookie, } = require("@budibase/backend-core/utils");
|
|
12
|
-
const { Cookies } = require("@budibase/backend-core/constants");
|
|
12
|
+
const { Cookies, Headers } = require("@budibase/backend-core/constants");
|
|
13
13
|
const { getRole } = require("@budibase/backend-core/roles");
|
|
14
14
|
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles");
|
|
15
15
|
const { generateUserMetadataID, isDevAppID } = require("../db/utils");
|
|
@@ -64,6 +64,20 @@ module.exports = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
64
64
|
appId = requestAppId;
|
|
65
65
|
// retrieving global user gets the right role
|
|
66
66
|
roleId = globalUser.roleId || roleId;
|
|
67
|
+
// Allow builders to specify their role via a header
|
|
68
|
+
const isBuilder = globalUser && globalUser.builder && globalUser.builder.global;
|
|
69
|
+
const isDevApp = appId && isDevAppID(appId);
|
|
70
|
+
const roleHeader = ctx.request && ctx.request.headers[Headers.PREVIEW_ROLE];
|
|
71
|
+
if (isBuilder && isDevApp && roleHeader) {
|
|
72
|
+
// Ensure the role is valid by ensuring a definition exists
|
|
73
|
+
try {
|
|
74
|
+
yield getRole(roleHeader);
|
|
75
|
+
roleId = roleHeader;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
// Swallow error and do nothing
|
|
79
|
+
}
|
|
80
|
+
}
|
|
67
81
|
}
|
|
68
82
|
// nothing more to do
|
|
69
83
|
if (!appId) {
|
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.0.105-alpha.
|
|
4
|
+
"version": "1.0.105-alpha.21",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "https://github.com/Budibase/budibase.git"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "rimraf dist/ && tsc && mv dist/src/* dist/ &&
|
|
12
|
+
"build": "rimraf dist/ && tsc && mv dist/src/* dist/ && rimraf dist/src/ && yarn postbuild",
|
|
13
13
|
"postbuild": "copyfiles -u 1 src/**/*.svelte dist/ && copyfiles -u 1 src/**/*.hbs dist/ && copyfiles -u 1 src/**/*.json dist/",
|
|
14
14
|
"test": "jest --coverage --maxWorkers=2",
|
|
15
15
|
"test:watch": "jest --watch",
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
"license": "GPL-3.0",
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@apidevtools/swagger-parser": "^10.0.3",
|
|
71
|
-
"@budibase/backend-core": "^1.0.105-alpha.
|
|
72
|
-
"@budibase/client": "^1.0.105-alpha.
|
|
73
|
-
"@budibase/string-templates": "^1.0.105-alpha.
|
|
71
|
+
"@budibase/backend-core": "^1.0.105-alpha.21",
|
|
72
|
+
"@budibase/client": "^1.0.105-alpha.21",
|
|
73
|
+
"@budibase/string-templates": "^1.0.105-alpha.21",
|
|
74
74
|
"@bull-board/api": "^3.7.0",
|
|
75
75
|
"@bull-board/koa": "^3.7.0",
|
|
76
76
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -18,9 +18,13 @@ const { DocumentTypes } = require("../db/utils");
|
|
|
18
18
|
const { doInTenant } = require("@budibase/backend-core/tenancy");
|
|
19
19
|
const { definitions: triggerDefs } = require("../automations/triggerInfo");
|
|
20
20
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context");
|
|
21
|
+
const { AutomationErrors } = require("../constants");
|
|
21
22
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId;
|
|
23
|
+
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId;
|
|
22
24
|
const CRON_STEP_ID = triggerDefs.CRON.stepId;
|
|
23
25
|
const STOPPED_STATUS = { success: false, status: "STOPPED" };
|
|
26
|
+
const { cloneDeep } = require("lodash/fp");
|
|
27
|
+
const env = require("../environment");
|
|
24
28
|
/**
|
|
25
29
|
* The automation orchestrator is a class responsible for executing automations.
|
|
26
30
|
* It handles the context of the automation and makes sure each step gets the correct
|
|
@@ -81,44 +85,162 @@ class Orchestrator {
|
|
|
81
85
|
}
|
|
82
86
|
this.executionOutput.steps.push(stepObj);
|
|
83
87
|
}
|
|
88
|
+
updateContextAndOutput(loopStepNumber, step, output, result) {
|
|
89
|
+
this.executionOutput.steps.splice(loopStepNumber, 0, {
|
|
90
|
+
id: step.id,
|
|
91
|
+
stepId: step.stepId,
|
|
92
|
+
outputs: Object.assign(Object.assign({}, output), { success: result.success, status: result.status }),
|
|
93
|
+
inputs: step.inputs,
|
|
94
|
+
});
|
|
95
|
+
this._context.steps.splice(loopStepNumber, 0, Object.assign(Object.assign({}, output), { success: result.success, status: result.status }));
|
|
96
|
+
}
|
|
84
97
|
execute() {
|
|
98
|
+
var _a;
|
|
85
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
100
|
let automation = this._automation;
|
|
87
101
|
const app = yield this.getApp();
|
|
88
102
|
let stopped = false;
|
|
103
|
+
let loopStep;
|
|
104
|
+
let stepCount = 0;
|
|
105
|
+
let loopStepNumber;
|
|
106
|
+
let loopSteps = [];
|
|
89
107
|
for (let step of automation.definition.steps) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
stepCount++;
|
|
109
|
+
let input;
|
|
110
|
+
if (step.stepId === LOOP_STEP_ID) {
|
|
111
|
+
loopStep = step;
|
|
112
|
+
loopStepNumber = stepCount;
|
|
93
113
|
continue;
|
|
94
114
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
if (loopStep) {
|
|
116
|
+
input = yield processObject(loopStep.inputs, this._context);
|
|
117
|
+
}
|
|
118
|
+
let iterations = loopStep ? input.binding.length : 1;
|
|
119
|
+
let iterationCount = 0;
|
|
120
|
+
for (let index = 0; index < iterations; index++) {
|
|
121
|
+
let originalStepInput = cloneDeep(step.inputs);
|
|
122
|
+
// Handle if the user has set a max iteration count or if it reaches the max limit set by us
|
|
123
|
+
if (loopStep) {
|
|
124
|
+
// lets first of all handle the input
|
|
125
|
+
// if the input is array then use it, if it is a string then split it on every new line
|
|
126
|
+
let newInput = yield processObject(loopStep.inputs, cloneDeep(this._context));
|
|
127
|
+
newInput = automationUtils.cleanInputValues(newInput, loopStep.schema.inputs);
|
|
128
|
+
this._context.steps[loopStepNumber] = {
|
|
129
|
+
currentItem: newInput.binding[index],
|
|
130
|
+
};
|
|
131
|
+
let tempOutput = { items: loopSteps, iterations: iterationCount };
|
|
132
|
+
if ((loopStep.inputs.option === "Array" &&
|
|
133
|
+
!Array.isArray(newInput.binding)) ||
|
|
134
|
+
(loopStep.inputs.option === "String" &&
|
|
135
|
+
typeof newInput.binding !== "string")) {
|
|
136
|
+
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
|
137
|
+
status: AutomationErrors.INCORRECT_TYPE,
|
|
138
|
+
success: false,
|
|
139
|
+
});
|
|
140
|
+
loopSteps = null;
|
|
141
|
+
loopStep = null;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
// The "Loop" binding in the front end is "fake", so replace it here so the context can understand it
|
|
145
|
+
// Pretty hacky because we need to account for the row object
|
|
146
|
+
for (let [key, value] of Object.entries(originalStepInput)) {
|
|
147
|
+
if (typeof value === "object") {
|
|
148
|
+
for (let [innerKey, innerValue] of Object.entries(originalStepInput[key])) {
|
|
149
|
+
if (typeof innerValue === "string") {
|
|
150
|
+
originalStepInput[key][innerKey] =
|
|
151
|
+
automationUtils.substituteLoopStep(innerValue, `steps.${loopStepNumber}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
if (typeof value === "string") {
|
|
157
|
+
originalStepInput[key] = automationUtils.substituteLoopStep(value, `steps.${loopStepNumber}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (index === parseInt(env.AUTOMATION_MAX_ITERATIONS) ||
|
|
162
|
+
index === loopStep.inputs.iterations) {
|
|
163
|
+
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
|
164
|
+
status: AutomationErrors.MAX_ITERATIONS,
|
|
165
|
+
success: true,
|
|
166
|
+
});
|
|
167
|
+
loopSteps = null;
|
|
168
|
+
loopStep = null;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
if (((_a = this._context.steps[loopStepNumber]) === null || _a === void 0 ? void 0 : _a.currentItem) ===
|
|
172
|
+
loopStep.inputs.failure) {
|
|
173
|
+
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
|
174
|
+
status: AutomationErrors.FAILURE_CONDITION,
|
|
175
|
+
success: false,
|
|
176
|
+
});
|
|
177
|
+
loopSteps = null;
|
|
178
|
+
loopStep = null;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// execution stopped, record state for that
|
|
183
|
+
if (stopped) {
|
|
184
|
+
this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS);
|
|
115
185
|
continue;
|
|
116
186
|
}
|
|
117
|
-
|
|
187
|
+
// If it's a loop step, we need to manually add the bindings to the context
|
|
188
|
+
let stepFn = yield this.getStepFunctionality(step.stepId);
|
|
189
|
+
let inputs = yield processObject(originalStepInput, this._context);
|
|
190
|
+
inputs = automationUtils.cleanInputValues(inputs, step.schema.inputs);
|
|
191
|
+
try {
|
|
192
|
+
// appId is always passed
|
|
193
|
+
let tenantId = app.tenantId || DEFAULT_TENANT_ID;
|
|
194
|
+
const outputs = yield doInTenant(tenantId, () => {
|
|
195
|
+
return stepFn({
|
|
196
|
+
inputs: inputs,
|
|
197
|
+
appId: this._appId,
|
|
198
|
+
emitter: this._emitter,
|
|
199
|
+
context: this._context,
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
this._context.steps[stepCount] = outputs;
|
|
203
|
+
// if filter causes us to stop execution don't break the loop, set a var
|
|
204
|
+
// so that we can finish iterating through the steps and record that it stopped
|
|
205
|
+
if (step.stepId === FILTER_STEP_ID && !outputs.success) {
|
|
206
|
+
stopped = true;
|
|
207
|
+
this.updateExecutionOutput(step.id, step.stepId, step.inputs, Object.assign(Object.assign({}, outputs), STOPPED_STATUS));
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (loopStep && loopSteps) {
|
|
211
|
+
loopSteps.push(outputs);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
this.updateExecutionOutput(step.id, step.stepId, step.inputs, outputs);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
console.error(`Automation error - ${step.stepId} - ${err}`);
|
|
219
|
+
return err;
|
|
220
|
+
}
|
|
221
|
+
if (loopStep) {
|
|
222
|
+
iterationCount++;
|
|
223
|
+
if (index === iterations - 1) {
|
|
224
|
+
loopStep = null;
|
|
225
|
+
this._context.steps.splice(loopStepNumber, 1);
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
118
229
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
230
|
+
if (loopSteps && loopSteps.length) {
|
|
231
|
+
let tempOutput = {
|
|
232
|
+
success: true,
|
|
233
|
+
items: loopSteps,
|
|
234
|
+
iterations: iterationCount,
|
|
235
|
+
};
|
|
236
|
+
this.executionOutput.steps.splice(loopStepNumber + 1, 0, {
|
|
237
|
+
id: step.id,
|
|
238
|
+
stepId: step.stepId,
|
|
239
|
+
outputs: tempOutput,
|
|
240
|
+
inputs: step.inputs,
|
|
241
|
+
});
|
|
242
|
+
this._context.steps.splice(loopStepNumber, 0, tempOutput);
|
|
243
|
+
loopSteps = null;
|
|
122
244
|
}
|
|
123
245
|
}
|
|
124
246
|
return this.executionOutput;
|