@budibase/server 0.9.185-alpha.0 → 0.9.185-alpha.12
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/Dockerfile +1 -1
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.4a7c5636.css +1 -0
- package/builder/assets/index.708945dd.js +1316 -0
- package/builder/assets/vendor.470042a4.js +152 -0
- package/builder/assets/vendor.5e1fe644.css +1 -0
- package/builder/index.html +4 -4
- package/coverage/clover.xml +1060 -928
- package/coverage/coverage-final.json +90 -88
- package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
- package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
- package/coverage/lcov-report/api/controllers/application.js.html +43 -13
- package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
- package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
- 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 +4 -4
- package/coverage/lcov-report/api/controllers/datasource.js.html +31 -7
- package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
- package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
- package/coverage/lcov-report/api/controllers/index.html +75 -75
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
- package/coverage/lcov-report/api/controllers/query.js.html +48 -210
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
- package/coverage/lcov-report/api/controllers/row/external.js.html +12 -6
- package/coverage/lcov-report/api/controllers/row/index.html +18 -18
- package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/utils.js.html +2 -2
- package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
- package/coverage/lcov-report/api/controllers/script.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/external.js.html +65 -8
- package/coverage/lcov-report/api/controllers/table/index.html +42 -42
- package/coverage/lcov-report/api/controllers/table/index.js.html +66 -12
- package/coverage/lcov-report/api/controllers/table/internal.js.html +49 -10
- package/coverage/lcov-report/api/controllers/table/utils.js.html +57 -45
- package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
- package/coverage/lcov-report/api/controllers/user.js.html +33 -18
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +9 -9
- package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
- package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
- 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 +2 -2
- package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +4 -4
- 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 +5 -2
- 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 +2 -2
- package/coverage/lcov-report/api/routes/table.js.html +35 -2
- 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 +2 -2
- package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
- package/coverage/lcov-report/automations/bullboard.js.html +71 -20
- package/coverage/lcov-report/automations/index.html +33 -48
- package/coverage/lcov-report/automations/index.js.html +2 -2
- 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 +3 -3
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +14 -14
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
- package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
- 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 +7 -7
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +22 -10
- package/coverage/lcov-report/automations/utils.js.html +42 -12
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +5 -2
- 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 +2 -2
- package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
- package/coverage/lcov-report/db/index.html +2 -2
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
- 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 +6 -6
- package/coverage/lcov-report/events/index.html +6 -6
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +5 -5
- package/coverage/lcov-report/index.html +94 -79
- 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 +2 -2
- package/coverage/lcov-report/middleware/authorized.js.html +5 -5
- package/coverage/lcov-report/middleware/builder.js.html +16 -7
- package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
- package/coverage/lcov-report/middleware/index.html +21 -21
- package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
- package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
- package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
- package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +83 -32
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +260 -0
- package/coverage/lcov-report/threads/query.js.html +269 -0
- 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 +144 -15
- package/coverage/lcov-report/utilities/global.js.html +2 -2
- package/coverage/lcov-report/utilities/index.html +34 -34
- package/coverage/lcov-report/utilities/index.js.html +12 -9
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
- package/coverage/lcov-report/utilities/queue/index.html +14 -14
- 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 +4 -4
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
- package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
- package/coverage/lcov-report/utilities/security.js.html +3 -3
- 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 +5 -5
- package/coverage/lcov.info +1753 -1527
- package/dist/api/controllers/application.js +11 -1
- package/dist/api/controllers/datasource.js +6 -2
- package/dist/api/controllers/deploy/index.js +2 -0
- package/dist/api/controllers/dev.js +4 -1
- package/dist/api/controllers/query.js +27 -57
- package/dist/api/controllers/row/ExternalRequest.js +2 -2
- package/dist/api/controllers/row/external.js +1 -0
- package/dist/api/controllers/table/external.js +17 -0
- package/dist/api/controllers/table/index.js +21 -2
- package/dist/api/controllers/table/internal.js +10 -1
- package/dist/api/controllers/table/utils.js +28 -27
- package/dist/api/controllers/user.js +10 -6
- package/dist/api/routes/query.js +1 -1
- package/dist/api/routes/table.js +7 -1
- package/dist/app.js +2 -11
- package/dist/automations/bullboard.js +37 -10
- package/dist/automations/triggers.js +7 -3
- package/dist/automations/utils.js +11 -2
- package/dist/constants/index.js +1 -0
- package/dist/definitions/datasource.js +1 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/sql.js +48 -8
- package/dist/integrations/base/sqlTable.js +1 -2
- package/dist/integrations/mysql.js +3 -1
- package/dist/integrations/postgres.js +2 -2
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +7 -6
- package/dist/{automations/thread.js → threads/automation.js} +23 -7
- package/dist/threads/index.js +58 -0
- package/dist/threads/query.js +61 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/csvParser.js +46 -5
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +8 -7
- package/scripts/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +11 -1
- package/src/api/controllers/datasource.js +10 -2
- package/src/api/controllers/deploy/index.js +2 -0
- package/src/api/controllers/dev.js +4 -1
- package/src/api/controllers/query.js +26 -80
- package/src/api/controllers/row/ExternalRequest.ts +6 -2
- package/src/api/controllers/row/external.js +2 -0
- package/src/api/controllers/table/external.js +19 -0
- package/src/api/controllers/table/index.js +20 -2
- package/src/api/controllers/table/internal.js +14 -1
- package/src/api/controllers/table/utils.js +36 -32
- package/src/api/controllers/user.js +15 -10
- package/src/api/routes/query.js +1 -0
- package/src/api/routes/table.js +11 -0
- package/src/api/routes/tests/misc.spec.js +5 -1
- package/src/app.ts +2 -10
- package/src/automations/bullboard.js +28 -11
- package/src/automations/tests/automation.spec.js +3 -4
- package/src/automations/triggers.js +7 -3
- package/src/automations/utils.js +12 -2
- package/src/constants/index.js +1 -0
- package/src/definitions/datasource.ts +3 -2
- package/src/integrations/airtable.ts +2 -1
- package/src/integrations/arangodb.ts +2 -1
- package/src/integrations/base/IntegrationBase.ts +6 -0
- package/src/integrations/base/datasourcePlus.ts +2 -1
- package/src/integrations/base/sql.ts +51 -9
- package/src/integrations/base/sqlTable.ts +1 -4
- package/src/integrations/couchdb.ts +2 -1
- package/src/integrations/dynamodb.ts +2 -1
- package/src/integrations/elasticsearch.ts +2 -1
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +1 -1
- package/src/integrations/postgres.ts +5 -5
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +2 -1
- package/src/middleware/builder.js +4 -1
- package/src/{automations/thread.js → threads/automation.js} +24 -7
- package/src/threads/index.js +60 -0
- package/src/threads/query.js +63 -0
- package/src/utilities/csvParser.js +48 -5
- package/src/utilities/index.js +1 -0
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/scriptRunner.js +4 -1
- package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
- package/src/utilities/tests/csvParser.spec.js +3 -0
- package/tsconfig.json +1 -1
- package/builder/assets/index.0e6a5c20.js +0 -201
- package/builder/assets/index.cf21e4d2.css +0 -29
- package/builder/assets/vendor.278a305c.js +0 -9
- package/builder/assets/vendor.d75d5eb7.css +0 -1
|
@@ -97,6 +97,7 @@ exports.syncUser = async function (ctx) {
|
|
|
97
97
|
.map(([appId]) => appId)
|
|
98
98
|
}
|
|
99
99
|
for (let prodAppId of prodAppIds) {
|
|
100
|
+
const roleId = roles[prodAppId]
|
|
100
101
|
const devAppId = getDevelopmentAppID(prodAppId)
|
|
101
102
|
for (let appId of [prodAppId, devAppId]) {
|
|
102
103
|
if (!(await doesDatabaseExist(appId))) {
|
|
@@ -115,17 +116,21 @@ exports.syncUser = async function (ctx) {
|
|
|
115
116
|
tableId: InternalTables.USER_METADATA,
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
// assign the roleId for the metadata doc
|
|
120
|
+
if (roleId) {
|
|
121
|
+
metadata.roleId = roleId
|
|
122
|
+
}
|
|
123
|
+
let combined = !deleting
|
|
124
|
+
? combineMetadataAndUser(user, metadata)
|
|
125
|
+
: {
|
|
126
|
+
...metadata,
|
|
127
|
+
status: UserStatus.INACTIVE,
|
|
128
|
+
metadata: BUILTIN_ROLE_IDS.PUBLIC,
|
|
129
|
+
}
|
|
130
|
+
// if its null then there was no updates required
|
|
131
|
+
if (combined) {
|
|
132
|
+
await db.put(combined)
|
|
127
133
|
}
|
|
128
|
-
await db.put(combined)
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
ctx.body = {
|
package/src/api/routes/query.js
CHANGED
package/src/api/routes/table.js
CHANGED
|
@@ -53,5 +53,16 @@ router
|
|
|
53
53
|
authorized(BUILDER),
|
|
54
54
|
tableController.destroy
|
|
55
55
|
)
|
|
56
|
+
// this is currently builder only, but in the future
|
|
57
|
+
// it could be carried out by an end user in app,
|
|
58
|
+
// however some thought will need to be had about
|
|
59
|
+
// implications for automations (triggers)
|
|
60
|
+
// new trigger type, bulk rows created
|
|
61
|
+
.post(
|
|
62
|
+
"/api/tables/:tableId/import",
|
|
63
|
+
paramResource("tableId"),
|
|
64
|
+
authorized(BUILDER),
|
|
65
|
+
tableController.bulkImport
|
|
66
|
+
)
|
|
56
67
|
|
|
57
68
|
module.exports = router
|
|
@@ -75,7 +75,11 @@ describe("run misc tests", () => {
|
|
|
75
75
|
},
|
|
76
76
|
})
|
|
77
77
|
const dataImport = {
|
|
78
|
-
csvString: "a,b,c,d\n1,2,3,4"
|
|
78
|
+
csvString: "a,b,c,d\n1,2,3,4",
|
|
79
|
+
schema: {},
|
|
80
|
+
}
|
|
81
|
+
for (let col of ["a", "b", "c", "d"]) {
|
|
82
|
+
dataImport.schema[col] = { type: "string" }
|
|
79
83
|
}
|
|
80
84
|
await tableUtils.handleDataImport(
|
|
81
85
|
config.getAppId(),
|
package/src/app.ts
CHANGED
|
@@ -41,16 +41,8 @@ app.use(
|
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
if (!env.isTest()) {
|
|
44
|
-
const
|
|
45
|
-
app.use(
|
|
46
|
-
if (ctx.path.startsWith(bullboard.pathPrefix)) {
|
|
47
|
-
ctx.status = 200
|
|
48
|
-
ctx.respond = false
|
|
49
|
-
bullApp(ctx.req, ctx.res)
|
|
50
|
-
} else {
|
|
51
|
-
await next()
|
|
52
|
-
}
|
|
53
|
-
})
|
|
44
|
+
const plugin = bullboard.init()
|
|
45
|
+
app.use(plugin)
|
|
54
46
|
}
|
|
55
47
|
|
|
56
48
|
app.context.eventEmitter = eventEmitter
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const { createBullBoard } = require("bull-board")
|
|
2
|
-
const { BullAdapter } = require("bull-board/bullAdapter")
|
|
3
|
-
const
|
|
1
|
+
const { createBullBoard } = require("@bull-board/api")
|
|
2
|
+
const { BullAdapter } = require("@bull-board/api/bullAdapter")
|
|
3
|
+
const { KoaAdapter } = require("@bull-board/koa")
|
|
4
4
|
const env = require("../environment")
|
|
5
5
|
const Queue = env.isTest()
|
|
6
6
|
? require("../utilities/queue/inMemoryQueue")
|
|
@@ -9,23 +9,40 @@ const { JobQueues } = require("../constants")
|
|
|
9
9
|
const { utils } = require("@budibase/auth/redis")
|
|
10
10
|
const { opts, redisProtocolUrl } = utils.getRedisOptions()
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const CLEANUP_PERIOD_MS = 60 * 1000
|
|
13
|
+
const queueConfig = redisProtocolUrl || { redis: opts }
|
|
14
|
+
let cleanupInternal = null
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
let automationQueue = new Queue(JobQueues.AUTOMATIONS, queueConfig)
|
|
17
|
+
|
|
18
|
+
async function cleanup() {
|
|
19
|
+
await automationQueue.clean(CLEANUP_PERIOD_MS, "completed")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const PATH_PREFIX = "/bulladmin"
|
|
16
23
|
|
|
17
24
|
exports.init = () => {
|
|
18
|
-
|
|
25
|
+
// cleanup the events every 5 minutes
|
|
26
|
+
if (!cleanupInternal) {
|
|
27
|
+
cleanupInternal = setInterval(cleanup, CLEANUP_PERIOD_MS)
|
|
28
|
+
// fire off an initial cleanup
|
|
29
|
+
cleanup().catch(err => {
|
|
30
|
+
console.error(`Unable to cleanup automation queue initially - ${err}`)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
19
33
|
// Set up queues for bull board admin
|
|
20
34
|
const queues = [automationQueue]
|
|
21
35
|
const adapters = []
|
|
36
|
+
const serverAdapter = new KoaAdapter()
|
|
22
37
|
for (let queue of queues) {
|
|
23
38
|
adapters.push(new BullAdapter(queue))
|
|
24
39
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
createBullBoard({
|
|
41
|
+
queues: adapters,
|
|
42
|
+
serverAdapter,
|
|
43
|
+
})
|
|
44
|
+
serverAdapter.setBasePath(PATH_PREFIX)
|
|
45
|
+
return serverAdapter.registerPlugin()
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
exports.queue = automationQueue
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
jest.mock("../../utilities/usageQuota")
|
|
2
|
-
jest.mock("
|
|
2
|
+
jest.mock("../../threads/automation")
|
|
3
3
|
jest.mock("../../utilities/redis", () => ({
|
|
4
4
|
init: jest.fn(),
|
|
5
5
|
checkTestFlag: () => {
|
|
@@ -11,8 +11,7 @@ jest.spyOn(global.console, "error")
|
|
|
11
11
|
|
|
12
12
|
require("../../environment")
|
|
13
13
|
const automation = require("../index")
|
|
14
|
-
const
|
|
15
|
-
const thread = require("../thread")
|
|
14
|
+
const thread = require("../../threads/automation")
|
|
16
15
|
const triggers = require("../triggers")
|
|
17
16
|
const { basicAutomation } = require("../../tests/utilities/structures")
|
|
18
17
|
const { wait } = require("../../utilities")
|
|
@@ -62,7 +61,7 @@ describe("Run through some parts of the automations system", () => {
|
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
|
-
}))
|
|
64
|
+
}), expect.any(Function))
|
|
66
65
|
})
|
|
67
66
|
|
|
68
67
|
it("should be able to clean inputs with the utilities", () => {
|
|
@@ -11,6 +11,10 @@ const utils = require("./utils")
|
|
|
11
11
|
const env = require("../environment")
|
|
12
12
|
|
|
13
13
|
const TRIGGER_DEFINITIONS = definitions
|
|
14
|
+
const JOB_OPTS = {
|
|
15
|
+
removeOnComplete: true,
|
|
16
|
+
removeOnFail: true,
|
|
17
|
+
}
|
|
14
18
|
|
|
15
19
|
async function queueRelevantRowAutomations(event, eventType) {
|
|
16
20
|
if (event.appId == null) {
|
|
@@ -47,7 +51,7 @@ async function queueRelevantRowAutomations(event, eventType) {
|
|
|
47
51
|
automationTrigger.inputs &&
|
|
48
52
|
automationTrigger.inputs.tableId === event.row.tableId
|
|
49
53
|
) {
|
|
50
|
-
await queue.add({ automation, event })
|
|
54
|
+
await queue.add({ automation, event }, JOB_OPTS)
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
@@ -86,7 +90,7 @@ exports.externalTrigger = async function (
|
|
|
86
90
|
automation.definition.trigger != null &&
|
|
87
91
|
automation.definition.trigger.stepId === definitions.APP.stepId &&
|
|
88
92
|
automation.definition.trigger.stepId === "APP" &&
|
|
89
|
-
!checkTestFlag(automation._id)
|
|
93
|
+
!(await checkTestFlag(automation._id))
|
|
90
94
|
) {
|
|
91
95
|
// values are likely to be submitted as strings, so we shall convert to correct type
|
|
92
96
|
const coercedFields = {}
|
|
@@ -100,7 +104,7 @@ exports.externalTrigger = async function (
|
|
|
100
104
|
if (getResponses) {
|
|
101
105
|
return utils.processEvent({ data })
|
|
102
106
|
} else {
|
|
103
|
-
return queue.add(data)
|
|
107
|
+
return queue.add(data, JOB_OPTS)
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
|
package/src/automations/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { Thread, ThreadType } = require("../threads")
|
|
2
2
|
const { definitions } = require("./triggerInfo")
|
|
3
3
|
const webhooks = require("../api/controllers/webhook")
|
|
4
4
|
const CouchDB = require("../db")
|
|
@@ -10,11 +10,12 @@ const { getDeployedAppID } = require("@budibase/auth/db")
|
|
|
10
10
|
|
|
11
11
|
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
|
12
12
|
const CRON_STEP_ID = definitions.CRON.stepId
|
|
13
|
+
const Runner = new Thread(ThreadType.AUTOMATION)
|
|
13
14
|
|
|
14
15
|
exports.processEvent = async job => {
|
|
15
16
|
try {
|
|
16
17
|
// need to actually await these so that an error can be captured properly
|
|
17
|
-
return await
|
|
18
|
+
return await Runner.run(job)
|
|
18
19
|
} catch (err) {
|
|
19
20
|
console.error(
|
|
20
21
|
`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`
|
|
@@ -162,3 +163,12 @@ exports.checkForWebhooks = async ({ appId, oldAuto, newAuto }) => {
|
|
|
162
163
|
}
|
|
163
164
|
return newAuto
|
|
164
165
|
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* When removing an app/unpublishing it need to make sure automations are cleaned up (cron).
|
|
169
|
+
* @param appId {string} the app that is being removed.
|
|
170
|
+
* @return {Promise<void>} clean is complete if this succeeds.
|
|
171
|
+
*/
|
|
172
|
+
exports.cleanupAutomations = async appId => {
|
|
173
|
+
await exports.disableAllCrons(appId)
|
|
174
|
+
}
|
package/src/constants/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Table } from "./common"
|
|
1
|
+
import { Row, Table } from "./common"
|
|
2
2
|
|
|
3
3
|
export enum Operation {
|
|
4
4
|
CREATE = "CREATE",
|
|
5
5
|
READ = "READ",
|
|
6
6
|
UPDATE = "UPDATE",
|
|
7
7
|
DELETE = "DELETE",
|
|
8
|
+
BULK_CREATE = "BULK_CREATE",
|
|
8
9
|
CREATE_TABLE = "CREATE_TABLE",
|
|
9
10
|
UPDATE_TABLE = "UPDATE_TABLE",
|
|
10
11
|
DELETE_TABLE = "DELETE_TABLE",
|
|
@@ -144,7 +145,7 @@ export interface QueryJson {
|
|
|
144
145
|
filters?: SearchFilters
|
|
145
146
|
sort?: SortJson
|
|
146
147
|
paginate?: PaginationJson
|
|
147
|
-
body?:
|
|
148
|
+
body?: Row | Row[]
|
|
148
149
|
table?: Table
|
|
149
150
|
meta?: {
|
|
150
151
|
table?: Table
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module AirtableModule {
|
|
8
9
|
const Airtable = require("airtable")
|
|
@@ -73,7 +74,7 @@ module AirtableModule {
|
|
|
73
74
|
},
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
class AirtableIntegration {
|
|
77
|
+
class AirtableIntegration implements IntegrationBase {
|
|
77
78
|
private config: AirtableConfig
|
|
78
79
|
private client: any
|
|
79
80
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module ArangoModule {
|
|
8
9
|
const { Database, aql } = require("arangojs")
|
|
@@ -55,7 +56,7 @@ module ArangoModule {
|
|
|
55
56
|
},
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
class ArangoDBIntegration {
|
|
59
|
+
class ArangoDBIntegration implements IntegrationBase {
|
|
59
60
|
private config: ArangodbConfig
|
|
60
61
|
private client: any
|
|
61
62
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Table } from "../../definitions/common"
|
|
2
|
+
import { IntegrationBase } from "./IntegrationBase"
|
|
2
3
|
|
|
3
|
-
export interface DatasourcePlus {
|
|
4
|
+
export interface DatasourcePlus extends IntegrationBase {
|
|
4
5
|
tables: Record<string, Table>
|
|
5
6
|
schemaErrors: Record<string, string>
|
|
6
7
|
|
|
@@ -13,22 +13,50 @@ import SqlTableQueryBuilder from "./sqlTable"
|
|
|
13
13
|
const BASE_LIMIT = 5000
|
|
14
14
|
|
|
15
15
|
type KnexQuery = Knex.QueryBuilder | Knex
|
|
16
|
+
// these are invalid dates sent by the client, need to convert them to a real max date
|
|
17
|
+
const MIN_ISO_DATE = "0000-00-00T00:00:00.000Z"
|
|
18
|
+
const MAX_ISO_DATE = "9999-00-00T00:00:00.000Z"
|
|
19
|
+
|
|
20
|
+
function parse(input: any) {
|
|
21
|
+
if (Array.isArray(input)) {
|
|
22
|
+
return JSON.stringify(input)
|
|
23
|
+
}
|
|
24
|
+
if (typeof input !== "string") {
|
|
25
|
+
return input
|
|
26
|
+
}
|
|
27
|
+
if (input === MAX_ISO_DATE) {
|
|
28
|
+
return new Date(8640000000000000)
|
|
29
|
+
}
|
|
30
|
+
if (input === MIN_ISO_DATE) {
|
|
31
|
+
return new Date(-8640000000000000)
|
|
32
|
+
}
|
|
33
|
+
if (isIsoDateString(input)) {
|
|
34
|
+
return new Date(input)
|
|
35
|
+
}
|
|
36
|
+
return input
|
|
37
|
+
}
|
|
16
38
|
|
|
17
39
|
function parseBody(body: any) {
|
|
18
40
|
for (let [key, value] of Object.entries(body)) {
|
|
19
|
-
|
|
20
|
-
body[key] = JSON.stringify(value)
|
|
21
|
-
}
|
|
22
|
-
if (typeof value !== "string") {
|
|
23
|
-
continue
|
|
24
|
-
}
|
|
25
|
-
if (isIsoDateString(value)) {
|
|
26
|
-
body[key] = new Date(value)
|
|
27
|
-
}
|
|
41
|
+
body[key] = parse(value)
|
|
28
42
|
}
|
|
29
43
|
return body
|
|
30
44
|
}
|
|
31
45
|
|
|
46
|
+
function parseFilters(filters: SearchFilters): SearchFilters {
|
|
47
|
+
for (let [key, value] of Object.entries(filters)) {
|
|
48
|
+
let parsed
|
|
49
|
+
if (typeof value === "object") {
|
|
50
|
+
parsed = parseFilters(value)
|
|
51
|
+
} else {
|
|
52
|
+
parsed = parse(value)
|
|
53
|
+
}
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
filters[key] = parsed
|
|
56
|
+
}
|
|
57
|
+
return filters
|
|
58
|
+
}
|
|
59
|
+
|
|
32
60
|
class InternalBuilder {
|
|
33
61
|
private readonly client: string
|
|
34
62
|
|
|
@@ -53,6 +81,7 @@ class InternalBuilder {
|
|
|
53
81
|
if (!filters) {
|
|
54
82
|
return query
|
|
55
83
|
}
|
|
84
|
+
filters = parseFilters(filters)
|
|
56
85
|
// if all or specified in filters, then everything is an or
|
|
57
86
|
const allOr = filters.allOr
|
|
58
87
|
if (filters.oneOf) {
|
|
@@ -179,6 +208,16 @@ class InternalBuilder {
|
|
|
179
208
|
}
|
|
180
209
|
}
|
|
181
210
|
|
|
211
|
+
bulkCreate(knex: Knex, json: QueryJson): KnexQuery {
|
|
212
|
+
const { endpoint, body } = json
|
|
213
|
+
let query: KnexQuery = knex(endpoint.entityId)
|
|
214
|
+
if (!Array.isArray(body)) {
|
|
215
|
+
return query
|
|
216
|
+
}
|
|
217
|
+
const parsedBody = body.map(row => parseBody(row))
|
|
218
|
+
return query.insert(parsedBody)
|
|
219
|
+
}
|
|
220
|
+
|
|
182
221
|
read(knex: Knex, json: QueryJson, limit: number): KnexQuery {
|
|
183
222
|
let { endpoint, resource, filters, sort, paginate, relationships } = json
|
|
184
223
|
const tableName = endpoint.entityId
|
|
@@ -294,6 +333,9 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
|
|
|
294
333
|
case Operation.DELETE:
|
|
295
334
|
query = builder.delete(client, json, opts)
|
|
296
335
|
break
|
|
336
|
+
case Operation.BULK_CREATE:
|
|
337
|
+
query = builder.bulkCreate(client, json)
|
|
338
|
+
break
|
|
297
339
|
case Operation.CREATE_TABLE:
|
|
298
340
|
case Operation.UPDATE_TABLE:
|
|
299
341
|
case Operation.DELETE_TABLE:
|
|
@@ -29,10 +29,7 @@ function generateSchema(
|
|
|
29
29
|
for (let [key, column] of Object.entries(table.schema)) {
|
|
30
30
|
// skip things that are already correct
|
|
31
31
|
const oldColumn = oldTable ? oldTable.schema[key] : null
|
|
32
|
-
if (
|
|
33
|
-
(oldColumn && oldColumn.type) ||
|
|
34
|
-
(primaryKey === key && !isJunction)
|
|
35
|
-
) {
|
|
32
|
+
if ((oldColumn && oldColumn.type) || (primaryKey === key && !isJunction)) {
|
|
36
33
|
continue
|
|
37
34
|
}
|
|
38
35
|
switch (column.type) {
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module CouchDBModule {
|
|
8
9
|
const PouchDB = require("pouchdb")
|
|
@@ -50,7 +51,7 @@ module CouchDBModule {
|
|
|
50
51
|
},
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
class CouchDBIntegration {
|
|
54
|
+
class CouchDBIntegration implements IntegrationBase {
|
|
54
55
|
private config: CouchDBConfig
|
|
55
56
|
private client: any
|
|
56
57
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module DynamoModule {
|
|
8
9
|
const AWS = require("aws-sdk")
|
|
@@ -113,7 +114,7 @@ module DynamoModule {
|
|
|
113
114
|
},
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
class DynamoDBIntegration {
|
|
117
|
+
class DynamoDBIntegration implements IntegrationBase {
|
|
117
118
|
private config: DynamoDBConfig
|
|
118
119
|
private client: any
|
|
119
120
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module ElasticsearchModule {
|
|
8
9
|
const { Client } = require("@elastic/elasticsearch")
|
|
@@ -74,7 +75,7 @@ module ElasticsearchModule {
|
|
|
74
75
|
},
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
class ElasticSearchIntegration {
|
|
78
|
+
class ElasticSearchIntegration implements IntegrationBase {
|
|
78
79
|
private config: ElasticsearchConfig
|
|
79
80
|
private client: any
|
|
80
81
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module MongoDBModule {
|
|
8
9
|
const { MongoClient } = require("mongodb")
|
|
@@ -62,7 +63,7 @@ module MongoDBModule {
|
|
|
62
63
|
},
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
class MongoIntegration {
|
|
66
|
+
class MongoIntegration implements IntegrationBase {
|
|
66
67
|
private config: MongoDBConfig
|
|
67
68
|
private client: any
|
|
68
69
|
|
|
@@ -130,7 +130,7 @@ module PostgresModule {
|
|
|
130
130
|
public tables: Record<string, Table> = {}
|
|
131
131
|
public schemaErrors: Record<string, string> = {}
|
|
132
132
|
|
|
133
|
-
COLUMNS_SQL!: string
|
|
133
|
+
COLUMNS_SQL!: string
|
|
134
134
|
|
|
135
135
|
PRIMARY_KEYS_SQL = `
|
|
136
136
|
select tc.table_schema, tc.table_name, kc.column_name as primary_key
|
|
@@ -165,11 +165,11 @@ module PostgresModule {
|
|
|
165
165
|
|
|
166
166
|
setSchema() {
|
|
167
167
|
if (!this.config.schema) {
|
|
168
|
-
this.config.schema =
|
|
168
|
+
this.config.schema = "public"
|
|
169
169
|
}
|
|
170
|
-
this.client.on(
|
|
171
|
-
client.query(`SET search_path TO ${this.config.schema}`)
|
|
172
|
-
})
|
|
170
|
+
this.client.on("connect", (client: any) => {
|
|
171
|
+
client.query(`SET search_path TO ${this.config.schema}`)
|
|
172
|
+
})
|
|
173
173
|
this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`
|
|
174
174
|
}
|
|
175
175
|
|
package/src/integrations/rest.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module RestModule {
|
|
8
9
|
const fetch = require("node-fetch")
|
|
@@ -131,7 +132,7 @@ module RestModule {
|
|
|
131
132
|
},
|
|
132
133
|
}
|
|
133
134
|
|
|
134
|
-
class RestIntegration {
|
|
135
|
+
class RestIntegration implements IntegrationBase {
|
|
135
136
|
private config: RestConfig
|
|
136
137
|
private headers: {
|
|
137
138
|
[key: string]: string
|
package/src/integrations/s3.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Integration, QueryTypes } from "../definitions/datasource"
|
|
2
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
2
3
|
|
|
3
4
|
module S3Module {
|
|
4
5
|
const AWS = require("aws-sdk")
|
|
@@ -42,7 +43,7 @@ module S3Module {
|
|
|
42
43
|
},
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
class S3Integration {
|
|
46
|
+
class S3Integration implements IntegrationBase {
|
|
46
47
|
private readonly config: S3Config
|
|
47
48
|
private client: any
|
|
48
49
|
private connectionPromise: Promise<any>
|
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
const CouchDB = require("../db")
|
|
9
9
|
const { DocumentTypes } = require("../db/utils")
|
|
10
10
|
const { PermissionTypes } = require("@budibase/auth/permissions")
|
|
11
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
11
12
|
|
|
12
13
|
const DEBOUNCE_TIME_SEC = 30
|
|
13
14
|
|
|
@@ -50,7 +51,9 @@ async function updateAppUpdatedAt(ctx) {
|
|
|
50
51
|
const db = new CouchDB(appId)
|
|
51
52
|
const metadata = await db.get(DocumentTypes.APP_METADATA)
|
|
52
53
|
metadata.updatedAt = new Date().toISOString()
|
|
53
|
-
await db.put(metadata)
|
|
54
|
+
const response = await db.put(metadata)
|
|
55
|
+
metadata._rev = response.rev
|
|
56
|
+
await appCache.invalidateAppMetadata(appId, metadata)
|
|
54
57
|
// set a new debounce record with a short TTL
|
|
55
58
|
await setDebounce(appId, DEBOUNCE_TIME_SEC)
|
|
56
59
|
}
|