@budibase/server 0.9.185-alpha.1 → 0.9.185-alpha.13
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/Dockerfile +1 -1
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.4a7c5636.css +1 -0
- package/builder/assets/index.dc495306.js +1317 -0
- package/builder/assets/vendor.470042a4.js +152 -0
- package/builder/assets/vendor.5e1fe644.css +1 -0
- package/builder/index.html +4 -4
- package/coverage/clover.xml +689 -598
- package/coverage/coverage-final.json +89 -87
- package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
- package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
- package/coverage/lcov-report/api/controllers/application.js.html +43 -13
- package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
- package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +4 -4
- package/coverage/lcov-report/api/controllers/datasource.js.html +129 -21
- package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
- package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
- package/coverage/lcov-report/api/controllers/index.html +83 -83
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
- package/coverage/lcov-report/api/controllers/query.js.html +48 -210
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
- package/coverage/lcov-report/api/controllers/row/external.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/index.html +10 -10
- package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/utils.js.html +2 -2
- package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
- package/coverage/lcov-report/api/controllers/script.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +11 -11
- package/coverage/lcov-report/api/controllers/table/index.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/internal.js.html +2 -2
- package/coverage/lcov-report/api/controllers/table/utils.js.html +8 -8
- package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
- package/coverage/lcov-report/api/controllers/user.js.html +33 -18
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +9 -9
- package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
- package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- 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/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +2 -2
- package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +4 -4
- package/coverage/lcov-report/api/routes/index.js.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/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +5 -2
- 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/row.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/static.js.html +2 -2
- 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/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +2 -2
- package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
- package/coverage/lcov-report/automations/bullboard.js.html +71 -20
- package/coverage/lcov-report/automations/index.html +33 -48
- package/coverage/lcov-report/automations/index.js.html +2 -2
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +14 -14
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
- package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
- 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 +7 -7
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +22 -10
- package/coverage/lcov-report/automations/utils.js.html +42 -12
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +25 -4
- 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/client.js.html +2 -2
- package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
- package/coverage/lcov-report/db/index.html +2 -2
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
- package/coverage/lcov-report/events/index.html +6 -6
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +5 -5
- package/coverage/lcov-report/index.html +83 -68
- 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 +2 -2
- package/coverage/lcov-report/middleware/authorized.js.html +4 -4
- package/coverage/lcov-report/middleware/builder.js.html +16 -7
- package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
- package/coverage/lcov-report/middleware/index.html +21 -21
- package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
- package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
- package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
- package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +83 -32
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +260 -0
- package/coverage/lcov-report/threads/query.js.html +269 -0
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- 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 +2 -2
- package/coverage/lcov-report/utilities/global.js.html +2 -2
- package/coverage/lcov-report/utilities/index.html +21 -21
- package/coverage/lcov-report/utilities/index.js.html +12 -9
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
- package/coverage/lcov-report/utilities/queue/index.html +14 -14
- 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 +4 -4
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
- package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
- package/coverage/lcov-report/utilities/security.js.html +3 -3
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
- package/coverage/lcov.info +1136 -972
- package/dist/api/controllers/application.js +11 -1
- package/dist/api/controllers/datasource.js +31 -7
- package/dist/api/controllers/deploy/index.js +2 -0
- package/dist/api/controllers/dev.js +4 -1
- package/dist/api/controllers/query.js +27 -57
- package/dist/api/controllers/user.js +10 -6
- package/dist/api/routes/query.js +1 -1
- package/dist/app.js +2 -11
- package/dist/automations/bullboard.js +37 -10
- package/dist/automations/triggers.js +7 -3
- package/dist/automations/utils.js +11 -2
- package/dist/constants/index.js +6 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/sql.js +36 -8
- package/dist/integrations/mysql.js +3 -1
- package/dist/integrations/utils.js +7 -1
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +7 -6
- package/dist/{automations/thread.js → threads/automation.js} +23 -7
- package/dist/threads/index.js +58 -0
- package/dist/threads/query.js +61 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +8 -7
- package/scripts/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +11 -1
- package/src/api/controllers/datasource.js +45 -9
- package/src/api/controllers/deploy/index.js +2 -0
- package/src/api/controllers/dev.js +4 -1
- package/src/api/controllers/query.js +26 -80
- package/src/api/controllers/user.js +15 -10
- package/src/api/routes/query.js +1 -0
- package/src/app.ts +2 -10
- package/src/automations/bullboard.js +28 -11
- package/src/automations/tests/automation.spec.js +3 -4
- package/src/automations/triggers.js +7 -3
- package/src/automations/utils.js +12 -2
- package/src/constants/index.js +7 -0
- package/src/integrations/airtable.ts +2 -1
- package/src/integrations/arangodb.ts +2 -1
- package/src/integrations/base/IntegrationBase.ts +6 -0
- package/src/integrations/base/datasourcePlus.ts +2 -1
- package/src/integrations/base/sql.ts +38 -9
- package/src/integrations/couchdb.ts +2 -1
- package/src/integrations/dynamodb.ts +2 -1
- package/src/integrations/elasticsearch.ts +2 -1
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +1 -1
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +2 -1
- package/src/integrations/utils.ts +6 -1
- package/src/middleware/builder.js +4 -1
- package/src/{automations/thread.js → threads/automation.js} +24 -7
- package/src/threads/index.js +60 -0
- package/src/threads/query.js +63 -0
- package/src/utilities/index.js +1 -0
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/scriptRunner.js +4 -1
- package/tsconfig.json +1 -1
- package/builder/assets/index.4feb6e69.js +0 -201
- package/builder/assets/index.a79ec0ef.css +0 -29
- package/builder/assets/vendor.278a305c.js +0 -9
- package/builder/assets/vendor.d75d5eb7.css +0 -1
package/src/constants/index.js
CHANGED
|
@@ -163,8 +163,15 @@ exports.MetadataTypes = {
|
|
|
163
163
|
AUTOMATION_TEST_HISTORY: "automationTestHistory",
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
exports.InvalidColumns = {
|
|
167
|
+
ID: "_id",
|
|
168
|
+
REV: "_rev",
|
|
169
|
+
TABLE_ID: "tableId",
|
|
170
|
+
}
|
|
171
|
+
|
|
166
172
|
exports.BuildSchemaErrors = {
|
|
167
173
|
NO_KEY: "no_key",
|
|
174
|
+
INVALID_COLUMN: "invalid_column",
|
|
168
175
|
}
|
|
169
176
|
|
|
170
177
|
// pass through the list from the auth/core lib
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module AirtableModule {
|
|
8
9
|
const Airtable = require("airtable")
|
|
@@ -73,7 +74,7 @@ module AirtableModule {
|
|
|
73
74
|
},
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
class AirtableIntegration {
|
|
77
|
+
class AirtableIntegration implements IntegrationBase {
|
|
77
78
|
private config: AirtableConfig
|
|
78
79
|
private client: any
|
|
79
80
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module ArangoModule {
|
|
8
9
|
const { Database, aql } = require("arangojs")
|
|
@@ -55,7 +56,7 @@ module ArangoModule {
|
|
|
55
56
|
},
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
class ArangoDBIntegration {
|
|
59
|
+
class ArangoDBIntegration implements IntegrationBase {
|
|
59
60
|
private config: ArangodbConfig
|
|
60
61
|
private client: any
|
|
61
62
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Table } from "../../definitions/common"
|
|
2
|
+
import { IntegrationBase } from "./IntegrationBase"
|
|
2
3
|
|
|
3
|
-
export interface DatasourcePlus {
|
|
4
|
+
export interface DatasourcePlus extends IntegrationBase {
|
|
4
5
|
tables: Record<string, Table>
|
|
5
6
|
schemaErrors: Record<string, string>
|
|
6
7
|
|
|
@@ -13,22 +13,50 @@ import SqlTableQueryBuilder from "./sqlTable"
|
|
|
13
13
|
const BASE_LIMIT = 5000
|
|
14
14
|
|
|
15
15
|
type KnexQuery = Knex.QueryBuilder | Knex
|
|
16
|
+
// these are invalid dates sent by the client, need to convert them to a real max date
|
|
17
|
+
const MIN_ISO_DATE = "0000-00-00T00:00:00.000Z"
|
|
18
|
+
const MAX_ISO_DATE = "9999-00-00T00:00:00.000Z"
|
|
19
|
+
|
|
20
|
+
function parse(input: any) {
|
|
21
|
+
if (Array.isArray(input)) {
|
|
22
|
+
return JSON.stringify(input)
|
|
23
|
+
}
|
|
24
|
+
if (typeof input !== "string") {
|
|
25
|
+
return input
|
|
26
|
+
}
|
|
27
|
+
if (input === MAX_ISO_DATE) {
|
|
28
|
+
return new Date(8640000000000000)
|
|
29
|
+
}
|
|
30
|
+
if (input === MIN_ISO_DATE) {
|
|
31
|
+
return new Date(-8640000000000000)
|
|
32
|
+
}
|
|
33
|
+
if (isIsoDateString(input)) {
|
|
34
|
+
return new Date(input)
|
|
35
|
+
}
|
|
36
|
+
return input
|
|
37
|
+
}
|
|
16
38
|
|
|
17
39
|
function parseBody(body: any) {
|
|
18
40
|
for (let [key, value] of Object.entries(body)) {
|
|
19
|
-
|
|
20
|
-
body[key] = JSON.stringify(value)
|
|
21
|
-
}
|
|
22
|
-
if (typeof value !== "string") {
|
|
23
|
-
continue
|
|
24
|
-
}
|
|
25
|
-
if (isIsoDateString(value)) {
|
|
26
|
-
body[key] = new Date(value)
|
|
27
|
-
}
|
|
41
|
+
body[key] = parse(value)
|
|
28
42
|
}
|
|
29
43
|
return body
|
|
30
44
|
}
|
|
31
45
|
|
|
46
|
+
function parseFilters(filters: SearchFilters): SearchFilters {
|
|
47
|
+
for (let [key, value] of Object.entries(filters)) {
|
|
48
|
+
let parsed
|
|
49
|
+
if (typeof value === "object") {
|
|
50
|
+
parsed = parseFilters(value)
|
|
51
|
+
} else {
|
|
52
|
+
parsed = parse(value)
|
|
53
|
+
}
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
filters[key] = parsed
|
|
56
|
+
}
|
|
57
|
+
return filters
|
|
58
|
+
}
|
|
59
|
+
|
|
32
60
|
class InternalBuilder {
|
|
33
61
|
private readonly client: string
|
|
34
62
|
|
|
@@ -53,6 +81,7 @@ class InternalBuilder {
|
|
|
53
81
|
if (!filters) {
|
|
54
82
|
return query
|
|
55
83
|
}
|
|
84
|
+
filters = parseFilters(filters)
|
|
56
85
|
// if all or specified in filters, then everything is an or
|
|
57
86
|
const allOr = filters.allOr
|
|
58
87
|
if (filters.oneOf) {
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module CouchDBModule {
|
|
8
9
|
const PouchDB = require("pouchdb")
|
|
@@ -50,7 +51,7 @@ module CouchDBModule {
|
|
|
50
51
|
},
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
class CouchDBIntegration {
|
|
54
|
+
class CouchDBIntegration implements IntegrationBase {
|
|
54
55
|
private config: CouchDBConfig
|
|
55
56
|
private client: any
|
|
56
57
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module DynamoModule {
|
|
8
9
|
const AWS = require("aws-sdk")
|
|
@@ -113,7 +114,7 @@ module DynamoModule {
|
|
|
113
114
|
},
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
class DynamoDBIntegration {
|
|
117
|
+
class DynamoDBIntegration implements IntegrationBase {
|
|
117
118
|
private config: DynamoDBConfig
|
|
118
119
|
private client: any
|
|
119
120
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module ElasticsearchModule {
|
|
8
9
|
const { Client } = require("@elastic/elasticsearch")
|
|
@@ -74,7 +75,7 @@ module ElasticsearchModule {
|
|
|
74
75
|
},
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
class ElasticSearchIntegration {
|
|
78
|
+
class ElasticSearchIntegration implements IntegrationBase {
|
|
78
79
|
private config: ElasticsearchConfig
|
|
79
80
|
private client: any
|
|
80
81
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module MongoDBModule {
|
|
8
9
|
const { MongoClient } = require("mongodb")
|
|
@@ -62,7 +63,7 @@ module MongoDBModule {
|
|
|
62
63
|
},
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
class MongoIntegration {
|
|
66
|
+
class MongoIntegration implements IntegrationBase {
|
|
66
67
|
private config: MongoDBConfig
|
|
67
68
|
private client: any
|
|
68
69
|
|
package/src/integrations/rest.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module RestModule {
|
|
8
9
|
const fetch = require("node-fetch")
|
|
@@ -131,7 +132,7 @@ module RestModule {
|
|
|
131
132
|
},
|
|
132
133
|
}
|
|
133
134
|
|
|
134
|
-
class RestIntegration {
|
|
135
|
+
class RestIntegration implements IntegrationBase {
|
|
135
136
|
private config: RestConfig
|
|
136
137
|
private headers: {
|
|
137
138
|
[key: string]: string
|
package/src/integrations/s3.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Integration, QueryTypes } from "../definitions/datasource"
|
|
2
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
2
3
|
|
|
3
4
|
module S3Module {
|
|
4
5
|
const AWS = require("aws-sdk")
|
|
@@ -42,7 +43,7 @@ module S3Module {
|
|
|
42
43
|
},
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
class S3Integration {
|
|
46
|
+
class S3Integration implements IntegrationBase {
|
|
46
47
|
private readonly config: S3Config
|
|
47
48
|
private client: any
|
|
48
49
|
private connectionPromise: Promise<any>
|
|
@@ -2,7 +2,7 @@ import { SqlQuery } from "../definitions/datasource"
|
|
|
2
2
|
import { Datasource, Table } from "../definitions/common"
|
|
3
3
|
import { SourceNames } from "../definitions/datasource"
|
|
4
4
|
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
|
5
|
-
const { FieldTypes, BuildSchemaErrors } = require("../constants")
|
|
5
|
+
const { FieldTypes, BuildSchemaErrors, InvalidColumns } = require("../constants")
|
|
6
6
|
|
|
7
7
|
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
|
8
8
|
const ROW_ID_REGEX = /^\[.*]$/g
|
|
@@ -161,13 +161,18 @@ export function finaliseExternalTables(
|
|
|
161
161
|
tables: { [key: string]: any },
|
|
162
162
|
entities: { [key: string]: any }
|
|
163
163
|
) {
|
|
164
|
+
const invalidColumns = Object.values(InvalidColumns)
|
|
164
165
|
const finalTables: { [key: string]: any } = {}
|
|
165
166
|
const errors: { [key: string]: string } = {}
|
|
166
167
|
for (let [name, table] of Object.entries(tables)) {
|
|
168
|
+
const schemaFields = Object.keys(table.schema)
|
|
167
169
|
// make sure every table has a key
|
|
168
170
|
if (table.primary == null || table.primary.length === 0) {
|
|
169
171
|
errors[name] = BuildSchemaErrors.NO_KEY
|
|
170
172
|
continue
|
|
173
|
+
} else if (schemaFields.find(field => invalidColumns.includes(field))) {
|
|
174
|
+
errors[name] = BuildSchemaErrors.INVALID_COLUMN
|
|
175
|
+
continue
|
|
171
176
|
}
|
|
172
177
|
// make sure all previous props have been added back
|
|
173
178
|
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
const CouchDB = require("../db")
|
|
9
9
|
const { DocumentTypes } = require("../db/utils")
|
|
10
10
|
const { PermissionTypes } = require("@budibase/auth/permissions")
|
|
11
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
11
12
|
|
|
12
13
|
const DEBOUNCE_TIME_SEC = 30
|
|
13
14
|
|
|
@@ -50,7 +51,9 @@ async function updateAppUpdatedAt(ctx) {
|
|
|
50
51
|
const db = new CouchDB(appId)
|
|
51
52
|
const metadata = await db.get(DocumentTypes.APP_METADATA)
|
|
52
53
|
metadata.updatedAt = new Date().toISOString()
|
|
53
|
-
await db.put(metadata)
|
|
54
|
+
const response = await db.put(metadata)
|
|
55
|
+
metadata._rev = response.rev
|
|
56
|
+
await appCache.invalidateAppMetadata(appId, metadata)
|
|
54
57
|
// set a new debounce record with a short TTL
|
|
55
58
|
await setDebounce(appId, DEBOUNCE_TIME_SEC)
|
|
56
59
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const actions = require("
|
|
2
|
-
const automationUtils = require("
|
|
1
|
+
const actions = require("../automations/actions")
|
|
2
|
+
const automationUtils = require("../automations/automationUtils")
|
|
3
3
|
const AutomationEmitter = require("../events/AutomationEmitter")
|
|
4
4
|
const { processObject } = require("@budibase/string-templates")
|
|
5
5
|
const { DEFAULT_TENANT_ID } = require("@budibase/auth").constants
|
|
@@ -8,8 +8,10 @@ const { DocumentTypes, isDevAppID } = require("../db/utils")
|
|
|
8
8
|
const { doInTenant } = require("@budibase/auth/tenancy")
|
|
9
9
|
const env = require("../environment")
|
|
10
10
|
const usage = require("../utilities/usageQuota")
|
|
11
|
+
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
|
11
12
|
|
|
12
13
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
|
14
|
+
const CRON_STEP_ID = triggerDefs.CRON.stepId
|
|
13
15
|
const STOPPED_STATUS = { success: false, status: "STOPPED" }
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -23,6 +25,8 @@ class Orchestrator {
|
|
|
23
25
|
this._chainCount = this._metadata ? this._metadata.automationChainCount : 0
|
|
24
26
|
this._appId = triggerOutput.appId
|
|
25
27
|
this._app = null
|
|
28
|
+
const triggerStepId = automation.definition.trigger.stepId
|
|
29
|
+
triggerOutput = this.cleanupTriggerOutputs(triggerStepId, triggerOutput)
|
|
26
30
|
// remove from context
|
|
27
31
|
delete triggerOutput.appId
|
|
28
32
|
delete triggerOutput.metadata
|
|
@@ -34,11 +38,17 @@ class Orchestrator {
|
|
|
34
38
|
this._emitter = new AutomationEmitter(this._chainCount + 1)
|
|
35
39
|
this.executionOutput = { trigger: {}, steps: [] }
|
|
36
40
|
// setup the execution output
|
|
37
|
-
const triggerStepId = automation.definition.trigger.stepId
|
|
38
41
|
const triggerId = automation.definition.trigger.id
|
|
39
42
|
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
cleanupTriggerOutputs(stepId, triggerOutput) {
|
|
46
|
+
if (stepId === CRON_STEP_ID) {
|
|
47
|
+
triggerOutput.timestamp = Date.now()
|
|
48
|
+
}
|
|
49
|
+
return triggerOutput
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
async getStepFunctionality(stepId) {
|
|
43
53
|
let step = await actions.getAction(stepId)
|
|
44
54
|
if (step == null) {
|
|
@@ -119,10 +129,17 @@ class Orchestrator {
|
|
|
119
129
|
}
|
|
120
130
|
}
|
|
121
131
|
|
|
122
|
-
module.exports =
|
|
132
|
+
module.exports = (input, callback) => {
|
|
123
133
|
const automationOrchestrator = new Orchestrator(
|
|
124
|
-
|
|
125
|
-
|
|
134
|
+
input.data.automation,
|
|
135
|
+
input.data.event
|
|
126
136
|
)
|
|
127
|
-
|
|
137
|
+
automationOrchestrator
|
|
138
|
+
.execute()
|
|
139
|
+
.then(response => {
|
|
140
|
+
callback(null, response)
|
|
141
|
+
})
|
|
142
|
+
.catch(err => {
|
|
143
|
+
callback(err)
|
|
144
|
+
})
|
|
128
145
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const workerFarm = require("worker-farm")
|
|
2
|
+
const env = require("../environment")
|
|
3
|
+
|
|
4
|
+
const ThreadType = {
|
|
5
|
+
QUERY: "query",
|
|
6
|
+
AUTOMATION: "automation",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function typeToFile(type) {
|
|
10
|
+
let filename = null
|
|
11
|
+
switch (type) {
|
|
12
|
+
case ThreadType.QUERY:
|
|
13
|
+
filename = "./query"
|
|
14
|
+
break
|
|
15
|
+
case ThreadType.AUTOMATION:
|
|
16
|
+
filename = "./automation"
|
|
17
|
+
break
|
|
18
|
+
default:
|
|
19
|
+
throw "Unknown thread type"
|
|
20
|
+
}
|
|
21
|
+
return require.resolve(filename)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class Thread {
|
|
25
|
+
constructor(type, opts = { timeoutMs: null, count: 1 }) {
|
|
26
|
+
this.type = type
|
|
27
|
+
if (!env.isTest()) {
|
|
28
|
+
const workerOpts = {
|
|
29
|
+
autoStart: true,
|
|
30
|
+
maxConcurrentWorkers: opts.count ? opts.count : 1,
|
|
31
|
+
}
|
|
32
|
+
if (opts.timeoutMs) {
|
|
33
|
+
workerOpts.maxCallTime = opts.timeoutMs
|
|
34
|
+
}
|
|
35
|
+
this.workers = workerFarm(workerOpts, typeToFile(type))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
run(data) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
let fncToCall
|
|
42
|
+
// if in test then don't use threading
|
|
43
|
+
if (env.isTest()) {
|
|
44
|
+
fncToCall = require(typeToFile(this.type))
|
|
45
|
+
} else {
|
|
46
|
+
fncToCall = this.workers
|
|
47
|
+
}
|
|
48
|
+
fncToCall(data, (err, response) => {
|
|
49
|
+
if (err) {
|
|
50
|
+
reject(err)
|
|
51
|
+
} else {
|
|
52
|
+
resolve(response)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports.Thread = Thread
|
|
60
|
+
module.exports.ThreadType = ThreadType
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const ScriptRunner = require("../utilities/scriptRunner")
|
|
2
|
+
const { integrations } = require("../integrations")
|
|
3
|
+
|
|
4
|
+
function formatResponse(resp) {
|
|
5
|
+
if (typeof resp === "string") {
|
|
6
|
+
try {
|
|
7
|
+
resp = JSON.parse(resp)
|
|
8
|
+
} catch (err) {
|
|
9
|
+
resp = { response: resp }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return resp
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function runAndTransform(datasource, queryVerb, query, transformer) {
|
|
16
|
+
const Integration = integrations[datasource.source]
|
|
17
|
+
if (!Integration) {
|
|
18
|
+
throw "Integration type does not exist."
|
|
19
|
+
}
|
|
20
|
+
const integration = new Integration(datasource.config)
|
|
21
|
+
|
|
22
|
+
let rows = formatResponse(await integration[queryVerb](query))
|
|
23
|
+
|
|
24
|
+
// transform as required
|
|
25
|
+
if (transformer) {
|
|
26
|
+
const runner = new ScriptRunner(transformer, { data: rows })
|
|
27
|
+
rows = runner.execute()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// needs to an array for next step
|
|
31
|
+
if (!Array.isArray(rows)) {
|
|
32
|
+
rows = [rows]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// map into JSON if just raw primitive here
|
|
36
|
+
if (rows.find(row => typeof row !== "object")) {
|
|
37
|
+
rows = rows.map(value => ({ value }))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// get all the potential fields in the schema
|
|
41
|
+
let keys = rows.flatMap(Object.keys)
|
|
42
|
+
|
|
43
|
+
if (integration.end) {
|
|
44
|
+
integration.end()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { rows, keys }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = (input, callback) => {
|
|
51
|
+
runAndTransform(
|
|
52
|
+
input.datasource,
|
|
53
|
+
input.queryVerb,
|
|
54
|
+
input.query,
|
|
55
|
+
input.transformer
|
|
56
|
+
)
|
|
57
|
+
.then(response => {
|
|
58
|
+
callback(null, response)
|
|
59
|
+
})
|
|
60
|
+
.catch(err => {
|
|
61
|
+
callback(err)
|
|
62
|
+
})
|
|
63
|
+
}
|
package/src/utilities/index.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.objectStoreUrl = () => {
|
|
|
48
48
|
* via a specific endpoint (under /api/assets/client).
|
|
49
49
|
* @param {string} appId In production we need the appId to look up the correct bucket, as the
|
|
50
50
|
* version of the client lib may differ between apps.
|
|
51
|
+
* @param {string} version The version to retrieve.
|
|
51
52
|
* @return {string} The URL to be inserted into appPackage response or server rendered
|
|
52
53
|
* app index file.
|
|
53
54
|
*/
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
const fetch = require("node-fetch")
|
|
2
2
|
const { VM, VMScript } = require("vm2")
|
|
3
|
+
const JS_TIMEOUT_MS = 1000
|
|
3
4
|
|
|
4
5
|
class ScriptRunner {
|
|
5
6
|
constructor(script, context) {
|
|
6
7
|
const code = `let fn = () => {\n${script}\n}; results.out = fn();`
|
|
7
|
-
this.vm = new VM(
|
|
8
|
+
this.vm = new VM({
|
|
9
|
+
timeout: JS_TIMEOUT_MS,
|
|
10
|
+
})
|
|
8
11
|
this.results = { out: "" }
|
|
9
12
|
this.vm.setGlobals(context)
|
|
10
13
|
this.vm.setGlobal("fetch", fetch)
|