@budibase/server 2.5.6-alpha.5 → 2.5.6-alpha.7
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.564a7c4f.js → index.5c1a6913.js} +357 -357
- package/builder/assets/index.c0265b74.css +6 -0
- package/builder/index.html +2 -2
- package/dist/api/controllers/plugin/index.js +2 -2
- package/dist/api/controllers/table/utils.js +2 -1
- package/dist/app.js +2 -2
- package/dist/package.json +9 -8
- package/dist/sdk/plugins/plugins.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- 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/jest.config.ts +3 -3
- package/nodemon.json +7 -3
- package/package.json +10 -9
- package/src/api/controllers/plugin/index.ts +2 -2
- package/src/api/controllers/table/utils.ts +2 -1
- package/src/app.ts +2 -2
- package/src/sdk/plugins/plugins.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.json +1 -7
- package/builder/assets/index.9e886d0a.css +0 -6
- package/dist/websocket.js +0 -22
- package/src/websocket.ts +0 -26
|
@@ -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/jest.config.ts
CHANGED
|
@@ -20,9 +20,9 @@ const baseConfig: Config.InitialProjectOptions = {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// add pro sources if they exist
|
|
23
|
-
if (fs.existsSync("
|
|
24
|
-
baseConfig.moduleNameMapper["@budibase/pro"] =
|
|
25
|
-
"<rootDir
|
|
23
|
+
if (fs.existsSync("../pro/packages")) {
|
|
24
|
+
baseConfig.moduleNameMapper!["@budibase/pro"] =
|
|
25
|
+
"<rootDir>/../pro/packages/pro/src"
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const config: Config.InitialOptions = {
|
package/nodemon.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"watch": ["src", "../backend-core", "
|
|
2
|
+
"watch": ["src", "../backend-core", "../pro/packages/pro"],
|
|
3
3
|
"ext": "js,ts,json",
|
|
4
|
-
"ignore": [
|
|
4
|
+
"ignore": [
|
|
5
|
+
"src/**/*.spec.ts",
|
|
6
|
+
"src/**/*.spec.js",
|
|
7
|
+
"../backend-core/dist/**/*"
|
|
8
|
+
],
|
|
5
9
|
"exec": "ts-node src/index.ts"
|
|
6
|
-
}
|
|
10
|
+
}
|
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.7",
|
|
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.7",
|
|
49
|
+
"@budibase/client": "2.5.6-alpha.7",
|
|
50
|
+
"@budibase/pro": "2.5.6-alpha.6",
|
|
51
|
+
"@budibase/shared-core": "2.5.6-alpha.7",
|
|
52
|
+
"@budibase/string-templates": "2.5.6-alpha.7",
|
|
53
|
+
"@budibase/types": "2.5.6-alpha.7",
|
|
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,7 +109,7 @@
|
|
|
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",
|
|
@@ -175,5 +176,5 @@
|
|
|
175
176
|
"optionalDependencies": {
|
|
176
177
|
"oracledb": "5.3.0"
|
|
177
178
|
},
|
|
178
|
-
"gitHead": "
|
|
179
|
+
"gitHead": "c34a935f5557c60d7bbf3556942828248057dd64"
|
|
179
180
|
}
|
|
@@ -2,7 +2,7 @@ import { npmUpload, urlUpload, githubUpload } from "./uploaders"
|
|
|
2
2
|
import { plugins as pluginCore } from "@budibase/backend-core"
|
|
3
3
|
import { PluginType, FileType, PluginSource } from "@budibase/types"
|
|
4
4
|
import env from "../../../environment"
|
|
5
|
-
import {
|
|
5
|
+
import { clientAppSocket } from "../../../websockets"
|
|
6
6
|
import sdk from "../../../sdk"
|
|
7
7
|
import { sdk as pro } from "@budibase/pro"
|
|
8
8
|
|
|
@@ -71,7 +71,7 @@ export async function create(ctx: any) {
|
|
|
71
71
|
|
|
72
72
|
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
clientAppSocket.emit("plugins-update", { name, hash: doc.hash })
|
|
75
75
|
ctx.body = {
|
|
76
76
|
message: "Plugin uploaded successfully",
|
|
77
77
|
plugins: [doc],
|
|
@@ -124,7 +124,8 @@ export function importToRows(
|
|
|
124
124
|
for (const [fieldName, schema] of Object.entries(table.schema)) {
|
|
125
125
|
// check whether the options need to be updated for inclusion as part of the data import
|
|
126
126
|
if (
|
|
127
|
-
schema.type === FieldTypes.OPTIONS
|
|
127
|
+
(schema.type === FieldTypes.OPTIONS ||
|
|
128
|
+
schema.type === FieldTypes.ARRAY) &&
|
|
128
129
|
row[fieldName] &&
|
|
129
130
|
(!schema.constraints!.inclusion ||
|
|
130
131
|
schema.constraints!.inclusion.indexOf(row[fieldName]) === -1)
|
package/src/app.ts
CHANGED
|
@@ -15,8 +15,8 @@ import * as api from "./api"
|
|
|
15
15
|
import * as automations from "./automations"
|
|
16
16
|
import { Thread } from "./threads"
|
|
17
17
|
import * as redis from "./utilities/redis"
|
|
18
|
+
import { initialise as initialiseWebsockets } from "./websockets"
|
|
18
19
|
import { events, logging, middleware, timers } from "@budibase/backend-core"
|
|
19
|
-
import { initialise as initialiseWebsockets } from "./websocket"
|
|
20
20
|
import { startup } from "./startup"
|
|
21
21
|
const Sentry = require("@sentry/node")
|
|
22
22
|
const destroyable = require("server-destroy")
|
|
@@ -61,7 +61,7 @@ if (env.isProd()) {
|
|
|
61
61
|
|
|
62
62
|
const server = http.createServer(app.callback())
|
|
63
63
|
destroyable(server)
|
|
64
|
-
initialiseWebsockets(server)
|
|
64
|
+
initialiseWebsockets(app, server)
|
|
65
65
|
|
|
66
66
|
let shuttingDown = false,
|
|
67
67
|
errCode = 0
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "@budibase/backend-core"
|
|
8
8
|
import { fileUpload } from "../../api/controllers/plugin/file"
|
|
9
9
|
import env from "../../environment"
|
|
10
|
-
import {
|
|
10
|
+
import { clientAppSocket } from "../../websockets"
|
|
11
11
|
import { sdk as pro } from "@budibase/pro"
|
|
12
12
|
|
|
13
13
|
export async function fetch(type?: PluginType) {
|
|
@@ -36,6 +36,6 @@ export async function processUploaded(plugin: FileType, source?: PluginSource) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
|
39
|
-
|
|
39
|
+
clientAppSocket.emit("plugin-update", { name: doc.name, hash: doc.hash })
|
|
40
40
|
return doc
|
|
41
41
|
}
|
|
@@ -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
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -10,19 +10,13 @@
|
|
|
10
10
|
"@budibase/backend-core": ["../backend-core/src"],
|
|
11
11
|
"@budibase/backend-core/*": ["../backend-core/*"],
|
|
12
12
|
"@budibase/shared-core": ["../shared-core/src"],
|
|
13
|
-
"@budibase/pro": ["
|
|
13
|
+
"@budibase/pro": ["../pro/packages/pro/src"]
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"ts-node": {
|
|
17
17
|
"require": ["tsconfig-paths/register"],
|
|
18
18
|
"swc": true
|
|
19
19
|
},
|
|
20
|
-
"references": [
|
|
21
|
-
{ "path": "../types" },
|
|
22
|
-
{ "path": "../backend-core" },
|
|
23
|
-
{ "path": "../shared-core" },
|
|
24
|
-
{ "path": "../../../budibase-pro/packages/pro" }
|
|
25
|
-
],
|
|
26
20
|
"include": ["src/**/*", "specs", "package.json"],
|
|
27
21
|
"exclude": ["node_modules", "dist"]
|
|
28
22
|
}
|