@budibase/server 2.5.6-alpha.3 → 2.5.6-alpha.30

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 (126) hide show
  1. package/builder/assets/index.44a18341.css +6 -0
  2. package/builder/assets/{index.a33a6c3d.js → index.87d46c61.js} +382 -366
  3. package/builder/index.html +2 -2
  4. package/dist/api/controllers/application.js +2 -3
  5. package/dist/api/controllers/automation.js +13 -7
  6. package/dist/api/controllers/dev.js +1 -1
  7. package/dist/api/controllers/plugin/index.js +6 -37
  8. package/dist/api/controllers/query/index.js +2 -2
  9. package/dist/api/controllers/row/ExternalRequest.js +21 -14
  10. package/dist/api/controllers/table/utils.js +9 -3
  11. package/dist/api/index.js +1 -2
  12. package/dist/api/routes/index.js +0 -2
  13. package/dist/app.js +2 -2
  14. package/dist/automations/actions.js +32 -6
  15. package/dist/automations/index.js +3 -2
  16. package/dist/automations/steps/bash.js +6 -6
  17. package/dist/automations/steps/createRow.js +11 -11
  18. package/dist/automations/steps/delay.js +3 -3
  19. package/dist/automations/steps/deleteRow.js +8 -8
  20. package/dist/automations/steps/discord.js +8 -8
  21. package/dist/automations/steps/executeQuery.js +9 -9
  22. package/dist/automations/steps/executeScript.js +6 -6
  23. package/dist/automations/steps/filter.js +6 -6
  24. package/dist/automations/steps/integromat.js +10 -10
  25. package/dist/automations/steps/loop.js +9 -9
  26. package/dist/automations/steps/outgoingWebhook.js +10 -10
  27. package/dist/automations/steps/queryRows.js +14 -14
  28. package/dist/automations/steps/sendSmtpEmail.js +9 -9
  29. package/dist/automations/steps/serverLog.js +4 -4
  30. package/dist/automations/steps/slack.js +6 -6
  31. package/dist/automations/steps/updateRow.js +11 -11
  32. package/dist/automations/steps/zapier.js +9 -9
  33. package/dist/automations/triggerInfo/app.js +5 -5
  34. package/dist/automations/triggerInfo/cron.js +4 -4
  35. package/dist/automations/triggerInfo/rowDeleted.js +5 -5
  36. package/dist/automations/triggerInfo/rowSaved.js +7 -7
  37. package/dist/automations/triggerInfo/rowUpdated.js +7 -7
  38. package/dist/automations/triggerInfo/webhook.js +6 -6
  39. package/dist/integrations/base/sqlTable.js +9 -2
  40. package/dist/integrations/index.js +3 -3
  41. package/dist/migrations/functions/syncQuotas.js +2 -0
  42. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -1
  43. package/dist/migrations/functions/usageQuotas/syncUsers.js +21 -0
  44. package/dist/sdk/app/backups/exports.js +1 -35
  45. package/dist/sdk/index.js +2 -0
  46. package/dist/{api/routes/cloud.js → sdk/plugins/index.js} +2 -14
  47. package/dist/sdk/plugins/plugins.js +53 -0
  48. package/dist/threads/automation.js +2 -2
  49. package/dist/tsconfig.build.tsbuildinfo +1 -1
  50. package/dist/utilities/fileSystem/plugin.js +33 -23
  51. package/dist/utilities/rowProcessor/utils.js +4 -5
  52. package/dist/watch.js +2 -2
  53. package/dist/websockets/client.js +14 -0
  54. package/dist/websockets/grid.js +60 -0
  55. package/dist/websockets/index.js +17 -0
  56. package/dist/websockets/websocket.js +78 -0
  57. package/package.json +11 -10
  58. package/src/api/controllers/application.ts +3 -3
  59. package/src/api/controllers/automation.ts +12 -6
  60. package/src/api/controllers/dev.ts +2 -2
  61. package/src/api/controllers/plugin/index.ts +8 -45
  62. package/src/api/controllers/query/index.ts +2 -2
  63. package/src/api/controllers/row/ExternalRequest.ts +21 -12
  64. package/src/api/controllers/table/utils.ts +10 -3
  65. package/src/api/index.ts +2 -4
  66. package/src/api/routes/index.ts +0 -2
  67. package/src/api/routes/tests/automation.spec.js +2 -2
  68. package/src/app.ts +2 -2
  69. package/src/automations/actions.ts +56 -24
  70. package/src/automations/index.ts +1 -1
  71. package/src/automations/steps/bash.ts +10 -7
  72. package/src/automations/steps/createRow.ts +15 -12
  73. package/src/automations/steps/delay.ts +6 -4
  74. package/src/automations/steps/deleteRow.ts +12 -9
  75. package/src/automations/steps/discord.ts +10 -8
  76. package/src/automations/steps/executeQuery.ts +13 -10
  77. package/src/automations/steps/executeScript.ts +10 -7
  78. package/src/automations/steps/filter.ts +8 -6
  79. package/src/automations/steps/integromat.ts +12 -10
  80. package/src/automations/steps/loop.ts +16 -10
  81. package/src/automations/steps/outgoingWebhook.ts +14 -11
  82. package/src/automations/steps/queryRows.ts +18 -15
  83. package/src/automations/steps/sendSmtpEmail.ts +11 -9
  84. package/src/automations/steps/serverLog.ts +6 -4
  85. package/src/automations/steps/slack.ts +8 -6
  86. package/src/automations/steps/updateRow.ts +15 -12
  87. package/src/automations/steps/zapier.ts +11 -9
  88. package/src/automations/tests/utilities/index.ts +2 -2
  89. package/src/automations/triggerInfo/app.ts +8 -5
  90. package/src/automations/triggerInfo/cron.ts +7 -4
  91. package/src/automations/triggerInfo/rowDeleted.ts +8 -5
  92. package/src/automations/triggerInfo/rowSaved.ts +10 -7
  93. package/src/automations/triggerInfo/rowUpdated.ts +10 -7
  94. package/src/automations/triggerInfo/webhook.ts +9 -6
  95. package/src/integration-test/postgres.spec.ts +2 -0
  96. package/src/integrations/base/sqlTable.ts +9 -2
  97. package/src/integrations/index.ts +3 -3
  98. package/src/migrations/functions/syncQuotas.ts +2 -0
  99. package/src/migrations/functions/usageQuotas/syncApps.ts +1 -2
  100. package/src/migrations/functions/usageQuotas/syncUsers.ts +9 -0
  101. package/src/migrations/functions/usageQuotas/tests/syncUsers.spec.ts +26 -0
  102. package/src/migrations/index.ts +1 -0
  103. package/src/sdk/app/backups/exports.ts +0 -35
  104. package/src/sdk/index.ts +2 -0
  105. package/src/sdk/plugins/index.ts +5 -0
  106. package/src/sdk/plugins/plugins.ts +41 -0
  107. package/src/tests/utilities/structures.ts +25 -17
  108. package/src/threads/automation.ts +2 -2
  109. package/src/utilities/fileSystem/plugin.ts +13 -4
  110. package/src/utilities/rowProcessor/utils.ts +9 -10
  111. package/src/watch.ts +2 -2
  112. package/src/websockets/client.ts +11 -0
  113. package/src/websockets/grid.ts +55 -0
  114. package/src/websockets/index.ts +14 -0
  115. package/src/websockets/websocket.ts +83 -0
  116. package/tsconfig.build.json +3 -5
  117. package/tsconfig.json +2 -1
  118. package/builder/assets/index.841e62d8.css +0 -6
  119. package/dist/api/controllers/cloud.js +0 -130
  120. package/dist/package.json +0 -179
  121. package/dist/websocket.js +0 -22
  122. package/src/api/controllers/cloud.ts +0 -119
  123. package/src/api/routes/cloud.ts +0 -18
  124. package/src/api/routes/tests/cloud.spec.ts +0 -54
  125. package/src/migrations/functions/tests/syncQuotas.spec.js +0 -26
  126. package/src/websocket.ts +0 -26
@@ -12,12 +12,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getDatasourcePlugin = exports.getPluginMetadata = void 0;
15
+ exports.getAutomationPlugin = exports.getDatasourcePlugin = exports.getPluginMetadata = void 0;
16
16
  const budibaseDir_1 = require("../budibaseDir");
17
17
  const fs_1 = __importDefault(require("fs"));
18
18
  const path_1 = require("path");
19
19
  const backend_core_1 = require("@budibase/backend-core");
20
20
  const DATASOURCE_PATH = (0, path_1.join)((0, budibaseDir_1.budibaseTempDir)(), "datasource");
21
+ const AUTOMATION_PATH = (0, path_1.join)((0, budibaseDir_1.budibaseTempDir)(), "automation");
21
22
  const getPluginMetadata = (path) => __awaiter(void 0, void 0, void 0, function* () {
22
23
  let metadata = {};
23
24
  try {
@@ -37,30 +38,39 @@ const getPluginMetadata = (path) => __awaiter(void 0, void 0, void 0, function*
37
38
  return { metadata, directory: path };
38
39
  });
39
40
  exports.getPluginMetadata = getPluginMetadata;
40
- const getDatasourcePlugin = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
41
+ function getPluginImpl(path, plugin) {
41
42
  var _a;
42
- const hash = (_a = plugin.schema) === null || _a === void 0 ? void 0 : _a.hash;
43
- if (!fs_1.default.existsSync(DATASOURCE_PATH)) {
44
- fs_1.default.mkdirSync(DATASOURCE_PATH);
45
- }
46
- const filename = (0, path_1.join)(DATASOURCE_PATH, plugin.name);
47
- const metadataName = `${filename}.bbmetadata`;
48
- if (fs_1.default.existsSync(filename)) {
49
- const currentHash = fs_1.default.readFileSync(metadataName, "utf8");
50
- // if hash is the same return the file, otherwise remove it and re-download
51
- if (currentHash === hash) {
52
- return require(filename);
43
+ return __awaiter(this, void 0, void 0, function* () {
44
+ const hash = (_a = plugin.schema) === null || _a === void 0 ? void 0 : _a.hash;
45
+ if (!fs_1.default.existsSync(path)) {
46
+ fs_1.default.mkdirSync(path);
53
47
  }
54
- else {
55
- console.log(`Updating plugin: ${plugin.name}`);
56
- delete require.cache[require.resolve(filename)];
57
- fs_1.default.unlinkSync(filename);
48
+ const filename = (0, path_1.join)(path, plugin.name);
49
+ const metadataName = `${filename}.bbmetadata`;
50
+ if (fs_1.default.existsSync(filename)) {
51
+ const currentHash = fs_1.default.readFileSync(metadataName, "utf8");
52
+ // if hash is the same return the file, otherwise remove it and re-download
53
+ if (currentHash === hash) {
54
+ return require(filename);
55
+ }
56
+ else {
57
+ console.log(`Updating plugin: ${plugin.name}`);
58
+ delete require.cache[require.resolve(filename)];
59
+ fs_1.default.unlinkSync(filename);
60
+ }
58
61
  }
59
- }
60
- const pluginKey = backend_core_1.objectStore.getPluginJSKey(plugin);
61
- const pluginJs = yield backend_core_1.objectStore.retrieve(backend_core_1.objectStore.ObjectStoreBuckets.PLUGINS, pluginKey);
62
- fs_1.default.writeFileSync(filename, pluginJs);
63
- fs_1.default.writeFileSync(metadataName, hash);
64
- return require(filename);
62
+ const pluginKey = backend_core_1.objectStore.getPluginJSKey(plugin);
63
+ const pluginJs = yield backend_core_1.objectStore.retrieve(backend_core_1.objectStore.ObjectStoreBuckets.PLUGINS, pluginKey);
64
+ fs_1.default.writeFileSync(filename, pluginJs);
65
+ fs_1.default.writeFileSync(metadataName, hash);
66
+ return require(filename);
67
+ });
68
+ }
69
+ const getDatasourcePlugin = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
70
+ return getPluginImpl(DATASOURCE_PATH, plugin);
65
71
  });
66
72
  exports.getDatasourcePlugin = getDatasourcePlugin;
73
+ const getAutomationPlugin = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
74
+ return getPluginImpl(AUTOMATION_PATH, plugin);
75
+ });
76
+ exports.getAutomationPlugin = getAutomationPlugin;
@@ -46,17 +46,16 @@ function processFormulas(table, rows, { dynamic, contextRows } = { dynamic: true
46
46
  for (let [column, schema] of Object.entries(table.schema)) {
47
47
  const isStatic = schema.formulaType === constants_1.FormulaTypes.STATIC;
48
48
  if (schema.type !== constants_1.FieldTypes.FORMULA ||
49
+ schema.formula == null ||
49
50
  (dynamic && isStatic) ||
50
51
  (!dynamic && !isStatic)) {
51
52
  continue;
52
53
  }
53
54
  // iterate through rows and process formula
54
55
  for (let i = 0; i < rowArray.length; i++) {
55
- if (schema.formula) {
56
- let row = rowArray[i];
57
- let context = contextRows ? contextRows[i] : row;
58
- rowArray[i] = Object.assign(Object.assign({}, row), { [column]: (0, string_templates_1.processStringSync)(schema.formula, context) });
59
- }
56
+ let row = rowArray[i];
57
+ let context = contextRows ? contextRows[i] : row;
58
+ rowArray[i] = Object.assign(Object.assign({}, row), { [column]: (0, string_templates_1.processStringSync)(schema.formula, context) });
60
59
  }
61
60
  }
62
61
  return single ? rowArray[0] : rowArray;
package/dist/watch.js CHANGED
@@ -18,7 +18,7 @@ const environment_1 = __importDefault(require("./environment"));
18
18
  const chokidar_1 = __importDefault(require("chokidar"));
19
19
  const fs_1 = __importDefault(require("fs"));
20
20
  const backend_core_1 = require("@budibase/backend-core");
21
- const plugin_1 = require("./api/controllers/plugin");
21
+ const plugins_1 = __importDefault(require("./sdk/plugins"));
22
22
  function watch() {
23
23
  const watchPath = path_1.default.join(environment_1.default.PLUGINS_DIR, "./**/*.tar.gz");
24
24
  chokidar_1.default
@@ -41,7 +41,7 @@ function watch() {
41
41
  const split = path.split("/");
42
42
  const name = split[split.length - 1];
43
43
  console.log("Importing plugin:", path);
44
- yield (0, plugin_1.processUploadedPlugin)({ name, path });
44
+ yield plugins_1.default.processUploaded({ name, path });
45
45
  }
46
46
  catch (err) {
47
47
  const message = (err === null || err === void 0 ? void 0 : err.message) ? err === null || err === void 0 ? void 0 : err.message : err;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const websocket_1 = __importDefault(require("./websocket"));
7
+ const authorized_1 = __importDefault(require("../middleware/authorized"));
8
+ const backend_core_1 = require("@budibase/backend-core");
9
+ class ClientAppWebsocket extends websocket_1.default {
10
+ constructor(app, server) {
11
+ super(app, server, "/socket/client", [(0, authorized_1.default)(backend_core_1.permissions.BUILDER)]);
12
+ }
13
+ }
14
+ exports.default = ClientAppWebsocket;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const authorized_1 = __importDefault(require("../middleware/authorized"));
16
+ const websocket_1 = __importDefault(require("./websocket"));
17
+ const backend_core_1 = require("@budibase/backend-core");
18
+ class GridSocket extends websocket_1.default {
19
+ constructor(app, server) {
20
+ super(app, server, "/socket/grid", [(0, authorized_1.default)(backend_core_1.permissions.BUILDER)]);
21
+ this.io.on("connection", socket => {
22
+ const user = socket.data.user;
23
+ console.log(`Spreadsheet user connected: ${user === null || user === void 0 ? void 0 : user.id}`);
24
+ // Socket state
25
+ let currentRoom;
26
+ // Initial identification of connected spreadsheet
27
+ socket.on("select-table", (tableId, callback) => __awaiter(this, void 0, void 0, function* () {
28
+ // Leave current room
29
+ if (currentRoom) {
30
+ socket.to(currentRoom).emit("user-disconnect", socket.data.user);
31
+ socket.leave(currentRoom);
32
+ }
33
+ // Join new room
34
+ currentRoom = tableId;
35
+ socket.join(currentRoom);
36
+ socket.to(currentRoom).emit("user-update", socket.data.user);
37
+ // Reply with all users in current room
38
+ const sockets = yield this.io.in(currentRoom).fetchSockets();
39
+ callback({
40
+ users: sockets.map(socket => socket.data.user),
41
+ id: user.id,
42
+ });
43
+ }));
44
+ // Handle users selecting a new cell
45
+ socket.on("select-cell", cellId => {
46
+ socket.data.user.selectedCellId = cellId;
47
+ if (currentRoom) {
48
+ socket.to(currentRoom).emit("user-update", socket.data.user);
49
+ }
50
+ });
51
+ // Disconnection cleanup
52
+ socket.on("disconnect", () => {
53
+ if (currentRoom) {
54
+ socket.to(currentRoom).emit("user-disconnect", socket.data.user);
55
+ }
56
+ });
57
+ });
58
+ }
59
+ }
60
+ exports.default = GridSocket;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.gridSocket = exports.clientAppSocket = exports.initialise = void 0;
7
+ const grid_1 = __importDefault(require("./grid"));
8
+ const client_1 = __importDefault(require("./client"));
9
+ let clientAppSocket;
10
+ exports.clientAppSocket = clientAppSocket;
11
+ let gridSocket;
12
+ exports.gridSocket = gridSocket;
13
+ const initialise = (app, server) => {
14
+ exports.clientAppSocket = clientAppSocket = new client_1.default(app, server);
15
+ exports.gridSocket = gridSocket = new grid_1.default(app, server);
16
+ };
17
+ exports.initialise = initialise;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const socket_io_1 = require("socket.io");
16
+ const http_1 = __importDefault(require("http"));
17
+ const cookies_1 = __importDefault(require("cookies"));
18
+ const koa_useragent_1 = require("koa-useragent");
19
+ const backend_core_1 = require("@budibase/backend-core");
20
+ const currentapp_1 = __importDefault(require("../middleware/currentapp"));
21
+ class Socket {
22
+ constructor(app, server, path, additionalMiddlewares) {
23
+ this.io = new socket_io_1.Server(server, {
24
+ path,
25
+ });
26
+ // Attach default middlewares
27
+ const authenticate = backend_core_1.auth.buildAuthMiddleware([], {
28
+ publicAllowed: true,
29
+ });
30
+ const middlewares = [
31
+ koa_useragent_1.userAgent,
32
+ authenticate,
33
+ currentapp_1.default,
34
+ ...(additionalMiddlewares || []),
35
+ ];
36
+ // Apply middlewares
37
+ this.io.use((socket, next) => __awaiter(this, void 0, void 0, function* () {
38
+ // Build fake koa context
39
+ const res = new http_1.default.ServerResponse(socket.request);
40
+ const ctx = Object.assign(Object.assign({}, app.createContext(socket.request, res)), {
41
+ // Additional overrides needed to make our middlewares work with this
42
+ // fake koa context
43
+ cookies: new cookies_1.default(socket.request, res), get: (field) => socket.request.headers[field], throw: (code, message) => {
44
+ throw new Error(message);
45
+ },
46
+ // Needed for koa-useragent middleware
47
+ headers: socket.request.headers, header: socket.request.headers,
48
+ // We don't really care about the path since it will never contain
49
+ // an app ID
50
+ path: "/socket" });
51
+ // Run all koa middlewares
52
+ try {
53
+ for (let [idx, middleware] of middlewares.entries()) {
54
+ yield middleware(ctx, () => {
55
+ if (idx === middlewares.length - 1) {
56
+ // Middlewares are finished.
57
+ // Extract some data from our enriched koa context to persist
58
+ // as metadata for the socket
59
+ socket.data.user = {
60
+ id: ctx.user._id,
61
+ email: ctx.user.email,
62
+ };
63
+ next();
64
+ }
65
+ });
66
+ }
67
+ }
68
+ catch (error) {
69
+ next(error);
70
+ }
71
+ }));
72
+ }
73
+ // Emit an event to all sockets
74
+ emit(event, payload) {
75
+ this.io.sockets.emit(event, payload);
76
+ }
77
+ }
78
+ exports.default = Socket;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.5.6-alpha.3",
4
+ "version": "2.5.6-alpha.30",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -45,12 +45,12 @@
45
45
  "license": "GPL-3.0",
46
46
  "dependencies": {
47
47
  "@apidevtools/swagger-parser": "10.0.3",
48
- "@budibase/backend-core": "2.5.6-alpha.3",
49
- "@budibase/client": "2.5.6-alpha.3",
50
- "@budibase/pro": "2.5.6-alpha.2",
51
- "@budibase/shared-core": "2.5.6-alpha.3",
52
- "@budibase/string-templates": "2.5.6-alpha.3",
53
- "@budibase/types": "2.5.6-alpha.3",
48
+ "@budibase/backend-core": "2.5.6-alpha.30",
49
+ "@budibase/client": "2.5.6-alpha.30",
50
+ "@budibase/pro": "2.5.6-alpha.29",
51
+ "@budibase/shared-core": "2.5.6-alpha.30",
52
+ "@budibase/string-templates": "2.5.6-alpha.30",
53
+ "@budibase/types": "2.5.6-alpha.30",
54
54
  "@bull-board/api": "3.7.0",
55
55
  "@bull-board/koa": "3.9.4",
56
56
  "@elastic/elasticsearch": "7.10.0",
@@ -65,6 +65,7 @@
65
65
  "bull": "4.10.1",
66
66
  "chmodr": "1.2.0",
67
67
  "chokidar": "3.5.3",
68
+ "cookies": "0.8.0",
68
69
  "csvtojson": "2.0.10",
69
70
  "curlconverter": "3.21.0",
70
71
  "dd-trace": "3.13.2",
@@ -108,14 +109,14 @@
108
109
  "redis": "4",
109
110
  "server-destroy": "1.0.1",
110
111
  "snowflake-promise": "^4.5.0",
111
- "socket.io": "^4.5.1",
112
+ "socket.io": "4.6.1",
112
113
  "svelte": "3.49.0",
113
114
  "swagger-parser": "10.0.3",
114
115
  "tar": "6.1.11",
115
116
  "to-json-schema": "0.2.5",
116
117
  "uuid": "3.3.2",
117
118
  "validate.js": "0.13.1",
118
- "vm2": "3.9.16",
119
+ "vm2": "3.9.17",
119
120
  "worker-farm": "1.7.0",
120
121
  "xml2js": "0.5.0",
121
122
  "yargs": "13.2.4"
@@ -175,5 +176,5 @@
175
176
  "optionalDependencies": {
176
177
  "oracledb": "5.3.0"
177
178
  },
178
- "gitHead": "38b2a2407eeb58c3f143c1d91d517e38b27cdd89"
179
+ "gitHead": "07ceb334c7ea3962f7268038653450a7be3a5ca8"
179
180
  }
@@ -1,5 +1,4 @@
1
1
  import env from "../../environment"
2
- import packageJson from "../../../package.json"
3
2
  import {
4
3
  createLinkView,
5
4
  createRoutingView,
@@ -24,6 +23,7 @@ import {
24
23
  migrations,
25
24
  objectStore,
26
25
  ErrorCode,
26
+ env as envCore,
27
27
  } from "@budibase/backend-core"
28
28
  import { USERS_TABLE_SCHEMA } from "../../constants"
29
29
  import { buildDefaultDocs } from "../../db/defaultData/datasource_bb_default"
@@ -264,7 +264,7 @@ async function performAppCreate(ctx: UserCtx) {
264
264
  _rev: undefined,
265
265
  appId,
266
266
  type: "app",
267
- version: packageJson.version,
267
+ version: envCore.VERSION,
268
268
  componentLibraries: ["@budibase/standard-components"],
269
269
  name: name,
270
270
  url: url,
@@ -433,7 +433,7 @@ export async function updateClient(ctx: UserCtx) {
433
433
  }
434
434
 
435
435
  // Update versions in app package
436
- const updatedToVersion = packageJson.version
436
+ const updatedToVersion = envCore.VERSION
437
437
  const appPackageUpdates = {
438
438
  version: updatedToVersion,
439
439
  revertableVersion: currentVersion,
@@ -16,9 +16,15 @@ import { setTestFlag, clearTestFlag } from "../../utilities/redis"
16
16
  import { context, cache, events } from "@budibase/backend-core"
17
17
  import { automations } from "@budibase/pro"
18
18
  import { Automation, BBContext } from "@budibase/types"
19
+ import { getActionDefinitions as actionDefs } from "../../automations/actions"
19
20
 
20
- const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS)
21
- const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
21
+ async function getActionDefinitions() {
22
+ return removeDeprecated(await actionDefs())
23
+ }
24
+
25
+ function getTriggerDefinitions() {
26
+ return removeDeprecated(triggers.TRIGGER_DEFINITIONS)
27
+ }
22
28
 
23
29
  /*************************
24
30
  * *
@@ -228,17 +234,17 @@ export async function clearLogError(ctx: BBContext) {
228
234
  }
229
235
 
230
236
  export async function getActionList(ctx: BBContext) {
231
- ctx.body = ACTION_DEFS
237
+ ctx.body = await getActionDefinitions()
232
238
  }
233
239
 
234
240
  export async function getTriggerList(ctx: BBContext) {
235
- ctx.body = TRIGGER_DEFS
241
+ ctx.body = getTriggerDefinitions()
236
242
  }
237
243
 
238
244
  export async function getDefinitionList(ctx: BBContext) {
239
245
  ctx.body = {
240
- trigger: TRIGGER_DEFS,
241
- action: ACTION_DEFS,
246
+ trigger: getTriggerDefinitions(),
247
+ action: await getActionDefinitions(),
242
248
  }
243
249
  }
244
250
 
@@ -4,7 +4,7 @@ import { checkSlashesInUrl } from "../../utilities"
4
4
  import { request } from "../../utilities/workerRequests"
5
5
  import { clearLock as redisClearLock } from "../../utilities/redis"
6
6
  import { DocumentType } from "../../db/utils"
7
- import { context } from "@budibase/backend-core"
7
+ import { context, env as envCore } from "@budibase/backend-core"
8
8
  import { events, db as dbCore, cache } from "@budibase/backend-core"
9
9
 
10
10
  async function redirect(ctx: any, method: string, path: string = "global") {
@@ -121,7 +121,7 @@ export async function revert(ctx: any) {
121
121
  }
122
122
 
123
123
  export async function getBudibaseVersion(ctx: any) {
124
- const version = require("../../../package.json").version
124
+ const version = envCore.VERSION
125
125
  ctx.body = {
126
126
  version,
127
127
  }
@@ -1,31 +1,11 @@
1
- import { npmUpload, urlUpload, githubUpload, fileUpload } from "./uploaders"
2
- import {
3
- plugins as pluginCore,
4
- db as dbCore,
5
- tenancy,
6
- objectStore,
7
- } from "@budibase/backend-core"
8
- import { PluginType, FileType, PluginSource, Plugin } from "@budibase/types"
1
+ import { npmUpload, urlUpload, githubUpload } from "./uploaders"
2
+ import { plugins as pluginCore } from "@budibase/backend-core"
3
+ import { PluginType, FileType, PluginSource } from "@budibase/types"
9
4
  import env from "../../../environment"
10
- import { ClientAppSocket } from "../../../websocket"
5
+ import { clientAppSocket } from "../../../websockets"
6
+ import sdk from "../../../sdk"
11
7
  import { sdk as pro } from "@budibase/pro"
12
8
 
13
- export async function getPlugins(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
9
  export async function upload(ctx: any) {
30
10
  const plugins: FileType[] =
31
11
  ctx.request.files.file.length > 1
@@ -35,7 +15,7 @@ export async function upload(ctx: any) {
35
15
  let docs = []
36
16
  // can do single or multiple plugins
37
17
  for (let plugin of plugins) {
38
- const doc = await processUploadedPlugin(plugin, PluginSource.FILE)
18
+ const doc = await sdk.plugins.processUploaded(plugin, PluginSource.FILE)
39
19
  docs.push(doc)
40
20
  }
41
21
  ctx.body = {
@@ -91,7 +71,7 @@ export async function create(ctx: any) {
91
71
 
92
72
  const doc = await pro.plugins.storePlugin(metadata, directory, source)
93
73
 
94
- ClientAppSocket.emit("plugins-update", { name, hash: doc.hash })
74
+ clientAppSocket.emit("plugins-update", { name, hash: doc.hash })
95
75
  ctx.body = {
96
76
  message: "Plugin uploaded successfully",
97
77
  plugins: [doc],
@@ -105,7 +85,7 @@ export async function create(ctx: any) {
105
85
  }
106
86
 
107
87
  export async function fetch(ctx: any) {
108
- ctx.body = await getPlugins()
88
+ ctx.body = await sdk.plugins.fetch()
109
89
  }
110
90
 
111
91
  export async function destroy(ctx: any) {
@@ -119,20 +99,3 @@ export async function destroy(ctx: any) {
119
99
  ctx.throw(400, err.message)
120
100
  }
121
101
  }
122
-
123
- export async function processUploadedPlugin(
124
- plugin: FileType,
125
- source?: PluginSource
126
- ) {
127
- const { metadata, directory } = await fileUpload(plugin)
128
- pluginCore.validate(metadata?.schema)
129
-
130
- // Only allow components in cloud
131
- if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {
132
- throw new Error("Only component plugins are supported outside of self-host")
133
- }
134
-
135
- const doc = await pro.plugins.storePlugin(metadata, directory, source)
136
- ClientAppSocket.emit("plugin-update", { name: doc.name, hash: doc.hash })
137
- return doc
138
- }
@@ -245,7 +245,7 @@ async function execute(
245
245
  }
246
246
  const runFn = () => Runner.run(inputs)
247
247
 
248
- const { rows, pagination, extra } = await quotas.addQuery(runFn, {
248
+ const { rows, pagination, extra, info } = await quotas.addQuery(runFn, {
249
249
  datasourceId: datasource._id,
250
250
  })
251
251
  // remove the raw from execution incase transformer being used to hide data
@@ -255,7 +255,7 @@ async function execute(
255
255
  if (opts && opts.rowsOnly) {
256
256
  ctx.body = rows
257
257
  } else {
258
- ctx.body = { data: rows, pagination, ...extra }
258
+ ctx.body = { data: rows, pagination, ...extra, ...info }
259
259
  }
260
260
  } catch (err) {
261
261
  ctx.throw(400, err)
@@ -1,31 +1,32 @@
1
1
  import {
2
+ Datasource,
3
+ FieldSchema,
4
+ FieldType,
2
5
  FilterType,
3
6
  IncludeRelationship,
4
7
  Operation,
5
8
  PaginationJson,
6
9
  RelationshipsJson,
10
+ RelationshipTypes,
11
+ Row,
7
12
  SearchFilters,
8
13
  SortJson,
9
- Datasource,
10
- FieldSchema,
11
- Row,
12
- Table,
13
- RelationshipTypes,
14
- FieldType,
15
14
  SortType,
15
+ Table,
16
16
  } from "@budibase/types"
17
17
  import {
18
+ breakExternalTableId,
18
19
  breakRowIdField,
20
+ convertRowId,
19
21
  generateRowIdField,
20
22
  isRowId,
21
- convertRowId,
23
+ isSQL,
22
24
  } from "../../../integrations/utils"
23
25
  import { getDatasourceAndQuery } from "./utils"
24
26
  import { FieldTypes } from "../../../constants"
25
- import { breakExternalTableId, isSQL } from "../../../integrations/utils"
26
27
  import { processObjectSync } from "@budibase/string-templates"
27
28
  import { cloneDeep } from "lodash/fp"
28
- import { processFormulas, processDates } from "../../../utilities/rowProcessor"
29
+ import { processDates, processFormulas } from "../../../utilities/rowProcessor"
29
30
  import { db as dbCore } from "@budibase/backend-core"
30
31
  import sdk from "../../../sdk"
31
32
 
@@ -382,10 +383,18 @@ export class ExternalRequest {
382
383
  }
383
384
  const display = linkedTable.primaryDisplay
384
385
  for (let key of Object.keys(row[relationship.column])) {
385
- const related: Row = row[relationship.column][key]
386
+ let relatedRow: Row = row[relationship.column][key]
387
+ // add this row as context for the relationship
388
+ for (let col of Object.values(linkedTable.schema)) {
389
+ if (col.type === FieldType.LINK && col.tableId === table._id) {
390
+ relatedRow[col.name] = [row]
391
+ }
392
+ }
393
+ relatedRow = processFormulas(linkedTable, relatedRow)
394
+ const relatedDisplay = display ? relatedRow[display] : undefined
386
395
  row[relationship.column][key] = {
387
- primaryDisplay: display ? related[display] : undefined,
388
- _id: related._id,
396
+ primaryDisplay: relatedDisplay || "Invalid display column",
397
+ _id: relatedRow._id,
389
398
  }
390
399
  }
391
400
  }
@@ -110,21 +110,28 @@ export function importToRows(
110
110
  table: Table,
111
111
  user: ContextUser | null = null
112
112
  ) {
113
+ let originalTable = table
113
114
  let finalData: any = []
114
115
  for (let i = 0; i < data.length; i++) {
115
116
  let row = data[i]
116
117
  row._id = generateRowID(table._id!)
117
118
  row.tableId = table._id
119
+
120
+ // We use a reference to table here and update it after input processing,
121
+ // so that we can auto increment auto IDs in imported data properly
118
122
  const processed = inputProcessing(user, table, row, {
119
123
  noAutoRelationships: true,
120
124
  })
121
125
  row = processed.row
122
126
  table = processed.table
123
127
 
124
- for (const [fieldName, schema] of Object.entries(table.schema)) {
125
- // check whether the options need to be updated for inclusion as part of the data import
128
+ // However here we must reference the original table, as we want to mutate
129
+ // the real schema of the table passed in, not the clone used for
130
+ // incrementing auto IDs
131
+ for (const [fieldName, schema] of Object.entries(originalTable.schema)) {
126
132
  if (
127
- schema.type === FieldTypes.OPTIONS &&
133
+ (schema.type === FieldTypes.OPTIONS ||
134
+ schema.type === FieldTypes.ARRAY) &&
128
135
  row[fieldName] &&
129
136
  (!schema.constraints!.inclusion ||
130
137
  schema.constraints!.inclusion.indexOf(row[fieldName]) === -1)