@budibase/server 1.0.46-alpha.7 → 1.0.48
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.dd9e386f.css → index.39e01193.css} +1 -1
- package/builder/assets/{index.af9e71d8.js → index.e083dcaf.js} +221 -223
- package/builder/assets/{vendor.3bd2f661.js → vendor.f9faf6ab.js} +12 -12
- package/builder/index.html +3 -3
- package/coverage/clover.xml +1637 -1793
- package/coverage/coverage-final.json +94 -98
- 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 +126 -210
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- 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 +36 -72
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/{migrations/usageQuotas/syncRows.js.html → api/controllers/hosting.js.html} +44 -41
- package/coverage/lcov-report/api/controllers/index.html +42 -27
- 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/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 +15 -15
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +44 -44
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +8 -8
- package/coverage/lcov-report/api/controllers/row/utils.js.html +57 -39
- 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/external.js.html +12 -12
- package/coverage/lcov-report/api/controllers/table/index.html +32 -32
- package/coverage/lcov-report/api/controllers/table/index.js.html +39 -57
- package/coverage/lcov-report/api/controllers/table/internal.js.html +34 -40
- package/coverage/lcov-report/api/controllers/table/utils.js.html +122 -83
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +20 -20
- 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 +10 -10
- 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/{migrations/usageQuotas/syncApps.js.html → api/routes/hosting.js.html} +27 -42
- package/coverage/lcov-report/api/routes/index.html +22 -7
- package/coverage/lcov-report/api/routes/index.js.html +10 -4
- 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 +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 +2 -17
- 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 +19 -13
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +20 -11
- 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 +11 -11
- package/coverage/lcov-report/constants/index.js.html +37 -40
- 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 +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +31 -31
- 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 +85 -85
- 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 +86 -116
- 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 +11 -11
- 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 +20 -20
- 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 +41 -275
- 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 +8 -23
- 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 +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +53 -53
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
- 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/users.js.html +5 -5
- package/coverage/lcov-report/utilities/workerRequests.js.html +108 -39
- package/coverage/lcov.info +2332 -2599
- package/dist/api/controllers/application.js +20 -49
- package/dist/api/controllers/datasource.js +0 -11
- package/dist/api/controllers/hosting.js +30 -0
- package/dist/api/controllers/row/ExternalRequest.js +2 -1
- package/dist/api/controllers/row/utils.js +8 -6
- package/dist/api/controllers/static/index.js +10 -59
- package/dist/api/controllers/table/index.js +4 -10
- package/dist/api/controllers/table/internal.js +0 -2
- package/dist/api/controllers/table/utils.js +17 -11
- package/dist/api/routes/hosting.js +11 -0
- package/dist/api/routes/index.js +2 -0
- package/dist/api/routes/static.js +1 -2
- package/dist/automations/steps/createRow.js +4 -2
- package/dist/automations/steps/deleteRow.js +4 -1
- package/dist/constants/index.js +5 -8
- package/dist/definitions/datasource.js +0 -1
- package/dist/environment.js +0 -1
- package/dist/integrations/base/sql.js +6 -13
- package/dist/integrations/index.js +0 -3
- package/dist/integrations/utils.js +9 -56
- package/dist/middleware/usageQuota.js +13 -82
- package/dist/package.json +5 -8
- package/dist/tests/utilities/TestConfiguration.js +1 -3
- package/dist/threads/query.js +0 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/{usageQuota/index.js → usageQuota.js} +31 -44
- package/dist/utilities/workerRequests.js +20 -0
- package/nodemon.json +1 -1
- package/package.json +6 -9
- package/src/api/controllers/application.js +24 -52
- package/src/api/controllers/datasource.js +0 -12
- package/src/api/controllers/hosting.js +22 -0
- package/src/api/controllers/row/ExternalRequest.ts +1 -1
- package/src/api/controllers/row/utils.js +12 -6
- package/src/api/controllers/static/index.js +10 -63
- package/src/api/controllers/table/index.js +9 -15
- package/src/api/controllers/table/internal.js +0 -2
- package/src/api/controllers/table/utils.js +24 -11
- package/src/api/routes/hosting.js +13 -0
- package/src/api/routes/index.js +2 -0
- package/src/api/routes/static.js +0 -5
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/hosting.spec.js +36 -0
- package/src/automations/steps/createRow.js +4 -2
- package/src/automations/steps/deleteRow.js +4 -1
- package/src/constants/index.js +8 -9
- package/src/definitions/datasource.ts +0 -3
- package/src/environment.js +0 -1
- package/src/integrations/base/sql.ts +7 -14
- package/src/integrations/index.ts +0 -3
- package/src/integrations/tests/sql.spec.js +0 -16
- package/src/integrations/utils.ts +11 -70
- package/src/middleware/tests/usageQuota.spec.js +24 -18
- package/src/middleware/usageQuota.js +15 -93
- package/src/tests/utilities/TestConfiguration.js +1 -3
- package/src/threads/query.js +0 -5
- package/src/utilities/usageQuota.js +73 -0
- package/src/utilities/workerRequests.js +23 -0
- package/coverage/lcov-report/migrations/usageQuotas/index.html +0 -141
- package/coverage/lcov-report/migrations/usageQuotas/index.js.html +0 -152
- package/coverage/lcov-report/utilities/usageQuota/index.html +0 -141
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +0 -356
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +0 -302
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +0 -134
- package/dist/integrations/googlesheets.js +0 -340
- package/dist/migrations/usageQuotas/index.js +0 -24
- package/dist/migrations/usageQuotas/syncApps.js +0 -26
- package/dist/migrations/usageQuotas/syncRows.js +0 -29
- package/dist/utilities/usageQuota/rows.js +0 -77
- package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
- package/src/api/routes/tests/static.spec.js +0 -98
- package/src/integrations/googlesheets.ts +0 -353
- package/src/migrations/tests/usageQuotas/index.spec.js +0 -27
- package/src/migrations/tests/usageQuotas/syncApps.spec.js +0 -37
- package/src/migrations/tests/usageQuotas/syncRows.spec.js +0 -43
- package/src/migrations/usageQuotas/index.js +0 -24
- package/src/migrations/usageQuotas/syncApps.js +0 -18
- package/src/migrations/usageQuotas/syncRows.js +0 -21
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +0 -72
- package/src/utilities/usageQuota/index.js +0 -92
- package/src/utilities/usageQuota/rows.js +0 -74
- package/src/utilities/usageQuota/usageQuoteReset.js +0 -18
|
@@ -8,15 +8,17 @@ const {
|
|
|
8
8
|
const { isEqual } = require("lodash/fp")
|
|
9
9
|
const { AutoFieldSubTypes, FieldTypes } = require("../../../constants")
|
|
10
10
|
const { inputProcessing } = require("../../../utilities/rowProcessor")
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
USERS_TABLE_SCHEMA,
|
|
13
|
+
SwitchableTypes,
|
|
14
|
+
CanSwitchTypes,
|
|
15
|
+
} = require("../../../constants")
|
|
12
16
|
const {
|
|
13
17
|
isExternalTable,
|
|
14
18
|
breakExternalTableId,
|
|
15
|
-
isSQL,
|
|
16
19
|
} = require("../../../integrations/utils")
|
|
17
20
|
const { getViews, saveView } = require("../view/utils")
|
|
18
21
|
const viewTemplate = require("../view/viewBuilder")
|
|
19
|
-
const usageQuota = require("../../../utilities/usageQuota")
|
|
20
22
|
|
|
21
23
|
exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
|
|
22
24
|
let updatedRows = []
|
|
@@ -113,11 +115,7 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
|
|
|
113
115
|
finalData.push(row)
|
|
114
116
|
}
|
|
115
117
|
|
|
116
|
-
await usageQuota.update(usageQuota.Properties.ROW, finalData.length, {
|
|
117
|
-
dryRun: true,
|
|
118
|
-
})
|
|
119
118
|
await db.bulkDocs(finalData)
|
|
120
|
-
await usageQuota.update(usageQuota.Properties.ROW, finalData.length)
|
|
121
119
|
let response = await db.put(table)
|
|
122
120
|
table._rev = response._rev
|
|
123
121
|
return table
|
|
@@ -248,9 +246,7 @@ exports.getTable = async (appId, tableId) => {
|
|
|
248
246
|
const db = new CouchDB(appId)
|
|
249
247
|
if (isExternalTable(tableId)) {
|
|
250
248
|
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
251
|
-
|
|
252
|
-
const table = await exports.getExternalTable(appId, datasourceId, tableName)
|
|
253
|
-
return { ...table, sql: isSQL(datasource) }
|
|
249
|
+
return exports.getExternalTable(appId, datasourceId, tableName)
|
|
254
250
|
} else {
|
|
255
251
|
return db.get(tableId)
|
|
256
252
|
}
|
|
@@ -348,6 +344,23 @@ exports.foreignKeyStructure = (keyName, meta = null) => {
|
|
|
348
344
|
return structure
|
|
349
345
|
}
|
|
350
346
|
|
|
347
|
+
exports.areSwitchableTypes = (type1, type2) => {
|
|
348
|
+
if (
|
|
349
|
+
SwitchableTypes.indexOf(type1) === -1 &&
|
|
350
|
+
SwitchableTypes.indexOf(type2) === -1
|
|
351
|
+
) {
|
|
352
|
+
return false
|
|
353
|
+
}
|
|
354
|
+
for (let option of CanSwitchTypes) {
|
|
355
|
+
const index1 = option.indexOf(type1),
|
|
356
|
+
index2 = option.indexOf(type2)
|
|
357
|
+
if (index1 !== -1 && index2 !== -1 && index1 !== index2) {
|
|
358
|
+
return true
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false
|
|
362
|
+
}
|
|
363
|
+
|
|
351
364
|
exports.hasTypeChanged = (table, oldTable) => {
|
|
352
365
|
if (!oldTable) {
|
|
353
366
|
return false
|
|
@@ -358,7 +371,7 @@ exports.hasTypeChanged = (table, oldTable) => {
|
|
|
358
371
|
continue
|
|
359
372
|
}
|
|
360
373
|
const newType = table.schema[key].type
|
|
361
|
-
if (oldType !== newType &&
|
|
374
|
+
if (oldType !== newType && !exports.areSwitchableTypes(oldType, newType)) {
|
|
362
375
|
return true
|
|
363
376
|
}
|
|
364
377
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const Router = require("@koa/router")
|
|
2
|
+
const controller = require("../controllers/hosting")
|
|
3
|
+
const authorized = require("../../middleware/authorized")
|
|
4
|
+
const { BUILDER } = require("@budibase/backend-core/permissions")
|
|
5
|
+
|
|
6
|
+
const router = Router()
|
|
7
|
+
|
|
8
|
+
router
|
|
9
|
+
.get("/api/hosting/urls", authorized(BUILDER), controller.fetchUrls)
|
|
10
|
+
// this isn't risky, doesn't return anything about apps other than names and URLs
|
|
11
|
+
.get("/api/hosting/apps", controller.getDeployedApps)
|
|
12
|
+
|
|
13
|
+
module.exports = router
|
package/src/api/routes/index.js
CHANGED
|
@@ -20,6 +20,7 @@ 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")
|
|
23
24
|
const backupRoutes = require("./backup")
|
|
24
25
|
const metadataRoutes = require("./metadata")
|
|
25
26
|
const devRoutes = require("./dev")
|
|
@@ -45,6 +46,7 @@ exports.mainRoutes = [
|
|
|
45
46
|
permissionRoutes,
|
|
46
47
|
datasourceRoutes,
|
|
47
48
|
queryRoutes,
|
|
49
|
+
hostingRoutes,
|
|
48
50
|
backupRoutes,
|
|
49
51
|
metadataRoutes,
|
|
50
52
|
devRoutes,
|
package/src/api/routes/static.js
CHANGED
|
@@ -46,10 +46,5 @@ 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
|
-
)
|
|
54
49
|
|
|
55
50
|
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("app1")
|
|
57
|
-
await config.createApp("app2")
|
|
56
|
+
await config.createApp(request, "app1")
|
|
57
|
+
await config.createApp(request, "app2")
|
|
58
58
|
|
|
59
59
|
const res = await request
|
|
60
60
|
.get(`/api/applications?status=${AppStatus.DEV}`)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// mock out node fetch for this
|
|
2
|
+
jest.mock("node-fetch")
|
|
3
|
+
|
|
4
|
+
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
|
5
|
+
const setup = require("./utilities")
|
|
6
|
+
|
|
7
|
+
describe("/hosting", () => {
|
|
8
|
+
let request = setup.getRequest()
|
|
9
|
+
let config = setup.getConfig()
|
|
10
|
+
let app
|
|
11
|
+
|
|
12
|
+
afterAll(setup.afterAll)
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
app = await config.init()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe("fetchUrls", () => {
|
|
19
|
+
it("should be able to fetch current app URLs", async () => {
|
|
20
|
+
const res = await request
|
|
21
|
+
.get(`/api/hosting/urls`)
|
|
22
|
+
.set(config.defaultHeaders())
|
|
23
|
+
.expect("Content-Type", /json/)
|
|
24
|
+
.expect(200)
|
|
25
|
+
expect(res.body.app).toEqual(`http://localhost:10000/app`)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it("should apply authorization to endpoint", async () => {
|
|
29
|
+
await checkBuilderEndpoint({
|
|
30
|
+
config,
|
|
31
|
+
method: "GET",
|
|
32
|
+
url: `/api/hosting/urls`,
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const rowController = require("../../api/controllers/row")
|
|
2
2
|
const automationUtils = require("../automationUtils")
|
|
3
|
+
const env = require("../../environment")
|
|
3
4
|
const usage = require("../../utilities/usageQuota")
|
|
4
5
|
const { buildCtx } = require("./utils")
|
|
5
6
|
|
|
@@ -82,9 +83,10 @@ exports.run = async function ({ inputs, appId, emitter }) {
|
|
|
82
83
|
inputs.row.tableId,
|
|
83
84
|
inputs.row
|
|
84
85
|
)
|
|
85
|
-
|
|
86
|
+
if (env.USE_QUOTAS) {
|
|
87
|
+
await usage.update(usage.Properties.ROW, 1)
|
|
88
|
+
}
|
|
86
89
|
await rowController.save(ctx)
|
|
87
|
-
await usage.update(usage.Properties.ROW, 1)
|
|
88
90
|
return {
|
|
89
91
|
row: inputs.row,
|
|
90
92
|
response: ctx.body,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const rowController = require("../../api/controllers/row")
|
|
2
|
+
const env = require("../../environment")
|
|
2
3
|
const usage = require("../../utilities/usageQuota")
|
|
3
4
|
const { buildCtx } = require("./utils")
|
|
4
5
|
const automationUtils = require("../automationUtils")
|
|
@@ -73,7 +74,9 @@ exports.run = async function ({ inputs, appId, emitter }) {
|
|
|
73
74
|
})
|
|
74
75
|
|
|
75
76
|
try {
|
|
76
|
-
|
|
77
|
+
if (env.isProd()) {
|
|
78
|
+
await usage.update(usage.Properties.ROW, -1)
|
|
79
|
+
}
|
|
77
80
|
await rowController.destroy(ctx)
|
|
78
81
|
return {
|
|
79
82
|
response: ctx.body,
|
package/src/constants/index.js
CHANGED
|
@@ -45,13 +45,16 @@ exports.FieldTypes = {
|
|
|
45
45
|
INTERNAL: "internal",
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
exports.
|
|
49
|
-
exports.FieldTypes.
|
|
50
|
-
exports.FieldTypes.OPTIONS,
|
|
51
|
-
exports.FieldTypes.NUMBER,
|
|
52
|
-
exports.FieldTypes.BOOLEAN,
|
|
48
|
+
exports.CanSwitchTypes = [
|
|
49
|
+
[exports.FieldTypes.JSON, exports.FieldTypes.ARRAY],
|
|
50
|
+
[exports.FieldTypes.STRING, exports.FieldTypes.OPTIONS],
|
|
51
|
+
[exports.FieldTypes.BOOLEAN, exports.FieldTypes.NUMBER],
|
|
53
52
|
]
|
|
54
53
|
|
|
54
|
+
exports.SwitchableTypes = exports.CanSwitchTypes.reduce((prev, current) =>
|
|
55
|
+
prev ? prev.concat(current) : current
|
|
56
|
+
)
|
|
57
|
+
|
|
55
58
|
exports.RelationshipTypes = {
|
|
56
59
|
ONE_TO_MANY: "one-to-many",
|
|
57
60
|
MANY_TO_ONE: "many-to-one",
|
|
@@ -75,10 +78,6 @@ exports.DataSourceOperation = {
|
|
|
75
78
|
DELETE_TABLE: "DELETE_TABLE",
|
|
76
79
|
}
|
|
77
80
|
|
|
78
|
-
exports.DatasourceAuthTypes = {
|
|
79
|
-
GOOGLE: "google",
|
|
80
|
-
}
|
|
81
|
-
|
|
82
81
|
exports.SortDirection = {
|
|
83
82
|
ASCENDING: "ASCENDING",
|
|
84
83
|
DESCENDING: "DESCENDING",
|
|
@@ -47,7 +47,6 @@ export enum SourceNames {
|
|
|
47
47
|
ARANGODB = "ARANGODB",
|
|
48
48
|
REST = "REST",
|
|
49
49
|
ORACLE = "ORACLE",
|
|
50
|
-
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
export enum IncludeRelationships {
|
|
@@ -87,8 +86,6 @@ export interface ExtraQueryConfig {
|
|
|
87
86
|
export interface Integration {
|
|
88
87
|
docs: string
|
|
89
88
|
plus?: boolean
|
|
90
|
-
auth?: { type: string }
|
|
91
|
-
relationships?: boolean
|
|
92
89
|
description: string
|
|
93
90
|
friendlyName: string
|
|
94
91
|
datasource: {}
|
package/src/environment.js
CHANGED
|
@@ -38,7 +38,6 @@ 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,
|
|
42
41
|
REDIS_URL: process.env.REDIS_URL,
|
|
43
42
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
|
44
43
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
|
@@ -72,22 +72,16 @@ class InternalBuilder {
|
|
|
72
72
|
|
|
73
73
|
// right now we only do filters on the specific table being queried
|
|
74
74
|
addFilters(
|
|
75
|
+
tableName: string,
|
|
75
76
|
query: KnexQuery,
|
|
76
|
-
filters: SearchFilters | undefined
|
|
77
|
-
opts: { relationship?: boolean; tableName?: string }
|
|
77
|
+
filters: SearchFilters | undefined
|
|
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
|
-
|
|
85
|
-
if (!opts.relationship && !isRelationshipField) {
|
|
86
|
-
fn(`${opts.tableName}.${key}`, value)
|
|
87
|
-
}
|
|
88
|
-
if (opts.relationship && isRelationshipField) {
|
|
89
|
-
fn(key, value)
|
|
90
|
-
}
|
|
84
|
+
fn(`${tableName}.${key}`, value)
|
|
91
85
|
}
|
|
92
86
|
}
|
|
93
87
|
if (!filters) {
|
|
@@ -278,7 +272,7 @@ class InternalBuilder {
|
|
|
278
272
|
if (foundOffset) {
|
|
279
273
|
query = query.offset(foundOffset)
|
|
280
274
|
}
|
|
281
|
-
query = this.addFilters(query, filters
|
|
275
|
+
query = this.addFilters(tableName, query, filters)
|
|
282
276
|
// add sorting to pre-query
|
|
283
277
|
query = this.addSorting(query, json)
|
|
284
278
|
// @ts-ignore
|
|
@@ -291,21 +285,20 @@ class InternalBuilder {
|
|
|
291
285
|
preQuery = this.addSorting(preQuery, json)
|
|
292
286
|
}
|
|
293
287
|
// handle joins
|
|
294
|
-
|
|
288
|
+
return this.addRelationships(
|
|
295
289
|
knex,
|
|
296
290
|
preQuery,
|
|
297
291
|
selectStatement,
|
|
298
292
|
tableName,
|
|
299
293
|
relationships
|
|
300
294
|
)
|
|
301
|
-
return this.addFilters(query, filters, { relationship: true })
|
|
302
295
|
}
|
|
303
296
|
|
|
304
297
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
305
298
|
const { endpoint, body, filters } = json
|
|
306
299
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
307
300
|
const parsedBody = parseBody(body)
|
|
308
|
-
query = this.addFilters(query, filters
|
|
301
|
+
query = this.addFilters(endpoint.entityId, query, filters)
|
|
309
302
|
// mysql can't use returning
|
|
310
303
|
if (opts.disableReturning) {
|
|
311
304
|
return query.update(parsedBody)
|
|
@@ -317,7 +310,7 @@ class InternalBuilder {
|
|
|
317
310
|
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
318
311
|
const { endpoint, filters } = json
|
|
319
312
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
320
|
-
query = this.addFilters(query, filters
|
|
313
|
+
query = this.addFilters(endpoint.entityId, query, filters)
|
|
321
314
|
// mysql can't use returning
|
|
322
315
|
if (opts.disableReturning) {
|
|
323
316
|
return query.delete()
|
|
@@ -9,7 +9,6 @@ const airtable = require("./airtable")
|
|
|
9
9
|
const mysql = require("./mysql")
|
|
10
10
|
const arangodb = require("./arangodb")
|
|
11
11
|
const rest = require("./rest")
|
|
12
|
-
const googlesheets = require("./googlesheets")
|
|
13
12
|
const { SourceNames } = require("../definitions/datasource")
|
|
14
13
|
|
|
15
14
|
const DEFINITIONS = {
|
|
@@ -24,7 +23,6 @@ const DEFINITIONS = {
|
|
|
24
23
|
[SourceNames.MYSQL]: mysql.schema,
|
|
25
24
|
[SourceNames.ARANGODB]: arangodb.schema,
|
|
26
25
|
[SourceNames.REST]: rest.schema,
|
|
27
|
-
[SourceNames.GOOGLE_SHEETS]: googlesheets.schema,
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
const INTEGRATIONS = {
|
|
@@ -39,7 +37,6 @@ const INTEGRATIONS = {
|
|
|
39
37
|
[SourceNames.MYSQL]: mysql.integration,
|
|
40
38
|
[SourceNames.ARANGODB]: arangodb.integration,
|
|
41
39
|
[SourceNames.REST]: rest.integration,
|
|
42
|
-
[SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
// optionally add oracle integration if the oracle binary can be installed
|
|
@@ -119,22 +119,6 @@ describe("SQL query builder", () => {
|
|
|
119
119
|
})
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
it("should allow filtering on a related field", () => {
|
|
123
|
-
const query = sql._query(generateReadJson({
|
|
124
|
-
filters: {
|
|
125
|
-
equal: {
|
|
126
|
-
age: 10,
|
|
127
|
-
"task.name": "task 1",
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
}))
|
|
131
|
-
// order of bindings changes because relationship filters occur outside inner query
|
|
132
|
-
expect(query).toEqual({
|
|
133
|
-
bindings: [10, limit, "task 1"],
|
|
134
|
-
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."age" = $1 limit $2) as "${TABLE_NAME}" where "task"."name" = $3`
|
|
135
|
-
})
|
|
136
|
-
})
|
|
137
|
-
|
|
138
122
|
it("should test an create statement", () => {
|
|
139
123
|
const query = sql._query(generateCreateJson(TABLE_NAME, {
|
|
140
124
|
name: "Michael",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SqlQuery } from "../definitions/datasource"
|
|
2
2
|
import { Datasource, Table } from "../definitions/common"
|
|
3
|
+
import { SourceNames } from "../definitions/datasource"
|
|
3
4
|
import { DocumentTypes, SEPARATOR } from "../db/utils"
|
|
4
5
|
import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants"
|
|
5
6
|
|
|
@@ -126,12 +127,7 @@ export function isSQL(datasource: Datasource): boolean {
|
|
|
126
127
|
if (!datasource || !datasource.source) {
|
|
127
128
|
return false
|
|
128
129
|
}
|
|
129
|
-
const SQL = [
|
|
130
|
-
SourceNames.POSTGRES,
|
|
131
|
-
SourceNames.SQL_SERVER,
|
|
132
|
-
SourceNames.MYSQL,
|
|
133
|
-
SourceNames.ORACLE,
|
|
134
|
-
]
|
|
130
|
+
const SQL = [SourceNames.POSTGRES, SourceNames.SQL_SERVER, SourceNames.MYSQL]
|
|
135
131
|
return SQL.indexOf(datasource.source) !== -1
|
|
136
132
|
}
|
|
137
133
|
|
|
@@ -143,59 +139,11 @@ export function isIsoDateString(str: string) {
|
|
|
143
139
|
return d.toISOString() === str
|
|
144
140
|
}
|
|
145
141
|
|
|
146
|
-
|
|
147
|
-
* This function will determine whether a column is a relationship and whether it
|
|
148
|
-
* is currently valid. The reason for the validity check is that tables can be deleted
|
|
149
|
-
* outside of Budibase control and if this is the case it will break Budibase relationships.
|
|
150
|
-
* The tableIds is a list passed down from the main finalise tables function, which is
|
|
151
|
-
* based on the tables that have just been fetched. This will only really be used on subsequent
|
|
152
|
-
* fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.
|
|
153
|
-
* @param column The column to check, to see if it is a valid relationship.
|
|
154
|
-
* @param tableIds The IDs of the tables which currently exist.
|
|
155
|
-
*/
|
|
156
|
-
function shouldCopyRelationship(
|
|
157
|
-
column: { type: string; tableId?: string },
|
|
158
|
-
tableIds: [string]
|
|
159
|
-
) {
|
|
160
|
-
return (
|
|
161
|
-
column.type === FieldTypes.LINK &&
|
|
162
|
-
column.tableId &&
|
|
163
|
-
tableIds.includes(column.tableId)
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean
|
|
169
|
-
* types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make
|
|
170
|
-
* sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a
|
|
171
|
-
* column has changed type in the external database then copying it over may not be possible.
|
|
172
|
-
* @param column The column to check for options or boolean type.
|
|
173
|
-
* @param fetchedColumn The fetched column to check for the type in the external database.
|
|
174
|
-
*/
|
|
175
|
-
function shouldCopySpecialColumn(
|
|
176
|
-
column: { type: string },
|
|
177
|
-
fetchedColumn: { type: string } | undefined
|
|
178
|
-
) {
|
|
179
|
-
return (
|
|
180
|
-
column.type === FieldTypes.OPTIONS ||
|
|
181
|
-
((!fetchedColumn || fetchedColumn.type === FieldTypes.NUMBER) &&
|
|
182
|
-
column.type === FieldTypes.BOOLEAN)
|
|
183
|
-
)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Looks for columns which need to be copied over into the new table definitions, like relationships
|
|
188
|
-
* and options types.
|
|
189
|
-
* @param tableName The name of the table which is being checked.
|
|
190
|
-
* @param table The specific table which is being checked.
|
|
191
|
-
* @param entities All the tables that existed before - the old table definitions.
|
|
192
|
-
* @param tableIds The IDs of the tables which exist now, to check if anything has been removed.
|
|
193
|
-
*/
|
|
142
|
+
// add the existing relationships from the entities if they exist, to prevent them from being overridden
|
|
194
143
|
function copyExistingPropsOver(
|
|
195
144
|
tableName: string,
|
|
196
145
|
table: Table,
|
|
197
|
-
entities: { [key: string]: any }
|
|
198
|
-
tableIds: [string]
|
|
146
|
+
entities: { [key: string]: any }
|
|
199
147
|
) {
|
|
200
148
|
if (entities && entities[tableName]) {
|
|
201
149
|
if (entities[tableName].primaryDisplay) {
|
|
@@ -206,10 +154,12 @@ function copyExistingPropsOver(
|
|
|
206
154
|
if (!existingTableSchema.hasOwnProperty(key)) {
|
|
207
155
|
continue
|
|
208
156
|
}
|
|
209
|
-
const column = existingTableSchema[key]
|
|
210
157
|
if (
|
|
211
|
-
|
|
212
|
-
|
|
158
|
+
existingTableSchema[key].type === FieldTypes.LINK ||
|
|
159
|
+
existingTableSchema[key].type === FieldTypes.OPTIONS ||
|
|
160
|
+
existingTableSchema[key].type === FieldTypes.ARRAY ||
|
|
161
|
+
((!table.schema[key] || table.schema[key].type === FieldTypes.NUMBER) &&
|
|
162
|
+
existingTableSchema[key].type === FieldTypes.BOOLEAN)
|
|
213
163
|
) {
|
|
214
164
|
table.schema[key] = existingTableSchema[key]
|
|
215
165
|
}
|
|
@@ -218,13 +168,6 @@ function copyExistingPropsOver(
|
|
|
218
168
|
return table
|
|
219
169
|
}
|
|
220
170
|
|
|
221
|
-
/**
|
|
222
|
-
* Look through the final table definitions to see if anything needs to be
|
|
223
|
-
* copied over from the old and if any errors have occurred mark them so
|
|
224
|
-
* that the user can be made aware.
|
|
225
|
-
* @param tables The list of tables that have been retrieved from the external database.
|
|
226
|
-
* @param entities The old list of tables, if there was any to look for definitions in.
|
|
227
|
-
*/
|
|
228
171
|
export function finaliseExternalTables(
|
|
229
172
|
tables: { [key: string]: any },
|
|
230
173
|
entities: { [key: string]: any }
|
|
@@ -232,8 +175,6 @@ export function finaliseExternalTables(
|
|
|
232
175
|
const invalidColumns = Object.values(InvalidColumns)
|
|
233
176
|
let finalTables: { [key: string]: any } = {}
|
|
234
177
|
const errors: { [key: string]: string } = {}
|
|
235
|
-
// @ts-ignore
|
|
236
|
-
const tableIds: [string] = Object.values(tables).map(table => table._id)
|
|
237
178
|
for (let [name, table] of Object.entries(tables)) {
|
|
238
179
|
const schemaFields = Object.keys(table.schema)
|
|
239
180
|
// make sure every table has a key
|
|
@@ -245,7 +186,7 @@ export function finaliseExternalTables(
|
|
|
245
186
|
continue
|
|
246
187
|
}
|
|
247
188
|
// make sure all previous props have been added back
|
|
248
|
-
finalTables[name] = copyExistingPropsOver(name, table, entities
|
|
189
|
+
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
|
249
190
|
}
|
|
250
191
|
// sort the tables by name
|
|
251
192
|
finalTables = Object.entries(finalTables)
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
jest.mock("../../db")
|
|
2
2
|
jest.mock("../../utilities/usageQuota")
|
|
3
|
+
jest.mock("../../environment", () => ({
|
|
4
|
+
isTest: () => true,
|
|
5
|
+
isProd: () => false,
|
|
6
|
+
isDev: () => true,
|
|
7
|
+
_set: () => {},
|
|
8
|
+
}))
|
|
3
9
|
jest.mock("@budibase/backend-core/tenancy", () => ({
|
|
4
10
|
getTenantId: () => "testing123"
|
|
5
11
|
}))
|
|
@@ -23,10 +29,9 @@ class TestConfiguration {
|
|
|
23
29
|
},
|
|
24
30
|
req: {
|
|
25
31
|
method: "POST",
|
|
26
|
-
url: "/
|
|
32
|
+
url: "/rows"
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
|
-
usageQuota.useQuotas = () => true
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
executeMiddleware() {
|
|
@@ -108,6 +113,7 @@ describe("usageQuota middleware", () => {
|
|
|
108
113
|
|
|
109
114
|
it("calculates and persists the correct usage quota for the relevant action", async () => {
|
|
110
115
|
config.setUrl("/rows")
|
|
116
|
+
config.setProd(true)
|
|
111
117
|
|
|
112
118
|
await config.executeMiddleware()
|
|
113
119
|
|
|
@@ -115,20 +121,20 @@ describe("usageQuota middleware", () => {
|
|
|
115
121
|
expect(config.next).toHaveBeenCalled()
|
|
116
122
|
})
|
|
117
123
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
it("calculates the correct file size from a file upload call and adds it to quota", async () => {
|
|
125
|
+
config.setUrl("/upload")
|
|
126
|
+
config.setProd(true)
|
|
127
|
+
config.setFiles([
|
|
128
|
+
{
|
|
129
|
+
size: 100
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
size: 10000
|
|
133
|
+
},
|
|
134
|
+
])
|
|
135
|
+
await config.executeMiddleware()
|
|
136
|
+
|
|
137
|
+
expect(usageQuota.update).toHaveBeenCalledWith("storage", 10100)
|
|
138
|
+
expect(config.next).toHaveBeenCalled()
|
|
139
|
+
})
|
|
134
140
|
})
|