@budibase/server 1.0.46-alpha.1 → 1.0.46-alpha.5
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.0df4f7ab.css → index.243ca52c.css} +1 -1
- package/builder/assets/{index.d109814f.js → index.298ba3d3.js} +184 -184
- package/builder/assets/{vendor.10e2ad1b.js → vendor.3bd2f661.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +1685 -1534
- package/coverage/coverage-final.json +98 -94
- 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 +192 -129
- 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 +30 -30
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +19 -34
- 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 +1 -1
- 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 +25 -25
- 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 +16 -16
- package/coverage/lcov-report/api/controllers/table/index.js.html +25 -25
- package/coverage/lcov-report/api/controllers/table/internal.js.html +40 -34
- package/coverage/lcov-report/api/controllers/table/utils.js.html +76 -61
- 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/api/routes/index.html +7 -22
- package/coverage/lcov-report/api/routes/index.js.html +4 -10
- 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 +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 +1 -1
- package/coverage/lcov-report/constants/index.js.html +22 -22
- 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 +99 -69
- 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 +34 -61
- package/coverage/lcov-report/middleware/index.html +25 -25
- 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 +275 -41
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/migrations/usageQuotas/index.html +141 -0
- package/coverage/lcov-report/migrations/usageQuotas/index.js.html +152 -0
- package/coverage/lcov-report/{api/routes/hosting.js.html → migrations/usageQuotas/syncApps.js.html} +42 -27
- package/coverage/lcov-report/{api/controllers/hosting.js.html → migrations/usageQuotas/syncRows.js.html} +41 -44
- 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 +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/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/utilities/usageQuota/usageQuoteReset.js.html +134 -0
- package/coverage/lcov-report/utilities/users.js.html +5 -5
- package/coverage/lcov-report/utilities/workerRequests.js.html +39 -108
- package/coverage/lcov.info +2415 -2154
- package/dist/api/controllers/application.js +45 -24
- package/dist/api/controllers/static/index.js +59 -10
- package/dist/api/controllers/table/internal.js +2 -0
- package/dist/api/controllers/table/utils.js +5 -0
- package/dist/api/routes/index.js +0 -2
- package/dist/api/routes/static.js +2 -1
- package/dist/automations/steps/createRow.js +2 -4
- package/dist/automations/steps/deleteRow.js +1 -4
- package/dist/environment.js +1 -0
- package/dist/integrations/rest.js +5 -5
- package/dist/integrations/s3.js +1 -1
- package/dist/integrations/utils.js +6 -3
- package/dist/middleware/currentapp.js +0 -9
- package/dist/middleware/usageQuota.js +82 -13
- package/dist/migrations/usageQuotas/index.js +24 -0
- package/dist/migrations/usageQuotas/syncApps.js +26 -0
- package/dist/migrations/usageQuotas/syncRows.js +29 -0
- package/dist/package.json +5 -5
- package/dist/tests/utilities/TestConfiguration.js +3 -1
- package/dist/threads/query.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- 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 +6 -6
- package/src/api/controllers/application.js +48 -27
- package/src/api/controllers/static/index.js +63 -10
- package/src/api/controllers/table/internal.js +2 -0
- package/src/api/controllers/table/utils.js +5 -0
- package/src/api/routes/index.js +0 -2
- package/src/api/routes/static.js +5 -0
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/static.spec.js +98 -0
- package/src/automations/steps/createRow.js +2 -4
- package/src/automations/steps/deleteRow.js +1 -4
- package/src/environment.js +1 -0
- package/src/integrations/rest.ts +9 -28
- package/src/integrations/s3.ts +1 -1
- package/src/integrations/utils.ts +18 -5
- package/src/middleware/currentapp.js +0 -9
- package/src/middleware/tests/usageQuota.spec.js +18 -24
- package/src/middleware/usageQuota.js +93 -15
- package/src/migrations/tests/usageQuotas/index.spec.js +27 -0
- package/src/migrations/tests/usageQuotas/syncApps.spec.js +37 -0
- package/src/migrations/tests/usageQuotas/syncRows.spec.js +43 -0
- package/src/migrations/usageQuotas/index.js +24 -0
- package/src/migrations/usageQuotas/syncApps.js +18 -0
- package/src/migrations/usageQuotas/syncRows.js +21 -0
- package/src/tests/utilities/TestConfiguration.js +3 -1
- package/src/threads/query.js +5 -0
- 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/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
|
@@ -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
|
+
})
|
|
@@ -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/environment.js
CHANGED
|
@@ -38,6 +38,7 @@ 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,
|
package/src/integrations/rest.ts
CHANGED
|
@@ -43,8 +43,8 @@ const coreFields = {
|
|
|
43
43
|
enum: Object.values(BodyTypes),
|
|
44
44
|
},
|
|
45
45
|
pagination: {
|
|
46
|
-
type: DatasourceFieldTypes.OBJECT
|
|
47
|
-
}
|
|
46
|
+
type: DatasourceFieldTypes.OBJECT
|
|
47
|
+
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
module RestModule {
|
|
@@ -178,17 +178,12 @@ module RestModule {
|
|
|
178
178
|
headers,
|
|
179
179
|
},
|
|
180
180
|
pagination: {
|
|
181
|
-
cursor: nextCursor
|
|
182
|
-
}
|
|
181
|
+
cursor: nextCursor
|
|
182
|
+
}
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
getUrl(
|
|
187
|
-
path: string,
|
|
188
|
-
queryString: string,
|
|
189
|
-
pagination: PaginationConfig | null,
|
|
190
|
-
paginationValues: PaginationValues | null
|
|
191
|
-
): string {
|
|
186
|
+
getUrl(path: string, queryString: string, pagination: PaginationConfig | null, paginationValues: PaginationValues | null): string {
|
|
192
187
|
// Add pagination params to query string if required
|
|
193
188
|
if (pagination?.location === "query" && paginationValues) {
|
|
194
189
|
const { pageParam, sizeParam } = pagination
|
|
@@ -222,22 +217,14 @@ module RestModule {
|
|
|
222
217
|
return complete
|
|
223
218
|
}
|
|
224
219
|
|
|
225
|
-
addBody(
|
|
226
|
-
bodyType: string,
|
|
227
|
-
body: string | any,
|
|
228
|
-
input: any,
|
|
229
|
-
pagination: PaginationConfig | null,
|
|
230
|
-
paginationValues: PaginationValues | null
|
|
231
|
-
) {
|
|
220
|
+
addBody(bodyType: string, body: string | any, input: any, pagination: PaginationConfig | null, paginationValues: PaginationValues | null) {
|
|
232
221
|
if (!input.headers) {
|
|
233
222
|
input.headers = {}
|
|
234
223
|
}
|
|
235
224
|
if (bodyType === BodyTypes.NONE) {
|
|
236
225
|
return input
|
|
237
226
|
}
|
|
238
|
-
let error,
|
|
239
|
-
object: any = {},
|
|
240
|
-
string = ""
|
|
227
|
+
let error, object: any = {}, string = ""
|
|
241
228
|
try {
|
|
242
229
|
if (body) {
|
|
243
230
|
string = typeof body !== "string" ? JSON.stringify(body) : body
|
|
@@ -346,7 +333,7 @@ module RestModule {
|
|
|
346
333
|
requestBody,
|
|
347
334
|
authConfigId,
|
|
348
335
|
pagination,
|
|
349
|
-
paginationValues
|
|
336
|
+
paginationValues
|
|
350
337
|
} = query
|
|
351
338
|
const authHeaders = this.getAuthHeaders(authConfigId)
|
|
352
339
|
|
|
@@ -365,13 +352,7 @@ module RestModule {
|
|
|
365
352
|
}
|
|
366
353
|
|
|
367
354
|
let input: any = { method, headers: this.headers }
|
|
368
|
-
input = this.addBody(
|
|
369
|
-
bodyType,
|
|
370
|
-
requestBody,
|
|
371
|
-
input,
|
|
372
|
-
pagination,
|
|
373
|
-
paginationValues
|
|
374
|
-
)
|
|
355
|
+
input = this.addBody(bodyType, requestBody, input, pagination, paginationValues)
|
|
375
356
|
|
|
376
357
|
this.startTimeMs = performance.now()
|
|
377
358
|
const url = this.getUrl(path, queryString, pagination, paginationValues)
|
package/src/integrations/s3.ts
CHANGED
|
@@ -153,8 +153,15 @@ export function isIsoDateString(str: string) {
|
|
|
153
153
|
* @param column The column to check, to see if it is a valid relationship.
|
|
154
154
|
* @param tableIds The IDs of the tables which currently exist.
|
|
155
155
|
*/
|
|
156
|
-
function shouldCopyRelationship(
|
|
157
|
-
|
|
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
|
+
)
|
|
158
165
|
}
|
|
159
166
|
|
|
160
167
|
/**
|
|
@@ -165,9 +172,15 @@ function shouldCopyRelationship(column: { type: string, tableId?: string }, tabl
|
|
|
165
172
|
* @param column The column to check for options or boolean type.
|
|
166
173
|
* @param fetchedColumn The fetched column to check for the type in the external database.
|
|
167
174
|
*/
|
|
168
|
-
function shouldCopySpecialColumn(
|
|
169
|
-
|
|
170
|
-
|
|
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
|
+
)
|
|
171
184
|
}
|
|
172
185
|
|
|
173
186
|
/**
|
|
@@ -47,15 +47,6 @@ module.exports = async (ctx, next) => {
|
|
|
47
47
|
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
|
48
48
|
) {
|
|
49
49
|
clearCookie(ctx, Cookies.CurrentApp)
|
|
50
|
-
// have to set the return url on the server side as client side is not available
|
|
51
|
-
setCookie(ctx, ctx.url, Cookies.RETURN_URL, {
|
|
52
|
-
// don't sign so the browser can easily read
|
|
53
|
-
sign: false,
|
|
54
|
-
// use the request domain to match how ui handles the return url cookie.
|
|
55
|
-
// it's important we don't use the shared domain here as the builder
|
|
56
|
-
// can't delete from it without awareness of the domain.
|
|
57
|
-
requestDomain: true,
|
|
58
|
-
})
|
|
59
50
|
return ctx.redirect("/")
|
|
60
51
|
}
|
|
61
52
|
|
|
@@ -1,11 +1,5 @@
|
|
|
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
|
-
}))
|
|
9
3
|
jest.mock("@budibase/backend-core/tenancy", () => ({
|
|
10
4
|
getTenantId: () => "testing123"
|
|
11
5
|
}))
|
|
@@ -29,9 +23,10 @@ class TestConfiguration {
|
|
|
29
23
|
},
|
|
30
24
|
req: {
|
|
31
25
|
method: "POST",
|
|
32
|
-
url: "/
|
|
26
|
+
url: "/applications"
|
|
33
27
|
}
|
|
34
28
|
}
|
|
29
|
+
usageQuota.useQuotas = () => true
|
|
35
30
|
}
|
|
36
31
|
|
|
37
32
|
executeMiddleware() {
|
|
@@ -113,7 +108,6 @@ describe("usageQuota middleware", () => {
|
|
|
113
108
|
|
|
114
109
|
it("calculates and persists the correct usage quota for the relevant action", async () => {
|
|
115
110
|
config.setUrl("/rows")
|
|
116
|
-
config.setProd(true)
|
|
117
111
|
|
|
118
112
|
await config.executeMiddleware()
|
|
119
113
|
|
|
@@ -121,20 +115,20 @@ describe("usageQuota middleware", () => {
|
|
|
121
115
|
expect(config.next).toHaveBeenCalled()
|
|
122
116
|
})
|
|
123
117
|
|
|
124
|
-
it("calculates the correct file size from a file upload call and adds it to quota", async () => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
})
|
|
118
|
+
// it("calculates the correct file size from a file upload call and adds it to quota", async () => {
|
|
119
|
+
// config.setUrl("/upload")
|
|
120
|
+
// config.setProd(true)
|
|
121
|
+
// config.setFiles([
|
|
122
|
+
// {
|
|
123
|
+
// size: 100
|
|
124
|
+
// },
|
|
125
|
+
// {
|
|
126
|
+
// size: 10000
|
|
127
|
+
// },
|
|
128
|
+
// ])
|
|
129
|
+
// await config.executeMiddleware()
|
|
130
|
+
|
|
131
|
+
// expect(usageQuota.update).toHaveBeenCalledWith("storage", 10100)
|
|
132
|
+
// expect(config.next).toHaveBeenCalled()
|
|
133
|
+
// })
|
|
140
134
|
})
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
const CouchDB = require("../db")
|
|
2
2
|
const usageQuota = require("../utilities/usageQuota")
|
|
3
|
-
const
|
|
4
|
-
const { getTenantId } = require("@budibase/backend-core/tenancy")
|
|
3
|
+
const { getUniqueRows } = require("../utilities/usageQuota/rows")
|
|
5
4
|
const {
|
|
6
5
|
isExternalTable,
|
|
7
6
|
isRowId: isExternalRowId,
|
|
8
7
|
} = require("../integrations/utils")
|
|
9
|
-
|
|
10
|
-
// tenants without limits
|
|
11
|
-
const EXCLUDED_TENANTS = ["bb", "default", "bbtest", "bbstaging"]
|
|
8
|
+
const migration = require("../migrations/usageQuotas")
|
|
12
9
|
|
|
13
10
|
// currently only counting new writes and deletes
|
|
14
11
|
const METHOD_MAP = {
|
|
@@ -18,13 +15,13 @@ const METHOD_MAP = {
|
|
|
18
15
|
|
|
19
16
|
const DOMAIN_MAP = {
|
|
20
17
|
rows: usageQuota.Properties.ROW,
|
|
21
|
-
upload: usageQuota.Properties.UPLOAD,
|
|
22
|
-
views: usageQuota.Properties.VIEW,
|
|
23
|
-
users: usageQuota.Properties.USER,
|
|
18
|
+
// upload: usageQuota.Properties.UPLOAD, // doesn't work yet
|
|
19
|
+
// views: usageQuota.Properties.VIEW, // doesn't work yet
|
|
20
|
+
// users: usageQuota.Properties.USER, // doesn't work yet
|
|
24
21
|
applications: usageQuota.Properties.APPS,
|
|
25
22
|
// this will not be updated by endpoint calls
|
|
26
23
|
// instead it will be updated by triggerInfo
|
|
27
|
-
automationRuns: usageQuota.Properties.AUTOMATION,
|
|
24
|
+
// automationRuns: usageQuota.Properties.AUTOMATION, // doesn't work yet
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
function getProperty(url) {
|
|
@@ -36,10 +33,7 @@ function getProperty(url) {
|
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
module.exports = async (ctx, next) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// if in development or a self hosted cloud usage quotas should not be executed
|
|
42
|
-
if (env.isDev() || env.SELF_HOSTED || EXCLUDED_TENANTS.includes(tenantId)) {
|
|
36
|
+
if (!usageQuota.useQuotas()) {
|
|
43
37
|
return next()
|
|
44
38
|
}
|
|
45
39
|
|
|
@@ -80,9 +74,93 @@ module.exports = async (ctx, next) => {
|
|
|
80
74
|
usage = files.map(file => file.size).reduce((total, size) => total + size)
|
|
81
75
|
}
|
|
82
76
|
try {
|
|
83
|
-
await
|
|
84
|
-
|
|
77
|
+
await migration.run()
|
|
78
|
+
await performRequest(ctx, next, property, usage)
|
|
85
79
|
} catch (err) {
|
|
86
80
|
ctx.throw(400, err)
|
|
87
81
|
}
|
|
88
82
|
}
|
|
83
|
+
|
|
84
|
+
const performRequest = async (ctx, next, property, usage) => {
|
|
85
|
+
const usageContext = {
|
|
86
|
+
skipNext: false,
|
|
87
|
+
skipUsage: false,
|
|
88
|
+
[usageQuota.Properties.APPS]: {},
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (usage === -1) {
|
|
92
|
+
if (PRE_DELETE[property]) {
|
|
93
|
+
await PRE_DELETE[property](ctx, usageContext)
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
if (PRE_CREATE[property]) {
|
|
97
|
+
await PRE_CREATE[property](ctx, usageContext)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// run the request
|
|
102
|
+
if (!usageContext.skipNext) {
|
|
103
|
+
await usageQuota.update(property, usage, { dryRun: true })
|
|
104
|
+
await next()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (usage === -1) {
|
|
108
|
+
if (POST_DELETE[property]) {
|
|
109
|
+
await POST_DELETE[property](ctx, usageContext)
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
if (POST_CREATE[property]) {
|
|
113
|
+
await POST_CREATE[property](ctx, usageContext)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// update the usage
|
|
118
|
+
if (!usageContext.skipUsage) {
|
|
119
|
+
await usageQuota.update(property, usage)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const appPreDelete = async (ctx, usageContext) => {
|
|
124
|
+
if (ctx.query.unpublish) {
|
|
125
|
+
// don't run usage decrement for unpublish
|
|
126
|
+
usageContext.skipUsage = true
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// store the row count to delete
|
|
131
|
+
const rows = await getUniqueRows([ctx.appId])
|
|
132
|
+
if (rows.length) {
|
|
133
|
+
usageContext[usageQuota.Properties.APPS] = { rowCount: rows.length }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const appPostDelete = async (ctx, usageContext) => {
|
|
138
|
+
// delete the app rows from usage
|
|
139
|
+
const rowCount = usageContext[usageQuota.Properties.APPS].rowCount
|
|
140
|
+
if (rowCount) {
|
|
141
|
+
await usageQuota.update(usageQuota.Properties.ROW, -rowCount)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const appPostCreate = async ctx => {
|
|
146
|
+
// app import & template creation
|
|
147
|
+
if (ctx.request.body.useTemplate === "true") {
|
|
148
|
+
const rows = await getUniqueRows([ctx.response.body.appId])
|
|
149
|
+
const rowCount = rows ? rows.length : 0
|
|
150
|
+
await usageQuota.update(usageQuota.Properties.ROW, rowCount)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const PRE_DELETE = {
|
|
155
|
+
[usageQuota.Properties.APPS]: appPreDelete,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const POST_DELETE = {
|
|
159
|
+
[usageQuota.Properties.APPS]: appPostDelete,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const PRE_CREATE = {}
|
|
163
|
+
|
|
164
|
+
const POST_CREATE = {
|
|
165
|
+
[usageQuota.Properties.APPS]: appPostCreate,
|
|
166
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const env = require("../../../environment")
|
|
2
|
+
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
3
|
+
|
|
4
|
+
const syncApps = jest.fn()
|
|
5
|
+
const syncRows = jest.fn()
|
|
6
|
+
|
|
7
|
+
jest.mock("../../usageQuotas/syncApps", () => ({ run: syncApps }) )
|
|
8
|
+
jest.mock("../../usageQuotas/syncRows", () => ({ run: syncRows }) )
|
|
9
|
+
|
|
10
|
+
const migrations = require("../../usageQuotas")
|
|
11
|
+
|
|
12
|
+
describe("run", () => {
|
|
13
|
+
let config = new TestConfig(false)
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
await config.init()
|
|
17
|
+
env._set("USE_QUOTAS", 1)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
afterAll(config.end)
|
|
21
|
+
|
|
22
|
+
it("runs the required migrations", async () => {
|
|
23
|
+
await migrations.run()
|
|
24
|
+
expect(syncApps).toHaveBeenCalledTimes(1)
|
|
25
|
+
expect(syncRows).toHaveBeenCalledTimes(1)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
2
|
+
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
3
|
+
const { getUsageQuotaDoc, update, Properties } = require("../../../utilities/usageQuota")
|
|
4
|
+
const syncApps = require("../../usageQuotas/syncApps")
|
|
5
|
+
const env = require("../../../environment")
|
|
6
|
+
|
|
7
|
+
describe("syncApps", () => {
|
|
8
|
+
let config = new TestConfig(false)
|
|
9
|
+
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
await config.init()
|
|
12
|
+
env._set("USE_QUOTAS", 1)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
afterAll(config.end)
|
|
16
|
+
|
|
17
|
+
it("runs successfully", async () => {
|
|
18
|
+
// create the usage quota doc and mock usages
|
|
19
|
+
const db = getGlobalDB()
|
|
20
|
+
await getUsageQuotaDoc(db)
|
|
21
|
+
await update(Properties.APPS, 3)
|
|
22
|
+
|
|
23
|
+
let usageDoc = await getUsageQuotaDoc(db)
|
|
24
|
+
expect(usageDoc.usageQuota.apps).toEqual(3)
|
|
25
|
+
|
|
26
|
+
// create an extra app to test the migration
|
|
27
|
+
await config.createApp("quota-test")
|
|
28
|
+
|
|
29
|
+
// migrate
|
|
30
|
+
await syncApps.run()
|
|
31
|
+
|
|
32
|
+
// assert the migration worked
|
|
33
|
+
usageDoc = await getUsageQuotaDoc(db)
|
|
34
|
+
expect(usageDoc.usageQuota.apps).toEqual(2)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
2
|
+
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
3
|
+
const { getUsageQuotaDoc, update, Properties } = require("../../../utilities/usageQuota")
|
|
4
|
+
const syncRows = require("../../usageQuotas/syncRows")
|
|
5
|
+
const env = require("../../../environment")
|
|
6
|
+
|
|
7
|
+
describe("syncRows", () => {
|
|
8
|
+
let config = new TestConfig(false)
|
|
9
|
+
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
await config.init()
|
|
12
|
+
env._set("USE_QUOTAS", 1)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
afterAll(config.end)
|
|
16
|
+
|
|
17
|
+
it("runs successfully", async () => {
|
|
18
|
+
// create the usage quota doc and mock usages
|
|
19
|
+
const db = getGlobalDB()
|
|
20
|
+
await getUsageQuotaDoc(db)
|
|
21
|
+
await update(Properties.ROW, 300)
|
|
22
|
+
|
|
23
|
+
let usageDoc = await getUsageQuotaDoc(db)
|
|
24
|
+
expect(usageDoc.usageQuota.rows).toEqual(300)
|
|
25
|
+
|
|
26
|
+
// app 1
|
|
27
|
+
await config.createTable()
|
|
28
|
+
await config.createRow()
|
|
29
|
+
// app 2
|
|
30
|
+
await config.createApp("second-app")
|
|
31
|
+
await config.createTable()
|
|
32
|
+
await config.createRow()
|
|
33
|
+
await config.createRow()
|
|
34
|
+
|
|
35
|
+
// migrate
|
|
36
|
+
await syncRows.run()
|
|
37
|
+
|
|
38
|
+
// assert the migration worked
|
|
39
|
+
usageDoc = await getUsageQuotaDoc(db)
|
|
40
|
+
expect(usageDoc.usageQuota.rows).toEqual(3)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const {
|
|
2
|
+
MIGRATIONS,
|
|
3
|
+
MIGRATION_DBS,
|
|
4
|
+
migrateIfRequired,
|
|
5
|
+
} = require("@budibase/backend-core/migrations")
|
|
6
|
+
const { useQuotas } = require("../../utilities/usageQuota")
|
|
7
|
+
const syncApps = require("./syncApps")
|
|
8
|
+
const syncRows = require("./syncRows")
|
|
9
|
+
|
|
10
|
+
exports.run = async () => {
|
|
11
|
+
if (!useQuotas()) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Jan 2022
|
|
16
|
+
await migrateIfRequired(
|
|
17
|
+
MIGRATION_DBS.GLOBAL_DB,
|
|
18
|
+
MIGRATIONS.QUOTAS_1,
|
|
19
|
+
async () => {
|
|
20
|
+
await syncApps.run()
|
|
21
|
+
await syncRows.run()
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
|
|
2
|
+
const { getAllApps } = require("@budibase/backend-core/db")
|
|
3
|
+
const CouchDB = require("../../db")
|
|
4
|
+
const { getUsageQuotaDoc } = require("../../utilities/usageQuota")
|
|
5
|
+
|
|
6
|
+
exports.run = async () => {
|
|
7
|
+
const db = getGlobalDB()
|
|
8
|
+
// get app count
|
|
9
|
+
const devApps = await getAllApps(CouchDB, { dev: true })
|
|
10
|
+
const appCount = devApps ? devApps.length : 0
|
|
11
|
+
|
|
12
|
+
// sync app count
|
|
13
|
+
const tenantId = getTenantId()
|
|
14
|
+
console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`)
|
|
15
|
+
const usageDoc = await getUsageQuotaDoc(db)
|
|
16
|
+
usageDoc.usageQuota.apps = appCount
|
|
17
|
+
await db.put(usageDoc)
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
|
|
2
|
+
const { getAllApps } = require("@budibase/backend-core/db")
|
|
3
|
+
const CouchDB = require("../../db")
|
|
4
|
+
const { getUsageQuotaDoc } = require("../../utilities/usageQuota")
|
|
5
|
+
const { getUniqueRows } = require("../../utilities/usageQuota/rows")
|
|
6
|
+
|
|
7
|
+
exports.run = async () => {
|
|
8
|
+
const db = getGlobalDB()
|
|
9
|
+
// get all rows in all apps
|
|
10
|
+
const allApps = await getAllApps(CouchDB, { all: true })
|
|
11
|
+
const appIds = allApps ? allApps.map(app => app.appId) : []
|
|
12
|
+
const rows = await getUniqueRows(appIds)
|
|
13
|
+
const rowCount = rows ? rows.length : 0
|
|
14
|
+
|
|
15
|
+
// sync row count
|
|
16
|
+
const tenantId = getTenantId()
|
|
17
|
+
console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`)
|
|
18
|
+
const usageDoc = await getUsageQuotaDoc(db)
|
|
19
|
+
usageDoc.usageQuota.rows = rowCount
|
|
20
|
+
await db.put(usageDoc)
|
|
21
|
+
}
|