@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.
Files changed (130) hide show
  1. package/builder/assets/{index.58b41739.js → index.05e726d8.js} +384 -366
  2. package/builder/assets/index.4eae16b2.css +6 -0
  3. package/builder/index.html +2 -2
  4. package/dist/api/controllers/application.js +3 -4
  5. package/dist/api/controllers/automation.js +13 -7
  6. package/dist/api/controllers/datasource.js +1 -1
  7. package/dist/api/controllers/dev.js +1 -1
  8. package/dist/api/controllers/plugin/index.js +6 -37
  9. package/dist/api/controllers/query/index.js +2 -2
  10. package/dist/api/controllers/row/ExternalRequest.js +21 -14
  11. package/dist/api/controllers/table/utils.js +9 -3
  12. package/dist/api/index.js +1 -2
  13. package/dist/api/routes/index.js +0 -2
  14. package/dist/app.js +2 -2
  15. package/dist/automations/actions.js +32 -6
  16. package/dist/automations/index.js +3 -2
  17. package/dist/automations/steps/bash.js +6 -6
  18. package/dist/automations/steps/createRow.js +11 -11
  19. package/dist/automations/steps/delay.js +3 -3
  20. package/dist/automations/steps/deleteRow.js +8 -8
  21. package/dist/automations/steps/discord.js +8 -8
  22. package/dist/automations/steps/executeQuery.js +9 -9
  23. package/dist/automations/steps/executeScript.js +6 -6
  24. package/dist/automations/steps/filter.js +6 -6
  25. package/dist/automations/steps/integromat.js +10 -10
  26. package/dist/automations/steps/loop.js +9 -9
  27. package/dist/automations/steps/outgoingWebhook.js +10 -10
  28. package/dist/automations/steps/queryRows.js +14 -14
  29. package/dist/automations/steps/sendSmtpEmail.js +9 -9
  30. package/dist/automations/steps/serverLog.js +4 -4
  31. package/dist/automations/steps/slack.js +6 -6
  32. package/dist/automations/steps/updateRow.js +11 -11
  33. package/dist/automations/steps/zapier.js +9 -9
  34. package/dist/automations/triggerInfo/app.js +5 -5
  35. package/dist/automations/triggerInfo/cron.js +4 -4
  36. package/dist/automations/triggerInfo/rowDeleted.js +5 -5
  37. package/dist/automations/triggerInfo/rowSaved.js +7 -7
  38. package/dist/automations/triggerInfo/rowUpdated.js +7 -7
  39. package/dist/automations/triggerInfo/webhook.js +6 -6
  40. package/dist/db/utils.js +3 -2
  41. package/dist/integrations/base/sqlTable.js +9 -2
  42. package/dist/integrations/index.js +3 -3
  43. package/dist/migrations/functions/syncQuotas.js +2 -0
  44. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -1
  45. package/dist/migrations/functions/usageQuotas/syncUsers.js +21 -0
  46. package/dist/sdk/app/backups/exports.js +14 -38
  47. package/dist/sdk/index.js +2 -0
  48. package/dist/{api/routes/cloud.js → sdk/plugins/index.js} +2 -14
  49. package/dist/sdk/plugins/plugins.js +53 -0
  50. package/dist/threads/automation.js +2 -2
  51. package/dist/tsconfig.build.tsbuildinfo +1 -1
  52. package/dist/utilities/fileSystem/plugin.js +33 -23
  53. package/dist/utilities/rowProcessor/utils.js +4 -5
  54. package/dist/watch.js +2 -2
  55. package/dist/websockets/client.js +14 -0
  56. package/dist/websockets/grid.js +60 -0
  57. package/dist/websockets/index.js +17 -0
  58. package/dist/websockets/websocket.js +78 -0
  59. package/package.json +11 -10
  60. package/src/api/controllers/application.ts +4 -4
  61. package/src/api/controllers/automation.ts +12 -6
  62. package/src/api/controllers/datasource.ts +15 -5
  63. package/src/api/controllers/dev.ts +2 -2
  64. package/src/api/controllers/plugin/index.ts +8 -45
  65. package/src/api/controllers/query/index.ts +2 -2
  66. package/src/api/controllers/row/ExternalRequest.ts +21 -12
  67. package/src/api/controllers/table/utils.ts +10 -3
  68. package/src/api/index.ts +2 -4
  69. package/src/api/routes/index.ts +0 -2
  70. package/src/api/routes/tests/automation.spec.js +2 -2
  71. package/src/app.ts +2 -2
  72. package/src/automations/actions.ts +56 -24
  73. package/src/automations/index.ts +1 -1
  74. package/src/automations/steps/bash.ts +10 -7
  75. package/src/automations/steps/createRow.ts +15 -12
  76. package/src/automations/steps/delay.ts +6 -4
  77. package/src/automations/steps/deleteRow.ts +12 -9
  78. package/src/automations/steps/discord.ts +10 -8
  79. package/src/automations/steps/executeQuery.ts +13 -10
  80. package/src/automations/steps/executeScript.ts +10 -7
  81. package/src/automations/steps/filter.ts +8 -6
  82. package/src/automations/steps/integromat.ts +12 -10
  83. package/src/automations/steps/loop.ts +16 -10
  84. package/src/automations/steps/outgoingWebhook.ts +14 -11
  85. package/src/automations/steps/queryRows.ts +18 -15
  86. package/src/automations/steps/sendSmtpEmail.ts +11 -9
  87. package/src/automations/steps/serverLog.ts +6 -4
  88. package/src/automations/steps/slack.ts +8 -6
  89. package/src/automations/steps/updateRow.ts +15 -12
  90. package/src/automations/steps/zapier.ts +11 -9
  91. package/src/automations/tests/utilities/index.ts +2 -2
  92. package/src/automations/triggerInfo/app.ts +8 -5
  93. package/src/automations/triggerInfo/cron.ts +7 -4
  94. package/src/automations/triggerInfo/rowDeleted.ts +8 -5
  95. package/src/automations/triggerInfo/rowSaved.ts +10 -7
  96. package/src/automations/triggerInfo/rowUpdated.ts +10 -7
  97. package/src/automations/triggerInfo/webhook.ts +9 -6
  98. package/src/db/utils.ts +1 -0
  99. package/src/integration-test/postgres.spec.ts +3 -1
  100. package/src/integrations/base/sqlTable.ts +9 -2
  101. package/src/integrations/index.ts +3 -3
  102. package/src/migrations/functions/syncQuotas.ts +2 -0
  103. package/src/migrations/functions/usageQuotas/syncApps.ts +1 -2
  104. package/src/migrations/functions/usageQuotas/syncUsers.ts +9 -0
  105. package/src/migrations/functions/usageQuotas/tests/syncUsers.spec.ts +26 -0
  106. package/src/migrations/index.ts +1 -0
  107. package/src/sdk/app/backups/exports.ts +17 -41
  108. package/src/sdk/index.ts +2 -0
  109. package/src/sdk/plugins/index.ts +5 -0
  110. package/src/sdk/plugins/plugins.ts +41 -0
  111. package/src/tests/utilities/structures.ts +25 -17
  112. package/src/threads/automation.ts +2 -2
  113. package/src/utilities/fileSystem/plugin.ts +13 -4
  114. package/src/utilities/rowProcessor/utils.ts +9 -10
  115. package/src/watch.ts +2 -2
  116. package/src/websockets/client.ts +11 -0
  117. package/src/websockets/grid.ts +55 -0
  118. package/src/websockets/index.ts +14 -0
  119. package/src/websockets/websocket.ts +83 -0
  120. package/tsconfig.build.json +3 -5
  121. package/tsconfig.json +2 -1
  122. package/builder/assets/index.841e62d8.css +0 -6
  123. package/dist/api/controllers/cloud.js +0 -130
  124. package/dist/package.json +0 -179
  125. package/dist/websocket.js +0 -22
  126. package/src/api/controllers/cloud.ts +0 -119
  127. package/src/api/routes/cloud.ts +0 -18
  128. package/src/api/routes/tests/cloud.spec.ts +0 -54
  129. package/src/migrations/functions/tests/syncQuotas.spec.js +0 -26
  130. package/src/websocket.ts +0 -26
@@ -1,18 +1,22 @@
1
- import { permissions, roles } from "@budibase/backend-core"
1
+ import { permissions, roles, utils } from "@budibase/backend-core"
2
2
  import { createHomeScreen } from "../../constants/screens"
3
3
  import { EMPTY_LAYOUT } from "../../constants/layouts"
4
4
  import { cloneDeep } from "lodash/fp"
5
- import { ACTION_DEFINITIONS, TRIGGER_DEFINITIONS } from "../../automations"
5
+ import {
6
+ BUILTIN_ACTION_DEFINITIONS,
7
+ TRIGGER_DEFINITIONS,
8
+ } from "../../automations"
6
9
  import {
7
10
  Automation,
8
11
  AutomationActionStepId,
12
+ AutomationStep,
13
+ AutomationStepType,
14
+ AutomationTrigger,
9
15
  AutomationTriggerStepId,
10
16
  Datasource,
11
17
  SourceName,
12
18
  } from "@budibase/types"
13
19
 
14
- const { v4: uuidv4 } = require("uuid")
15
-
16
20
  export function basicTable() {
17
21
  return {
18
22
  name: "TestTable",
@@ -71,19 +75,19 @@ export function view(tableId: string) {
71
75
  }
72
76
 
73
77
  export function automationStep(
74
- actionDefinition = ACTION_DEFINITIONS.CREATE_ROW
75
- ) {
78
+ actionDefinition = BUILTIN_ACTION_DEFINITIONS.CREATE_ROW
79
+ ): AutomationStep {
76
80
  return {
77
- id: uuidv4(),
81
+ id: utils.newid(),
78
82
  ...actionDefinition,
79
83
  }
80
84
  }
81
85
 
82
86
  export function automationTrigger(
83
87
  triggerDefinition = TRIGGER_DEFINITIONS.ROW_SAVED
84
- ) {
88
+ ): AutomationTrigger {
85
89
  return {
86
- id: uuidv4(),
90
+ id: utils.newid(),
87
91
  ...triggerDefinition,
88
92
  }
89
93
  }
@@ -106,7 +110,7 @@ export function newAutomation({ steps, trigger }: any = {}) {
106
110
  return automation
107
111
  }
108
112
 
109
- export function basicAutomation(appId?: string) {
113
+ export function basicAutomation(appId?: string): Automation {
110
114
  return {
111
115
  name: "My Automation",
112
116
  screenId: "kasdkfldsafkl",
@@ -119,18 +123,22 @@ export function basicAutomation(appId?: string) {
119
123
  tagline: "test",
120
124
  icon: "test",
121
125
  description: "test",
122
- type: "trigger",
126
+ type: AutomationStepType.TRIGGER,
123
127
  id: "test",
124
128
  inputs: {},
125
129
  schema: {
126
- inputs: {},
127
- outputs: {},
130
+ inputs: {
131
+ properties: {},
132
+ },
133
+ outputs: {
134
+ properties: {},
135
+ },
128
136
  },
129
137
  },
130
138
  steps: [],
131
139
  },
132
140
  type: "automation",
133
- appId,
141
+ appId: appId!,
134
142
  }
135
143
  }
136
144
 
@@ -154,7 +162,7 @@ export function loopAutomation(tableId: string, loopOpts?: any): Automation {
154
162
  inputs: {
155
163
  tableId,
156
164
  },
157
- schema: ACTION_DEFINITIONS.QUERY_ROWS.schema,
165
+ schema: BUILTIN_ACTION_DEFINITIONS.QUERY_ROWS.schema,
158
166
  },
159
167
  {
160
168
  id: "c",
@@ -163,7 +171,7 @@ export function loopAutomation(tableId: string, loopOpts?: any): Automation {
163
171
  internal: true,
164
172
  inputs: loopOpts,
165
173
  blockToLoop: "d",
166
- schema: ACTION_DEFINITIONS.LOOP.schema,
174
+ schema: BUILTIN_ACTION_DEFINITIONS.LOOP.schema,
167
175
  },
168
176
  {
169
177
  id: "d",
@@ -173,7 +181,7 @@ export function loopAutomation(tableId: string, loopOpts?: any): Automation {
173
181
  inputs: {
174
182
  text: "log statement",
175
183
  },
176
- schema: ACTION_DEFINITIONS.SERVER_LOG.schema,
184
+ schema: BUILTIN_ACTION_DEFINITIONS.SERVER_LOG.schema,
177
185
  },
178
186
  ],
179
187
  trigger: {
@@ -27,8 +27,8 @@ import { processObject } from "@budibase/string-templates"
27
27
  import { cloneDeep } from "lodash/fp"
28
28
  import * as sdkUtils from "../sdk/utils"
29
29
  import env from "../environment"
30
- const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
31
- const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
30
+ const FILTER_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.FILTER.stepId
31
+ const LOOP_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.LOOP.stepId
32
32
  const CRON_STEP_ID = triggerDefs.CRON.stepId
33
33
  const STOPPED_STATUS = { success: true, status: AutomationStatus.STOPPED }
34
34
 
@@ -5,6 +5,7 @@ import { join } from "path"
5
5
  import { objectStore } from "@budibase/backend-core"
6
6
 
7
7
  const DATASOURCE_PATH = join(budibaseTempDir(), "datasource")
8
+ const AUTOMATION_PATH = join(budibaseTempDir(), "automation")
8
9
 
9
10
  export const getPluginMetadata = async (path: string) => {
10
11
  let metadata: any = {}
@@ -33,12 +34,12 @@ export const getPluginMetadata = async (path: string) => {
33
34
  return { metadata, directory: path }
34
35
  }
35
36
 
36
- export const getDatasourcePlugin = async (plugin: Plugin) => {
37
+ async function getPluginImpl(path: string, plugin: Plugin) {
37
38
  const hash = plugin.schema?.hash
38
- if (!fs.existsSync(DATASOURCE_PATH)) {
39
- fs.mkdirSync(DATASOURCE_PATH)
39
+ if (!fs.existsSync(path)) {
40
+ fs.mkdirSync(path)
40
41
  }
41
- const filename = join(DATASOURCE_PATH, plugin.name)
42
+ const filename = join(path, plugin.name)
42
43
  const metadataName = `${filename}.bbmetadata`
43
44
  if (fs.existsSync(filename)) {
44
45
  const currentHash = fs.readFileSync(metadataName, "utf8")
@@ -62,3 +63,11 @@ export const getDatasourcePlugin = async (plugin: Plugin) => {
62
63
 
63
64
  return require(filename)
64
65
  }
66
+
67
+ export const getDatasourcePlugin = async (plugin: Plugin) => {
68
+ return getPluginImpl(DATASOURCE_PATH, plugin)
69
+ }
70
+
71
+ export const getAutomationPlugin = async (plugin: Plugin) => {
72
+ return getPluginImpl(AUTOMATION_PATH, plugin)
73
+ }
@@ -1,11 +1,11 @@
1
1
  import {
2
- FieldTypes,
3
- FormulaTypes,
4
2
  AutoFieldDefaultNames,
5
3
  AutoFieldSubTypes,
4
+ FieldTypes,
5
+ FormulaTypes,
6
6
  } from "../../constants"
7
7
  import { processStringSync } from "@budibase/string-templates"
8
- import { FieldSchema, Table, Row } from "@budibase/types"
8
+ import { FieldSchema, FieldType, Row, Table } from "@budibase/types"
9
9
 
10
10
  /**
11
11
  * If the subtype has been lost for any reason this works out what
@@ -50,6 +50,7 @@ export function processFormulas(
50
50
  const isStatic = schema.formulaType === FormulaTypes.STATIC
51
51
  if (
52
52
  schema.type !== FieldTypes.FORMULA ||
53
+ schema.formula == null ||
53
54
  (dynamic && isStatic) ||
54
55
  (!dynamic && !isStatic)
55
56
  ) {
@@ -57,13 +58,11 @@ export function processFormulas(
57
58
  }
58
59
  // iterate through rows and process formula
59
60
  for (let i = 0; i < rowArray.length; i++) {
60
- if (schema.formula) {
61
- let row = rowArray[i]
62
- let context = contextRows ? contextRows[i] : row
63
- rowArray[i] = {
64
- ...row,
65
- [column]: processStringSync(schema.formula, context),
66
- }
61
+ let row = rowArray[i]
62
+ let context = contextRows ? contextRows[i] : row
63
+ rowArray[i] = {
64
+ ...row,
65
+ [column]: processStringSync(schema.formula, context),
67
66
  }
68
67
  }
69
68
  }
package/src/watch.ts CHANGED
@@ -3,7 +3,7 @@ import env from "./environment"
3
3
  import chokidar from "chokidar"
4
4
  import fs from "fs"
5
5
  import { constants, tenancy } from "@budibase/backend-core"
6
- import { processUploadedPlugin } from "./api/controllers/plugin"
6
+ import pluginsSdk from "./sdk/plugins"
7
7
 
8
8
  export function watch() {
9
9
  const watchPath = path.join(env.PLUGINS_DIR, "./**/*.tar.gz")
@@ -27,7 +27,7 @@ export function watch() {
27
27
  const split = path.split("/")
28
28
  const name = split[split.length - 1]
29
29
  console.log("Importing plugin:", path)
30
- await processUploadedPlugin({ name, path })
30
+ await pluginsSdk.processUploaded({ name, path })
31
31
  } catch (err: any) {
32
32
  const message = err?.message ? err?.message : err
33
33
  console.error("Failed to import plugin:", message)
@@ -0,0 +1,11 @@
1
+ import Socket from "./websocket"
2
+ import authorized from "../middleware/authorized"
3
+ import http from "http"
4
+ import Koa from "koa"
5
+ import { permissions } from "@budibase/backend-core"
6
+
7
+ export default class ClientAppWebsocket extends Socket {
8
+ constructor(app: Koa, server: http.Server) {
9
+ super(app, server, "/socket/client", [authorized(permissions.BUILDER)])
10
+ }
11
+ }
@@ -0,0 +1,55 @@
1
+ import authorized from "../middleware/authorized"
2
+ import Socket from "./websocket"
3
+ import { permissions } from "@budibase/backend-core"
4
+ import http from "http"
5
+ import Koa from "koa"
6
+
7
+ export default class GridSocket extends Socket {
8
+ constructor(app: Koa, server: http.Server) {
9
+ super(app, server, "/socket/grid", [authorized(permissions.BUILDER)])
10
+
11
+ this.io.on("connection", socket => {
12
+ const user = socket.data.user
13
+ console.log(`Spreadsheet user connected: ${user?.id}`)
14
+
15
+ // Socket state
16
+ let currentRoom: string
17
+
18
+ // Initial identification of connected spreadsheet
19
+ socket.on("select-table", async (tableId, callback) => {
20
+ // Leave current room
21
+ if (currentRoom) {
22
+ socket.to(currentRoom).emit("user-disconnect", socket.data.user)
23
+ socket.leave(currentRoom)
24
+ }
25
+
26
+ // Join new room
27
+ currentRoom = tableId
28
+ socket.join(currentRoom)
29
+ socket.to(currentRoom).emit("user-update", socket.data.user)
30
+
31
+ // Reply with all users in current room
32
+ const sockets = await this.io.in(currentRoom).fetchSockets()
33
+ callback({
34
+ users: sockets.map(socket => socket.data.user),
35
+ id: user.id,
36
+ })
37
+ })
38
+
39
+ // Handle users selecting a new cell
40
+ socket.on("select-cell", cellId => {
41
+ socket.data.user.selectedCellId = cellId
42
+ if (currentRoom) {
43
+ socket.to(currentRoom).emit("user-update", socket.data.user)
44
+ }
45
+ })
46
+
47
+ // Disconnection cleanup
48
+ socket.on("disconnect", () => {
49
+ if (currentRoom) {
50
+ socket.to(currentRoom).emit("user-disconnect", socket.data.user)
51
+ }
52
+ })
53
+ })
54
+ }
55
+ }
@@ -0,0 +1,14 @@
1
+ import http from "http"
2
+ import Koa from "koa"
3
+ import GridSocket from "./grid"
4
+ import ClientAppSocket from "./client"
5
+
6
+ let clientAppSocket: ClientAppSocket
7
+ let gridSocket: GridSocket
8
+
9
+ export const initialise = (app: Koa, server: http.Server) => {
10
+ clientAppSocket = new ClientAppSocket(app, server)
11
+ gridSocket = new GridSocket(app, server)
12
+ }
13
+
14
+ export { clientAppSocket, gridSocket }
@@ -0,0 +1,83 @@
1
+ import { Server } from "socket.io"
2
+ import http from "http"
3
+ import Koa from "koa"
4
+ import Cookies from "cookies"
5
+ import { userAgent } from "koa-useragent"
6
+ import { auth } from "@budibase/backend-core"
7
+ import currentApp from "../middleware/currentapp"
8
+
9
+ export default class Socket {
10
+ io: Server
11
+
12
+ constructor(
13
+ app: Koa,
14
+ server: http.Server,
15
+ path: string,
16
+ additionalMiddlewares?: any[]
17
+ ) {
18
+ this.io = new Server(server, {
19
+ path,
20
+ })
21
+
22
+ // Attach default middlewares
23
+ const authenticate = auth.buildAuthMiddleware([], {
24
+ publicAllowed: true,
25
+ })
26
+ const middlewares = [
27
+ userAgent,
28
+ authenticate,
29
+ currentApp,
30
+ ...(additionalMiddlewares || []),
31
+ ]
32
+
33
+ // Apply middlewares
34
+ this.io.use(async (socket, next) => {
35
+ // Build fake koa context
36
+ const res = new http.ServerResponse(socket.request)
37
+ const ctx: any = {
38
+ ...app.createContext(socket.request, res),
39
+
40
+ // Additional overrides needed to make our middlewares work with this
41
+ // fake koa context
42
+ cookies: new Cookies(socket.request, res),
43
+ get: (field: string) => socket.request.headers[field],
44
+ throw: (code: number, message: string) => {
45
+ throw new Error(message)
46
+ },
47
+
48
+ // Needed for koa-useragent middleware
49
+ headers: socket.request.headers,
50
+ header: socket.request.headers,
51
+
52
+ // We don't really care about the path since it will never contain
53
+ // an app ID
54
+ path: "/socket",
55
+ }
56
+
57
+ // Run all koa middlewares
58
+ try {
59
+ for (let [idx, middleware] of middlewares.entries()) {
60
+ await middleware(ctx, () => {
61
+ if (idx === middlewares.length - 1) {
62
+ // Middlewares are finished.
63
+ // Extract some data from our enriched koa context to persist
64
+ // as metadata for the socket
65
+ socket.data.user = {
66
+ id: ctx.user._id,
67
+ email: ctx.user.email,
68
+ }
69
+ next()
70
+ }
71
+ })
72
+ }
73
+ } catch (error: any) {
74
+ next(error)
75
+ }
76
+ })
77
+ }
78
+
79
+ // Emit an event to all sockets
80
+ emit(event: string, payload: any) {
81
+ this.io.sockets.emit(event, payload)
82
+ }
83
+ }
@@ -8,13 +8,11 @@
8
8
  "esModuleInterop": true,
9
9
  "resolveJsonModule": true,
10
10
  "incremental": true,
11
- "types": [ "node", "jest" ],
12
- "outDir": "dist",
11
+ "types": ["node", "jest"],
12
+ "outDir": "dist/src",
13
13
  "skipLibCheck": true
14
14
  },
15
- "include": [
16
- "src/**/*"
17
- ],
15
+ "include": ["src/**/*"],
18
16
  "exclude": [
19
17
  "node_modules",
20
18
  "dist",
package/tsconfig.json CHANGED
@@ -5,6 +5,7 @@
5
5
  "declaration": true,
6
6
  "sourceMap": true,
7
7
  "baseUrl": ".",
8
+ "outDir": "dist",
8
9
  "paths": {
9
10
  "@budibase/types": ["../types/src"],
10
11
  "@budibase/backend-core": ["../backend-core/src"],
@@ -23,6 +24,6 @@
23
24
  { "path": "../shared-core" },
24
25
  { "path": "../../../budibase-pro/packages/pro" }
25
26
  ],
26
- "include": ["src/**/*", "specs", "package.json"],
27
+ "include": ["src/**/*", "specs"],
27
28
  "exclude": ["node_modules", "dist"]
28
29
  }