@budibase/server 2.5.6-alpha.4 → 2.5.6-alpha.41
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.58b41739.js → index.05e726d8.js} +384 -366
- package/builder/assets/index.4eae16b2.css +6 -0
- package/builder/index.html +2 -2
- package/dist/api/controllers/application.js +3 -4
- package/dist/api/controllers/automation.js +13 -7
- package/dist/api/controllers/datasource.js +1 -1
- package/dist/api/controllers/dev.js +1 -1
- package/dist/api/controllers/plugin/index.js +6 -37
- package/dist/api/controllers/query/index.js +2 -2
- package/dist/api/controllers/row/ExternalRequest.js +21 -14
- package/dist/api/controllers/table/utils.js +9 -3
- package/dist/api/index.js +1 -2
- package/dist/api/routes/index.js +0 -2
- package/dist/app.js +2 -2
- package/dist/automations/actions.js +32 -6
- package/dist/automations/index.js +3 -2
- package/dist/automations/steps/bash.js +6 -6
- package/dist/automations/steps/createRow.js +11 -11
- package/dist/automations/steps/delay.js +3 -3
- package/dist/automations/steps/deleteRow.js +8 -8
- package/dist/automations/steps/discord.js +8 -8
- package/dist/automations/steps/executeQuery.js +9 -9
- package/dist/automations/steps/executeScript.js +6 -6
- package/dist/automations/steps/filter.js +6 -6
- package/dist/automations/steps/integromat.js +10 -10
- package/dist/automations/steps/loop.js +9 -9
- package/dist/automations/steps/outgoingWebhook.js +10 -10
- package/dist/automations/steps/queryRows.js +14 -14
- package/dist/automations/steps/sendSmtpEmail.js +9 -9
- package/dist/automations/steps/serverLog.js +4 -4
- package/dist/automations/steps/slack.js +6 -6
- package/dist/automations/steps/updateRow.js +11 -11
- package/dist/automations/steps/zapier.js +9 -9
- package/dist/automations/triggerInfo/app.js +5 -5
- package/dist/automations/triggerInfo/cron.js +4 -4
- package/dist/automations/triggerInfo/rowDeleted.js +5 -5
- package/dist/automations/triggerInfo/rowSaved.js +7 -7
- package/dist/automations/triggerInfo/rowUpdated.js +7 -7
- package/dist/automations/triggerInfo/webhook.js +6 -6
- package/dist/db/utils.js +3 -2
- package/dist/integrations/base/sqlTable.js +9 -2
- package/dist/integrations/index.js +3 -3
- package/dist/migrations/functions/syncQuotas.js +2 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +0 -1
- package/dist/migrations/functions/usageQuotas/syncUsers.js +21 -0
- package/dist/sdk/app/backups/exports.js +14 -38
- package/dist/sdk/index.js +2 -0
- package/dist/{api/routes/cloud.js → sdk/plugins/index.js} +2 -14
- package/dist/sdk/plugins/plugins.js +53 -0
- package/dist/threads/automation.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/plugin.js +33 -23
- package/dist/utilities/rowProcessor/utils.js +4 -5
- package/dist/watch.js +2 -2
- package/dist/websockets/client.js +14 -0
- package/dist/websockets/grid.js +60 -0
- package/dist/websockets/index.js +17 -0
- package/dist/websockets/websocket.js +78 -0
- package/package.json +11 -10
- package/src/api/controllers/application.ts +4 -4
- package/src/api/controllers/automation.ts +12 -6
- package/src/api/controllers/datasource.ts +15 -5
- package/src/api/controllers/dev.ts +2 -2
- package/src/api/controllers/plugin/index.ts +8 -45
- package/src/api/controllers/query/index.ts +2 -2
- package/src/api/controllers/row/ExternalRequest.ts +21 -12
- package/src/api/controllers/table/utils.ts +10 -3
- package/src/api/index.ts +2 -4
- package/src/api/routes/index.ts +0 -2
- package/src/api/routes/tests/automation.spec.js +2 -2
- package/src/app.ts +2 -2
- package/src/automations/actions.ts +56 -24
- package/src/automations/index.ts +1 -1
- package/src/automations/steps/bash.ts +10 -7
- package/src/automations/steps/createRow.ts +15 -12
- package/src/automations/steps/delay.ts +6 -4
- package/src/automations/steps/deleteRow.ts +12 -9
- package/src/automations/steps/discord.ts +10 -8
- package/src/automations/steps/executeQuery.ts +13 -10
- package/src/automations/steps/executeScript.ts +10 -7
- package/src/automations/steps/filter.ts +8 -6
- package/src/automations/steps/integromat.ts +12 -10
- package/src/automations/steps/loop.ts +16 -10
- package/src/automations/steps/outgoingWebhook.ts +14 -11
- package/src/automations/steps/queryRows.ts +18 -15
- package/src/automations/steps/sendSmtpEmail.ts +11 -9
- package/src/automations/steps/serverLog.ts +6 -4
- package/src/automations/steps/slack.ts +8 -6
- package/src/automations/steps/updateRow.ts +15 -12
- package/src/automations/steps/zapier.ts +11 -9
- package/src/automations/tests/utilities/index.ts +2 -2
- package/src/automations/triggerInfo/app.ts +8 -5
- package/src/automations/triggerInfo/cron.ts +7 -4
- package/src/automations/triggerInfo/rowDeleted.ts +8 -5
- package/src/automations/triggerInfo/rowSaved.ts +10 -7
- package/src/automations/triggerInfo/rowUpdated.ts +10 -7
- package/src/automations/triggerInfo/webhook.ts +9 -6
- package/src/db/utils.ts +1 -0
- package/src/integration-test/postgres.spec.ts +3 -1
- package/src/integrations/base/sqlTable.ts +9 -2
- package/src/integrations/index.ts +3 -3
- package/src/migrations/functions/syncQuotas.ts +2 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +1 -2
- package/src/migrations/functions/usageQuotas/syncUsers.ts +9 -0
- package/src/migrations/functions/usageQuotas/tests/syncUsers.spec.ts +26 -0
- package/src/migrations/index.ts +1 -0
- package/src/sdk/app/backups/exports.ts +17 -41
- package/src/sdk/index.ts +2 -0
- package/src/sdk/plugins/index.ts +5 -0
- package/src/sdk/plugins/plugins.ts +41 -0
- package/src/tests/utilities/structures.ts +25 -17
- package/src/threads/automation.ts +2 -2
- package/src/utilities/fileSystem/plugin.ts +13 -4
- package/src/utilities/rowProcessor/utils.ts +9 -10
- package/src/watch.ts +2 -2
- package/src/websockets/client.ts +11 -0
- package/src/websockets/grid.ts +55 -0
- package/src/websockets/index.ts +14 -0
- package/src/websockets/websocket.ts +83 -0
- package/tsconfig.build.json +3 -5
- package/tsconfig.json +2 -1
- package/builder/assets/index.841e62d8.css +0 -6
- package/dist/api/controllers/cloud.js +0 -130
- package/dist/package.json +0 -179
- package/dist/websocket.js +0 -22
- package/src/api/controllers/cloud.ts +0 -119
- package/src/api/routes/cloud.ts +0 -18
- package/src/api/routes/tests/cloud.spec.ts +0 -54
- package/src/migrations/functions/tests/syncQuotas.spec.js +0 -26
- package/src/websocket.ts +0 -26
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import TestConfig from "../../../tests/utilities/TestConfiguration"
|
|
2
2
|
import { context } from "@budibase/backend-core"
|
|
3
|
-
import {
|
|
3
|
+
import { BUILTIN_ACTION_DEFINITIONS, getAction } from "../../actions"
|
|
4
4
|
import emitter from "../../../events/index"
|
|
5
5
|
import env from "../../../environment"
|
|
6
6
|
|
|
@@ -57,4 +57,4 @@ export async function runStep(stepId: string, inputs: any, stepContext?: any) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export const apiKey = "test"
|
|
60
|
-
export const actions =
|
|
60
|
+
export const actions = BUILTIN_ACTION_DEFINITIONS
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
fields: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.OBJECT,
|
|
22
|
+
customType: AutomationCustomIOType.TRIGGER_SCHEMA,
|
|
20
23
|
title: "Fields",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
fields: {
|
|
28
|
-
type:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
29
32
|
description: "Fields submitted from the app frontend",
|
|
30
|
-
customType:
|
|
33
|
+
customType: AutomationCustomIOType.TRIGGER_SCHEMA,
|
|
31
34
|
},
|
|
32
35
|
},
|
|
33
36
|
required: ["fields"],
|
|
34
37
|
},
|
|
35
38
|
},
|
|
36
|
-
type:
|
|
39
|
+
type: AutomationStepType.TRIGGER,
|
|
37
40
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
cron: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.CRON,
|
|
20
23
|
title: "Expression",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,12 +28,12 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
timestamp: {
|
|
28
|
-
type:
|
|
31
|
+
type: AutomationIOType.NUMBER,
|
|
29
32
|
description: "Timestamp the cron was executed",
|
|
30
33
|
},
|
|
31
34
|
},
|
|
32
35
|
required: ["timestamp"],
|
|
33
36
|
},
|
|
34
37
|
},
|
|
35
|
-
type:
|
|
38
|
+
type: AutomationStepType.TRIGGER,
|
|
36
39
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The row that was deleted",
|
|
31
34
|
},
|
|
32
35
|
},
|
|
33
36
|
required: ["row"],
|
|
34
37
|
},
|
|
35
38
|
},
|
|
36
|
-
type:
|
|
39
|
+
type: AutomationStepType.TRIGGER,
|
|
37
40
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The new row that was created",
|
|
31
34
|
},
|
|
32
35
|
id: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.STRING,
|
|
34
37
|
description: "Row ID - can be used for updating",
|
|
35
38
|
},
|
|
36
39
|
revision: {
|
|
37
|
-
type:
|
|
40
|
+
type: AutomationIOType.STRING,
|
|
38
41
|
description: "Revision of row",
|
|
39
42
|
},
|
|
40
43
|
},
|
|
41
44
|
required: ["row", "id"],
|
|
42
45
|
},
|
|
43
46
|
},
|
|
44
|
-
type:
|
|
47
|
+
type: AutomationStepType.TRIGGER,
|
|
45
48
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The row that was updated",
|
|
31
34
|
},
|
|
32
35
|
id: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.STRING,
|
|
34
37
|
description: "Row ID - can be used for updating",
|
|
35
38
|
},
|
|
36
39
|
revision: {
|
|
37
|
-
type:
|
|
40
|
+
type: AutomationIOType.STRING,
|
|
38
41
|
description: "Revision of row",
|
|
39
42
|
},
|
|
40
43
|
},
|
|
41
44
|
required: ["row", "id"],
|
|
42
45
|
},
|
|
43
46
|
},
|
|
44
|
-
type:
|
|
47
|
+
type: AutomationStepType.TRIGGER,
|
|
45
48
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,13 +18,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
schemaUrl: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.WEBHOOK_URL,
|
|
20
23
|
title: "Schema URL",
|
|
21
24
|
},
|
|
22
25
|
triggerUrl: {
|
|
23
|
-
type:
|
|
24
|
-
customType:
|
|
26
|
+
type: AutomationIOType.STRING,
|
|
27
|
+
customType: AutomationCustomIOType.WEBHOOK_URL,
|
|
25
28
|
title: "Trigger URL",
|
|
26
29
|
},
|
|
27
30
|
},
|
|
@@ -30,12 +33,12 @@ export const definition: AutomationTriggerSchema = {
|
|
|
30
33
|
outputs: {
|
|
31
34
|
properties: {
|
|
32
35
|
body: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.OBJECT,
|
|
34
37
|
description: "Body of the request which hit the webhook",
|
|
35
38
|
},
|
|
36
39
|
},
|
|
37
40
|
required: ["body"],
|
|
38
41
|
},
|
|
39
42
|
},
|
|
40
|
-
type:
|
|
43
|
+
type: AutomationStepType.TRIGGER,
|
|
41
44
|
}
|
package/src/db/utils.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const isProdAppID = dbCore.isProdAppID
|
|
|
27
27
|
export const USER_METDATA_PREFIX = `${DocumentType.ROW}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`
|
|
28
28
|
export const LINK_USER_METADATA_PREFIX = `${DocumentType.LINK}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`
|
|
29
29
|
export const TABLE_ROW_PREFIX = `${DocumentType.ROW}${SEPARATOR}${DocumentType.TABLE}`
|
|
30
|
+
export const AUTOMATION_LOG_PREFIX = `${DocumentType.AUTOMATION_LOG}${SEPARATOR}`
|
|
30
31
|
export const ViewName = dbCore.ViewName
|
|
31
32
|
export const InternalTables = dbCore.InternalTable
|
|
32
33
|
export const UNICODE_MAX = dbCore.UNICODE_MAX
|
|
@@ -349,7 +349,7 @@ describe("row api - postgres", () => {
|
|
|
349
349
|
},
|
|
350
350
|
plus: true,
|
|
351
351
|
source: "POSTGRES",
|
|
352
|
-
type: "
|
|
352
|
+
type: "datasource_plus",
|
|
353
353
|
_id: expect.any(String),
|
|
354
354
|
_rev: expect.any(String),
|
|
355
355
|
createdAt: expect.any(String),
|
|
@@ -921,6 +921,7 @@ describe("row api - postgres", () => {
|
|
|
921
921
|
[m2mFieldName]: [
|
|
922
922
|
{
|
|
923
923
|
_id: row._id,
|
|
924
|
+
primaryDisplay: "Invalid display column",
|
|
924
925
|
},
|
|
925
926
|
],
|
|
926
927
|
})
|
|
@@ -929,6 +930,7 @@ describe("row api - postgres", () => {
|
|
|
929
930
|
[m2mFieldName]: [
|
|
930
931
|
{
|
|
931
932
|
_id: row._id,
|
|
933
|
+
primaryDisplay: "Invalid display column",
|
|
932
934
|
},
|
|
933
935
|
],
|
|
934
936
|
})
|
|
@@ -79,10 +79,17 @@ function generateSchema(
|
|
|
79
79
|
if (!relatedTable) {
|
|
80
80
|
throw "Referenced table doesn't exist"
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
const relatedPrimary = relatedTable.primary[0]
|
|
83
|
+
const externalType = relatedTable.schema[relatedPrimary].externalType
|
|
84
|
+
if (externalType) {
|
|
85
|
+
schema.specificType(column.foreignKey, externalType)
|
|
86
|
+
} else {
|
|
87
|
+
schema.integer(column.foreignKey).unsigned()
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
schema
|
|
84
91
|
.foreign(column.foreignKey)
|
|
85
|
-
.references(`${tableName}.${
|
|
92
|
+
.references(`${tableName}.${relatedPrimary}`)
|
|
86
93
|
}
|
|
87
94
|
break
|
|
88
95
|
}
|
|
@@ -14,11 +14,11 @@ import firebase from "./firebase"
|
|
|
14
14
|
import redis from "./redis"
|
|
15
15
|
import snowflake from "./snowflake"
|
|
16
16
|
import oracle from "./oracle"
|
|
17
|
-
import { getPlugins } from "../api/controllers/plugin"
|
|
18
17
|
import { SourceName, Integration, PluginType } from "@budibase/types"
|
|
19
18
|
import { getDatasourcePlugin } from "../utilities/fileSystem"
|
|
20
19
|
import env from "../environment"
|
|
21
20
|
import { cloneDeep } from "lodash"
|
|
21
|
+
import sdk from "../sdk"
|
|
22
22
|
|
|
23
23
|
const DEFINITIONS: { [key: string]: Integration } = {
|
|
24
24
|
[SourceName.POSTGRES]: postgres.schema,
|
|
@@ -79,7 +79,7 @@ export async function getDefinition(source: SourceName): Promise<Integration> {
|
|
|
79
79
|
export async function getDefinitions() {
|
|
80
80
|
const pluginSchemas: { [key: string]: Integration } = {}
|
|
81
81
|
if (env.SELF_HOSTED) {
|
|
82
|
-
const plugins = await
|
|
82
|
+
const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)
|
|
83
83
|
// extract the actual schema from each custom
|
|
84
84
|
for (let plugin of plugins) {
|
|
85
85
|
const sourceId = plugin.name
|
|
@@ -103,7 +103,7 @@ export async function getIntegration(integration: string) {
|
|
|
103
103
|
return INTEGRATIONS[integration]
|
|
104
104
|
}
|
|
105
105
|
if (env.SELF_HOSTED) {
|
|
106
|
-
const plugins = await
|
|
106
|
+
const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)
|
|
107
107
|
for (let plugin of plugins) {
|
|
108
108
|
if (plugin.name === integration) {
|
|
109
109
|
// need to use commonJS require due to its dynamic runtime nature
|
|
@@ -2,6 +2,7 @@ import { runQuotaMigration } from "./usageQuotas"
|
|
|
2
2
|
import * as syncApps from "./usageQuotas/syncApps"
|
|
3
3
|
import * as syncRows from "./usageQuotas/syncRows"
|
|
4
4
|
import * as syncPlugins from "./usageQuotas/syncPlugins"
|
|
5
|
+
import * as syncUsers from "./usageQuotas/syncUsers"
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Synchronise quotas to the state of the db.
|
|
@@ -11,5 +12,6 @@ export const run = async () => {
|
|
|
11
12
|
await syncApps.run()
|
|
12
13
|
await syncRows.run()
|
|
13
14
|
await syncPlugins.run()
|
|
15
|
+
await syncUsers.run()
|
|
14
16
|
})
|
|
15
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { db as dbCore } from "@budibase/backend-core"
|
|
2
2
|
import { quotas } from "@budibase/pro"
|
|
3
3
|
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
|
4
4
|
|
|
@@ -8,7 +8,6 @@ export const run = async () => {
|
|
|
8
8
|
const appCount = devApps ? devApps.length : 0
|
|
9
9
|
|
|
10
10
|
// sync app count
|
|
11
|
-
const tenantId = tenancy.getTenantId()
|
|
12
11
|
console.log(`Syncing app count: ${appCount}`)
|
|
13
12
|
await quotas.setUsage(appCount, StaticQuotaName.APPS, QuotaUsageType.STATIC)
|
|
14
13
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { users } from "@budibase/backend-core"
|
|
2
|
+
import { quotas } from "@budibase/pro"
|
|
3
|
+
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
|
4
|
+
|
|
5
|
+
export const run = async () => {
|
|
6
|
+
const userCount = await users.getUserCount()
|
|
7
|
+
console.log(`Syncing user count: ${userCount}`)
|
|
8
|
+
await quotas.setUsage(userCount, StaticQuotaName.USERS, QuotaUsageType.STATIC)
|
|
9
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import TestConfig from "../../../../tests/utilities/TestConfiguration"
|
|
2
|
+
import * as syncUsers from "../syncUsers"
|
|
3
|
+
import { quotas } from "@budibase/pro"
|
|
4
|
+
|
|
5
|
+
describe("syncUsers", () => {
|
|
6
|
+
let config = new TestConfig(false)
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await config.init()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
afterAll(config.end)
|
|
13
|
+
|
|
14
|
+
it("syncs users", async () => {
|
|
15
|
+
return config.doInContext(null, async () => {
|
|
16
|
+
await config.createUser()
|
|
17
|
+
|
|
18
|
+
await syncUsers.run()
|
|
19
|
+
|
|
20
|
+
const usageDoc = await quotas.getQuotaUsage()
|
|
21
|
+
// default + additional user
|
|
22
|
+
const userCount = 2
|
|
23
|
+
expect(usageDoc.usageQuota.users).toBe(userCount)
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
})
|
package/src/migrations/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import env from "../environment"
|
|
|
11
11
|
// migration functions
|
|
12
12
|
import * as userEmailViewCasing from "./functions/userEmailViewCasing"
|
|
13
13
|
import * as syncQuotas from "./functions/syncQuotas"
|
|
14
|
+
import * as syncUsers from "./functions/usageQuotas/syncUsers"
|
|
14
15
|
import * as appUrls from "./functions/appUrls"
|
|
15
16
|
import * as tableSettings from "./functions/tableSettings"
|
|
16
17
|
import * as backfill from "./functions/backfill"
|
|
@@ -3,6 +3,7 @@ import { budibaseTempDir } from "../../../utilities/budibaseDir"
|
|
|
3
3
|
import { streamFile, createTempFolder } from "../../../utilities/fileSystem"
|
|
4
4
|
import { ObjectStoreBuckets } from "../../../constants"
|
|
5
5
|
import {
|
|
6
|
+
AUTOMATION_LOG_PREFIX,
|
|
6
7
|
LINK_USER_METADATA_PREFIX,
|
|
7
8
|
TABLE_ROW_PREFIX,
|
|
8
9
|
USER_METDATA_PREFIX,
|
|
@@ -20,11 +21,15 @@ const uuid = require("uuid/v4")
|
|
|
20
21
|
const tar = require("tar")
|
|
21
22
|
const MemoryStream = require("memorystream")
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
interface DBDumpOpts {
|
|
24
25
|
filter?: any
|
|
25
26
|
exportPath?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ExportOpts extends DBDumpOpts {
|
|
26
30
|
tar?: boolean
|
|
27
31
|
excludeRows?: boolean
|
|
32
|
+
excludeLogs?: boolean
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
function tarFilesToTmp(tmpDir: string, files: string[]) {
|
|
@@ -49,7 +54,7 @@ function tarFilesToTmp(tmpDir: string, files: string[]) {
|
|
|
49
54
|
* a filter function or the name of the export.
|
|
50
55
|
* @return {*} either a readable stream or a string
|
|
51
56
|
*/
|
|
52
|
-
export async function exportDB(dbName: string, opts:
|
|
57
|
+
export async function exportDB(dbName: string, opts: DBDumpOpts = {}) {
|
|
53
58
|
const exportOpts = {
|
|
54
59
|
filter: opts?.filter,
|
|
55
60
|
batch_size: 1000,
|
|
@@ -76,11 +81,14 @@ export async function exportDB(dbName: string, opts: ExportOpts = {}) {
|
|
|
76
81
|
})
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
function defineFilter(excludeRows?: boolean) {
|
|
84
|
+
function defineFilter(excludeRows?: boolean, excludeLogs?: boolean) {
|
|
80
85
|
const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX]
|
|
81
86
|
if (excludeRows) {
|
|
82
87
|
ids.push(TABLE_ROW_PREFIX)
|
|
83
88
|
}
|
|
89
|
+
if (excludeLogs) {
|
|
90
|
+
ids.push(AUTOMATION_LOG_PREFIX)
|
|
91
|
+
}
|
|
84
92
|
return (doc: any) =>
|
|
85
93
|
!ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr)
|
|
86
94
|
}
|
|
@@ -130,8 +138,7 @@ export async function exportApp(appId: string, config?: ExportOpts) {
|
|
|
130
138
|
// enforce an export of app DB to the tmp path
|
|
131
139
|
const dbPath = join(tmpPath, DB_EXPORT_FILE)
|
|
132
140
|
await exportDB(appId, {
|
|
133
|
-
|
|
134
|
-
filter: defineFilter(config?.excludeRows),
|
|
141
|
+
filter: defineFilter(config?.excludeRows, config?.excludeLogs),
|
|
135
142
|
exportPath: dbPath,
|
|
136
143
|
})
|
|
137
144
|
// if tar requested, return where the tarball is
|
|
@@ -148,41 +155,6 @@ export async function exportApp(appId: string, config?: ExportOpts) {
|
|
|
148
155
|
}
|
|
149
156
|
}
|
|
150
157
|
|
|
151
|
-
/**
|
|
152
|
-
* Export all apps + global DB (if supplied) to a single tarball, this includes
|
|
153
|
-
* the attachments for each app as well.
|
|
154
|
-
* @param {object[]} appMetadata The IDs and names of apps to export.
|
|
155
|
-
* @param {string} globalDbContents The contents of the global DB to export as well.
|
|
156
|
-
* @return {string} The path to the tarball.
|
|
157
|
-
*/
|
|
158
|
-
export async function exportMultipleApps(
|
|
159
|
-
appMetadata: { appId: string; name: string }[],
|
|
160
|
-
globalDbContents?: string
|
|
161
|
-
) {
|
|
162
|
-
const tmpPath = join(budibaseTempDir(), uuid())
|
|
163
|
-
fs.mkdirSync(tmpPath)
|
|
164
|
-
let exportPromises: Promise<void>[] = []
|
|
165
|
-
// export each app to a directory, then move it into the complete export
|
|
166
|
-
const exportAndMove = async (appId: string, appName: string) => {
|
|
167
|
-
const path = await exportApp(appId)
|
|
168
|
-
await fs.promises.rename(path, join(tmpPath, appName))
|
|
169
|
-
}
|
|
170
|
-
for (let metadata of appMetadata) {
|
|
171
|
-
exportPromises.push(exportAndMove(metadata.appId, metadata.name))
|
|
172
|
-
}
|
|
173
|
-
// wait for all exports to finish
|
|
174
|
-
await Promise.all(exportPromises)
|
|
175
|
-
// add the global DB contents
|
|
176
|
-
if (globalDbContents) {
|
|
177
|
-
fs.writeFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), globalDbContents)
|
|
178
|
-
}
|
|
179
|
-
const appNames = appMetadata.map(metadata => metadata.name)
|
|
180
|
-
const tarPath = tarFilesToTmp(tmpPath, [...appNames, GLOBAL_DB_EXPORT_FILE])
|
|
181
|
-
// clear up the tmp path now tarball generated
|
|
182
|
-
fs.rmSync(tmpPath, { recursive: true, force: true })
|
|
183
|
-
return tarPath
|
|
184
|
-
}
|
|
185
|
-
|
|
186
158
|
/**
|
|
187
159
|
* Streams a backup of the database state for an app
|
|
188
160
|
* @param {string} appId The ID of the app which is to be backed up.
|
|
@@ -190,6 +162,10 @@ export async function exportMultipleApps(
|
|
|
190
162
|
* @returns {*} a readable stream of the backup which is written in real time
|
|
191
163
|
*/
|
|
192
164
|
export async function streamExportApp(appId: string, excludeRows: boolean) {
|
|
193
|
-
const tmpPath = await exportApp(appId, {
|
|
165
|
+
const tmpPath = await exportApp(appId, {
|
|
166
|
+
excludeRows,
|
|
167
|
+
excludeLogs: true,
|
|
168
|
+
tar: true,
|
|
169
|
+
})
|
|
194
170
|
return streamFile(tmpPath)
|
|
195
171
|
}
|
package/src/sdk/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { default as datasources } from "./app/datasources"
|
|
|
6
6
|
import { default as queries } from "./app/queries"
|
|
7
7
|
import { default as rows } from "./app/rows"
|
|
8
8
|
import { default as users } from "./users"
|
|
9
|
+
import { default as plugins } from "./plugins"
|
|
9
10
|
|
|
10
11
|
const sdk = {
|
|
11
12
|
backups,
|
|
@@ -16,6 +17,7 @@ const sdk = {
|
|
|
16
17
|
users,
|
|
17
18
|
datasources,
|
|
18
19
|
queries,
|
|
20
|
+
plugins,
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
// default export for TS
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FileType, Plugin, PluginSource, PluginType } from "@budibase/types"
|
|
2
|
+
import {
|
|
3
|
+
db as dbCore,
|
|
4
|
+
objectStore,
|
|
5
|
+
plugins as pluginCore,
|
|
6
|
+
tenancy,
|
|
7
|
+
} from "@budibase/backend-core"
|
|
8
|
+
import { fileUpload } from "../../api/controllers/plugin/file"
|
|
9
|
+
import env from "../../environment"
|
|
10
|
+
import { clientAppSocket } from "../../websockets"
|
|
11
|
+
import { sdk as pro } from "@budibase/pro"
|
|
12
|
+
|
|
13
|
+
export async function fetch(type?: PluginType) {
|
|
14
|
+
const db = tenancy.getGlobalDB()
|
|
15
|
+
const response = await db.allDocs(
|
|
16
|
+
dbCore.getPluginParams(null, {
|
|
17
|
+
include_docs: true,
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
let plugins = response.rows.map((row: any) => row.doc) as Plugin[]
|
|
21
|
+
plugins = objectStore.enrichPluginURLs(plugins)
|
|
22
|
+
if (type) {
|
|
23
|
+
return plugins.filter((plugin: Plugin) => plugin.schema?.type === type)
|
|
24
|
+
} else {
|
|
25
|
+
return plugins
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function processUploaded(plugin: FileType, source?: PluginSource) {
|
|
30
|
+
const { metadata, directory } = await fileUpload(plugin)
|
|
31
|
+
pluginCore.validate(metadata?.schema)
|
|
32
|
+
|
|
33
|
+
// Only allow components in cloud
|
|
34
|
+
if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {
|
|
35
|
+
throw new Error("Only component plugins are supported outside of self-host")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
|
39
|
+
clientAppSocket.emit("plugin-update", { name: doc.name, hash: doc.hash })
|
|
40
|
+
return doc
|
|
41
|
+
}
|