@budibase/server 1.0.48 → 1.0.49-alpha.3
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/builder/assets/{index.e083dcaf.js → index.21e57eb4.js} +234 -231
- package/builder/assets/index.83c0944f.css +1 -0
- package/builder/assets/{vendor.f9faf6ab.js → vendor.d526bfe8.js} +12 -12
- package/builder/index.html +3 -3
- package/coverage/clover.xml +2338 -2028
- package/coverage/coverage-final.json +100 -95
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +210 -126
- package/coverage/lcov-report/api/controllers/auth.js.html +18 -6
- package/coverage/lcov-report/api/controllers/automation.js.html +21 -21
- 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 +72 -36
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +53 -53
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +6 -6
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +119 -0
- package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.js.html +19 -19
- package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +16 -16
- package/coverage/lcov-report/api/controllers/row/index.html +48 -33
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +95 -158
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +41 -17
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +551 -0
- package/coverage/lcov-report/api/controllers/row/utils.js.html +39 -57
- package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
- package/coverage/lcov-report/api/controllers/script.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +629 -0
- package/coverage/lcov-report/api/controllers/table/external.js.html +12 -12
- package/coverage/lcov-report/api/controllers/table/index.html +46 -31
- package/coverage/lcov-report/api/controllers/table/index.js.html +53 -77
- package/coverage/lcov-report/api/controllers/table/internal.js.html +59 -35
- package/coverage/lcov-report/api/controllers/table/utils.js.html +217 -73
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +30 -24
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +14 -14
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
- package/coverage/lcov-report/api/controllers/webhook.js.html +15 -15
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +8 -8
- 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 +1 -1
- package/coverage/lcov-report/api/routes/index.html +18 -18
- package/coverage/lcov-report/api/routes/index.js.html +3 -3
- 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/{hosting.js.html → migrations.js.html} +17 -14
- 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/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 +17 -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 +24 -24
- package/coverage/lcov-report/automations/automationUtils.js.html +5 -5
- package/coverage/lcov-report/automations/bullboard.js.html +16 -16
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
- package/coverage/lcov-report/automations/steps/createRow.js.html +13 -19
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
- package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
- package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
- package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
- package/coverage/lcov-report/automations/steps/index.html +13 -13
- package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
- package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
- package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
- package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
- package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
- 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 +18 -18
- package/coverage/lcov-report/automations/utils.js.html +32 -32
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +53 -26
- package/coverage/lcov-report/constants/layouts.js.html +5 -5
- package/coverage/lcov-report/constants/screens.js.html +4 -4
- package/coverage/lcov-report/db/client.js.html +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +18 -18
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +38 -41
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +15 -15
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +86 -86
- 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 +5 -5
- package/coverage/lcov-report/events/utils.js.html +3 -3
- package/coverage/lcov-report/index.html +114 -99
- 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/authorized.js.html +166 -64
- package/coverage/lcov-report/middleware/builder.js.html +8 -8
- package/coverage/lcov-report/middleware/currentapp.js.html +29 -29
- package/coverage/lcov-report/middleware/index.html +30 -30
- package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +270 -42
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +15 -15
- package/coverage/lcov-report/threads/index.js.html +10 -10
- package/coverage/lcov-report/threads/query.js.html +23 -8
- package/coverage/lcov-report/threads/utils.js.html +14 -14
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
- package/coverage/lcov-report/utilities/global.js.html +26 -26
- package/coverage/lcov-report/utilities/index.html +19 -19
- package/coverage/lcov-report/utilities/index.js.html +25 -25
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
- 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 +27 -27
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +115 -79
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +75 -27
- package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
- package/coverage/lcov-report/utilities/security.js.html +8 -8
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +141 -0
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +356 -0
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +302 -0
- package/coverage/lcov-report/{api/controllers/hosting.js.html → utilities/usageQuota/usageQuoteReset.js.html} +36 -48
- package/coverage/lcov-report/utilities/users.js.html +5 -5
- package/coverage/lcov-report/utilities/workerRequests.js.html +39 -108
- package/coverage/lcov.info +3656 -3057
- package/dist/api/controllers/application.js +61 -34
- package/dist/api/controllers/auth.js +4 -0
- package/dist/api/controllers/datasource.js +11 -0
- package/dist/api/controllers/migrations.js +21 -0
- package/dist/api/controllers/row/internal.js +30 -53
- package/dist/api/controllers/row/internalSearch.js +12 -4
- package/dist/api/controllers/row/staticFormula.js +147 -0
- package/dist/api/controllers/row/utils.js +6 -8
- package/dist/api/controllers/static/index.js +59 -10
- package/dist/api/controllers/table/bulkFormula.js +160 -0
- package/dist/api/controllers/table/index.js +12 -9
- package/dist/api/controllers/table/internal.js +9 -0
- package/dist/api/controllers/table/utils.js +41 -12
- package/dist/api/controllers/user.js +2 -0
- package/dist/api/routes/index.js +2 -2
- package/dist/api/routes/migrations.js +9 -0
- package/dist/api/routes/static.js +2 -1
- package/dist/app.js +35 -5
- package/dist/automations/steps/createRow.js +2 -4
- package/dist/automations/steps/deleteRow.js +1 -4
- package/dist/constants/index.js +7 -0
- package/dist/db/linkedRows/index.js +4 -5
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +2 -0
- package/dist/integrations/base/sql.js +13 -6
- package/dist/integrations/googlesheets.js +340 -0
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/utils.js +57 -9
- package/dist/middleware/authorized.js +55 -30
- package/dist/middleware/usageQuota.js +80 -13
- package/dist/migrations/functions/appUrls.js +46 -0
- package/dist/migrations/functions/quotas1.js +50 -0
- package/dist/migrations/functions/usageQuotas/index.js +20 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +32 -0
- package/dist/migrations/functions/usageQuotas/syncRows.js +35 -0
- package/dist/migrations/functions/userEmailViewCasing.js +24 -0
- package/dist/migrations/index.js +62 -0
- package/dist/package.json +8 -5
- package/dist/tests/utilities/TestConfiguration.js +13 -6
- package/dist/threads/query.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/rowProcessor/index.js +18 -11
- package/dist/utilities/rowProcessor/utils.js +14 -4
- package/dist/utilities/{usageQuota.js → usageQuota/index.js} +44 -31
- package/dist/utilities/usageQuota/rows.js +77 -0
- package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
- package/dist/utilities/workerRequests.js +0 -20
- package/nodemon.json +1 -1
- package/package.json +9 -6
- package/src/api/controllers/application.js +52 -24
- package/src/api/controllers/auth.js +4 -0
- package/src/api/controllers/datasource.js +12 -0
- package/src/api/controllers/migrations.js +13 -0
- package/src/api/controllers/row/internal.js +29 -50
- package/src/api/controllers/row/internalSearch.js +12 -4
- package/src/api/controllers/row/staticFormula.js +157 -0
- package/src/api/controllers/row/utils.js +6 -12
- package/src/api/controllers/static/index.js +63 -10
- package/src/api/controllers/table/bulkFormula.js +183 -0
- package/src/api/controllers/table/index.js +16 -24
- package/src/api/controllers/table/internal.js +9 -1
- package/src/api/controllers/table/utils.js +57 -9
- package/src/api/controllers/user.js +2 -0
- package/src/api/routes/index.js +2 -2
- package/src/api/routes/migrations.js +14 -0
- package/src/api/routes/static.js +5 -0
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/auth.spec.js +1 -2
- package/src/api/routes/tests/static.spec.js +98 -0
- package/src/app.ts +18 -5
- package/src/automations/steps/createRow.js +2 -4
- package/src/automations/steps/deleteRow.js +1 -4
- package/src/constants/index.js +9 -0
- package/src/db/linkedRows/index.js +4 -5
- package/src/definitions/common.ts +3 -0
- package/src/definitions/datasource.ts +3 -0
- package/src/environment.js +2 -0
- package/src/integrations/base/sql.ts +14 -7
- package/src/integrations/googlesheets.ts +353 -0
- package/src/integrations/index.ts +3 -0
- package/src/integrations/tests/sql.spec.js +16 -0
- package/src/integrations/utils.ts +71 -11
- package/src/middleware/authorized.js +64 -30
- package/src/middleware/tests/authorized.spec.js +6 -4
- package/src/middleware/tests/usageQuota.spec.js +18 -24
- package/src/middleware/usageQuota.js +91 -15
- package/src/migrations/functions/appUrls.ts +34 -0
- package/src/migrations/functions/quotas1.ts +20 -0
- package/src/migrations/functions/tests/appUrls.spec.js +29 -0
- package/src/migrations/functions/tests/quotas1.spec.js +27 -0
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +25 -0
- package/src/migrations/functions/usageQuotas/index.ts +8 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +18 -0
- package/src/migrations/functions/usageQuotas/syncRows.ts +21 -0
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +37 -0
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +43 -0
- package/src/migrations/functions/userEmailViewCasing.ts +13 -0
- package/src/migrations/index.ts +56 -0
- package/src/tests/utilities/TestConfiguration.js +14 -6
- package/src/threads/query.js +5 -0
- package/src/utilities/rowProcessor/index.js +24 -12
- package/src/utilities/rowProcessor/utils.js +23 -7
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
- package/src/utilities/usageQuota/index.js +92 -0
- package/src/utilities/usageQuota/rows.js +74 -0
- package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
- package/src/utilities/workerRequests.js +0 -23
- package/builder/assets/index.39e01193.css +0 -1
- package/dist/api/controllers/hosting.js +0 -30
- package/dist/api/routes/hosting.js +0 -11
- package/src/api/controllers/hosting.js +0 -22
- package/src/api/routes/hosting.js +0 -13
- package/src/api/routes/tests/hosting.spec.js +0 -36
- package/src/utilities/usageQuota.js +0 -73
|
@@ -2,13 +2,9 @@ const CouchDB = require("../../../db")
|
|
|
2
2
|
const internal = require("./internal")
|
|
3
3
|
const external = require("./external")
|
|
4
4
|
const csvParser = require("../../../utilities/csvParser")
|
|
5
|
-
const { isExternalTable } = require("../../../integrations/utils")
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
getDatasourceParams,
|
|
9
|
-
BudibaseInternalDB,
|
|
10
|
-
} = require("../../../db/utils")
|
|
11
|
-
const { getTable } = require("./utils")
|
|
5
|
+
const { isExternalTable, isSQL } = require("../../../integrations/utils")
|
|
6
|
+
const { getDatasourceParams } = require("../../../db/utils")
|
|
7
|
+
const { getTable, getAllInternalTables } = require("./utils")
|
|
12
8
|
|
|
13
9
|
function pickApi({ tableId, table }) {
|
|
14
10
|
if (table && !tableId) {
|
|
@@ -26,17 +22,7 @@ function pickApi({ tableId, table }) {
|
|
|
26
22
|
exports.fetch = async function (ctx) {
|
|
27
23
|
const db = new CouchDB(ctx.appId)
|
|
28
24
|
|
|
29
|
-
const
|
|
30
|
-
getTableParams(null, {
|
|
31
|
-
include_docs: true,
|
|
32
|
-
})
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
const internal = internalTables.rows.map(row => ({
|
|
36
|
-
...row.doc,
|
|
37
|
-
type: "internal",
|
|
38
|
-
sourceId: BudibaseInternalDB._id,
|
|
39
|
-
}))
|
|
25
|
+
const internal = await getAllInternalTables(ctx.appId)
|
|
40
26
|
|
|
41
27
|
const externalTables = await db.allDocs(
|
|
42
28
|
getDatasourceParams("plus", {
|
|
@@ -44,12 +30,18 @@ exports.fetch = async function (ctx) {
|
|
|
44
30
|
})
|
|
45
31
|
)
|
|
46
32
|
|
|
47
|
-
const external = externalTables.rows.flatMap(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
33
|
+
const external = externalTables.rows.flatMap(tableDoc => {
|
|
34
|
+
let entities = tableDoc.doc.entities
|
|
35
|
+
if (entities) {
|
|
36
|
+
return Object.values(entities).map(entity => ({
|
|
37
|
+
...entity,
|
|
38
|
+
type: "external",
|
|
39
|
+
sourceId: tableDoc.doc._id,
|
|
40
|
+
sql: isSQL(tableDoc.doc),
|
|
41
|
+
}))
|
|
42
|
+
} else {
|
|
43
|
+
return []
|
|
44
|
+
}
|
|
53
45
|
})
|
|
54
46
|
|
|
55
47
|
ctx.body = [...internal, ...external]
|
|
@@ -8,6 +8,9 @@ const {
|
|
|
8
8
|
getTable,
|
|
9
9
|
handleDataImport,
|
|
10
10
|
} = require("./utils")
|
|
11
|
+
const usageQuota = require("../../../utilities/usageQuota")
|
|
12
|
+
const { cleanupAttachments } = require("../../../utilities/rowProcessor")
|
|
13
|
+
const { runStaticFormulaChecks } = require("./bulkFormula")
|
|
11
14
|
|
|
12
15
|
exports.save = async function (ctx) {
|
|
13
16
|
const appId = ctx.appId
|
|
@@ -103,7 +106,8 @@ exports.save = async function (ctx) {
|
|
|
103
106
|
tableToSave._rev = result.rev
|
|
104
107
|
|
|
105
108
|
tableToSave = await tableSaveFunctions.after(tableToSave)
|
|
106
|
-
|
|
109
|
+
// has to run after, make sure it has _id
|
|
110
|
+
await runStaticFormulaChecks(appId, tableToSave, { oldTable })
|
|
107
111
|
return tableToSave
|
|
108
112
|
}
|
|
109
113
|
|
|
@@ -119,6 +123,7 @@ exports.destroy = async function (ctx) {
|
|
|
119
123
|
})
|
|
120
124
|
)
|
|
121
125
|
await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
|
|
126
|
+
await usageQuota.update(usageQuota.Properties.ROW, -rows.rows.length)
|
|
122
127
|
|
|
123
128
|
// update linked rows
|
|
124
129
|
await linkRows.updateLinks({
|
|
@@ -139,6 +144,9 @@ exports.destroy = async function (ctx) {
|
|
|
139
144
|
await db.deleteIndex(existingIndex)
|
|
140
145
|
}
|
|
141
146
|
|
|
147
|
+
// has to run after, make sure it has _id
|
|
148
|
+
await runStaticFormulaChecks(appId, tableToDelete, { deletion: true })
|
|
149
|
+
await cleanupAttachments(appId, tableToDelete, { rows })
|
|
142
150
|
return tableToDelete
|
|
143
151
|
}
|
|
144
152
|
|
|
@@ -4,10 +4,15 @@ const {
|
|
|
4
4
|
getRowParams,
|
|
5
5
|
generateRowID,
|
|
6
6
|
InternalTables,
|
|
7
|
+
getTableParams,
|
|
8
|
+
BudibaseInternalDB,
|
|
7
9
|
} = require("../../../db/utils")
|
|
8
|
-
const { isEqual } = require("lodash
|
|
10
|
+
const { isEqual } = require("lodash")
|
|
9
11
|
const { AutoFieldSubTypes, FieldTypes } = require("../../../constants")
|
|
10
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
inputProcessing,
|
|
14
|
+
cleanupAttachments,
|
|
15
|
+
} = require("../../../utilities/rowProcessor")
|
|
11
16
|
const {
|
|
12
17
|
USERS_TABLE_SCHEMA,
|
|
13
18
|
SwitchableTypes,
|
|
@@ -16,11 +21,29 @@ const {
|
|
|
16
21
|
const {
|
|
17
22
|
isExternalTable,
|
|
18
23
|
breakExternalTableId,
|
|
24
|
+
isSQL,
|
|
19
25
|
} = require("../../../integrations/utils")
|
|
20
26
|
const { getViews, saveView } = require("../view/utils")
|
|
21
27
|
const viewTemplate = require("../view/viewBuilder")
|
|
28
|
+
const usageQuota = require("../../../utilities/usageQuota")
|
|
29
|
+
const { cloneDeep } = require("lodash/fp")
|
|
30
|
+
|
|
31
|
+
exports.clearColumns = async (appId, table, columnNames) => {
|
|
32
|
+
const db = new CouchDB(appId)
|
|
33
|
+
const rows = await db.allDocs(
|
|
34
|
+
getRowParams(table._id, null, {
|
|
35
|
+
include_docs: true,
|
|
36
|
+
})
|
|
37
|
+
)
|
|
38
|
+
return db.bulkDocs(
|
|
39
|
+
rows.rows.map(({ doc }) => {
|
|
40
|
+
columnNames.forEach(colName => delete doc[colName])
|
|
41
|
+
return doc
|
|
42
|
+
})
|
|
43
|
+
)
|
|
44
|
+
}
|
|
22
45
|
|
|
23
|
-
exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
|
|
46
|
+
exports.checkForColumnUpdates = async (appId, db, oldTable, updatedTable) => {
|
|
24
47
|
let updatedRows = []
|
|
25
48
|
const rename = updatedTable._rename
|
|
26
49
|
let deletedColumns = []
|
|
@@ -37,16 +60,20 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
|
|
|
37
60
|
include_docs: true,
|
|
38
61
|
})
|
|
39
62
|
)
|
|
40
|
-
|
|
63
|
+
const rawRows = rows.rows.map(({ doc }) => doc)
|
|
64
|
+
updatedRows = rawRows.map(row => {
|
|
65
|
+
row = cloneDeep(row)
|
|
41
66
|
if (rename) {
|
|
42
|
-
|
|
43
|
-
delete
|
|
67
|
+
row[rename.updated] = row[rename.old]
|
|
68
|
+
delete row[rename.old]
|
|
44
69
|
} else if (deletedColumns.length !== 0) {
|
|
45
|
-
deletedColumns.forEach(colName => delete
|
|
70
|
+
deletedColumns.forEach(colName => delete row[colName])
|
|
46
71
|
}
|
|
47
|
-
return
|
|
72
|
+
return row
|
|
48
73
|
})
|
|
49
74
|
|
|
75
|
+
// cleanup any attachments from object storage for deleted attachment columns
|
|
76
|
+
await cleanupAttachments(appId, updatedTable, { oldTable, rows: rawRows })
|
|
50
77
|
// Update views
|
|
51
78
|
await exports.checkForViewUpdates(db, updatedTable, rename, deletedColumns)
|
|
52
79
|
delete updatedTable._rename
|
|
@@ -115,7 +142,11 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
|
|
|
115
142
|
finalData.push(row)
|
|
116
143
|
}
|
|
117
144
|
|
|
145
|
+
await usageQuota.update(usageQuota.Properties.ROW, finalData.length, {
|
|
146
|
+
dryRun: true,
|
|
147
|
+
})
|
|
118
148
|
await db.bulkDocs(finalData)
|
|
149
|
+
await usageQuota.update(usageQuota.Properties.ROW, finalData.length)
|
|
119
150
|
let response = await db.put(table)
|
|
120
151
|
table._rev = response._rev
|
|
121
152
|
return table
|
|
@@ -203,6 +234,7 @@ class TableSaveFunctions {
|
|
|
203
234
|
// when confirmed valid
|
|
204
235
|
async mid(table) {
|
|
205
236
|
let response = await exports.checkForColumnUpdates(
|
|
237
|
+
this.appId,
|
|
206
238
|
this.db,
|
|
207
239
|
this.oldTable,
|
|
208
240
|
table
|
|
@@ -228,6 +260,20 @@ class TableSaveFunctions {
|
|
|
228
260
|
}
|
|
229
261
|
}
|
|
230
262
|
|
|
263
|
+
exports.getAllInternalTables = async appId => {
|
|
264
|
+
const db = new CouchDB(appId)
|
|
265
|
+
const internalTables = await db.allDocs(
|
|
266
|
+
getTableParams(null, {
|
|
267
|
+
include_docs: true,
|
|
268
|
+
})
|
|
269
|
+
)
|
|
270
|
+
return internalTables.rows.map(tableDoc => ({
|
|
271
|
+
...tableDoc.doc,
|
|
272
|
+
type: "internal",
|
|
273
|
+
sourceId: BudibaseInternalDB._id,
|
|
274
|
+
}))
|
|
275
|
+
}
|
|
276
|
+
|
|
231
277
|
exports.getAllExternalTables = async (appId, datasourceId) => {
|
|
232
278
|
const db = new CouchDB(appId)
|
|
233
279
|
const datasource = await db.get(datasourceId)
|
|
@@ -246,7 +292,9 @@ exports.getTable = async (appId, tableId) => {
|
|
|
246
292
|
const db = new CouchDB(appId)
|
|
247
293
|
if (isExternalTable(tableId)) {
|
|
248
294
|
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
249
|
-
|
|
295
|
+
const datasource = await db.get(datasourceId)
|
|
296
|
+
const table = await exports.getExternalTable(appId, datasourceId, tableName)
|
|
297
|
+
return { ...table, sql: isSQL(datasource) }
|
|
250
298
|
} else {
|
|
251
299
|
return db.get(tableId)
|
|
252
300
|
}
|
|
@@ -167,6 +167,8 @@ exports.updateSelfMetadata = async function (ctx) {
|
|
|
167
167
|
ctx.request.body._id = ctx.user._id
|
|
168
168
|
// make sure no stale rev
|
|
169
169
|
delete ctx.request.body._rev
|
|
170
|
+
// make sure no csrf token
|
|
171
|
+
delete ctx.request.body.csrfToken
|
|
170
172
|
await exports.updateMetadata(ctx)
|
|
171
173
|
}
|
|
172
174
|
|
package/src/api/routes/index.js
CHANGED
|
@@ -20,11 +20,11 @@ const integrationRoutes = require("./integration")
|
|
|
20
20
|
const permissionRoutes = require("./permission")
|
|
21
21
|
const datasourceRoutes = require("./datasource")
|
|
22
22
|
const queryRoutes = require("./query")
|
|
23
|
-
const hostingRoutes = require("./hosting")
|
|
24
23
|
const backupRoutes = require("./backup")
|
|
25
24
|
const metadataRoutes = require("./metadata")
|
|
26
25
|
const devRoutes = require("./dev")
|
|
27
26
|
const cloudRoutes = require("./cloud")
|
|
27
|
+
const migrationRoutes = require("./migrations")
|
|
28
28
|
|
|
29
29
|
exports.mainRoutes = [
|
|
30
30
|
authRoutes,
|
|
@@ -46,7 +46,6 @@ exports.mainRoutes = [
|
|
|
46
46
|
permissionRoutes,
|
|
47
47
|
datasourceRoutes,
|
|
48
48
|
queryRoutes,
|
|
49
|
-
hostingRoutes,
|
|
50
49
|
backupRoutes,
|
|
51
50
|
metadataRoutes,
|
|
52
51
|
devRoutes,
|
|
@@ -55,6 +54,7 @@ exports.mainRoutes = [
|
|
|
55
54
|
// this could be breaking as koa may recognise other routes as this
|
|
56
55
|
tableRoutes,
|
|
57
56
|
rowRoutes,
|
|
57
|
+
migrationRoutes,
|
|
58
58
|
]
|
|
59
59
|
|
|
60
60
|
exports.staticRoutes = staticRoutes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const Router = require("@koa/router")
|
|
2
|
+
const migrationsController = require("../controllers/migrations")
|
|
3
|
+
const router = Router()
|
|
4
|
+
const { internalApi } = require("@budibase/backend-core/auth")
|
|
5
|
+
|
|
6
|
+
router
|
|
7
|
+
.post("/api/migrations/run", internalApi, migrationsController.migrate)
|
|
8
|
+
.get(
|
|
9
|
+
"/api/migrations/definitions",
|
|
10
|
+
internalApi,
|
|
11
|
+
migrationsController.fetchDefinitions
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
module.exports = router
|
package/src/api/routes/static.js
CHANGED
|
@@ -46,5 +46,10 @@ router
|
|
|
46
46
|
)
|
|
47
47
|
// TODO: this likely needs to be secured in some way
|
|
48
48
|
.get("/:appId/:path*", controller.serveApp)
|
|
49
|
+
.post(
|
|
50
|
+
"/api/attachments/:datasourceId/url",
|
|
51
|
+
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
|
52
|
+
controller.getSignedUploadURL
|
|
53
|
+
)
|
|
49
54
|
|
|
50
55
|
module.exports = router
|
|
@@ -53,8 +53,8 @@ describe("/applications", () => {
|
|
|
53
53
|
|
|
54
54
|
describe("fetch", () => {
|
|
55
55
|
it("lists all applications", async () => {
|
|
56
|
-
await config.createApp(
|
|
57
|
-
await config.createApp(
|
|
56
|
+
await config.createApp("app1")
|
|
57
|
+
await config.createApp("app2")
|
|
58
58
|
|
|
59
59
|
const res = await request
|
|
60
60
|
.get(`/api/applications?status=${AppStatus.DEV}`)
|
|
@@ -13,10 +13,9 @@ describe("/authenticate", () => {
|
|
|
13
13
|
|
|
14
14
|
describe("fetch self", () => {
|
|
15
15
|
it("should be able to fetch self", async () => {
|
|
16
|
-
const headers = await config.login()
|
|
17
16
|
const res = await request
|
|
18
17
|
.get(`/api/self`)
|
|
19
|
-
.set(
|
|
18
|
+
.set(config.defaultHeaders())
|
|
20
19
|
.expect("Content-Type", /json/)
|
|
21
20
|
.expect(200)
|
|
22
21
|
expect(res.body._id).toEqual(generateUserMetadataID("us_uuid1"))
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
jest.mock("node-fetch")
|
|
2
|
+
jest.mock("aws-sdk", () => ({
|
|
3
|
+
config: {
|
|
4
|
+
update: jest.fn(),
|
|
5
|
+
},
|
|
6
|
+
DynamoDB: {
|
|
7
|
+
DocumentClient: jest.fn(),
|
|
8
|
+
},
|
|
9
|
+
S3: jest.fn(() => ({
|
|
10
|
+
getSignedUrl: jest.fn(() => {
|
|
11
|
+
return "my-url"
|
|
12
|
+
}),
|
|
13
|
+
})),
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
const setup = require("./utilities")
|
|
17
|
+
|
|
18
|
+
describe("/attachments", () => {
|
|
19
|
+
let request = setup.getRequest()
|
|
20
|
+
let config = setup.getConfig()
|
|
21
|
+
let app
|
|
22
|
+
|
|
23
|
+
afterAll(setup.afterAll)
|
|
24
|
+
|
|
25
|
+
beforeEach(async () => {
|
|
26
|
+
app = await config.init()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe("generateSignedUrls", () => {
|
|
30
|
+
let datasource
|
|
31
|
+
|
|
32
|
+
beforeEach(async () => {
|
|
33
|
+
datasource = await config.createDatasource({
|
|
34
|
+
datasource: {
|
|
35
|
+
type: "datasource",
|
|
36
|
+
name: "Test",
|
|
37
|
+
source: "S3",
|
|
38
|
+
config: {},
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it("should be able to generate a signed upload URL", async () => {
|
|
44
|
+
const bucket = "foo"
|
|
45
|
+
const key = "bar"
|
|
46
|
+
const res = await request
|
|
47
|
+
.post(`/api/attachments/${datasource._id}/url`)
|
|
48
|
+
.send({ bucket, key })
|
|
49
|
+
.set(config.defaultHeaders())
|
|
50
|
+
.expect("Content-Type", /json/)
|
|
51
|
+
.expect(200)
|
|
52
|
+
expect(res.body.signedUrl).toEqual("my-url")
|
|
53
|
+
expect(res.body.publicUrl).toEqual(
|
|
54
|
+
`https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("should handle an invalid datasource ID", async () => {
|
|
59
|
+
const res = await request
|
|
60
|
+
.post(`/api/attachments/foo/url`)
|
|
61
|
+
.send({
|
|
62
|
+
bucket: "foo",
|
|
63
|
+
key: "bar",
|
|
64
|
+
})
|
|
65
|
+
.set(config.defaultHeaders())
|
|
66
|
+
.expect("Content-Type", /json/)
|
|
67
|
+
.expect(400)
|
|
68
|
+
expect(res.body.message).toEqual(
|
|
69
|
+
"The specified datasource could not be found"
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it("should require a bucket parameter", async () => {
|
|
74
|
+
const res = await request
|
|
75
|
+
.post(`/api/attachments/${datasource._id}/url`)
|
|
76
|
+
.send({
|
|
77
|
+
bucket: undefined,
|
|
78
|
+
key: "bar",
|
|
79
|
+
})
|
|
80
|
+
.set(config.defaultHeaders())
|
|
81
|
+
.expect("Content-Type", /json/)
|
|
82
|
+
.expect(400)
|
|
83
|
+
expect(res.body.message).toEqual("bucket and key values are required")
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it("should require a key parameter", async () => {
|
|
87
|
+
const res = await request
|
|
88
|
+
.post(`/api/attachments/${datasource._id}/url`)
|
|
89
|
+
.send({
|
|
90
|
+
bucket: "foo",
|
|
91
|
+
})
|
|
92
|
+
.set(config.defaultHeaders())
|
|
93
|
+
.expect("Content-Type", /json/)
|
|
94
|
+
.expect(400)
|
|
95
|
+
expect(res.body.message).toEqual("bucket and key values are required")
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
})
|
package/src/app.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// need to load environment first
|
|
2
2
|
import { ExtendableContext } from "koa"
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import * as env from "./environment"
|
|
5
5
|
const CouchDB = require("./db")
|
|
6
6
|
require("@budibase/backend-core").init(CouchDB)
|
|
7
7
|
const Koa = require("koa")
|
|
@@ -16,6 +16,7 @@ const Sentry = require("@sentry/node")
|
|
|
16
16
|
const fileSystem = require("./utilities/fileSystem")
|
|
17
17
|
const bullboard = require("./automations/bullboard")
|
|
18
18
|
const redis = require("./utilities/redis")
|
|
19
|
+
import * as migrations from "./migrations"
|
|
19
20
|
|
|
20
21
|
const app = new Koa()
|
|
21
22
|
|
|
@@ -84,13 +85,25 @@ module.exports = server.listen(env.PORT || 0, async () => {
|
|
|
84
85
|
await automations.init()
|
|
85
86
|
})
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
console.error(err)
|
|
88
|
+
const shutdown = () => {
|
|
89
89
|
server.close()
|
|
90
90
|
server.destroy()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
process.on("uncaughtException", err => {
|
|
94
|
+
console.error(err)
|
|
95
|
+
shutdown()
|
|
91
96
|
})
|
|
92
97
|
|
|
93
98
|
process.on("SIGTERM", () => {
|
|
94
|
-
|
|
95
|
-
server.destroy()
|
|
99
|
+
shutdown()
|
|
96
100
|
})
|
|
101
|
+
|
|
102
|
+
// run migrations on startup if not done via http
|
|
103
|
+
// not recommended in a clustered environment
|
|
104
|
+
if (!env.HTTP_MIGRATIONS) {
|
|
105
|
+
migrations.migrate().catch(err => {
|
|
106
|
+
console.error("Error performing migrations. Exiting.\n", err)
|
|
107
|
+
shutdown()
|
|
108
|
+
})
|
|
109
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const rowController = require("../../api/controllers/row")
|
|
2
2
|
const automationUtils = require("../automationUtils")
|
|
3
|
-
const env = require("../../environment")
|
|
4
3
|
const usage = require("../../utilities/usageQuota")
|
|
5
4
|
const { buildCtx } = require("./utils")
|
|
6
5
|
|
|
@@ -83,10 +82,9 @@ exports.run = async function ({ inputs, appId, emitter }) {
|
|
|
83
82
|
inputs.row.tableId,
|
|
84
83
|
inputs.row
|
|
85
84
|
)
|
|
86
|
-
|
|
87
|
-
await usage.update(usage.Properties.ROW, 1)
|
|
88
|
-
}
|
|
85
|
+
await usage.update(usage.Properties.ROW, 1, { dryRun: true })
|
|
89
86
|
await rowController.save(ctx)
|
|
87
|
+
await usage.update(usage.Properties.ROW, 1)
|
|
90
88
|
return {
|
|
91
89
|
row: inputs.row,
|
|
92
90
|
response: ctx.body,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const rowController = require("../../api/controllers/row")
|
|
2
|
-
const env = require("../../environment")
|
|
3
2
|
const usage = require("../../utilities/usageQuota")
|
|
4
3
|
const { buildCtx } = require("./utils")
|
|
5
4
|
const automationUtils = require("../automationUtils")
|
|
@@ -74,9 +73,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
|
|
|
74
73
|
})
|
|
75
74
|
|
|
76
75
|
try {
|
|
77
|
-
|
|
78
|
-
await usage.update(usage.Properties.ROW, -1)
|
|
79
|
-
}
|
|
76
|
+
await usage.update(usage.Properties.ROW, -1)
|
|
80
77
|
await rowController.destroy(ctx)
|
|
81
78
|
return {
|
|
82
79
|
response: ctx.body,
|
package/src/constants/index.js
CHANGED
|
@@ -61,6 +61,11 @@ exports.RelationshipTypes = {
|
|
|
61
61
|
MANY_TO_MANY: "many-to-many",
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
exports.FormulaTypes = {
|
|
65
|
+
STATIC: "static",
|
|
66
|
+
DYNAMIC: "dynamic",
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
exports.AuthTypes = {
|
|
65
70
|
APP: "app",
|
|
66
71
|
BUILDER: "builder",
|
|
@@ -78,6 +83,10 @@ exports.DataSourceOperation = {
|
|
|
78
83
|
DELETE_TABLE: "DELETE_TABLE",
|
|
79
84
|
}
|
|
80
85
|
|
|
86
|
+
exports.DatasourceAuthTypes = {
|
|
87
|
+
GOOGLE: "google",
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
exports.SortDirection = {
|
|
82
91
|
ASCENDING: "ASCENDING",
|
|
83
92
|
DESCENDING: "DESCENDING",
|
|
@@ -72,7 +72,7 @@ async function getLinksForRows(appId, rows) {
|
|
|
72
72
|
)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
async function getFullLinkedDocs(
|
|
75
|
+
async function getFullLinkedDocs(appId, links) {
|
|
76
76
|
// create DBs
|
|
77
77
|
const db = new CouchDB(appId)
|
|
78
78
|
const linkedRowIds = links.map(link => link.id)
|
|
@@ -146,13 +146,12 @@ exports.updateLinks = async function (args) {
|
|
|
146
146
|
/**
|
|
147
147
|
* Given a table and a list of rows this will retrieve all of the attached docs and enrich them into the row.
|
|
148
148
|
* This is required for formula fields, this may only be utilised internally (for now).
|
|
149
|
-
* @param {
|
|
149
|
+
* @param {string} appId The ID of the app which this request is in the context of.
|
|
150
150
|
* @param {object} table The table from which the rows originated.
|
|
151
151
|
* @param {array<object>} rows The rows which are to be enriched.
|
|
152
152
|
* @return {Promise<*>} returns the rows with all of the enriched relationships on it.
|
|
153
153
|
*/
|
|
154
|
-
exports.attachFullLinkedDocs = async (
|
|
155
|
-
const appId = ctx.appId
|
|
154
|
+
exports.attachFullLinkedDocs = async (appId, table, rows) => {
|
|
156
155
|
const linkedTableIds = getLinkedTableIDs(table)
|
|
157
156
|
if (linkedTableIds.length === 0) {
|
|
158
157
|
return rows
|
|
@@ -166,7 +165,7 @@ exports.attachFullLinkedDocs = async (ctx, table, rows) => {
|
|
|
166
165
|
// clear any existing links that could be dupe'd
|
|
167
166
|
rows = clearRelationshipFields(table, rows)
|
|
168
167
|
// now get the docs and combine into the rows
|
|
169
|
-
let linked = await getFullLinkedDocs(
|
|
168
|
+
let linked = await getFullLinkedDocs(appId, links)
|
|
170
169
|
const linkedTables = []
|
|
171
170
|
for (let row of rows) {
|
|
172
171
|
for (let link of links.filter(link => link.thisId === row._id)) {
|
|
@@ -17,6 +17,8 @@ export interface FieldSchema {
|
|
|
17
17
|
autocolumn?: boolean
|
|
18
18
|
throughFrom?: string
|
|
19
19
|
throughTo?: string
|
|
20
|
+
formula?: string
|
|
21
|
+
formulaType?: string
|
|
20
22
|
main?: boolean
|
|
21
23
|
meta?: {
|
|
22
24
|
toTable: string
|
|
@@ -46,6 +48,7 @@ export interface Table extends Base {
|
|
|
46
48
|
schema: TableSchema
|
|
47
49
|
primaryDisplay?: string
|
|
48
50
|
sourceId?: string
|
|
51
|
+
relatedFormula?: string[]
|
|
49
52
|
constrained?: string[]
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -47,6 +47,7 @@ export enum SourceNames {
|
|
|
47
47
|
ARANGODB = "ARANGODB",
|
|
48
48
|
REST = "REST",
|
|
49
49
|
ORACLE = "ORACLE",
|
|
50
|
+
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export enum IncludeRelationships {
|
|
@@ -86,6 +87,8 @@ export interface ExtraQueryConfig {
|
|
|
86
87
|
export interface Integration {
|
|
87
88
|
docs: string
|
|
88
89
|
plus?: boolean
|
|
90
|
+
auth?: { type: string }
|
|
91
|
+
relationships?: boolean
|
|
89
92
|
description: string
|
|
90
93
|
friendlyName: string
|
|
91
94
|
datasource: {}
|
package/src/environment.js
CHANGED
|
@@ -38,10 +38,12 @@ module.exports = {
|
|
|
38
38
|
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
|
39
39
|
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
|
40
40
|
USE_QUOTAS: process.env.USE_QUOTAS,
|
|
41
|
+
EXCLUDE_QUOTAS_TENANTS: process.env.EXCLUDE_QUOTAS_TENANTS,
|
|
41
42
|
REDIS_URL: process.env.REDIS_URL,
|
|
42
43
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
|
43
44
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
|
44
45
|
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
|
46
|
+
HTTP_MIGRATIONS: process.env.HTTP_MIGRATIONS,
|
|
45
47
|
// environment
|
|
46
48
|
NODE_ENV: process.env.NODE_ENV,
|
|
47
49
|
JEST_WORKER_ID: process.env.JEST_WORKER_ID,
|
|
@@ -72,16 +72,22 @@ class InternalBuilder {
|
|
|
72
72
|
|
|
73
73
|
// right now we only do filters on the specific table being queried
|
|
74
74
|
addFilters(
|
|
75
|
-
tableName: string,
|
|
76
75
|
query: KnexQuery,
|
|
77
|
-
filters: SearchFilters | undefined
|
|
76
|
+
filters: SearchFilters | undefined,
|
|
77
|
+
opts: { relationship?: boolean; tableName?: string }
|
|
78
78
|
): KnexQuery {
|
|
79
79
|
function iterate(
|
|
80
80
|
structure: { [key: string]: any },
|
|
81
81
|
fn: (key: string, value: any) => void
|
|
82
82
|
) {
|
|
83
83
|
for (let [key, value] of Object.entries(structure)) {
|
|
84
|
-
|
|
84
|
+
const isRelationshipField = key.includes(".")
|
|
85
|
+
if (!opts.relationship && !isRelationshipField) {
|
|
86
|
+
fn(`${opts.tableName}.${key}`, value)
|
|
87
|
+
}
|
|
88
|
+
if (opts.relationship && isRelationshipField) {
|
|
89
|
+
fn(key, value)
|
|
90
|
+
}
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
if (!filters) {
|
|
@@ -272,7 +278,7 @@ class InternalBuilder {
|
|
|
272
278
|
if (foundOffset) {
|
|
273
279
|
query = query.offset(foundOffset)
|
|
274
280
|
}
|
|
275
|
-
query = this.addFilters(
|
|
281
|
+
query = this.addFilters(query, filters, { tableName })
|
|
276
282
|
// add sorting to pre-query
|
|
277
283
|
query = this.addSorting(query, json)
|
|
278
284
|
// @ts-ignore
|
|
@@ -285,20 +291,21 @@ class InternalBuilder {
|
|
|
285
291
|
preQuery = this.addSorting(preQuery, json)
|
|
286
292
|
}
|
|
287
293
|
// handle joins
|
|
288
|
-
|
|
294
|
+
query = this.addRelationships(
|
|
289
295
|
knex,
|
|
290
296
|
preQuery,
|
|
291
297
|
selectStatement,
|
|
292
298
|
tableName,
|
|
293
299
|
relationships
|
|
294
300
|
)
|
|
301
|
+
return this.addFilters(query, filters, { relationship: true })
|
|
295
302
|
}
|
|
296
303
|
|
|
297
304
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
298
305
|
const { endpoint, body, filters } = json
|
|
299
306
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
300
307
|
const parsedBody = parseBody(body)
|
|
301
|
-
query = this.addFilters(endpoint.entityId
|
|
308
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
302
309
|
// mysql can't use returning
|
|
303
310
|
if (opts.disableReturning) {
|
|
304
311
|
return query.update(parsedBody)
|
|
@@ -310,7 +317,7 @@ class InternalBuilder {
|
|
|
310
317
|
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
311
318
|
const { endpoint, filters } = json
|
|
312
319
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
313
|
-
query = this.addFilters(endpoint.entityId
|
|
320
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
314
321
|
// mysql can't use returning
|
|
315
322
|
if (opts.disableReturning) {
|
|
316
323
|
return query.delete()
|