@budibase/server 0.9.167-alpha.4 → 0.9.167-alpha.8
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.60f832ce.js → index.553837db.js} +34 -34
- package/builder/assets/{index.18ad7651.css → index.c4a1fb7f.css} +1 -1
- package/builder/assets/{vendor.60887453.js → vendor.278a305c.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +273 -245
- package/coverage/coverage-final.json +9 -8
- 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/hosting.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +26 -26
- 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/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query.js.html +129 -24
- 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/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 +12 -57
- package/coverage/lcov-report/api/controllers/table/index.html +10 -10
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/utils.js.html +8 -38
- 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/hosting.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/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +9 -3
- 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/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +31 -10
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +19 -19
- 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 +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- 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/thread.js.html +54 -12
- 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 +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- 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 +12 -12
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +9 -9
- 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 +37 -37
- 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 +1 -1
- package/coverage/lcov-report/middleware/index.html +1 -1
- package/coverage/lcov-report/middleware/joi-validator.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/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 +22 -7
- 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 +143 -0
- 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/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +450 -402
- package/dist/api/controllers/query.js +26 -8
- package/dist/api/controllers/script.js +4 -16
- package/dist/api/controllers/table/utils.js +2 -10
- package/dist/api/routes/query.js +3 -1
- package/dist/automations/actions.js +9 -3
- package/dist/automations/thread.js +14 -3
- package/dist/package.json +5 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/scriptRunner.js +19 -0
- package/package.json +6 -5
- package/src/api/controllers/query.js +46 -11
- package/src/api/controllers/script.js +4 -19
- package/src/api/controllers/table/utils.js +2 -12
- package/src/api/routes/query.js +3 -1
- package/src/automations/actions.js +10 -3
- package/src/automations/thread.js +17 -3
- package/src/integrations/tests/mongo.spec.js +10 -6
- package/src/utilities/scriptRunner.js +21 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const fetch = require("node-fetch");
|
|
3
|
+
const { VM, VMScript } = require("vm2");
|
|
4
|
+
class ScriptRunner {
|
|
5
|
+
constructor(script, context) {
|
|
6
|
+
const code = `let fn = () => {\n${script}\n}; results.out = fn();`;
|
|
7
|
+
this.vm = new VM();
|
|
8
|
+
this.results = { out: "" };
|
|
9
|
+
this.vm.setGlobals(context);
|
|
10
|
+
this.vm.setGlobal("fetch", fetch);
|
|
11
|
+
this.vm.setGlobal("results", this.results);
|
|
12
|
+
this.script = new VMScript(code);
|
|
13
|
+
}
|
|
14
|
+
execute() {
|
|
15
|
+
this.vm.run(this.script);
|
|
16
|
+
return this.results.out;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
module.exports = ScriptRunner;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "0.9.167-alpha.
|
|
4
|
+
"version": "0.9.167-alpha.8",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
"author": "Budibase",
|
|
69
69
|
"license": "AGPL-3.0-or-later",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@budibase/auth": "^0.9.167-alpha.
|
|
72
|
-
"@budibase/client": "^0.9.167-alpha.
|
|
73
|
-
"@budibase/string-templates": "^0.9.167-alpha.
|
|
71
|
+
"@budibase/auth": "^0.9.167-alpha.8",
|
|
72
|
+
"@budibase/client": "^0.9.167-alpha.8",
|
|
73
|
+
"@budibase/string-templates": "^0.9.167-alpha.8",
|
|
74
74
|
"@elastic/elasticsearch": "7.10.0",
|
|
75
75
|
"@koa/router": "8.0.0",
|
|
76
76
|
"@sendgrid/mail": "7.1.1",
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
"to-json-schema": "0.2.5",
|
|
120
120
|
"uuid": "3.3.2",
|
|
121
121
|
"validate.js": "0.13.1",
|
|
122
|
+
"vm2": "^3.9.3",
|
|
122
123
|
"yargs": "13.2.4",
|
|
123
124
|
"zlib": "1.0.5"
|
|
124
125
|
},
|
|
@@ -148,5 +149,5 @@
|
|
|
148
149
|
"typescript": "^4.3.5",
|
|
149
150
|
"update-dotenv": "^1.1.1"
|
|
150
151
|
},
|
|
151
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "bc396fb840e24afc2bcf01383b493bdd3d783b29"
|
|
152
153
|
}
|
|
@@ -4,6 +4,7 @@ const { generateQueryID, getQueryParams } = require("../../db/utils")
|
|
|
4
4
|
const { integrations } = require("../../integrations")
|
|
5
5
|
const { BaseQueryVerbs } = require("../../constants")
|
|
6
6
|
const env = require("../../environment")
|
|
7
|
+
const ScriptRunner = require("../../utilities/scriptRunner")
|
|
7
8
|
|
|
8
9
|
// simple function to append "readable" to all read queries
|
|
9
10
|
function enrichQueries(input) {
|
|
@@ -28,12 +29,39 @@ function formatResponse(resp) {
|
|
|
28
29
|
resp = { response: resp }
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
if (!Array.isArray(resp)) {
|
|
32
|
-
resp = [resp]
|
|
33
|
-
}
|
|
34
32
|
return resp
|
|
35
33
|
}
|
|
36
34
|
|
|
35
|
+
async function runAndTransform(
|
|
36
|
+
integration,
|
|
37
|
+
queryVerb,
|
|
38
|
+
enrichedQuery,
|
|
39
|
+
transformer
|
|
40
|
+
) {
|
|
41
|
+
let rows = formatResponse(await integration[queryVerb](enrichedQuery))
|
|
42
|
+
|
|
43
|
+
// transform as required
|
|
44
|
+
if (transformer) {
|
|
45
|
+
const runner = new ScriptRunner(transformer, { data: rows })
|
|
46
|
+
rows = runner.execute()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// needs to an array for next step
|
|
50
|
+
if (!Array.isArray(rows)) {
|
|
51
|
+
rows = [rows]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// map into JSON if just raw primitive here
|
|
55
|
+
if (rows.find(row => typeof row !== "object")) {
|
|
56
|
+
rows = rows.map(value => ({ value }))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// get all the potential fields in the schema
|
|
60
|
+
let keys = rows.flatMap(Object.keys)
|
|
61
|
+
|
|
62
|
+
return { rows, keys }
|
|
63
|
+
}
|
|
64
|
+
|
|
37
65
|
exports.fetch = async function (ctx) {
|
|
38
66
|
const db = new CouchDB(ctx.appId)
|
|
39
67
|
|
|
@@ -122,15 +150,16 @@ exports.preview = async function (ctx) {
|
|
|
122
150
|
ctx.throw(400, "Integration type does not exist.")
|
|
123
151
|
}
|
|
124
152
|
|
|
125
|
-
const { fields, parameters, queryVerb } = ctx.request.body
|
|
126
|
-
|
|
153
|
+
const { fields, parameters, queryVerb, transformer } = ctx.request.body
|
|
127
154
|
const enrichedQuery = await enrichQueryFields(fields, parameters)
|
|
128
|
-
|
|
129
155
|
const integration = new Integration(datasource.config)
|
|
130
|
-
const rows = formatResponse(await integration[queryVerb](enrichedQuery))
|
|
131
156
|
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
const { rows, keys } = await runAndTransform(
|
|
158
|
+
integration,
|
|
159
|
+
queryVerb,
|
|
160
|
+
enrichedQuery,
|
|
161
|
+
transformer
|
|
162
|
+
)
|
|
134
163
|
|
|
135
164
|
ctx.body = {
|
|
136
165
|
rows,
|
|
@@ -158,10 +187,16 @@ exports.execute = async function (ctx) {
|
|
|
158
187
|
query.fields,
|
|
159
188
|
ctx.request.body.parameters
|
|
160
189
|
)
|
|
161
|
-
|
|
162
190
|
const integration = new Integration(datasource.config)
|
|
191
|
+
|
|
163
192
|
// call the relevant CRUD method on the integration class
|
|
164
|
-
|
|
193
|
+
const { rows } = await runAndTransform(
|
|
194
|
+
integration,
|
|
195
|
+
query.queryVerb,
|
|
196
|
+
enrichedQuery,
|
|
197
|
+
query.transformer
|
|
198
|
+
)
|
|
199
|
+
ctx.body = rows
|
|
165
200
|
// cleanup
|
|
166
201
|
if (integration.end) {
|
|
167
202
|
integration.end()
|
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
const
|
|
2
|
-
const vm = require("vm")
|
|
3
|
-
|
|
4
|
-
class ScriptExecutor {
|
|
5
|
-
constructor(body) {
|
|
6
|
-
const code = `let fn = () => {\n${body.script}\n}; out = fn();`
|
|
7
|
-
this.script = new vm.Script(code)
|
|
8
|
-
this.context = vm.createContext(body.context)
|
|
9
|
-
this.context.fetch = fetch
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
execute() {
|
|
13
|
-
this.script.runInContext(this.context)
|
|
14
|
-
return this.context.out
|
|
15
|
-
}
|
|
16
|
-
}
|
|
1
|
+
const ScriptRunner = require("../../utilities/scriptRunner")
|
|
17
2
|
|
|
18
3
|
exports.execute = async function (ctx) {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
ctx.body =
|
|
4
|
+
const { script, context } = ctx.request.body
|
|
5
|
+
const runner = new ScriptRunner(script, context)
|
|
6
|
+
ctx.body = runner.execute()
|
|
22
7
|
}
|
|
23
8
|
|
|
24
9
|
exports.save = async function (ctx) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const CouchDB = require("../../../db")
|
|
2
|
-
const linkRows = require("../../../db/linkedRows")
|
|
3
2
|
const csvParser = require("../../../utilities/csvParser")
|
|
4
3
|
const {
|
|
5
4
|
getRowParams,
|
|
@@ -93,19 +92,10 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
|
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
finalData.push(
|
|
98
|
-
linkRows.updateLinks({
|
|
99
|
-
appId,
|
|
100
|
-
eventType: linkRows.EventType.ROW_SAVE,
|
|
101
|
-
row,
|
|
102
|
-
tableId: row.tableId,
|
|
103
|
-
table,
|
|
104
|
-
})
|
|
105
|
-
)
|
|
95
|
+
finalData.push(row)
|
|
106
96
|
}
|
|
107
97
|
|
|
108
|
-
await db.bulkDocs(
|
|
98
|
+
await db.bulkDocs(finalData)
|
|
109
99
|
let response = await db.put(table)
|
|
110
100
|
table._rev = response._rev
|
|
111
101
|
}
|
package/src/api/routes/query.js
CHANGED
|
@@ -31,7 +31,8 @@ function generateQueryValidation() {
|
|
|
31
31
|
})),
|
|
32
32
|
queryVerb: Joi.string().allow().required(),
|
|
33
33
|
extra: Joi.object().optional(),
|
|
34
|
-
schema: Joi.object({}).required().unknown(true)
|
|
34
|
+
schema: Joi.object({}).required().unknown(true),
|
|
35
|
+
transformer: Joi.string().optional(),
|
|
35
36
|
}))
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -42,6 +43,7 @@ function generateQueryPreviewValidation() {
|
|
|
42
43
|
queryVerb: Joi.string().allow().required(),
|
|
43
44
|
extra: Joi.object().optional(),
|
|
44
45
|
datasourceId: Joi.string().required(),
|
|
46
|
+
transformer: Joi.string().optional(),
|
|
45
47
|
parameters: Joi.object({}).required().unknown(true)
|
|
46
48
|
}))
|
|
47
49
|
}
|
|
@@ -3,7 +3,6 @@ const createRow = require("./steps/createRow")
|
|
|
3
3
|
const updateRow = require("./steps/updateRow")
|
|
4
4
|
const deleteRow = require("./steps/deleteRow")
|
|
5
5
|
const executeScript = require("./steps/executeScript")
|
|
6
|
-
const bash = require("./steps/bash")
|
|
7
6
|
const executeQuery = require("./steps/executeQuery")
|
|
8
7
|
const outgoingWebhook = require("./steps/outgoingWebhook")
|
|
9
8
|
const serverLog = require("./steps/serverLog")
|
|
@@ -14,6 +13,7 @@ const integromat = require("./steps/integromat")
|
|
|
14
13
|
let filter = require("./steps/filter")
|
|
15
14
|
let delay = require("./steps/delay")
|
|
16
15
|
let queryRow = require("./steps/queryRows")
|
|
16
|
+
const env = require("../environment")
|
|
17
17
|
|
|
18
18
|
const ACTION_IMPLS = {
|
|
19
19
|
SEND_EMAIL_SMTP: sendSmtpEmail.run,
|
|
@@ -22,7 +22,6 @@ const ACTION_IMPLS = {
|
|
|
22
22
|
DELETE_ROW: deleteRow.run,
|
|
23
23
|
OUTGOING_WEBHOOK: outgoingWebhook.run,
|
|
24
24
|
EXECUTE_SCRIPT: executeScript.run,
|
|
25
|
-
EXECUTE_BASH: bash.run,
|
|
26
25
|
EXECUTE_QUERY: executeQuery.run,
|
|
27
26
|
SERVER_LOG: serverLog.run,
|
|
28
27
|
DELAY: delay.run,
|
|
@@ -42,7 +41,6 @@ const ACTION_DEFINITIONS = {
|
|
|
42
41
|
OUTGOING_WEBHOOK: outgoingWebhook.definition,
|
|
43
42
|
EXECUTE_SCRIPT: executeScript.definition,
|
|
44
43
|
EXECUTE_QUERY: executeQuery.definition,
|
|
45
|
-
EXECUTE_BASH: bash.definition,
|
|
46
44
|
SERVER_LOG: serverLog.definition,
|
|
47
45
|
DELAY: delay.definition,
|
|
48
46
|
FILTER: filter.definition,
|
|
@@ -54,6 +52,15 @@ const ACTION_DEFINITIONS = {
|
|
|
54
52
|
integromat: integromat.definition,
|
|
55
53
|
}
|
|
56
54
|
|
|
55
|
+
// don't add the bash script/definitions unless in self host
|
|
56
|
+
// the fact this isn't included in any definitions means it cannot be
|
|
57
|
+
// ran at all
|
|
58
|
+
if (env.SELF_HOSTED) {
|
|
59
|
+
const bash = require("./steps/bash")
|
|
60
|
+
ACTION_IMPLS["EXECUTE_BASH"] = bash.run
|
|
61
|
+
ACTION_DEFINITIONS["EXECUTE_BASH"] = bash.definition
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
/* istanbul ignore next */
|
|
58
65
|
exports.getAction = async function (actionName) {
|
|
59
66
|
if (ACTION_IMPLS[actionName] != null) {
|
|
@@ -10,6 +10,7 @@ const env = require("../environment")
|
|
|
10
10
|
const usage = require("../utilities/usageQuota")
|
|
11
11
|
|
|
12
12
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
|
13
|
+
const STOPPED_STATUS = { success: false, status: "STOPPED" }
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* The automation orchestrator is a class responsible for executing automations.
|
|
@@ -68,7 +69,13 @@ class Orchestrator {
|
|
|
68
69
|
async execute() {
|
|
69
70
|
let automation = this._automation
|
|
70
71
|
const app = await this.getApp()
|
|
72
|
+
let stopped = false
|
|
71
73
|
for (let step of automation.definition.steps) {
|
|
74
|
+
// execution stopped, record state for that
|
|
75
|
+
if (stopped) {
|
|
76
|
+
this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS)
|
|
77
|
+
continue
|
|
78
|
+
}
|
|
72
79
|
let stepFn = await this.getStepFunctionality(step.stepId)
|
|
73
80
|
step.inputs = await processObject(step.inputs, this._context)
|
|
74
81
|
step.inputs = automationUtils.cleanInputValues(
|
|
@@ -86,10 +93,17 @@ class Orchestrator {
|
|
|
86
93
|
context: this._context,
|
|
87
94
|
})
|
|
88
95
|
})
|
|
96
|
+
this._context.steps.push(outputs)
|
|
97
|
+
// if filter causes us to stop execution don't break the loop, set a var
|
|
98
|
+
// so that we can finish iterating through the steps and record that it stopped
|
|
89
99
|
if (step.stepId === FILTER_STEP_ID && !outputs.success) {
|
|
90
|
-
|
|
100
|
+
stopped = true
|
|
101
|
+
this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
|
|
102
|
+
...outputs,
|
|
103
|
+
...STOPPED_STATUS,
|
|
104
|
+
})
|
|
105
|
+
continue
|
|
91
106
|
}
|
|
92
|
-
this._context.steps.push(outputs)
|
|
93
107
|
this.updateExecutionOutput(step.id, step.stepId, step.inputs, outputs)
|
|
94
108
|
} catch (err) {
|
|
95
109
|
console.error(`Automation error - ${step.stepId} - ${err}`)
|
|
@@ -99,7 +113,7 @@ class Orchestrator {
|
|
|
99
113
|
|
|
100
114
|
// Increment quota for automation runs
|
|
101
115
|
if (!env.SELF_HOSTED && !isDevAppID(this._appId)) {
|
|
102
|
-
usage.update(usage.Properties.AUTOMATION, 1)
|
|
116
|
+
await usage.update(usage.Properties.AUTOMATION, 1)
|
|
103
117
|
}
|
|
104
118
|
return this.executionOutput
|
|
105
119
|
}
|
|
@@ -27,7 +27,7 @@ describe("MongoDB Integration", () => {
|
|
|
27
27
|
const body = {
|
|
28
28
|
name: "Hello"
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
await config.integration.create({
|
|
31
31
|
index: indexName,
|
|
32
32
|
json: body,
|
|
33
33
|
extra: { collection: 'testCollection', actionTypes: 'insertOne'}
|
|
@@ -54,7 +54,7 @@ describe("MongoDB Integration", () => {
|
|
|
54
54
|
},
|
|
55
55
|
extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
await config.integration.delete(query)
|
|
58
58
|
expect(config.integration.client.deleteOne).toHaveBeenCalledWith(query.json)
|
|
59
59
|
})
|
|
60
60
|
|
|
@@ -65,7 +65,7 @@ describe("MongoDB Integration", () => {
|
|
|
65
65
|
},
|
|
66
66
|
extra: { collection: 'testCollection', actionTypes: 'updateOne'}
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
await config.integration.update(query)
|
|
69
69
|
expect(config.integration.client.updateOne).toHaveBeenCalledWith(query.json)
|
|
70
70
|
})
|
|
71
71
|
|
|
@@ -75,10 +75,14 @@ describe("MongoDB Integration", () => {
|
|
|
75
75
|
const query = {
|
|
76
76
|
extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
|
|
77
77
|
}
|
|
78
|
-
// Weird, need to do an IIFE for jest to recognize that it throws
|
|
79
|
-
expect(() => config.integration.read(query)()).toThrow(expect.any(Object))
|
|
80
78
|
|
|
79
|
+
let error = null
|
|
80
|
+
try {
|
|
81
|
+
await config.integration.read(query)
|
|
82
|
+
} catch (err) {
|
|
83
|
+
error = err
|
|
84
|
+
}
|
|
85
|
+
expect(error).toBeDefined()
|
|
81
86
|
restore()
|
|
82
87
|
})
|
|
83
|
-
|
|
84
88
|
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const fetch = require("node-fetch")
|
|
2
|
+
const { VM, VMScript } = require("vm2")
|
|
3
|
+
|
|
4
|
+
class ScriptRunner {
|
|
5
|
+
constructor(script, context) {
|
|
6
|
+
const code = `let fn = () => {\n${script}\n}; results.out = fn();`
|
|
7
|
+
this.vm = new VM()
|
|
8
|
+
this.results = { out: "" }
|
|
9
|
+
this.vm.setGlobals(context)
|
|
10
|
+
this.vm.setGlobal("fetch", fetch)
|
|
11
|
+
this.vm.setGlobal("results", this.results)
|
|
12
|
+
this.script = new VMScript(code)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute() {
|
|
16
|
+
this.vm.run(this.script)
|
|
17
|
+
return this.results.out
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = ScriptRunner
|