@budibase/server 1.0.212-alpha.11 → 1.0.212-alpha.14
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__/node-fetch.ts +9 -0
- package/builder/assets/index.1f366fcc.js +977 -0
- package/builder/assets/{index.969c2236.css → index.7786f497.css} +2 -2
- package/builder/assets/{vendor.9bf2fcb4.js → vendor.001dcf8c.js} +163 -163
- package/builder/index.html +3 -3
- package/coverage/clover.xml +616 -588
- package/coverage/coverage-final.json +20 -20
- 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 +111 -12
- 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 +16 -16
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +19 -19
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/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 +1 -1
- 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 +15 -15
- package/coverage/lcov-report/api/index.js.html +22 -13
- 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 +32 -2
- 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 +1 -1
- 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/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 +58 -34
- package/coverage/lcov-report/automations/steps/index.html +11 -11
- 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 +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/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +14 -14
- 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 +13 -13
- package/coverage/lcov-report/db/linkedRows/index.js.html +10 -7
- 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 +25 -52
- 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 +56 -56
- 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 +10 -10
- 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/threads/automation.js.html +17 -8
- package/coverage/lcov-report/threads/index.html +25 -25
- package/coverage/lcov-report/threads/query.js.html +143 -68
- package/coverage/lcov-report/threads/utils.js.html +4 -4
- 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 +14 -14
- package/coverage/lcov-report/utilities/index.html +1 -1
- package/coverage/lcov-report/utilities/index.js.html +9 -9
- 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 +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +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 +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +1094 -1046
- package/dist/api/controllers/application.js +18 -15
- package/dist/api/controllers/automation.js +28 -2
- package/dist/api/controllers/query/index.js +6 -0
- package/dist/api/index.js +4 -1
- package/dist/api/routes/automation.js +2 -0
- package/dist/automations/logging/index.js +70 -0
- package/dist/automations/steps/filter.js +38 -29
- package/dist/db/linkedRows/index.js +1 -0
- package/dist/db/utils.js +3 -31
- package/dist/environment.js +1 -0
- package/dist/integrations/queries/sql.js +3 -0
- package/dist/integrations/rest.js +1 -1
- package/dist/package.json +6 -6
- package/dist/tests/utilities/TestConfiguration.js +19 -6
- package/dist/threads/automation.js +5 -2
- package/dist/threads/index.js +15 -1
- package/dist/threads/query.js +18 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/api/controllers/application.ts +18 -14
- package/src/api/controllers/automation.js +35 -2
- package/src/api/controllers/query/index.ts +6 -0
- package/src/api/index.js +4 -1
- package/src/api/routes/automation.js +10 -0
- package/src/api/routes/tests/query.spec.js +166 -0
- package/src/automations/logging/index.ts +35 -0
- package/src/automations/steps/filter.js +36 -28
- package/src/automations/tests/filter.spec.js +2 -1
- package/src/db/linkedRows/index.js +1 -0
- package/src/db/utils.js +4 -13
- package/src/environment.js +1 -0
- package/src/integrations/queries/sql.ts +3 -1
- package/src/integrations/rest.ts +1 -1
- package/src/integrations/tests/rest.spec.js +16 -1
- package/src/migrations/tests/index.spec.ts +18 -2
- package/src/module.d.ts +1 -0
- package/src/tests/utilities/TestConfiguration.js +22 -3
- package/src/threads/automation.js +5 -2
- package/src/threads/index.ts +5 -1
- package/src/threads/query.js +28 -3
- package/builder/assets/index.a7550206.js +0 -978
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.0.212-alpha.
|
|
4
|
+
"version": "1.0.212-alpha.14",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -77,11 +77,11 @@
|
|
|
77
77
|
"license": "GPL-3.0",
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
80
|
-
"@budibase/backend-core": "^1.0.212-alpha.
|
|
81
|
-
"@budibase/client": "^1.0.212-alpha.
|
|
82
|
-
"@budibase/pro": "1.0.212-alpha.
|
|
83
|
-
"@budibase/string-templates": "^1.0.212-alpha.
|
|
84
|
-
"@budibase/types": "^1.0.212-alpha.
|
|
80
|
+
"@budibase/backend-core": "^1.0.212-alpha.14",
|
|
81
|
+
"@budibase/client": "^1.0.212-alpha.14",
|
|
82
|
+
"@budibase/pro": "1.0.212-alpha.13",
|
|
83
|
+
"@budibase/string-templates": "^1.0.212-alpha.14",
|
|
84
|
+
"@budibase/types": "^1.0.212-alpha.14",
|
|
85
85
|
"@bull-board/api": "3.7.0",
|
|
86
86
|
"@bull-board/koa": "3.9.4",
|
|
87
87
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -195,5 +195,5 @@
|
|
|
195
195
|
"optionalDependencies": {
|
|
196
196
|
"oracledb": "5.3.0"
|
|
197
197
|
},
|
|
198
|
-
"gitHead": "
|
|
198
|
+
"gitHead": "5147929cb55fe0ad5fa21adf64774458b7176c7e"
|
|
199
199
|
}
|
|
@@ -45,10 +45,12 @@ const { getTenantId, isMultiTenant } = require("@budibase/backend-core/tenancy")
|
|
|
45
45
|
import { syncGlobalUsers } from "./user"
|
|
46
46
|
const { app: appCache } = require("@budibase/backend-core/cache")
|
|
47
47
|
import { cleanupAutomations } from "../../automations/utils"
|
|
48
|
+
import { checkAppMetadata } from "../../automations/logging"
|
|
48
49
|
const {
|
|
49
50
|
getAppDB,
|
|
50
51
|
getProdAppDB,
|
|
51
52
|
updateAppId,
|
|
53
|
+
doInAppContext,
|
|
52
54
|
} = require("@budibase/backend-core/context")
|
|
53
55
|
import { getUniqueRows } from "../../utilities/usageQuota/rows"
|
|
54
56
|
import { quotas } from "@budibase/pro"
|
|
@@ -192,7 +194,7 @@ export const fetch = async (ctx: any) => {
|
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
|
|
195
|
-
ctx.body = apps
|
|
197
|
+
ctx.body = await checkAppMetadata(apps)
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
export const fetchAppDefinition = async (ctx: any) => {
|
|
@@ -548,22 +550,24 @@ export const sync = async (ctx: any, next: any) => {
|
|
|
548
550
|
}
|
|
549
551
|
|
|
550
552
|
const updateAppPackage = async (appPackage: any, appId: any) => {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
+
return doInAppContext(appId, async () => {
|
|
554
|
+
const db = getAppDB()
|
|
555
|
+
const application = await db.get(DocumentTypes.APP_METADATA)
|
|
553
556
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
557
|
+
const newAppPackage = { ...application, ...appPackage }
|
|
558
|
+
if (appPackage._rev !== application._rev) {
|
|
559
|
+
newAppPackage._rev = application._rev
|
|
560
|
+
}
|
|
558
561
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
+
// the locked by property is attached by server but generated from
|
|
563
|
+
// Redis, shouldn't ever store it
|
|
564
|
+
delete newAppPackage.lockedBy
|
|
562
565
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
566
|
+
await db.put(newAppPackage)
|
|
567
|
+
// remove any cached metadata, so that it will be updated
|
|
568
|
+
await appCache.invalidateAppMetadata(appId)
|
|
569
|
+
return newAppPackage
|
|
570
|
+
})
|
|
567
571
|
}
|
|
568
572
|
|
|
569
573
|
const createEmptyAppPackage = async (ctx: any, app: any) => {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const actions = require("../../automations/actions")
|
|
2
2
|
const triggers = require("../../automations/triggers")
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
getAutomationParams,
|
|
5
|
+
generateAutomationID,
|
|
6
|
+
DocumentTypes,
|
|
7
|
+
} = require("../../db/utils")
|
|
4
8
|
const {
|
|
5
9
|
checkForWebhooks,
|
|
6
10
|
updateTestHistory,
|
|
@@ -9,8 +13,14 @@ const {
|
|
|
9
13
|
const { deleteEntityMetadata } = require("../../utilities")
|
|
10
14
|
const { MetadataTypes } = require("../../constants")
|
|
11
15
|
const { setTestFlag, clearTestFlag } = require("../../utilities/redis")
|
|
12
|
-
const {
|
|
16
|
+
const {
|
|
17
|
+
getAppDB,
|
|
18
|
+
getProdAppDB,
|
|
19
|
+
doInAppContext,
|
|
20
|
+
} = require("@budibase/backend-core/context")
|
|
13
21
|
const { events } = require("@budibase/backend-core")
|
|
22
|
+
const { app } = require("@budibase/backend-core/cache")
|
|
23
|
+
const { automations } = require("@budibase/pro")
|
|
14
24
|
|
|
15
25
|
const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS)
|
|
16
26
|
const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
|
|
@@ -183,6 +193,29 @@ exports.destroy = async function (ctx) {
|
|
|
183
193
|
await events.automation.deleted(oldAutomation)
|
|
184
194
|
}
|
|
185
195
|
|
|
196
|
+
exports.logSearch = async function (ctx) {
|
|
197
|
+
ctx.body = await automations.logs.logSearch(ctx.request.body)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
exports.clearLogError = async function (ctx) {
|
|
201
|
+
const { automationId, appId } = ctx.request.body
|
|
202
|
+
await doInAppContext(appId, async () => {
|
|
203
|
+
const db = getProdAppDB()
|
|
204
|
+
const metadata = await db.get(DocumentTypes.APP_METADATA)
|
|
205
|
+
if (!automationId) {
|
|
206
|
+
delete metadata.automationErrors
|
|
207
|
+
} else if (
|
|
208
|
+
metadata.automationErrors &&
|
|
209
|
+
metadata.automationErrors[automationId]
|
|
210
|
+
) {
|
|
211
|
+
delete metadata.automationErrors[automationId]
|
|
212
|
+
}
|
|
213
|
+
await db.put(metadata)
|
|
214
|
+
await app.invalidateAppMetadata(metadata.appId, metadata)
|
|
215
|
+
ctx.body = { message: `Error logs cleared.` }
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
186
219
|
exports.getActionList = async function (ctx) {
|
|
187
220
|
ctx.body = ACTION_DEFS
|
|
188
221
|
}
|
|
@@ -129,6 +129,9 @@ export async function preview(ctx: any) {
|
|
|
129
129
|
parameters,
|
|
130
130
|
transformer,
|
|
131
131
|
queryId,
|
|
132
|
+
ctx: {
|
|
133
|
+
user: ctx.user,
|
|
134
|
+
},
|
|
132
135
|
})
|
|
133
136
|
|
|
134
137
|
const { rows, keys, info, extra } = await quotas.addQuery(runFn)
|
|
@@ -172,6 +175,9 @@ async function execute(ctx: any, opts = { rowsOnly: false }) {
|
|
|
172
175
|
parameters: enrichedParameters,
|
|
173
176
|
transformer: query.transformer,
|
|
174
177
|
queryId: ctx.params.queryId,
|
|
178
|
+
ctx: {
|
|
179
|
+
user: ctx.user,
|
|
180
|
+
},
|
|
175
181
|
})
|
|
176
182
|
|
|
177
183
|
const { rows, pagination, extra } = await quotas.addQuery(runFn)
|
package/src/api/index.js
CHANGED
|
@@ -51,6 +51,16 @@ router
|
|
|
51
51
|
automationValidator(false),
|
|
52
52
|
controller.create
|
|
53
53
|
)
|
|
54
|
+
.post(
|
|
55
|
+
"/api/automations/logs/search",
|
|
56
|
+
authorized(BUILDER),
|
|
57
|
+
controller.logSearch
|
|
58
|
+
)
|
|
59
|
+
.delete(
|
|
60
|
+
"/api/automations/logs",
|
|
61
|
+
authorized(BUILDER),
|
|
62
|
+
controller.clearLogError
|
|
63
|
+
)
|
|
54
64
|
.delete(
|
|
55
65
|
"/api/automations/:id/:rev",
|
|
56
66
|
paramResource("id"),
|
|
@@ -346,4 +346,170 @@ describe("/queries", () => {
|
|
|
346
346
|
expect(contents).toBe(null)
|
|
347
347
|
})
|
|
348
348
|
})
|
|
349
|
+
|
|
350
|
+
describe("Current User Request Mapping", () => {
|
|
351
|
+
|
|
352
|
+
async function previewGet(datasource, fields, params) {
|
|
353
|
+
return config.previewQuery(request, config, datasource, fields, params)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async function previewPost(datasource, fields, params) {
|
|
357
|
+
return config.previewQuery(request, config, datasource, fields, params, "create")
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
it("should parse global and query level header mappings", async () => {
|
|
361
|
+
const userDetails = config.getUserDetails()
|
|
362
|
+
|
|
363
|
+
const datasource = await config.restDatasource({
|
|
364
|
+
defaultHeaders: {
|
|
365
|
+
"test": "headerVal",
|
|
366
|
+
"emailHdr": "{{[user].[email]}}"
|
|
367
|
+
}
|
|
368
|
+
})
|
|
369
|
+
const res = await previewGet(datasource, {
|
|
370
|
+
path: "www.google.com",
|
|
371
|
+
queryString: "email={{[user].[email]}}",
|
|
372
|
+
headers: {
|
|
373
|
+
queryHdr : "{{[user].[firstName]}}",
|
|
374
|
+
secondHdr : "1234"
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
379
|
+
expect(parsedRequest.opts.headers).toEqual({
|
|
380
|
+
"test": "headerVal",
|
|
381
|
+
"emailHdr": userDetails.email,
|
|
382
|
+
"queryHdr": userDetails.firstName,
|
|
383
|
+
"secondHdr" : "1234"
|
|
384
|
+
})
|
|
385
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?email=" + userDetails.email)
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
it("should bind the current user to query parameters", async () => {
|
|
389
|
+
const userDetails = config.getUserDetails()
|
|
390
|
+
|
|
391
|
+
const datasource = await config.restDatasource()
|
|
392
|
+
|
|
393
|
+
const res = await previewGet(datasource, {
|
|
394
|
+
path: "www.google.com",
|
|
395
|
+
queryString: "test={{myEmail}}&testName={{myName}}&testParam={{testParam}}",
|
|
396
|
+
}, {
|
|
397
|
+
"myEmail" : "{{[user].[email]}}",
|
|
398
|
+
"myName" : "{{[user].[firstName]}}",
|
|
399
|
+
"testParam" : "1234"
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?test=" + userDetails.email +
|
|
403
|
+
"&testName=" + userDetails.firstName + "&testParam=1234")
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
it("should bind the current user the request body - plain text", async () => {
|
|
407
|
+
const userDetails = config.getUserDetails()
|
|
408
|
+
const datasource = await config.restDatasource()
|
|
409
|
+
|
|
410
|
+
const res = await previewPost(datasource, {
|
|
411
|
+
path: "www.google.com",
|
|
412
|
+
queryString: "testParam={{testParam}}",
|
|
413
|
+
requestBody: "This is plain text and this is my email: {{[user].[email]}}. This is a test param: {{testParam}}",
|
|
414
|
+
bodyType: "text"
|
|
415
|
+
}, {
|
|
416
|
+
"testParam" : "1234"
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
420
|
+
expect(parsedRequest.opts.body).toEqual(`This is plain text and this is my email: ${userDetails.email}. This is a test param: 1234`)
|
|
421
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
it("should bind the current user the request body - json", async () => {
|
|
425
|
+
const userDetails = config.getUserDetails()
|
|
426
|
+
const datasource = await config.restDatasource()
|
|
427
|
+
|
|
428
|
+
const res = await previewPost(datasource, {
|
|
429
|
+
path: "www.google.com",
|
|
430
|
+
queryString: "testParam={{testParam}}",
|
|
431
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
432
|
+
bodyType: "json"
|
|
433
|
+
}, {
|
|
434
|
+
"testParam" : "1234",
|
|
435
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
439
|
+
const test = `{"email":"${userDetails.email}","queryCode":1234,"userRef":"${userDetails.firstName}"}`
|
|
440
|
+
expect(parsedRequest.opts.body).toEqual(test)
|
|
441
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
it("should bind the current user the request body - xml", async () => {
|
|
445
|
+
const userDetails = config.getUserDetails()
|
|
446
|
+
const datasource = await config.restDatasource()
|
|
447
|
+
|
|
448
|
+
const res = await previewPost(datasource, {
|
|
449
|
+
path: "www.google.com",
|
|
450
|
+
queryString: "testParam={{testParam}}",
|
|
451
|
+
requestBody: "<note> <email>{{[user].[email]}}</email> <code>{{testParam}}</code> " +
|
|
452
|
+
"<ref>{{userId}}</ref> <somestring>testing</somestring> </note>",
|
|
453
|
+
bodyType: "xml"
|
|
454
|
+
}, {
|
|
455
|
+
"testParam" : "1234",
|
|
456
|
+
"userId" : "{{[user].[firstName]}}"
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
460
|
+
const test = `<note> <email>${userDetails.email}</email> <code>1234</code> <ref>${userDetails.firstName}</ref> <somestring>testing</somestring> </note>`
|
|
461
|
+
|
|
462
|
+
expect(parsedRequest.opts.body).toEqual(test)
|
|
463
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
it("should bind the current user the request body - form-data", async () => {
|
|
467
|
+
const userDetails = config.getUserDetails()
|
|
468
|
+
const datasource = await config.restDatasource()
|
|
469
|
+
|
|
470
|
+
const res = await previewPost(datasource, {
|
|
471
|
+
path: "www.google.com",
|
|
472
|
+
queryString: "testParam={{testParam}}",
|
|
473
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
474
|
+
bodyType: "form"
|
|
475
|
+
}, {
|
|
476
|
+
"testParam" : "1234",
|
|
477
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
481
|
+
|
|
482
|
+
const emailData = parsedRequest.opts.body._streams[1]
|
|
483
|
+
expect(emailData).toEqual(userDetails.email)
|
|
484
|
+
|
|
485
|
+
const queryCodeData = parsedRequest.opts.body._streams[4]
|
|
486
|
+
expect(queryCodeData).toEqual("1234")
|
|
487
|
+
|
|
488
|
+
const userRef = parsedRequest.opts.body._streams[7]
|
|
489
|
+
expect(userRef).toEqual(userDetails.firstName)
|
|
490
|
+
|
|
491
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
it("should bind the current user the request body - encoded", async () => {
|
|
495
|
+
const userDetails = config.getUserDetails()
|
|
496
|
+
const datasource = await config.restDatasource()
|
|
497
|
+
|
|
498
|
+
const res = await previewPost(datasource, {
|
|
499
|
+
path: "www.google.com",
|
|
500
|
+
queryString: "testParam={{testParam}}",
|
|
501
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
502
|
+
bodyType: "encoded"
|
|
503
|
+
}, {
|
|
504
|
+
"testParam" : "1234",
|
|
505
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
506
|
+
})
|
|
507
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
508
|
+
|
|
509
|
+
expect(parsedRequest.opts.body.email).toEqual(userDetails.email)
|
|
510
|
+
expect(parsedRequest.opts.body.queryCode).toEqual("1234")
|
|
511
|
+
expect(parsedRequest.opts.body.userRef).toEqual(userDetails.firstName)
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
});
|
|
349
515
|
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as env from "../../environment"
|
|
2
|
+
import { AutomationResults, Automation, App } from "@budibase/types"
|
|
3
|
+
import { automations } from "@budibase/pro"
|
|
4
|
+
import { db as dbUtils } from "@budibase/backend-core"
|
|
5
|
+
|
|
6
|
+
export async function storeLog(
|
|
7
|
+
automation: Automation,
|
|
8
|
+
results: AutomationResults
|
|
9
|
+
) {
|
|
10
|
+
// can disable this if un-needed in self-host, also only do this for prod apps
|
|
11
|
+
if (env.DISABLE_AUTOMATION_LOGS) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
await automations.logs.storeLog(automation, results)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function checkAppMetadata(apps: App[]) {
|
|
18
|
+
const maxStartDate = await automations.logs.oldestLogDate()
|
|
19
|
+
for (let metadata of apps) {
|
|
20
|
+
if (!metadata.automationErrors) {
|
|
21
|
+
continue
|
|
22
|
+
}
|
|
23
|
+
for (let [key, errors] of Object.entries(metadata.automationErrors)) {
|
|
24
|
+
const updated = []
|
|
25
|
+
for (let error of errors) {
|
|
26
|
+
const startDate = error.split(dbUtils.SEPARATOR)[2]
|
|
27
|
+
if (startDate > maxStartDate) {
|
|
28
|
+
updated.push(error)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
metadata.automationErrors[key] = updated
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return apps
|
|
35
|
+
}
|
|
@@ -50,43 +50,51 @@ exports.definition = {
|
|
|
50
50
|
outputs: {
|
|
51
51
|
properties: {
|
|
52
52
|
success: {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
description: "Whether the action was successful",
|
|
55
|
+
},
|
|
56
|
+
result: {
|
|
53
57
|
type: "boolean",
|
|
54
58
|
description: "Whether the logic block passed",
|
|
55
59
|
},
|
|
56
60
|
},
|
|
57
|
-
required: ["success"],
|
|
61
|
+
required: ["success", "result"],
|
|
58
62
|
},
|
|
59
63
|
},
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
exports.run = async function filter({ inputs }) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
value
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
67
|
+
try {
|
|
68
|
+
let { field, condition, value } = inputs
|
|
69
|
+
// coerce types so that we can use them
|
|
70
|
+
if (!isNaN(value) && !isNaN(field)) {
|
|
71
|
+
value = parseFloat(value)
|
|
72
|
+
field = parseFloat(field)
|
|
73
|
+
} else if (!isNaN(Date.parse(value)) && !isNaN(Date.parse(field))) {
|
|
74
|
+
value = Date.parse(value)
|
|
75
|
+
field = Date.parse(field)
|
|
76
|
+
}
|
|
77
|
+
let result = false
|
|
78
|
+
if (typeof field !== "object" && typeof value !== "object") {
|
|
79
|
+
switch (condition) {
|
|
80
|
+
case FilterConditions.EQUAL:
|
|
81
|
+
result = field === value
|
|
82
|
+
break
|
|
83
|
+
case FilterConditions.NOT_EQUAL:
|
|
84
|
+
result = field !== value
|
|
85
|
+
break
|
|
86
|
+
case FilterConditions.GREATER_THAN:
|
|
87
|
+
result = field > value
|
|
88
|
+
break
|
|
89
|
+
case FilterConditions.LESS_THAN:
|
|
90
|
+
result = field < value
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
result = false
|
|
87
95
|
}
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
return { success: true, result }
|
|
97
|
+
} catch (err) {
|
|
98
|
+
return { success: false, result: false }
|
|
90
99
|
}
|
|
91
|
-
return { success }
|
|
92
100
|
}
|
|
@@ -6,7 +6,8 @@ describe("test the filter logic", () => {
|
|
|
6
6
|
let res = await setup.runStep(setup.actions.FILTER.stepId,
|
|
7
7
|
{ field, condition, value }
|
|
8
8
|
)
|
|
9
|
-
expect(res.
|
|
9
|
+
expect(res.result).toEqual(pass)
|
|
10
|
+
expect(res.success).toEqual(true)
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
it("should be able test equality", async () => {
|
|
@@ -65,6 +65,7 @@ async function getLinksForRows(rows) {
|
|
|
65
65
|
// return duplicates, could be querying for both tables in a relation
|
|
66
66
|
return getUniqueByProp(
|
|
67
67
|
responses
|
|
68
|
+
.filter(el => el != null)
|
|
68
69
|
// create a unique ID which we can use for getting only unique ones
|
|
69
70
|
.map(el => ({ ...el, unique: el.id + el.thisId + el.fieldName })),
|
|
70
71
|
"unique"
|
package/src/db/utils.js
CHANGED
|
@@ -11,6 +11,8 @@ const {
|
|
|
11
11
|
isProdAppID,
|
|
12
12
|
getDevelopmentAppID,
|
|
13
13
|
generateAppID,
|
|
14
|
+
getQueryIndex,
|
|
15
|
+
ViewNames,
|
|
14
16
|
} = require("@budibase/backend-core/db")
|
|
15
17
|
|
|
16
18
|
const UNICODE_MAX = "\ufff0"
|
|
@@ -22,11 +24,7 @@ const AppStatus = {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const DocumentTypes = {
|
|
25
|
-
|
|
26
|
-
DEV: CoreDocTypes.DEV,
|
|
27
|
-
APP_DEV: CoreDocTypes.APP_DEV,
|
|
28
|
-
APP_METADATA: CoreDocTypes.APP_METADATA,
|
|
29
|
-
ROLE: CoreDocTypes.ROLE,
|
|
27
|
+
...CoreDocTypes,
|
|
30
28
|
TABLE: "ta",
|
|
31
29
|
ROW: "ro",
|
|
32
30
|
USER: "us",
|
|
@@ -45,11 +43,6 @@ const DocumentTypes = {
|
|
|
45
43
|
USER_FLAG: "flag",
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
const ViewNames = {
|
|
49
|
-
LINK: "by_link",
|
|
50
|
-
ROUTING: "screen_routes",
|
|
51
|
-
}
|
|
52
|
-
|
|
53
46
|
const InternalTables = {
|
|
54
47
|
USER_METADATA: "ta_users",
|
|
55
48
|
}
|
|
@@ -89,9 +82,7 @@ exports.generateDevAppID = getDevelopmentAppID
|
|
|
89
82
|
exports.generateRoleID = generateRoleID
|
|
90
83
|
exports.getRoleParams = getRoleParams
|
|
91
84
|
|
|
92
|
-
exports.getQueryIndex =
|
|
93
|
-
return `database/${viewName}`
|
|
94
|
-
}
|
|
85
|
+
exports.getQueryIndex = getQueryIndex
|
|
95
86
|
|
|
96
87
|
/**
|
|
97
88
|
* If creating DB allDocs/query params with only a single top level ID this can be used, this
|
package/src/environment.js
CHANGED
|
@@ -78,6 +78,7 @@ module.exports = {
|
|
|
78
78
|
ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
|
|
79
79
|
DISABLE_THREADING: process.env.DISABLE_THREADING,
|
|
80
80
|
DISABLE_DEVELOPER_LICENSE: process.env.DISABLE_DEVELOPER_LICENSE,
|
|
81
|
+
DISABLE_AUTOMATION_LOGS: process.env.DISABLE_AUTOMATION_LOGS,
|
|
81
82
|
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
|
82
83
|
ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
|
|
83
84
|
SELF_HOSTED: process.env.SELF_HOSTED,
|
|
@@ -9,7 +9,9 @@ export function enrichQueryFields(
|
|
|
9
9
|
parameters = {}
|
|
10
10
|
) {
|
|
11
11
|
const enrichedQuery: { [key: string]: any } = Array.isArray(fields) ? [] : {}
|
|
12
|
-
|
|
12
|
+
if (!fields || !parameters) {
|
|
13
|
+
return enrichedQuery
|
|
14
|
+
}
|
|
13
15
|
// enrich the fields with dynamic parameters
|
|
14
16
|
for (let key of Object.keys(fields)) {
|
|
15
17
|
if (fields[key] == null) {
|
package/src/integrations/rest.ts
CHANGED
|
@@ -155,12 +155,27 @@ describe("REST Integration", () => {
|
|
|
155
155
|
expect(output.headers["Content-Type"]).toEqual("application/json")
|
|
156
156
|
})
|
|
157
157
|
|
|
158
|
-
it("should allow XML", () => {
|
|
158
|
+
it("should allow raw XML", () => {
|
|
159
|
+
const output = config.integration.addBody("xml", "<a>1</a><b>2</b>", {})
|
|
160
|
+
expect(output.body.includes("<a>1</a>")).toEqual(true)
|
|
161
|
+
expect(output.body.includes("<b>2</b>")).toEqual(true)
|
|
162
|
+
expect(output.headers["Content-Type"]).toEqual("application/xml")
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it("should allow a valid js object and parse the contents to xml", () => {
|
|
159
166
|
const output = config.integration.addBody("xml", input, {})
|
|
160
167
|
expect(output.body.includes("<a>1</a>")).toEqual(true)
|
|
161
168
|
expect(output.body.includes("<b>2</b>")).toEqual(true)
|
|
162
169
|
expect(output.headers["Content-Type"]).toEqual("application/xml")
|
|
163
170
|
})
|
|
171
|
+
|
|
172
|
+
it("should allow a valid json string and parse the contents to xml", () => {
|
|
173
|
+
const output = config.integration.addBody("xml", JSON.stringify(input), {})
|
|
174
|
+
expect(output.body.includes("<a>1</a>")).toEqual(true)
|
|
175
|
+
expect(output.body.includes("<b>2</b>")).toEqual(true)
|
|
176
|
+
expect(output.headers["Content-Type"]).toEqual("application/xml")
|
|
177
|
+
})
|
|
178
|
+
|
|
164
179
|
})
|
|
165
180
|
|
|
166
181
|
describe("response", () => {
|
|
@@ -93,8 +93,24 @@ describe("migrations", () => {
|
|
|
93
93
|
await clearMigrations()
|
|
94
94
|
const appId = config.prodAppId
|
|
95
95
|
const roles = { [appId]: "role_12345" }
|
|
96
|
-
await config.createUser(
|
|
97
|
-
|
|
96
|
+
await config.createUser(
|
|
97
|
+
undefined,
|
|
98
|
+
undefined,
|
|
99
|
+
undefined,
|
|
100
|
+
undefined,
|
|
101
|
+
false,
|
|
102
|
+
true,
|
|
103
|
+
roles
|
|
104
|
+
) // admin only
|
|
105
|
+
await config.createUser(
|
|
106
|
+
undefined,
|
|
107
|
+
undefined,
|
|
108
|
+
undefined,
|
|
109
|
+
undefined,
|
|
110
|
+
false,
|
|
111
|
+
false,
|
|
112
|
+
roles
|
|
113
|
+
) // non admin non builder
|
|
98
114
|
await config.createTable()
|
|
99
115
|
await config.createRow()
|
|
100
116
|
await config.createRow()
|
package/src/module.d.ts
CHANGED