@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.
- package/builder/assets/index.44a18341.css +6 -0
- package/builder/assets/{index.a33a6c3d.js → index.87d46c61.js} +382 -366
- package/builder/index.html +2 -2
- package/dist/api/controllers/application.js +2 -3
- package/dist/api/controllers/automation.js +13 -7
- 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/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 +1 -35
- 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 +3 -3
- package/src/api/controllers/automation.ts +12 -6
- 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/integration-test/postgres.spec.ts +2 -0
- 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 +0 -35
- 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
|
@@ -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
|
-
|
|
41
|
+
function getPluginImpl(path, plugin) {
|
|
41
42
|
var _a;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
fs_1.default.
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
fs_1.default.
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
49
|
-
"@budibase/client": "2.5.6-alpha.
|
|
50
|
-
"@budibase/pro": "2.5.6-alpha.
|
|
51
|
-
"@budibase/shared-core": "2.5.6-alpha.
|
|
52
|
-
"@budibase/string-templates": "2.5.6-alpha.
|
|
53
|
-
"@budibase/types": "2.5.6-alpha.
|
|
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": "
|
|
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.
|
|
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": "
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
21
|
-
|
|
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 =
|
|
237
|
+
ctx.body = await getActionDefinitions()
|
|
232
238
|
}
|
|
233
239
|
|
|
234
240
|
export async function getTriggerList(ctx: BBContext) {
|
|
235
|
-
ctx.body =
|
|
241
|
+
ctx.body = getTriggerDefinitions()
|
|
236
242
|
}
|
|
237
243
|
|
|
238
244
|
export async function getDefinitionList(ctx: BBContext) {
|
|
239
245
|
ctx.body = {
|
|
240
|
-
trigger:
|
|
241
|
-
action:
|
|
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 =
|
|
124
|
+
const version = envCore.VERSION
|
|
125
125
|
ctx.body = {
|
|
126
126
|
version,
|
|
127
127
|
}
|
|
@@ -1,31 +1,11 @@
|
|
|
1
|
-
import { npmUpload, urlUpload, githubUpload
|
|
2
|
-
import {
|
|
3
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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:
|
|
388
|
-
_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
|
-
|
|
125
|
-
|
|
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)
|