@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/environment.js
CHANGED
|
@@ -74,10 +74,13 @@ module.exports = {
|
|
|
74
74
|
DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,
|
|
75
75
|
QUERY_THREAD_TIMEOUT: parseIntSafe(process.env.QUERY_THREAD_TIMEOUT),
|
|
76
76
|
SQL_MAX_ROWS: process.env.SQL_MAX_ROWS,
|
|
77
|
+
BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,
|
|
78
|
+
BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,
|
|
77
79
|
// flags
|
|
78
80
|
ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
|
|
79
81
|
DISABLE_THREADING: process.env.DISABLE_THREADING,
|
|
80
82
|
DISABLE_DEVELOPER_LICENSE: process.env.DISABLE_DEVELOPER_LICENSE,
|
|
83
|
+
DISABLE_AUTOMATION_LOGS: process.env.DISABLE_AUTOMATION_LOGS,
|
|
81
84
|
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
|
82
85
|
ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
|
|
83
86
|
SELF_HOSTED: process.env.SELF_HOSTED,
|
|
@@ -18,6 +18,7 @@ module AirtableModule {
|
|
|
18
18
|
description:
|
|
19
19
|
"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",
|
|
20
20
|
friendlyName: "Airtable",
|
|
21
|
+
type: "Spreadsheet",
|
|
21
22
|
datasource: {
|
|
22
23
|
apiKey: {
|
|
23
24
|
type: DatasourceFieldTypes.PASSWORD,
|
|
@@ -19,6 +19,7 @@ module ArangoModule {
|
|
|
19
19
|
const SCHEMA: Integration = {
|
|
20
20
|
docs: "https://github.com/arangodb/arangojs",
|
|
21
21
|
friendlyName: "ArangoDB",
|
|
22
|
+
type: "Non-relational",
|
|
22
23
|
description:
|
|
23
24
|
"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",
|
|
24
25
|
datasource: {
|
|
@@ -89,6 +89,32 @@ function parseFilters(filters: SearchFilters | undefined): SearchFilters {
|
|
|
89
89
|
return filters
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
function generateSelectStatement(
|
|
93
|
+
json: QueryJson,
|
|
94
|
+
knex: Knex
|
|
95
|
+
): (string | Knex.Raw)[] {
|
|
96
|
+
const { resource, meta } = json
|
|
97
|
+
const schema = meta?.table?.schema
|
|
98
|
+
return resource.fields.map(field => {
|
|
99
|
+
const fieldNames = field.split(/\./g)
|
|
100
|
+
const tableName = fieldNames[0]
|
|
101
|
+
const columnName = fieldNames[1]
|
|
102
|
+
if (
|
|
103
|
+
columnName &&
|
|
104
|
+
schema?.[columnName] &&
|
|
105
|
+
knex.client.config.client === SqlClients.POSTGRES
|
|
106
|
+
) {
|
|
107
|
+
const externalType = schema[columnName].externalType
|
|
108
|
+
if (externalType?.includes("money")) {
|
|
109
|
+
return knex.raw(
|
|
110
|
+
`"${tableName}"."${columnName}"::money::numeric as "${field}"`
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return `${field} as ${field}`
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
92
118
|
class InternalBuilder {
|
|
93
119
|
private readonly client: string
|
|
94
120
|
|
|
@@ -216,9 +242,7 @@ class InternalBuilder {
|
|
|
216
242
|
}
|
|
217
243
|
|
|
218
244
|
addRelationships(
|
|
219
|
-
knex: Knex,
|
|
220
245
|
query: KnexQuery,
|
|
221
|
-
fields: string | string[],
|
|
222
246
|
fromTable: string,
|
|
223
247
|
relationships: RelationshipsJson[] | undefined
|
|
224
248
|
): KnexQuery {
|
|
@@ -323,12 +347,12 @@ class InternalBuilder {
|
|
|
323
347
|
if (!resource) {
|
|
324
348
|
resource = { fields: [] }
|
|
325
349
|
}
|
|
326
|
-
let selectStatement: string | string[] = "*"
|
|
350
|
+
let selectStatement: string | (string | Knex.Raw)[] = "*"
|
|
327
351
|
// handle select
|
|
328
352
|
if (resource.fields && resource.fields.length > 0) {
|
|
329
353
|
// select the resources as the format "table.columnName" - this is what is provided
|
|
330
354
|
// by the resource builder further up
|
|
331
|
-
selectStatement =
|
|
355
|
+
selectStatement = generateSelectStatement(json, knex)
|
|
332
356
|
}
|
|
333
357
|
let foundLimit = limit || BASE_LIMIT
|
|
334
358
|
// handle pagination
|
|
@@ -363,13 +387,7 @@ class InternalBuilder {
|
|
|
363
387
|
preQuery = this.addSorting(preQuery, json)
|
|
364
388
|
}
|
|
365
389
|
// handle joins
|
|
366
|
-
query = this.addRelationships(
|
|
367
|
-
knex,
|
|
368
|
-
preQuery,
|
|
369
|
-
selectStatement,
|
|
370
|
-
tableName,
|
|
371
|
-
relationships
|
|
372
|
-
)
|
|
390
|
+
query = this.addRelationships(preQuery, tableName, relationships)
|
|
373
391
|
return this.addFilters(query, filters, { relationship: true })
|
|
374
392
|
}
|
|
375
393
|
|
|
@@ -16,6 +16,7 @@ module CouchDBModule {
|
|
|
16
16
|
const SCHEMA: Integration = {
|
|
17
17
|
docs: "https://docs.couchdb.org/en/stable/",
|
|
18
18
|
friendlyName: "CouchDB",
|
|
19
|
+
type: "Non-relational",
|
|
19
20
|
description:
|
|
20
21
|
"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
|
|
21
22
|
datasource: {
|
|
@@ -21,6 +21,7 @@ module DynamoModule {
|
|
|
21
21
|
description:
|
|
22
22
|
"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
|
|
23
23
|
friendlyName: "DynamoDB",
|
|
24
|
+
type: "Non-relational",
|
|
24
25
|
datasource: {
|
|
25
26
|
region: {
|
|
26
27
|
type: DatasourceFieldTypes.STRING,
|
|
@@ -17,6 +17,7 @@ module ElasticsearchModule {
|
|
|
17
17
|
description:
|
|
18
18
|
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
|
|
19
19
|
friendlyName: "ElasticSearch",
|
|
20
|
+
type: "Non-relational",
|
|
20
21
|
datasource: {
|
|
21
22
|
url: {
|
|
22
23
|
type: DatasourceFieldTypes.STRING,
|
|
@@ -16,6 +16,7 @@ module Firebase {
|
|
|
16
16
|
const SCHEMA: Integration = {
|
|
17
17
|
docs: "https://firebase.google.com/docs/firestore/quickstart",
|
|
18
18
|
friendlyName: "Firestore",
|
|
19
|
+
type: "Non-relational",
|
|
19
20
|
description:
|
|
20
21
|
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
|
21
22
|
datasource: {
|
|
@@ -12,6 +12,7 @@ const rest = require("./rest")
|
|
|
12
12
|
const googlesheets = require("./googlesheets")
|
|
13
13
|
const firebase = require("./firebase")
|
|
14
14
|
const redis = require("./redis")
|
|
15
|
+
const snowflake = require("./snowflake")
|
|
15
16
|
const { SourceNames } = require("../definitions/datasource")
|
|
16
17
|
const environment = require("../environment")
|
|
17
18
|
|
|
@@ -29,6 +30,7 @@ const DEFINITIONS = {
|
|
|
29
30
|
[SourceNames.REST]: rest.schema,
|
|
30
31
|
[SourceNames.FIRESTORE]: firebase.schema,
|
|
31
32
|
[SourceNames.REDIS]: redis.schema,
|
|
33
|
+
[SourceNames.SNOWFLAKE]: snowflake.schema,
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const INTEGRATIONS = {
|
|
@@ -46,6 +48,8 @@ const INTEGRATIONS = {
|
|
|
46
48
|
[SourceNames.FIRESTORE]: firebase.integration,
|
|
47
49
|
[SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
|
|
48
50
|
[SourceNames.REDIS]: redis.integration,
|
|
51
|
+
[SourceNames.FIREBASE]: firebase.integration,
|
|
52
|
+
[SourceNames.SNOWFLAKE]: snowflake.integration,
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
// optionally add oracle integration if the oracle binary can be installed
|
|
@@ -44,6 +44,7 @@ module MSSQLModule {
|
|
|
44
44
|
description:
|
|
45
45
|
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
|
46
46
|
friendlyName: "MS SQL Server",
|
|
47
|
+
type: "Relational",
|
|
47
48
|
datasource: {
|
|
48
49
|
user: {
|
|
49
50
|
type: DatasourceFieldTypes.STRING,
|
|
@@ -246,6 +247,7 @@ module MSSQLModule {
|
|
|
246
247
|
autocolumn: !!autoColumns.find((col: string) => col === name),
|
|
247
248
|
name: name,
|
|
248
249
|
...convertSqlType(def.DATA_TYPE),
|
|
250
|
+
externalType: def.DATA_TYPE,
|
|
249
251
|
}
|
|
250
252
|
}
|
|
251
253
|
tables[tableName] = {
|
|
@@ -24,6 +24,7 @@ module MongoDBModule {
|
|
|
24
24
|
const SCHEMA: Integration = {
|
|
25
25
|
docs: "https://github.com/mongodb/node-mongodb-native",
|
|
26
26
|
friendlyName: "MongoDB",
|
|
27
|
+
type: "Non-relational",
|
|
27
28
|
description:
|
|
28
29
|
"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
|
|
29
30
|
datasource: {
|
|
@@ -36,6 +36,7 @@ module MySQLModule {
|
|
|
36
36
|
docs: "https://github.com/sidorares/node-mysql2",
|
|
37
37
|
plus: true,
|
|
38
38
|
friendlyName: "MySQL",
|
|
39
|
+
type: "Relational",
|
|
39
40
|
description:
|
|
40
41
|
"MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
|
|
41
42
|
datasource: {
|
|
@@ -232,6 +233,7 @@ module MySQLModule {
|
|
|
232
233
|
autocolumn: isAuto,
|
|
233
234
|
constraints,
|
|
234
235
|
...convertSqlType(column.Type),
|
|
236
|
+
externalType: column.Type,
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
if (!tables[tableName]) {
|
|
@@ -40,6 +40,7 @@ module OracleModule {
|
|
|
40
40
|
docs: "https://github.com/oracle/node-oracledb",
|
|
41
41
|
plus: true,
|
|
42
42
|
friendlyName: "Oracle",
|
|
43
|
+
type: "Relational",
|
|
43
44
|
description:
|
|
44
45
|
"Oracle Database is an object-relational database management system developed by Oracle Corporation",
|
|
45
46
|
datasource: {
|
|
@@ -47,6 +47,7 @@ module PostgresModule {
|
|
|
47
47
|
docs: "https://node-postgres.com",
|
|
48
48
|
plus: true,
|
|
49
49
|
friendlyName: "PostgreSQL",
|
|
50
|
+
type: "Relational",
|
|
50
51
|
description:
|
|
51
52
|
"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
|
|
52
53
|
datasource: {
|
|
@@ -271,6 +272,7 @@ module PostgresModule {
|
|
|
271
272
|
autocolumn: isAuto,
|
|
272
273
|
name: columnName,
|
|
273
274
|
...convertSqlType(column.data_type),
|
|
275
|
+
externalType: column.data_type,
|
|
274
276
|
}
|
|
275
277
|
}
|
|
276
278
|
|
|
@@ -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
|
@@ -64,6 +64,7 @@ module RestModule {
|
|
|
64
64
|
description:
|
|
65
65
|
"With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",
|
|
66
66
|
friendlyName: "REST API",
|
|
67
|
+
type: "API",
|
|
67
68
|
datasource: {
|
|
68
69
|
url: {
|
|
69
70
|
type: DatasourceFieldTypes.STRING,
|
|
@@ -286,7 +287,7 @@ module RestModule {
|
|
|
286
287
|
input.body = form
|
|
287
288
|
break
|
|
288
289
|
case BodyTypes.XML:
|
|
289
|
-
if (object != null) {
|
|
290
|
+
if (object != null && Object.keys(object).length) {
|
|
290
291
|
string = new XmlBuilder().buildObject(object)
|
|
291
292
|
}
|
|
292
293
|
input.body = string
|
package/src/integrations/s3.ts
CHANGED
|
@@ -17,6 +17,7 @@ module S3Module {
|
|
|
17
17
|
description:
|
|
18
18
|
"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.",
|
|
19
19
|
friendlyName: "Amazon S3",
|
|
20
|
+
type: "Object store",
|
|
20
21
|
datasource: {
|
|
21
22
|
region: {
|
|
22
23
|
type: "string",
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Integration, QueryTypes, SqlQuery } from "../definitions/datasource"
|
|
2
|
+
import { Snowflake } from "snowflake-promise"
|
|
3
|
+
|
|
4
|
+
module SnowflakeModule {
|
|
5
|
+
interface SnowflakeConfig {
|
|
6
|
+
account: string
|
|
7
|
+
username: string
|
|
8
|
+
password: string
|
|
9
|
+
warehouse: string
|
|
10
|
+
database: string
|
|
11
|
+
schema: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SCHEMA: Integration = {
|
|
15
|
+
docs: "https://developers.snowflake.com/",
|
|
16
|
+
description:
|
|
17
|
+
"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",
|
|
18
|
+
friendlyName: "Snowflake",
|
|
19
|
+
type: "Relational",
|
|
20
|
+
datasource: {
|
|
21
|
+
account: {
|
|
22
|
+
type: "string",
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
username: {
|
|
26
|
+
type: "string",
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
password: {
|
|
30
|
+
type: "password",
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
warehouse: {
|
|
34
|
+
type: "string",
|
|
35
|
+
required: true,
|
|
36
|
+
},
|
|
37
|
+
database: {
|
|
38
|
+
type: "string",
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
schema: {
|
|
42
|
+
type: "string",
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
query: {
|
|
47
|
+
create: {
|
|
48
|
+
type: QueryTypes.SQL,
|
|
49
|
+
},
|
|
50
|
+
read: {
|
|
51
|
+
type: QueryTypes.SQL,
|
|
52
|
+
},
|
|
53
|
+
update: {
|
|
54
|
+
type: QueryTypes.SQL,
|
|
55
|
+
},
|
|
56
|
+
delete: {
|
|
57
|
+
type: QueryTypes.SQL,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
class SnowflakeIntegration {
|
|
63
|
+
private client: Snowflake
|
|
64
|
+
|
|
65
|
+
constructor(config: SnowflakeConfig) {
|
|
66
|
+
this.client = new Snowflake(config)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async internalQuery(query: SqlQuery) {
|
|
70
|
+
await this.client.connect()
|
|
71
|
+
try {
|
|
72
|
+
return await this.client.execute(query.sql)
|
|
73
|
+
} catch (err: any) {
|
|
74
|
+
throw err?.message.split(":")[1] || err?.message
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async create(query: SqlQuery) {
|
|
79
|
+
return this.internalQuery(query)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async read(query: SqlQuery) {
|
|
83
|
+
return this.internalQuery(query)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async update(query: SqlQuery) {
|
|
87
|
+
return this.internalQuery(query)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async delete(query: SqlQuery) {
|
|
91
|
+
return this.internalQuery(query)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = {
|
|
96
|
+
schema: SCHEMA,
|
|
97
|
+
integration: SnowflakeIntegration,
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -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
|
}
|