@budibase/server 1.0.218 → 1.0.219-alpha.2
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.00d6b4be.js +977 -0
- package/builder/assets/index.7786f497.css +6 -0
- package/builder/assets/{vendor.9bf2fcb4.js → vendor.001dcf8c.js} +163 -163
- package/builder/index.html +3 -3
- package/coverage/clover.xml +868 -794
- package/coverage/coverage-final.json +26 -26
- 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 +9 -6
- 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 +21 -21
- 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 +47 -17
- package/coverage/lcov-report/api/controllers/row/index.html +34 -34
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +95 -11
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +17 -8
- 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 +57 -12
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +17 -17
- 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 +4 -4
- 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 +27 -51
- 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 +74 -74
- 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 +18 -9
- package/coverage/lcov-report/threads/index.html +25 -25
- package/coverage/lcov-report/threads/query.js.html +283 -76
- 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 +1553 -1425
- package/dist/api/controllers/application.js +18 -15
- package/dist/api/controllers/automation.js +28 -2
- package/dist/api/controllers/backup.js +3 -2
- package/dist/api/controllers/query/index.js +25 -0
- package/dist/api/controllers/row/external.js +19 -7
- package/dist/api/controllers/row/internalSearch.js +22 -1
- package/dist/api/controllers/row/utils.js +3 -0
- package/dist/api/index.js +4 -1
- package/dist/api/routes/automation.js +2 -0
- package/dist/automations/automationUtils.js +16 -4
- package/dist/automations/logging/index.js +70 -0
- package/dist/automations/steps/filter.js +38 -29
- package/dist/automations/triggers.js +1 -1
- package/dist/db/linkedRows/index.js +1 -0
- package/dist/db/utils.js +4 -31
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +1 -0
- package/dist/integrations/airtable.js +1 -0
- package/dist/integrations/arangodb.js +1 -0
- package/dist/integrations/base/sql.js +20 -3
- package/dist/integrations/couchdb.js +1 -0
- package/dist/integrations/dynamodb.js +1 -0
- package/dist/integrations/elasticsearch.js +1 -0
- package/dist/integrations/firebase.js +1 -0
- package/dist/integrations/googlesheets.js +1 -0
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/microsoftSqlServer.js +2 -1
- package/dist/integrations/mongodb.js +1 -0
- package/dist/integrations/mysql.js +2 -1
- package/dist/integrations/oracle.js +1 -0
- package/dist/integrations/postgres.js +2 -1
- package/dist/integrations/queries/sql.js +3 -0
- package/dist/integrations/redis.js +1 -0
- package/dist/integrations/rest.js +2 -1
- package/dist/integrations/s3.js +1 -0
- package/dist/integrations/snowflake.js +102 -0
- package/dist/package.json +7 -6
- package/dist/tests/utilities/TestConfiguration.js +19 -6
- package/dist/threads/automation.js +6 -3
- package/dist/threads/index.js +15 -1
- package/dist/threads/query.js +54 -8
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +16 -6
- package/package.json +8 -7
- package/scripts/integrations/oracle/instantclient/linux/arm64/basiclite-19.10.zip +0 -0
- package/scripts/integrations/oracle/instantclient/linux/arm64/install.sh +23 -0
- package/scripts/integrations/oracle/instantclient/linux/install.sh +10 -0
- package/src/api/controllers/application.ts +18 -14
- package/src/api/controllers/automation.js +35 -2
- package/src/api/controllers/backup.js +3 -2
- package/src/api/controllers/query/index.ts +29 -1
- package/src/api/controllers/row/external.js +19 -9
- package/src/api/controllers/row/internalSearch.js +28 -0
- package/src/api/controllers/row/utils.js +3 -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/automationUtils.js +19 -4
- 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/automations/triggers.js +1 -1
- package/src/db/linkedRows/index.js +1 -0
- package/src/db/utils.js +5 -13
- package/src/definitions/common.ts +1 -0
- package/src/definitions/datasource.ts +2 -0
- package/src/environment.js +1 -0
- package/src/integrations/airtable.ts +1 -0
- package/src/integrations/arangodb.ts +1 -0
- package/src/integrations/base/sql.ts +25 -11
- package/src/integrations/couchdb.ts +1 -0
- package/src/integrations/dynamodb.ts +1 -0
- package/src/integrations/elasticsearch.ts +1 -0
- package/src/integrations/firebase.ts +1 -0
- package/src/integrations/googlesheets.ts +1 -0
- package/src/integrations/index.ts +4 -0
- package/src/integrations/microsoftSqlServer.ts +2 -0
- package/src/integrations/mongodb.ts +1 -0
- package/src/integrations/mysql.ts +2 -0
- package/src/integrations/oracle.ts +1 -0
- package/src/integrations/postgres.ts +2 -0
- package/src/integrations/queries/sql.ts +3 -1
- package/src/integrations/redis.ts +1 -0
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +1 -0
- package/src/integrations/snowflake.ts +99 -0
- package/src/integrations/tests/rest.spec.js +16 -1
- package/src/migrations/tests/index.spec.ts +18 -2
- package/src/module.d.ts +2 -0
- package/src/tests/utilities/TestConfiguration.js +22 -3
- package/src/threads/automation.js +6 -3
- package/src/threads/index.ts +5 -1
- package/src/threads/query.js +79 -10
- package/src/utilities/fileSystem/index.js +22 -8
- package/builder/assets/index.24307ca0.css +0 -6
- package/builder/assets/index.36419068.js +0 -1316
|
@@ -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
|
@@ -8,3 +8,5 @@ declare module "@budibase/backend-core/constants"
|
|
|
8
8
|
declare module "@budibase/backend-core/auth"
|
|
9
9
|
declare module "@budibase/backend-core/sessions"
|
|
10
10
|
declare module "@budibase/backend-core/encryption"
|
|
11
|
+
declare module "@budibase/backend-core/utils"
|
|
12
|
+
declare module "@budibase/backend-core/redis"
|
|
@@ -28,6 +28,8 @@ const { encrypt } = require("@budibase/backend-core/encryption")
|
|
|
28
28
|
|
|
29
29
|
const GLOBAL_USER_ID = "us_uuid1"
|
|
30
30
|
const EMAIL = "babs@babs.com"
|
|
31
|
+
const FIRSTNAME = "Barbara"
|
|
32
|
+
const LASTNAME = "Barbington"
|
|
31
33
|
const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
|
|
32
34
|
|
|
33
35
|
class TestConfiguration {
|
|
@@ -59,6 +61,15 @@ class TestConfiguration {
|
|
|
59
61
|
return this.prodAppId
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
getUserDetails() {
|
|
65
|
+
return {
|
|
66
|
+
globalId: GLOBAL_USER_ID,
|
|
67
|
+
email: EMAIL,
|
|
68
|
+
firstName: FIRSTNAME,
|
|
69
|
+
lastName: LASTNAME,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
async doInContext(appId, task) {
|
|
63
74
|
if (!appId) {
|
|
64
75
|
appId = this.appId
|
|
@@ -118,6 +129,8 @@ class TestConfiguration {
|
|
|
118
129
|
// USER / AUTH
|
|
119
130
|
async globalUser({
|
|
120
131
|
id = GLOBAL_USER_ID,
|
|
132
|
+
firstName = FIRSTNAME,
|
|
133
|
+
lastName = LASTNAME,
|
|
121
134
|
builder = true,
|
|
122
135
|
admin = false,
|
|
123
136
|
email = EMAIL,
|
|
@@ -135,6 +148,8 @@ class TestConfiguration {
|
|
|
135
148
|
...existing,
|
|
136
149
|
roles: roles || {},
|
|
137
150
|
tenantId: TENANT_ID,
|
|
151
|
+
firstName,
|
|
152
|
+
lastName,
|
|
138
153
|
}
|
|
139
154
|
await createASession(id, {
|
|
140
155
|
sessionId: "sessionid",
|
|
@@ -161,6 +176,8 @@ class TestConfiguration {
|
|
|
161
176
|
|
|
162
177
|
async createUser(
|
|
163
178
|
id = null,
|
|
179
|
+
firstName = FIRSTNAME,
|
|
180
|
+
lastName = LASTNAME,
|
|
164
181
|
email = EMAIL,
|
|
165
182
|
builder = true,
|
|
166
183
|
admin = false,
|
|
@@ -169,6 +186,8 @@ class TestConfiguration {
|
|
|
169
186
|
const globalId = !id ? `us_${Math.random()}` : `us_${id}`
|
|
170
187
|
const resp = await this.globalUser({
|
|
171
188
|
id: globalId,
|
|
189
|
+
firstName,
|
|
190
|
+
lastName,
|
|
172
191
|
email,
|
|
173
192
|
builder,
|
|
174
193
|
admin,
|
|
@@ -520,14 +539,14 @@ class TestConfiguration {
|
|
|
520
539
|
|
|
521
540
|
// QUERY
|
|
522
541
|
|
|
523
|
-
async previewQuery(request, config, datasource, fields) {
|
|
542
|
+
async previewQuery(request, config, datasource, fields, params, verb) {
|
|
524
543
|
return request
|
|
525
544
|
.post(`/api/queries/preview`)
|
|
526
545
|
.send({
|
|
527
546
|
datasourceId: datasource._id,
|
|
528
|
-
parameters: {},
|
|
547
|
+
parameters: params || {},
|
|
529
548
|
fields,
|
|
530
|
-
queryVerb: "read",
|
|
549
|
+
queryVerb: verb || "read",
|
|
531
550
|
name: datasource.name,
|
|
532
551
|
})
|
|
533
552
|
.set(config.defaultHeaders())
|
|
@@ -9,11 +9,12 @@ const { doInTenant } = require("@budibase/backend-core/tenancy")
|
|
|
9
9
|
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
|
10
10
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
|
11
11
|
const { AutomationErrors, LoopStepTypes } = require("../constants")
|
|
12
|
+
const { storeLog } = require("../automations/logging")
|
|
12
13
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
|
13
14
|
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
|
|
14
15
|
|
|
15
16
|
const CRON_STEP_ID = triggerDefs.CRON.stepId
|
|
16
|
-
const STOPPED_STATUS = { success:
|
|
17
|
+
const STOPPED_STATUS = { success: true, status: "STOPPED" }
|
|
17
18
|
const { cloneDeep } = require("lodash/fp")
|
|
18
19
|
const env = require("../environment")
|
|
19
20
|
|
|
@@ -218,7 +219,7 @@ class Orchestrator {
|
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
if (
|
|
221
|
-
index ===
|
|
222
|
+
index === env.AUTOMATION_MAX_ITERATION ||
|
|
222
223
|
index === parseInt(loopStep.inputs.iterations)
|
|
223
224
|
) {
|
|
224
225
|
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
|
@@ -275,7 +276,7 @@ class Orchestrator {
|
|
|
275
276
|
this._context.steps[stepCount] = outputs
|
|
276
277
|
// if filter causes us to stop execution don't break the loop, set a var
|
|
277
278
|
// so that we can finish iterating through the steps and record that it stopped
|
|
278
|
-
if (step.stepId === FILTER_STEP_ID && !outputs.
|
|
279
|
+
if (step.stepId === FILTER_STEP_ID && !outputs.result) {
|
|
279
280
|
stopped = true
|
|
280
281
|
this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
|
|
281
282
|
...outputs,
|
|
@@ -325,6 +326,8 @@ class Orchestrator {
|
|
|
325
326
|
}
|
|
326
327
|
}
|
|
327
328
|
|
|
329
|
+
// store the logs for the automation run
|
|
330
|
+
await storeLog(this._automation, this.executionOutput)
|
|
328
331
|
return this.executionOutput
|
|
329
332
|
}
|
|
330
333
|
}
|
package/src/threads/index.ts
CHANGED
|
@@ -77,7 +77,7 @@ export class Thread {
|
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
static
|
|
80
|
+
static stopThreads() {
|
|
81
81
|
return new Promise<void>(resolve => {
|
|
82
82
|
if (Thread.workerRefs.length === 0) {
|
|
83
83
|
resolve()
|
|
@@ -95,4 +95,8 @@ export class Thread {
|
|
|
95
95
|
Thread.workerRefs = []
|
|
96
96
|
})
|
|
97
97
|
}
|
|
98
|
+
|
|
99
|
+
static async shutdown() {
|
|
100
|
+
await Thread.stopThreads()
|
|
101
|
+
}
|
|
98
102
|
}
|
package/src/threads/query.js
CHANGED
|
@@ -4,6 +4,13 @@ const ScriptRunner = require("../utilities/scriptRunner")
|
|
|
4
4
|
const { integrations } = require("../integrations")
|
|
5
5
|
const { processStringSync } = require("@budibase/string-templates")
|
|
6
6
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
|
7
|
+
const {
|
|
8
|
+
refreshOAuthToken,
|
|
9
|
+
updateUserOAuth,
|
|
10
|
+
} = require("@budibase/backend-core/auth")
|
|
11
|
+
const { user: userCache } = require("@budibase/backend-core/cache")
|
|
12
|
+
const { getGlobalIDFromUserMetadataID } = require("../db/utils")
|
|
13
|
+
|
|
7
14
|
const { isSQL } = require("../integrations/utils")
|
|
8
15
|
const {
|
|
9
16
|
enrichQueryFields,
|
|
@@ -21,29 +28,56 @@ class QueryRunner {
|
|
|
21
28
|
this.queryId = input.queryId
|
|
22
29
|
this.noRecursiveQuery = flags.noRecursiveQuery
|
|
23
30
|
this.cachedVariables = []
|
|
31
|
+
// Additional context items for enrichment
|
|
32
|
+
this.ctx = input.ctx
|
|
24
33
|
// allows the response from a query to be stored throughout this
|
|
25
34
|
// execution so that if it needs to be re-used for another variable
|
|
26
35
|
// it can be
|
|
27
36
|
this.queryResponse = {}
|
|
28
37
|
this.hasRerun = false
|
|
38
|
+
this.hasRefreshedOAuth = false
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
async execute() {
|
|
32
42
|
let { datasource, fields, queryVerb, transformer } = this
|
|
43
|
+
|
|
33
44
|
const Integration = integrations[datasource.source]
|
|
34
45
|
if (!Integration) {
|
|
35
46
|
throw "Integration type does not exist."
|
|
36
47
|
}
|
|
48
|
+
|
|
49
|
+
if (datasource.config.authConfigs) {
|
|
50
|
+
datasource.config.authConfigs = datasource.config.authConfigs.map(
|
|
51
|
+
config => {
|
|
52
|
+
return enrichQueryFields(config, this.ctx)
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
37
57
|
const integration = new Integration(datasource.config)
|
|
38
58
|
|
|
39
59
|
// pre-query, make sure datasource variables are added to parameters
|
|
40
60
|
const parameters = await this.addDatasourceVariables()
|
|
61
|
+
|
|
62
|
+
// Enrich the parameters with the addition context items.
|
|
63
|
+
// 'user' is now a reserved variable key in mapping parameters
|
|
64
|
+
const enrichedParameters = enrichQueryFields(parameters, this.ctx)
|
|
65
|
+
const enrichedContext = { ...enrichedParameters, ...this.ctx }
|
|
66
|
+
|
|
67
|
+
// Parse global headers
|
|
68
|
+
if (datasource.config.defaultHeaders) {
|
|
69
|
+
datasource.config.defaultHeaders = enrichQueryFields(
|
|
70
|
+
datasource.config.defaultHeaders,
|
|
71
|
+
enrichedContext
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
41
75
|
let query
|
|
42
76
|
// handle SQL injections by interpolating the variables
|
|
43
77
|
if (isSQL(datasource)) {
|
|
44
|
-
query = interpolateSQL(fields,
|
|
78
|
+
query = interpolateSQL(fields, enrichedParameters, integration)
|
|
45
79
|
} else {
|
|
46
|
-
query = enrichQueryFields(fields,
|
|
80
|
+
query = enrichQueryFields(fields, enrichedContext)
|
|
47
81
|
}
|
|
48
82
|
|
|
49
83
|
// Add pagination values for REST queries
|
|
@@ -67,20 +101,24 @@ class QueryRunner {
|
|
|
67
101
|
if (transformer) {
|
|
68
102
|
const runner = new ScriptRunner(transformer, {
|
|
69
103
|
data: rows,
|
|
70
|
-
params:
|
|
104
|
+
params: enrichedParameters,
|
|
71
105
|
})
|
|
72
106
|
rows = runner.execute()
|
|
73
107
|
}
|
|
74
108
|
|
|
75
109
|
// if the request fails we retry once, invalidating the cached value
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
if (info && info.code >= 400 && !this.hasRerun) {
|
|
111
|
+
if (
|
|
112
|
+
this.ctx.user?.provider &&
|
|
113
|
+
info.code === 401 &&
|
|
114
|
+
!this.hasRefreshedOAuth
|
|
115
|
+
) {
|
|
116
|
+
await this.refreshOAuth2(this.ctx)
|
|
117
|
+
// Attempt to refresh the access token from the provider
|
|
118
|
+
this.hasRefreshedOAuth = true
|
|
119
|
+
}
|
|
120
|
+
|
|
82
121
|
this.hasRerun = true
|
|
83
|
-
// invalidate the cache value
|
|
84
122
|
await threadUtils.invalidateDynamicVariables(this.cachedVariables)
|
|
85
123
|
return this.execute()
|
|
86
124
|
}
|
|
@@ -126,6 +164,37 @@ class QueryRunner {
|
|
|
126
164
|
).execute()
|
|
127
165
|
}
|
|
128
166
|
|
|
167
|
+
async refreshOAuth2(ctx) {
|
|
168
|
+
const { oauth2, providerType, _id } = ctx.user
|
|
169
|
+
const { configId } = ctx.auth
|
|
170
|
+
|
|
171
|
+
if (!providerType || !oauth2?.refreshToken) {
|
|
172
|
+
throw new Error("No refresh token found for authenticated user")
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const resp = await refreshOAuthToken(
|
|
176
|
+
oauth2.refreshToken,
|
|
177
|
+
providerType,
|
|
178
|
+
configId
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// Refresh session flow. Should be in same location as refreshOAuthToken
|
|
182
|
+
// There are several other properties available in 'resp'
|
|
183
|
+
if (!resp.err) {
|
|
184
|
+
const globalUserId = getGlobalIDFromUserMetadataID(_id)
|
|
185
|
+
await updateUserOAuth(globalUserId, resp)
|
|
186
|
+
this.ctx.user = await userCache.getUser(globalUserId)
|
|
187
|
+
} else {
|
|
188
|
+
// In this event the user may have oAuth issues that
|
|
189
|
+
// could require re-authenticating with their provider.
|
|
190
|
+
throw new Error(
|
|
191
|
+
"OAuth2 access token could not be refreshed: " + resp.err.toString()
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return resp
|
|
196
|
+
}
|
|
197
|
+
|
|
129
198
|
async getDynamicVariable(variable) {
|
|
130
199
|
let { parameters } = this
|
|
131
200
|
const queryId = variable.queryId,
|
|
@@ -21,6 +21,7 @@ const env = require("../../environment")
|
|
|
21
21
|
const {
|
|
22
22
|
USER_METDATA_PREFIX,
|
|
23
23
|
LINK_USER_METADATA_PREFIX,
|
|
24
|
+
TABLE_ROW_PREFIX,
|
|
24
25
|
} = require("../../db/utils")
|
|
25
26
|
const MemoryStream = require("memorystream")
|
|
26
27
|
const { getAppId } = require("@budibase/backend-core/context")
|
|
@@ -109,6 +110,23 @@ exports.apiFileReturn = contents => {
|
|
|
109
110
|
return fs.createReadStream(path)
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
exports.defineFilter = excludeRows => {
|
|
114
|
+
if (excludeRows) {
|
|
115
|
+
return doc =>
|
|
116
|
+
!(
|
|
117
|
+
doc._id.includes(USER_METDATA_PREFIX) ||
|
|
118
|
+
doc._id.includes(LINK_USER_METADATA_PREFIX) ||
|
|
119
|
+
doc._id.includes(TABLE_ROW_PREFIX)
|
|
120
|
+
)
|
|
121
|
+
} else if (!excludeRows) {
|
|
122
|
+
return doc =>
|
|
123
|
+
!(
|
|
124
|
+
doc._id.includes(USER_METDATA_PREFIX) ||
|
|
125
|
+
doc._id.includes(LINK_USER_METADATA_PREFIX)
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
112
130
|
/**
|
|
113
131
|
* Local utility to back up the database state for an app, excluding global user
|
|
114
132
|
* data or user relationships.
|
|
@@ -116,14 +134,10 @@ exports.apiFileReturn = contents => {
|
|
|
116
134
|
* @param {object} config Config to send to export DB
|
|
117
135
|
* @returns {*} either a string or a stream of the backup
|
|
118
136
|
*/
|
|
119
|
-
const backupAppData = async (appId, config) => {
|
|
137
|
+
const backupAppData = async (appId, config, includeRows) => {
|
|
120
138
|
return await exports.exportDB(appId, {
|
|
121
139
|
...config,
|
|
122
|
-
filter:
|
|
123
|
-
!(
|
|
124
|
-
doc._id.includes(USER_METDATA_PREFIX) ||
|
|
125
|
-
doc._id.includes(LINK_USER_METADATA_PREFIX)
|
|
126
|
-
),
|
|
140
|
+
filter: exports.defineFilter(includeRows),
|
|
127
141
|
})
|
|
128
142
|
}
|
|
129
143
|
|
|
@@ -142,8 +156,8 @@ exports.performBackup = async (appId, backupName) => {
|
|
|
142
156
|
* @param {string} appId The ID of the app which is to be backed up.
|
|
143
157
|
* @returns {*} a readable stream of the backup which is written in real time
|
|
144
158
|
*/
|
|
145
|
-
exports.streamBackup = async appId => {
|
|
146
|
-
return await backupAppData(appId, { stream: true })
|
|
159
|
+
exports.streamBackup = async (appId, includeRows) => {
|
|
160
|
+
return await backupAppData(appId, { stream: true }, includeRows)
|
|
147
161
|
}
|
|
148
162
|
|
|
149
163
|
/**
|