@budibase/server 1.0.219 → 1.0.220-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__/node-fetch.ts +9 -0
- package/builder/assets/index.530f60fc.js +978 -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 +927 -832
- package/coverage/coverage-final.json +29 -29
- 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 +33 -33
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +159 -21
- 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 +5 -2
- 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 +2 -2
- 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 +81 -81
- 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 +301 -79
- 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 +16 -16
- 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 +57 -9
- package/coverage/lcov.info +1656 -1489
- 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/public/applications.js +1 -1
- package/dist/api/controllers/public/utils.js +8 -1
- package/dist/api/controllers/query/index.js +31 -3
- package/dist/api/controllers/row/external.js +19 -7
- package/dist/api/controllers/row/internalSearch.js +47 -10
- 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/api/routes/public/rows.js +7 -2
- package/dist/api/routes/utils/validators.js +1 -0
- package/dist/app.js +20 -0
- package/dist/automations/automationUtils.js +16 -4
- package/dist/automations/logging/index.js +70 -0
- package/dist/automations/steps/executeQuery.js +1 -1
- 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 +3 -0
- package/dist/integrations/airtable.js +1 -0
- package/dist/integrations/arangodb.js +1 -0
- package/dist/integrations/base/sql.js +22 -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 +65 -12
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +16 -6
- package/dist/utilities/workerRequests.js +8 -0
- package/package.json +8 -7
- package/scripts/dev/manage.js +2 -0
- 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/specs/openapi.json +9 -5
- package/specs/openapi.yaml +10 -4
- 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/public/applications.ts +2 -2
- package/src/api/controllers/public/utils.ts +8 -1
- package/src/api/controllers/query/index.ts +40 -4
- package/src/api/controllers/row/external.js +19 -9
- package/src/api/controllers/row/internalSearch.js +55 -9
- 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/public/rows.ts +7 -2
- package/src/api/routes/tests/query.spec.js +166 -1
- package/src/api/routes/utils/validators.js +1 -0
- package/src/app.ts +30 -1
- package/src/automations/automationUtils.js +19 -4
- package/src/automations/logging/index.ts +35 -0
- package/src/automations/steps/executeQuery.js +1 -1
- 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/definitions/openapi.ts +471 -469
- package/src/environment.js +3 -0
- package/src/integrations/airtable.ts +1 -0
- package/src/integrations/arangodb.ts +1 -0
- package/src/integrations/base/sql.ts +29 -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 +88 -14
- package/src/utilities/fileSystem/index.js +22 -8
- package/src/utilities/workerRequests.js +16 -0
- package/builder/assets/index.1c640a53.js +0 -1316
- package/builder/assets/index.24307ca0.css +0 -6
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"),
|
|
@@ -150,6 +150,11 @@ read.push(new Endpoint("get", "/tables/:tableId/rows/:rowId", controller.read))
|
|
|
150
150
|
* query:
|
|
151
151
|
* type: object
|
|
152
152
|
* properties:
|
|
153
|
+
* allOr:
|
|
154
|
+
* type: boolean
|
|
155
|
+
* description: Specifies that a row should be returned if it satisfies
|
|
156
|
+
* any of the specified options, rather than requiring it to fulfill all
|
|
157
|
+
* the search parameters. This defaults to false, meaning AND logic will be used.
|
|
153
158
|
* string:
|
|
154
159
|
* type: object
|
|
155
160
|
* example:
|
|
@@ -167,9 +172,9 @@ read.push(new Endpoint("get", "/tables/:tableId/rows/:rowId", controller.read))
|
|
|
167
172
|
* range:
|
|
168
173
|
* type: object
|
|
169
174
|
* description: Searches within a range, the format of this must be
|
|
170
|
-
*
|
|
175
|
+
* in the format of an object with a "low" and "high" property.
|
|
171
176
|
* example:
|
|
172
|
-
* columnName1:
|
|
177
|
+
* columnName1: { low: 10, high: 20 }
|
|
173
178
|
* equal:
|
|
174
179
|
* type: object
|
|
175
180
|
* description: Searches for rows that have a column value that is
|
|
@@ -218,7 +218,6 @@ describe("/queries", () => {
|
|
|
218
218
|
expect(res.body.schemaFields).toEqual(["a", "b"])
|
|
219
219
|
expect(res.body.rows.length).toEqual(1)
|
|
220
220
|
expect(events.query.previewed).toBeCalledTimes(1)
|
|
221
|
-
datasource.config = { schema: "public" }
|
|
222
221
|
expect(events.query.previewed).toBeCalledWith(datasource, query)
|
|
223
222
|
})
|
|
224
223
|
|
|
@@ -346,4 +345,170 @@ describe("/queries", () => {
|
|
|
346
345
|
expect(contents).toBe(null)
|
|
347
346
|
})
|
|
348
347
|
})
|
|
348
|
+
|
|
349
|
+
describe("Current User Request Mapping", () => {
|
|
350
|
+
|
|
351
|
+
async function previewGet(datasource, fields, params) {
|
|
352
|
+
return config.previewQuery(request, config, datasource, fields, params)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async function previewPost(datasource, fields, params) {
|
|
356
|
+
return config.previewQuery(request, config, datasource, fields, params, "create")
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
it("should parse global and query level header mappings", async () => {
|
|
360
|
+
const userDetails = config.getUserDetails()
|
|
361
|
+
|
|
362
|
+
const datasource = await config.restDatasource({
|
|
363
|
+
defaultHeaders: {
|
|
364
|
+
"test": "headerVal",
|
|
365
|
+
"emailHdr": "{{[user].[email]}}"
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
const res = await previewGet(datasource, {
|
|
369
|
+
path: "www.google.com",
|
|
370
|
+
queryString: "email={{[user].[email]}}",
|
|
371
|
+
headers: {
|
|
372
|
+
queryHdr : "{{[user].[firstName]}}",
|
|
373
|
+
secondHdr : "1234"
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
378
|
+
expect(parsedRequest.opts.headers).toEqual({
|
|
379
|
+
"test": "headerVal",
|
|
380
|
+
"emailHdr": userDetails.email,
|
|
381
|
+
"queryHdr": userDetails.firstName,
|
|
382
|
+
"secondHdr" : "1234"
|
|
383
|
+
})
|
|
384
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?email=" + userDetails.email)
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
it("should bind the current user to query parameters", async () => {
|
|
388
|
+
const userDetails = config.getUserDetails()
|
|
389
|
+
|
|
390
|
+
const datasource = await config.restDatasource()
|
|
391
|
+
|
|
392
|
+
const res = await previewGet(datasource, {
|
|
393
|
+
path: "www.google.com",
|
|
394
|
+
queryString: "test={{myEmail}}&testName={{myName}}&testParam={{testParam}}",
|
|
395
|
+
}, {
|
|
396
|
+
"myEmail" : "{{[user].[email]}}",
|
|
397
|
+
"myName" : "{{[user].[firstName]}}",
|
|
398
|
+
"testParam" : "1234"
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?test=" + userDetails.email +
|
|
402
|
+
"&testName=" + userDetails.firstName + "&testParam=1234")
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
it("should bind the current user the request body - plain text", async () => {
|
|
406
|
+
const userDetails = config.getUserDetails()
|
|
407
|
+
const datasource = await config.restDatasource()
|
|
408
|
+
|
|
409
|
+
const res = await previewPost(datasource, {
|
|
410
|
+
path: "www.google.com",
|
|
411
|
+
queryString: "testParam={{testParam}}",
|
|
412
|
+
requestBody: "This is plain text and this is my email: {{[user].[email]}}. This is a test param: {{testParam}}",
|
|
413
|
+
bodyType: "text"
|
|
414
|
+
}, {
|
|
415
|
+
"testParam" : "1234"
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
419
|
+
expect(parsedRequest.opts.body).toEqual(`This is plain text and this is my email: ${userDetails.email}. This is a test param: 1234`)
|
|
420
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
it("should bind the current user the request body - json", async () => {
|
|
424
|
+
const userDetails = config.getUserDetails()
|
|
425
|
+
const datasource = await config.restDatasource()
|
|
426
|
+
|
|
427
|
+
const res = await previewPost(datasource, {
|
|
428
|
+
path: "www.google.com",
|
|
429
|
+
queryString: "testParam={{testParam}}",
|
|
430
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
431
|
+
bodyType: "json"
|
|
432
|
+
}, {
|
|
433
|
+
"testParam" : "1234",
|
|
434
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
438
|
+
const test = `{"email":"${userDetails.email}","queryCode":1234,"userRef":"${userDetails.firstName}"}`
|
|
439
|
+
expect(parsedRequest.opts.body).toEqual(test)
|
|
440
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
it("should bind the current user the request body - xml", async () => {
|
|
444
|
+
const userDetails = config.getUserDetails()
|
|
445
|
+
const datasource = await config.restDatasource()
|
|
446
|
+
|
|
447
|
+
const res = await previewPost(datasource, {
|
|
448
|
+
path: "www.google.com",
|
|
449
|
+
queryString: "testParam={{testParam}}",
|
|
450
|
+
requestBody: "<note> <email>{{[user].[email]}}</email> <code>{{testParam}}</code> " +
|
|
451
|
+
"<ref>{{userId}}</ref> <somestring>testing</somestring> </note>",
|
|
452
|
+
bodyType: "xml"
|
|
453
|
+
}, {
|
|
454
|
+
"testParam" : "1234",
|
|
455
|
+
"userId" : "{{[user].[firstName]}}"
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
459
|
+
const test = `<note> <email>${userDetails.email}</email> <code>1234</code> <ref>${userDetails.firstName}</ref> <somestring>testing</somestring> </note>`
|
|
460
|
+
|
|
461
|
+
expect(parsedRequest.opts.body).toEqual(test)
|
|
462
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
it("should bind the current user the request body - form-data", async () => {
|
|
466
|
+
const userDetails = config.getUserDetails()
|
|
467
|
+
const datasource = await config.restDatasource()
|
|
468
|
+
|
|
469
|
+
const res = await previewPost(datasource, {
|
|
470
|
+
path: "www.google.com",
|
|
471
|
+
queryString: "testParam={{testParam}}",
|
|
472
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
473
|
+
bodyType: "form"
|
|
474
|
+
}, {
|
|
475
|
+
"testParam" : "1234",
|
|
476
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
477
|
+
})
|
|
478
|
+
|
|
479
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
480
|
+
|
|
481
|
+
const emailData = parsedRequest.opts.body._streams[1]
|
|
482
|
+
expect(emailData).toEqual(userDetails.email)
|
|
483
|
+
|
|
484
|
+
const queryCodeData = parsedRequest.opts.body._streams[4]
|
|
485
|
+
expect(queryCodeData).toEqual("1234")
|
|
486
|
+
|
|
487
|
+
const userRef = parsedRequest.opts.body._streams[7]
|
|
488
|
+
expect(userRef).toEqual(userDetails.firstName)
|
|
489
|
+
|
|
490
|
+
expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
it("should bind the current user the request body - encoded", async () => {
|
|
494
|
+
const userDetails = config.getUserDetails()
|
|
495
|
+
const datasource = await config.restDatasource()
|
|
496
|
+
|
|
497
|
+
const res = await previewPost(datasource, {
|
|
498
|
+
path: "www.google.com",
|
|
499
|
+
queryString: "testParam={{testParam}}",
|
|
500
|
+
requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
|
|
501
|
+
bodyType: "encoded"
|
|
502
|
+
}, {
|
|
503
|
+
"testParam" : "1234",
|
|
504
|
+
"userRef" : "{{[user].[firstName]}}"
|
|
505
|
+
})
|
|
506
|
+
const parsedRequest = JSON.parse(res.body.extra.raw)
|
|
507
|
+
|
|
508
|
+
expect(parsedRequest.opts.body.email).toEqual(userDetails.email)
|
|
509
|
+
expect(parsedRequest.opts.body.queryCode).toEqual("1234")
|
|
510
|
+
expect(parsedRequest.opts.body.userRef).toEqual(userDetails.firstName)
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
});
|
|
349
514
|
})
|
package/src/app.ts
CHANGED
|
@@ -18,7 +18,9 @@ const { logAlert } = require("@budibase/backend-core/logging")
|
|
|
18
18
|
const { Thread } = require("./threads")
|
|
19
19
|
import redis from "./utilities/redis"
|
|
20
20
|
import * as migrations from "./migrations"
|
|
21
|
-
import { events, installation } from "@budibase/backend-core"
|
|
21
|
+
import { events, installation, tenancy } from "@budibase/backend-core"
|
|
22
|
+
import { createAdminUser, getChecklist } from "./utilities/workerRequests"
|
|
23
|
+
import { tenantSucceeded } from "@budibase/backend-core/dist/src/events/publishers/backfill"
|
|
22
24
|
|
|
23
25
|
const app = new Koa()
|
|
24
26
|
|
|
@@ -110,6 +112,33 @@ module.exports = server.listen(env.PORT || 0, async () => {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
115
|
+
// check and create admin user if required
|
|
116
|
+
if (
|
|
117
|
+
env.SELF_HOSTED &&
|
|
118
|
+
!env.MULTI_TENANCY &&
|
|
119
|
+
env.BB_ADMIN_USER_EMAIL &&
|
|
120
|
+
env.BB_ADMIN_USER_PASSWORD
|
|
121
|
+
) {
|
|
122
|
+
const checklist = await getChecklist()
|
|
123
|
+
if (!checklist?.adminUser?.checked) {
|
|
124
|
+
try {
|
|
125
|
+
const tenantId = tenancy.getTenantId()
|
|
126
|
+
await createAdminUser(
|
|
127
|
+
env.BB_ADMIN_USER_EMAIL,
|
|
128
|
+
env.BB_ADMIN_USER_PASSWORD,
|
|
129
|
+
tenantId
|
|
130
|
+
)
|
|
131
|
+
console.log(
|
|
132
|
+
"Admin account automatically created for",
|
|
133
|
+
env.BB_ADMIN_USER_EMAIL
|
|
134
|
+
)
|
|
135
|
+
} catch (e) {
|
|
136
|
+
logAlert("Error creating initial admin user. Exiting.", e)
|
|
137
|
+
shutdown()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
113
142
|
// check for version updates
|
|
114
143
|
await installation.checkInstallVersion()
|
|
115
144
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
const { getTable } = require("../api/controllers/table/utils")
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
findHBSBlocks,
|
|
4
|
+
decodeJSBinding,
|
|
5
|
+
isJSBinding,
|
|
6
|
+
encodeJSBinding,
|
|
7
|
+
} = require("@budibase/string-templates")
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
* When values are input to the system generally they will be of type string as this is required for template strings.
|
|
@@ -77,11 +82,21 @@ exports.getError = err => {
|
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
exports.substituteLoopStep = (hbsString, substitute) => {
|
|
80
|
-
let blocks =
|
|
85
|
+
let blocks = []
|
|
86
|
+
let checkForJS = isJSBinding(hbsString)
|
|
87
|
+
if (checkForJS) {
|
|
88
|
+
hbsString = decodeJSBinding(hbsString)
|
|
89
|
+
blocks.push(hbsString)
|
|
90
|
+
} else {
|
|
91
|
+
blocks = findHBSBlocks(hbsString)
|
|
92
|
+
}
|
|
81
93
|
for (let block of blocks) {
|
|
82
|
-
let oldBlock = block
|
|
83
94
|
block = block.replace(/loop/, substitute)
|
|
84
|
-
|
|
95
|
+
if (checkForJS) {
|
|
96
|
+
hbsString = encodeJSBinding(block)
|
|
97
|
+
} else {
|
|
98
|
+
hbsString = block
|
|
99
|
+
}
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
return hbsString
|
|
@@ -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 () => {
|
|
@@ -97,7 +97,7 @@ exports.externalTrigger = async function (
|
|
|
97
97
|
// values are likely to be submitted as strings, so we shall convert to correct type
|
|
98
98
|
const coercedFields = {}
|
|
99
99
|
const fields = automation.definition.trigger.inputs.fields
|
|
100
|
-
for (let key of Object.keys(fields)) {
|
|
100
|
+
for (let key of Object.keys(fields || {})) {
|
|
101
101
|
coercedFields[key] = coerce(params.fields[key], fields[key])
|
|
102
102
|
}
|
|
103
103
|
params.fields = coercedFields
|
|
@@ -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
|
}
|
|
@@ -74,6 +67,7 @@ exports.isDevAppID = isDevAppID
|
|
|
74
67
|
exports.isProdAppID = isProdAppID
|
|
75
68
|
exports.USER_METDATA_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
|
|
76
69
|
exports.LINK_USER_METADATA_PREFIX = `${DocumentTypes.LINK}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
|
|
70
|
+
exports.TABLE_ROW_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${DocumentTypes.TABLE}`
|
|
77
71
|
exports.ViewNames = ViewNames
|
|
78
72
|
exports.InternalTables = InternalTables
|
|
79
73
|
exports.DocumentTypes = DocumentTypes
|
|
@@ -88,9 +82,7 @@ exports.generateDevAppID = getDevelopmentAppID
|
|
|
88
82
|
exports.generateRoleID = generateRoleID
|
|
89
83
|
exports.getRoleParams = getRoleParams
|
|
90
84
|
|
|
91
|
-
exports.getQueryIndex =
|
|
92
|
-
return `database/${viewName}`
|
|
93
|
-
}
|
|
85
|
+
exports.getQueryIndex = getQueryIndex
|
|
94
86
|
|
|
95
87
|
/**
|
|
96
88
|
* If creating DB allDocs/query params with only a single top level ID this can be used, this
|
|
@@ -50,6 +50,7 @@ export enum SourceNames {
|
|
|
50
50
|
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
|
51
51
|
FIRESTORE = "FIRESTORE",
|
|
52
52
|
REDIS = "REDIS",
|
|
53
|
+
SNOWFLAKE = "SNOWFLAKE",
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export enum IncludeRelationships {
|
|
@@ -93,6 +94,7 @@ export interface Integration {
|
|
|
93
94
|
relationships?: boolean
|
|
94
95
|
description: string
|
|
95
96
|
friendlyName: string
|
|
97
|
+
type?: string
|
|
96
98
|
datasource: {}
|
|
97
99
|
query: {
|
|
98
100
|
[key: string]: QueryDefinition
|