@budibase/server 1.3.12 → 1.3.15-alpha.0
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/__mocks__/mongodb.ts +1 -1
- package/builder/assets/index.b266d29f.js +995 -0
- package/builder/assets/{index.e50bda9f.css → index.f5c54dd2.css} +2 -2
- package/builder/index.html +2 -4
- package/coverage/clover.xml +377 -313
- package/coverage/coverage-final.json +22 -22
- package/coverage/lcov-report/api/controllers/apikeys.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 +8 -5
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +82 -13
- package/coverage/lcov-report/api/controllers/datasource.js.html +20 -20
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +32 -32
- package/coverage/lcov-report/api/controllers/integration.js.html +6 -6
- 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/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/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 +204 -12
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.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 +12 -12
- 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/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/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/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.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 +1 -1
- 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 +24 -24
- package/coverage/lcov-report/automations/index.js.html +18 -9
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.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/loop.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/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 +126 -24
- 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/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +18 -18
- 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 +2 -2
- package/coverage/lcov-report/db/utils.js.html +56 -20
- 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 +48 -48
- 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/builder.js.html +12 -12
- package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
- 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/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +16 -16
- package/coverage/lcov-report/utilities/index.html +19 -19
- package/coverage/lcov-report/utilities/index.js.html +66 -42
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
- 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 +5 -5
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +4 -4
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +2 -2
- 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/rows.js.html +6 -3
- 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 +692 -564
- package/dist/api/controllers/application.js +6 -9
- package/dist/api/controllers/backup.js +2 -1
- package/dist/api/controllers/component.js +18 -1
- package/dist/api/controllers/datasource.js +4 -4
- package/dist/api/controllers/deploy/index.js +17 -2
- package/dist/api/controllers/integration.js +4 -4
- package/dist/api/controllers/plugin.js +119 -0
- package/dist/api/controllers/row/ExternalRequest.js +1 -1
- package/dist/api/controllers/screen.js +51 -2
- package/dist/api/controllers/static/index.js +1 -0
- package/dist/api/controllers/static/templates/BudibaseApp.svelte +10 -0
- package/dist/api/controllers/static/templates/preview.hbs +3 -1
- package/dist/api/routes/index.js +2 -0
- package/dist/api/routes/plugin.js +38 -0
- package/dist/app.js +9 -0
- package/dist/automations/index.js +10 -5
- package/dist/automations/triggers.js +39 -5
- package/dist/automations/utils.js +16 -7
- package/dist/db/utils.js +10 -1
- package/dist/environment.js +1 -0
- package/dist/integrations/airtable.js +126 -129
- package/dist/integrations/arangodb.js +86 -89
- package/dist/integrations/base/query.js +2 -2
- package/dist/integrations/couchdb.js +80 -83
- package/dist/integrations/dynamodb.js +161 -164
- package/dist/integrations/elasticsearch.js +135 -138
- package/dist/integrations/firebase.js +154 -157
- package/dist/integrations/googlesheets.js +323 -327
- package/dist/integrations/index.js +93 -51
- package/dist/integrations/microsoftSqlServer.js +240 -243
- package/dist/integrations/mongodb.js +239 -242
- package/dist/integrations/mysql.js +215 -219
- package/dist/integrations/oracle.js +318 -322
- package/dist/integrations/postgres.js +262 -265
- package/dist/integrations/redis.js +134 -139
- package/dist/integrations/rest.js +293 -281
- package/dist/integrations/s3.js +61 -64
- package/dist/integrations/snowflake.js +83 -86
- package/dist/package.json +8 -6
- package/dist/threads/automation.js +6 -0
- package/dist/threads/query.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +71 -6
- package/dist/utilities/index.js +8 -0
- package/dist/utilities/rowProcessor/utils.js +1 -1
- package/dist/utilities/usageQuota/rows.js +2 -1
- package/dist/watch.js +77 -0
- package/package.json +9 -7
- package/scripts/dev/manage.js +1 -0
- package/src/api/controllers/application.ts +2 -6
- package/src/api/controllers/backup.js +2 -1
- package/src/api/controllers/component.js +25 -2
- package/src/api/controllers/datasource.js +4 -4
- package/src/api/controllers/deploy/index.ts +17 -4
- package/src/api/controllers/integration.js +4 -4
- package/src/api/controllers/plugin.ts +110 -0
- package/src/api/controllers/row/ExternalRequest.ts +1 -1
- package/src/api/controllers/screen.js +65 -1
- package/src/api/controllers/static/index.ts +1 -0
- package/src/api/controllers/static/templates/BudibaseApp.svelte +10 -0
- package/src/api/controllers/static/templates/preview.hbs +3 -1
- package/src/api/routes/index.ts +2 -0
- package/src/api/routes/plugin.ts +13 -0
- package/src/api/routes/tests/query.spec.js +11 -28
- package/src/app.ts +12 -0
- package/src/automations/index.js +6 -3
- package/src/automations/triggers.js +44 -10
- package/src/automations/utils.ts +21 -9
- package/src/db/utils.js +12 -0
- package/src/definitions/datasource.ts +1 -0
- package/src/environment.js +1 -0
- package/src/integrations/airtable.ts +116 -118
- package/src/integrations/arangodb.ts +87 -89
- package/src/integrations/base/query.ts +2 -2
- package/src/integrations/couchdb.ts +83 -89
- package/src/integrations/dynamodb.ts +173 -175
- package/src/integrations/elasticsearch.ts +120 -122
- package/src/integrations/firebase.ts +157 -159
- package/src/integrations/googlesheets.ts +328 -338
- package/src/integrations/index.ts +59 -21
- package/src/integrations/microsoftSqlServer.ts +249 -251
- package/src/integrations/mongodb.ts +261 -258
- package/src/integrations/mysql.ts +229 -234
- package/src/integrations/oracle.ts +373 -380
- package/src/integrations/postgres.ts +264 -268
- package/src/integrations/redis.ts +128 -132
- package/src/integrations/rest.ts +325 -317
- package/src/integrations/s3.ts +68 -71
- package/src/integrations/snowflake.ts +80 -82
- package/src/integrations/tests/{airtable.spec.js → airtable.spec.ts} +21 -18
- package/src/integrations/tests/{arangodb.spec.js → arangodb.spec.ts} +12 -9
- package/src/integrations/tests/{couchdb.spec.js → couchdb.spec.ts} +33 -27
- package/src/integrations/tests/{dynamodb.spec.js → dynamodb.spec.ts} +45 -41
- package/src/integrations/tests/{elasticsearch.spec.js → elasticsearch.spec.ts} +22 -21
- package/src/integrations/tests/{firebase.spec.js → firebase.spec.ts} +33 -28
- package/src/integrations/tests/{microsoftSqlServer.spec.js → microsoftSqlServer.spec.ts} +12 -11
- package/src/integrations/tests/{mongo.spec.js → mongo.spec.ts} +46 -35
- package/src/integrations/tests/{mysql.spec.js → mysql.spec.ts} +17 -15
- package/src/integrations/tests/{oracle.spec.js → oracle.spec.ts} +19 -17
- package/src/integrations/tests/{postgres.spec.js → postgres.spec.ts} +19 -17
- package/src/integrations/tests/{redis.spec.js → redis.spec.ts} +27 -18
- package/src/integrations/tests/{rest.spec.js → rest.spec.ts} +57 -14
- package/src/integrations/tests/{s3.spec.js → s3.spec.ts} +10 -8
- package/src/integrations/tests/{sql.spec.js → sql.spec.ts} +228 -177
- package/src/module.d.ts +1 -0
- package/src/threads/automation.ts +6 -0
- package/src/threads/query.ts +2 -2
- package/src/utilities/fileSystem/index.js +75 -6
- package/src/utilities/index.js +8 -0
- package/src/utilities/rowProcessor/utils.js +1 -1
- package/src/utilities/usageQuota/rows.js +2 -1
- package/src/watch.ts +38 -0
- package/builder/assets/index.a4ba55ba.js +0 -875
- package/builder/assets/vendor.5e1fe644.css +0 -1
- package/builder/assets/vendor.67dbd8fa.js +0 -248
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
getScreenParams,
|
|
3
|
+
generateScreenID,
|
|
4
|
+
getPluginParams,
|
|
5
|
+
DocumentType,
|
|
6
|
+
} = require("../../db/utils")
|
|
2
7
|
const { AccessController } = require("@budibase/backend-core/roles")
|
|
3
8
|
const { getAppDB } = require("@budibase/backend-core/context")
|
|
4
9
|
const { events } = require("@budibase/backend-core")
|
|
10
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
11
|
+
const { updateAppPackage } = require("./application")
|
|
5
12
|
|
|
6
13
|
exports.fetch = async ctx => {
|
|
7
14
|
const db = getAppDB()
|
|
@@ -32,6 +39,47 @@ exports.save = async ctx => {
|
|
|
32
39
|
|
|
33
40
|
const response = await db.put(screen)
|
|
34
41
|
|
|
42
|
+
// Find any custom components being used
|
|
43
|
+
let pluginNames = []
|
|
44
|
+
let pluginAdded = false
|
|
45
|
+
findPlugins(screen.props, pluginNames)
|
|
46
|
+
if (pluginNames.length) {
|
|
47
|
+
const globalDB = getGlobalDB()
|
|
48
|
+
const pluginsResponse = await globalDB.allDocs(
|
|
49
|
+
getPluginParams(null, {
|
|
50
|
+
include_docs: true,
|
|
51
|
+
})
|
|
52
|
+
)
|
|
53
|
+
const requiredPlugins = pluginsResponse.rows
|
|
54
|
+
.map(row => row.doc)
|
|
55
|
+
.filter(plugin => {
|
|
56
|
+
return (
|
|
57
|
+
plugin.schema.type === "component" &&
|
|
58
|
+
pluginNames.includes(`plugin/${plugin.name}`)
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Update the app metadata
|
|
63
|
+
const application = await db.get(DocumentType.APP_METADATA)
|
|
64
|
+
let usedPlugins = application.usedPlugins || []
|
|
65
|
+
|
|
66
|
+
requiredPlugins.forEach(plugin => {
|
|
67
|
+
if (!usedPlugins.find(x => x._id === plugin._id)) {
|
|
68
|
+
pluginAdded = true
|
|
69
|
+
usedPlugins.push({
|
|
70
|
+
_id: plugin._id,
|
|
71
|
+
name: plugin.name,
|
|
72
|
+
version: plugin.version,
|
|
73
|
+
jsUrl: plugin.jsUrl,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
if (pluginAdded) {
|
|
79
|
+
await updateAppPackage({ usedPlugins }, ctx.appId)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
35
83
|
if (eventFn) {
|
|
36
84
|
await eventFn(screen)
|
|
37
85
|
}
|
|
@@ -40,6 +88,7 @@ exports.save = async ctx => {
|
|
|
40
88
|
...screen,
|
|
41
89
|
_id: response.id,
|
|
42
90
|
_rev: response.rev,
|
|
91
|
+
pluginAdded,
|
|
43
92
|
}
|
|
44
93
|
}
|
|
45
94
|
|
|
@@ -56,3 +105,18 @@ exports.destroy = async ctx => {
|
|
|
56
105
|
}
|
|
57
106
|
ctx.status = 200
|
|
58
107
|
}
|
|
108
|
+
|
|
109
|
+
const findPlugins = (component, foundPlugins) => {
|
|
110
|
+
if (!component) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
if (component._component.startsWith("plugin")) {
|
|
114
|
+
if (!foundPlugins.includes(component._component)) {
|
|
115
|
+
foundPlugins.push(component._component)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!component._children || !component._children.length) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
component._children.forEach(child => findPlugins(child, foundPlugins))
|
|
122
|
+
}
|
|
@@ -113,6 +113,7 @@ export const serveApp = async function (ctx: any) {
|
|
|
113
113
|
production: env.isProd(),
|
|
114
114
|
appId,
|
|
115
115
|
clientLibPath: clientLibraryPath(appId, appInfo.version, ctx),
|
|
116
|
+
usedPlugins: appInfo.usedPlugins,
|
|
116
117
|
})
|
|
117
118
|
|
|
118
119
|
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export let favicon = ""
|
|
4
4
|
|
|
5
5
|
export let clientLibPath
|
|
6
|
+
export let usedPlugins
|
|
6
7
|
</script>
|
|
7
8
|
|
|
8
9
|
<svelte:head>
|
|
@@ -83,6 +84,15 @@
|
|
|
83
84
|
</script>
|
|
84
85
|
<script type="application/javascript" src={clientLibPath}>
|
|
85
86
|
</script>
|
|
87
|
+
<!-- Custom components need inserted after the core client library -->
|
|
88
|
+
<!-- But before loadBudibase is called -->
|
|
89
|
+
{#if usedPlugins?.length}
|
|
90
|
+
{#each usedPlugins as plugin}
|
|
91
|
+
<script
|
|
92
|
+
type="application/javascript"
|
|
93
|
+
src={`/plugins/${plugin.jsUrl}`}></script>
|
|
94
|
+
{/each}
|
|
95
|
+
{/if}
|
|
86
96
|
<script type="application/javascript">
|
|
87
97
|
if (window.loadBudibase) {
|
|
88
98
|
window.loadBudibase()
|
|
@@ -66,7 +66,8 @@
|
|
|
66
66
|
customTheme,
|
|
67
67
|
previewDevice,
|
|
68
68
|
navigation,
|
|
69
|
-
hiddenComponentIds
|
|
69
|
+
hiddenComponentIds,
|
|
70
|
+
usedPlugins
|
|
70
71
|
} = parsed
|
|
71
72
|
|
|
72
73
|
// Set some flags so the app knows we're in the builder
|
|
@@ -81,6 +82,7 @@
|
|
|
81
82
|
window["##BUDIBASE_PREVIEW_DEVICE##"] = previewDevice
|
|
82
83
|
window["##BUDIBASE_PREVIEW_NAVIGATION##"] = navigation
|
|
83
84
|
window["##BUDIBASE_HIDDEN_COMPONENT_IDS##"] = hiddenComponentIds
|
|
85
|
+
window["##BUDIBASE_USED_PLUGINS##"] = usedPlugins
|
|
84
86
|
|
|
85
87
|
// Initialise app
|
|
86
88
|
try {
|
package/src/api/routes/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import metadataRoutes from "./metadata"
|
|
|
24
24
|
import devRoutes from "./dev"
|
|
25
25
|
import cloudRoutes from "./cloud"
|
|
26
26
|
import migrationRoutes from "./migrations"
|
|
27
|
+
import pluginRoutes from "./plugin"
|
|
27
28
|
|
|
28
29
|
export { default as staticRoutes } from "./static"
|
|
29
30
|
export { default as publicRoutes } from "./public"
|
|
@@ -57,4 +58,5 @@ export const mainRoutes = [
|
|
|
57
58
|
tableRoutes,
|
|
58
59
|
rowRoutes,
|
|
59
60
|
migrationRoutes,
|
|
61
|
+
pluginRoutes,
|
|
60
62
|
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Router from "@koa/router"
|
|
2
|
+
import * as controller from "../controllers/plugin"
|
|
3
|
+
import authorized from "../../middleware/authorized"
|
|
4
|
+
import { BUILDER } from "@budibase/backend-core/permissions"
|
|
5
|
+
|
|
6
|
+
const router = new Router()
|
|
7
|
+
|
|
8
|
+
router
|
|
9
|
+
.post("/api/plugin/upload", authorized(BUILDER), controller.upload)
|
|
10
|
+
.get("/api/plugin", authorized(BUILDER), controller.fetch)
|
|
11
|
+
.delete("/api/plugin/:pluginId", authorized(BUILDER), controller.destroy)
|
|
12
|
+
|
|
13
|
+
export default router
|
|
@@ -231,20 +231,6 @@ describe("/queries", () => {
|
|
|
231
231
|
url: `/api/queries/preview`,
|
|
232
232
|
})
|
|
233
233
|
})
|
|
234
|
-
|
|
235
|
-
it("should fail with invalid integration type", async () => {
|
|
236
|
-
const { datasource } = await createInvalidIntegration()
|
|
237
|
-
await request
|
|
238
|
-
.post(`/api/queries/preview`)
|
|
239
|
-
.send({
|
|
240
|
-
datasourceId: datasource._id,
|
|
241
|
-
parameters: {},
|
|
242
|
-
fields: {},
|
|
243
|
-
queryVerb: "read",
|
|
244
|
-
})
|
|
245
|
-
.set(config.defaultHeaders())
|
|
246
|
-
.expect(400)
|
|
247
|
-
})
|
|
248
234
|
})
|
|
249
235
|
|
|
250
236
|
describe("execute", () => {
|
|
@@ -261,17 +247,14 @@ describe("/queries", () => {
|
|
|
261
247
|
})
|
|
262
248
|
|
|
263
249
|
it("should fail with invalid integration type", async () => {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
})
|
|
273
|
-
.set(config.defaultHeaders())
|
|
274
|
-
.expect(400)
|
|
250
|
+
let error
|
|
251
|
+
try {
|
|
252
|
+
await createInvalidIntegration()
|
|
253
|
+
} catch (err) {
|
|
254
|
+
error = err
|
|
255
|
+
}
|
|
256
|
+
expect(error).toBeDefined()
|
|
257
|
+
expect(error.message).toBe("No datasource implementation found.")
|
|
275
258
|
})
|
|
276
259
|
})
|
|
277
260
|
|
|
@@ -311,7 +294,7 @@ describe("/queries", () => {
|
|
|
311
294
|
"url": "string",
|
|
312
295
|
"value": "string"
|
|
313
296
|
})
|
|
314
|
-
expect(res.body.rows[0].url).toContain("doctype
|
|
297
|
+
expect(res.body.rows[0].url).toContain("doctype%20html")
|
|
315
298
|
})
|
|
316
299
|
|
|
317
300
|
it("check that it automatically retries on fail with cached dynamics", async () => {
|
|
@@ -396,7 +379,7 @@ describe("/queries", () => {
|
|
|
396
379
|
"queryHdr": userDetails.firstName,
|
|
397
380
|
"secondHdr" : "1234"
|
|
398
381
|
})
|
|
399
|
-
expect(res.body.rows[0].url).toEqual("http://www.google.com?email=" + userDetails.email)
|
|
382
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?email=" + userDetails.email.replace("@", "%40"))
|
|
400
383
|
})
|
|
401
384
|
|
|
402
385
|
it("should bind the current user to query parameters", async () => {
|
|
@@ -413,7 +396,7 @@ describe("/queries", () => {
|
|
|
413
396
|
"testParam" : "1234"
|
|
414
397
|
})
|
|
415
398
|
|
|
416
|
-
expect(res.body.rows[0].url).toEqual("http://www.google.com?test=" + userDetails.email +
|
|
399
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?test=" + userDetails.email.replace("@", "%40") +
|
|
417
400
|
"&testName=" + userDetails.firstName + "&testParam=1234")
|
|
418
401
|
})
|
|
419
402
|
|
package/src/app.ts
CHANGED
|
@@ -26,10 +26,12 @@ const bullboard = require("./automations/bullboard")
|
|
|
26
26
|
const { logAlert } = require("@budibase/backend-core/logging")
|
|
27
27
|
const { pinoSettings } = require("@budibase/backend-core")
|
|
28
28
|
const { Thread } = require("./threads")
|
|
29
|
+
const fs = require("fs")
|
|
29
30
|
import redis from "./utilities/redis"
|
|
30
31
|
import * as migrations from "./migrations"
|
|
31
32
|
import { events, installation, tenancy } from "@budibase/backend-core"
|
|
32
33
|
import { createAdminUser, getChecklist } from "./utilities/workerRequests"
|
|
34
|
+
import { watch } from "./watch"
|
|
33
35
|
|
|
34
36
|
const app = new Koa()
|
|
35
37
|
|
|
@@ -139,6 +141,16 @@ module.exports = server.listen(env.PORT || 0, async () => {
|
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
// monitor plugin directory if required
|
|
145
|
+
if (
|
|
146
|
+
env.SELF_HOSTED &&
|
|
147
|
+
!env.MULTI_TENANCY &&
|
|
148
|
+
env.PLUGINS_DIR &&
|
|
149
|
+
fs.existsSync(env.PLUGINS_DIR)
|
|
150
|
+
) {
|
|
151
|
+
watch()
|
|
152
|
+
}
|
|
153
|
+
|
|
142
154
|
// check for version updates
|
|
143
155
|
await installation.checkInstallVersion()
|
|
144
156
|
|
package/src/automations/index.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
const { processEvent } = require("./utils")
|
|
2
2
|
const { queue, shutdown } = require("./bullboard")
|
|
3
|
-
const { TRIGGER_DEFINITIONS } = require("./triggers")
|
|
3
|
+
const { TRIGGER_DEFINITIONS, rebootTrigger } = require("./triggers")
|
|
4
4
|
const { ACTION_DEFINITIONS } = require("./actions")
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* This module is built purely to kick off the worker farm and manage the inputs/outputs
|
|
8
8
|
*/
|
|
9
|
-
exports.init = function () {
|
|
9
|
+
exports.init = async function () {
|
|
10
10
|
// this promise will not complete
|
|
11
|
-
|
|
11
|
+
const promise = queue.process(async job => {
|
|
12
12
|
await processEvent(job)
|
|
13
13
|
})
|
|
14
|
+
// on init we need to trigger any reboot automations
|
|
15
|
+
await rebootTrigger()
|
|
16
|
+
return promise
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
exports.getQueues = () => {
|
|
@@ -9,6 +9,7 @@ const { checkTestFlag } = require("../utilities/redis")
|
|
|
9
9
|
const utils = require("./utils")
|
|
10
10
|
const env = require("../environment")
|
|
11
11
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
|
12
|
+
const { getAllApps } = require("@budibase/backend-core/db")
|
|
12
13
|
|
|
13
14
|
const TRIGGER_DEFINITIONS = definitions
|
|
14
15
|
const JOB_OPTS = {
|
|
@@ -16,24 +17,27 @@ const JOB_OPTS = {
|
|
|
16
17
|
removeOnFail: true,
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
async function getAllAutomations() {
|
|
21
|
+
const db = getAppDB()
|
|
22
|
+
let automations = await db.allDocs(
|
|
23
|
+
getAutomationParams(null, { include_docs: true })
|
|
24
|
+
)
|
|
25
|
+
return automations.rows.map(row => row.doc)
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
async function queueRelevantRowAutomations(event, eventType) {
|
|
20
29
|
if (event.appId == null) {
|
|
21
30
|
throw `No appId specified for ${eventType} - check event emitters.`
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
doInAppContext(event.appId, async () => {
|
|
25
|
-
|
|
26
|
-
let automations = await db.allDocs(
|
|
27
|
-
getAutomationParams(null, { include_docs: true })
|
|
28
|
-
)
|
|
34
|
+
let automations = await getAllAutomations()
|
|
29
35
|
|
|
30
36
|
// filter down to the correct event type
|
|
31
|
-
automations = automations.
|
|
32
|
-
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
return trigger && trigger.event === eventType
|
|
36
|
-
})
|
|
37
|
+
automations = automations.filter(automation => {
|
|
38
|
+
const trigger = automation.definition.trigger
|
|
39
|
+
return trigger && trigger.event === eventType
|
|
40
|
+
})
|
|
37
41
|
|
|
38
42
|
for (let automation of automations) {
|
|
39
43
|
let automationDef = automation.definition
|
|
@@ -110,4 +114,34 @@ exports.externalTrigger = async function (
|
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
|
|
117
|
+
exports.rebootTrigger = async () => {
|
|
118
|
+
// reboot cron option is only available on the main thread at
|
|
119
|
+
// startup and only usable in self host
|
|
120
|
+
if (env.isInThread() || !env.SELF_HOSTED) {
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
// iterate through all production apps, find the reboot crons
|
|
124
|
+
// and trigger events for them
|
|
125
|
+
const appIds = await getAllApps({ dev: false, idsOnly: true })
|
|
126
|
+
for (let prodAppId of appIds) {
|
|
127
|
+
await doInAppContext(prodAppId, async () => {
|
|
128
|
+
let automations = await getAllAutomations()
|
|
129
|
+
let rebootEvents = []
|
|
130
|
+
for (let automation of automations) {
|
|
131
|
+
if (utils.isRebootTrigger(automation)) {
|
|
132
|
+
const job = {
|
|
133
|
+
automation,
|
|
134
|
+
event: {
|
|
135
|
+
appId: prodAppId,
|
|
136
|
+
timestamp: Date.now(),
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
rebootEvents.push(queue.add(job, JOB_OPTS))
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
await Promise.all(rebootEvents)
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
113
147
|
exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS
|
package/src/automations/utils.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { tenancy } from "@budibase/backend-core"
|
|
|
17
17
|
import { quotas } from "@budibase/pro"
|
|
18
18
|
import { Automation } from "@budibase/types"
|
|
19
19
|
|
|
20
|
+
const REBOOT_CRON = "@reboot"
|
|
20
21
|
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
|
21
22
|
const CRON_STEP_ID = definitions.CRON.stepId
|
|
22
23
|
const Runner = new Thread(ThreadType.AUTOMATION)
|
|
@@ -109,22 +110,33 @@ export async function clearMetadata() {
|
|
|
109
110
|
await db.bulkDocs(automationMetadata)
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
export function isCronTrigger(auto: Automation) {
|
|
114
|
+
return (
|
|
115
|
+
auto &&
|
|
116
|
+
auto.definition.trigger &&
|
|
117
|
+
auto.definition.trigger.stepId === CRON_STEP_ID
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function isRebootTrigger(auto: Automation) {
|
|
122
|
+
const trigger = auto ? auto.definition.trigger : null
|
|
123
|
+
return isCronTrigger(auto) && trigger?.inputs.cron === REBOOT_CRON
|
|
124
|
+
}
|
|
125
|
+
|
|
112
126
|
/**
|
|
113
127
|
* This function handles checking of any cron jobs that need to be enabled/updated.
|
|
114
128
|
* @param {string} appId The ID of the app in which we are checking for webhooks
|
|
115
129
|
* @param {object|undefined} automation The automation object to be updated.
|
|
116
130
|
*/
|
|
117
|
-
export async function enableCronTrigger(appId: any, automation:
|
|
131
|
+
export async function enableCronTrigger(appId: any, automation: Automation) {
|
|
118
132
|
const trigger = automation ? automation.definition.trigger : null
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
auto &&
|
|
122
|
-
auto.definition.trigger &&
|
|
123
|
-
auto.definition.trigger.stepId === CRON_STEP_ID
|
|
124
|
-
)
|
|
125
|
-
}
|
|
133
|
+
|
|
126
134
|
// need to create cron job
|
|
127
|
-
if (
|
|
135
|
+
if (
|
|
136
|
+
isCronTrigger(automation) &&
|
|
137
|
+
!isRebootTrigger(automation) &&
|
|
138
|
+
trigger?.inputs.cron
|
|
139
|
+
) {
|
|
128
140
|
// make a job id rather than letting Bull decide, makes it easier to handle on way out
|
|
129
141
|
const jobId = `${appId}_cron_${newid()}`
|
|
130
142
|
const job: any = await queue.add(
|
package/src/db/utils.js
CHANGED
|
@@ -42,6 +42,7 @@ const DocumentType = {
|
|
|
42
42
|
MEM_VIEW: "view",
|
|
43
43
|
USER_FLAG: "flag",
|
|
44
44
|
AUTOMATION_METADATA: "meta_au",
|
|
45
|
+
PLUGIN: "plg",
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const InternalTables = {
|
|
@@ -370,6 +371,10 @@ exports.getMemoryViewParams = (otherProps = {}) => {
|
|
|
370
371
|
return getDocParams(DocumentType.MEM_VIEW, null, otherProps)
|
|
371
372
|
}
|
|
372
373
|
|
|
374
|
+
exports.generatePluginID = name => {
|
|
375
|
+
return `${DocumentType.PLUGIN}${SEPARATOR}${name}`
|
|
376
|
+
}
|
|
377
|
+
|
|
373
378
|
/**
|
|
374
379
|
* This can be used with the db.allDocs to get a list of IDs
|
|
375
380
|
*/
|
|
@@ -379,3 +384,10 @@ exports.getMultiIDParams = ids => {
|
|
|
379
384
|
include_docs: true,
|
|
380
385
|
}
|
|
381
386
|
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Gets parameters for retrieving automations, this is a utility function for the getDocParams function.
|
|
390
|
+
*/
|
|
391
|
+
exports.getPluginParams = (pluginId = null, otherProps = {}) => {
|
|
392
|
+
return getDocParams(DocumentType.PLUGIN, pluginId, otherProps)
|
|
393
|
+
}
|
package/src/environment.js
CHANGED
|
@@ -74,6 +74,7 @@ module.exports = {
|
|
|
74
74
|
SQL_MAX_ROWS: process.env.SQL_MAX_ROWS,
|
|
75
75
|
BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,
|
|
76
76
|
BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,
|
|
77
|
+
PLUGINS_DIR: process.env.PLUGINS_DIR || "/plugins",
|
|
77
78
|
// flags
|
|
78
79
|
ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
|
|
79
80
|
DISABLE_THREADING: process.env.DISABLE_THREADING,
|