chore: Remove websocket server on RTS (#37827)

Remove the websocket server on RTS. The RTS abbreviation has now
completely lost significance. Let's now call it `rts`, in memory. 🙂


## Automation

/test sanity

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12078784104>
> Commit: f858c993b42c987dde43d791757f21524f5a6a40
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12078784104&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Fri, 29 Nov 2024 04:42:47 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

- **Bug Fixes**
- Removed unnecessary socket-related dependencies and constants,
streamlining the application.

- **New Features**
- Enhanced application performance by eliminating real-time
communication features that were no longer necessary.

- **Chores**
- Cleaned up the codebase by removing outdated socket management files
and constants, simplifying the overall architecture.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Shrikant Sharat Kandula 2024-11-29 14:36:28 +05:30 committed by GitHub
parent f308ca887c
commit 1c344b7433
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 8 additions and 482 deletions

View File

@ -30,8 +30,7 @@
"loglevel": "^1.8.1", "loglevel": "^1.8.1",
"mongodb": "^5.8.0", "mongodb": "^5.8.0",
"nodemailer": "6.9.9", "nodemailer": "6.9.9",
"readline-sync": "1.4.10", "readline-sync": "1.4.10"
"socket.io": "^4.6.2"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.14", "@types/express": "^4.17.14",

View File

@ -1,6 +1,5 @@
const BASE_API_URL = "http://localhost:8091"; const BASE_API_URL = "http://localhost:8091";
export const RTS_BASE_PATH = "/rts";
export const RTS_BASE_API_PATH = "/rts-api/v1"; export const RTS_BASE_API_PATH = "/rts-api/v1";
export const RTS_BASE_API_URL = `${BASE_API_URL}${RTS_BASE_API_PATH}`; export const RTS_BASE_API_URL = `${BASE_API_URL}${RTS_BASE_API_PATH}`;

View File

@ -1,11 +0,0 @@
export const APP_ROOM_PREFIX = "app:";
export const PAGE_ROOM_PREFIX = "page:";
export const ROOT_NAMESPACE = "/";
export const PAGE_EDIT_NAMESPACE = "/page/edit";
export const EDITORS_EVENT_NAME = "collab:online_editors";
export const START_EDIT_EVENT_NAME = "collab:start_edit";
export const LEAVE_EDIT_EVENT_NAME = "collab:leave_edit";
export const MOUSE_POINTER_EVENT_NAME = "collab:mouse_pointer";
export const RELEASE_VERSION_EVENT_NAME = "info:release_version";
export const PAGE_VISIBILITY_EVENT_NAME = "info:page_visibility";

View File

@ -1,136 +0,0 @@
import type { Server, Socket } from "socket.io";
import { tryAuth } from "@middlewares/socket-auth";
import {
START_EDIT_EVENT_NAME,
LEAVE_EDIT_EVENT_NAME,
MOUSE_POINTER_EVENT_NAME,
PAGE_EDIT_NAMESPACE,
PAGE_ROOM_PREFIX,
EDITORS_EVENT_NAME,
} from "@constants/socket";
import type { Policy, MousePointerEvent } from "@utils/models";
import { AppUser, CurrentEditorsEvent } from "@utils/models";
function subscribeToEditEvents(socket: Socket, appRoomPrefix: string) {
socket.on(START_EDIT_EVENT_NAME, (resourceId) => {
if (socket.data.email) {
// user is authenticated, join the room now
joinEditRoom(socket, resourceId, appRoomPrefix);
} else {
// user not authenticated yet, save the resource id and room prefix to join later after auth
socket.data.pendingRoomId = resourceId;
socket.data.pendingRoomPrefix = appRoomPrefix;
}
});
socket.on(LEAVE_EDIT_EVENT_NAME, (resourceId) => {
const roomName = appRoomPrefix + resourceId;
socket.leave(roomName); // remove this socket from room
});
}
async function onAppSocketConnected(socket: Socket) {
const isAuthenticated = await tryAuthAndJoinPendingRoom(socket);
if (isAuthenticated) {
socket.join("email:" + socket.data.email);
}
}
async function onPageSocketConnected(socket: Socket, socketIo: Server) {
const isAuthenticated = await tryAuthAndJoinPendingRoom(socket);
if (isAuthenticated) {
socket.on(MOUSE_POINTER_EVENT_NAME, (event: MousePointerEvent) => {
event.user = new AppUser(socket.data.name, socket.data.email);
event.socketId = socket.id;
socketIo
.of(PAGE_EDIT_NAMESPACE)
.to(PAGE_ROOM_PREFIX + event.pageId)
.emit(MOUSE_POINTER_EVENT_NAME, event);
});
}
}
async function tryAuthAndJoinPendingRoom(socket: Socket) {
const isAuthenticated = await tryAuth(socket);
if (socket.data.pendingRoomId) {
// an appId or pageId is pending for this socket, join now
joinEditRoom(
socket,
socket.data.pendingRoomId,
socket.data.pendingRoomPrefix,
);
}
return isAuthenticated;
}
function joinEditRoom(socket: Socket, roomId: string, roomPrefix: string) {
// remove this socket from any other rooms with roomPrefix
if (socket.rooms) {
socket.rooms.forEach((roomName) => {
if (roomName.startsWith(roomPrefix)) {
socket.leave(roomName);
}
});
}
// add this socket to room with application id
const roomName = roomPrefix + roomId;
socket.join(roomName);
}
function findPolicyEmails(policies: Policy[], permission: string): string[] {
const emails: string[] = [];
for (const policy of policies) {
if (policy.permission === permission) {
for (const email of policy.users) {
emails.push(email);
}
break;
}
}
return emails;
}
function sendCurrentUsers(socketIo, roomName: string, roomPrefix: string) {
if (roomName.startsWith(roomPrefix)) {
socketIo
.in(roomName)
.fetchSockets()
.then((sockets) => {
const onlineUsernames = new Set<string>();
const onlineUsers = new Array<AppUser>();
if (sockets) {
sockets.forEach((s) => {
if (!onlineUsernames.has(s.data.email)) {
onlineUsers.push(new AppUser(s.data.name, s.data.email));
}
onlineUsernames.add(s.data.email);
});
}
const resourceId = roomName.replace(roomPrefix, ""); // get resourceId from room name by removing the prefix
const response = new CurrentEditorsEvent(resourceId, onlineUsers);
socketIo.to(roomName).emit(EDITORS_EVENT_NAME, response);
});
}
}
export {
subscribeToEditEvents,
onAppSocketConnected,
onPageSocketConnected,
sendCurrentUsers,
findPolicyEmails,
};

View File

@ -1,74 +0,0 @@
import type { Socket } from "socket.io";
import log from "loglevel";
import axios from "axios";
import { BASE_APPSMITH_API_URL } from "@constants/routes";
export async function tryAuth(socket: Socket) {
/* ********************************************************* */
// TODO: This change is not being used at the moment. Instead of using the environment variable API_BASE_URL
// we should be able to derive the API_BASE_URL from the host header. This will make configuration simpler
// for the user. The problem with this implementation is that Axios doesn't work for https endpoints currently.
// This needs to be debugged.
/* ********************************************************* */
// const host = socket.handshake.headers.host;
const connectionCookie = socket?.handshake?.headers?.cookie;
if (
connectionCookie === undefined ||
connectionCookie === null ||
connectionCookie === ""
) {
return false;
}
const matchedCookie = connectionCookie.match(/\bSESSION=\S+/);
if (!matchedCookie) {
return false;
}
const sessionCookie = matchedCookie[0];
let response;
try {
response = await axios.request({
method: "GET",
url: BASE_APPSMITH_API_URL + "/users/me",
headers: {
Cookie: sessionCookie,
},
});
} catch (error) {
if (error.response?.status === 401) {
// eslint-disable-next-line no-console
console.info(
"401 received when authenticating user with cookie: " + sessionCookie,
);
} else if (error.response) {
log.error(
"Error response received while authentication: ",
JSON.stringify(error.response.data), // this is so the message shows up in one line.
);
} else {
log.error("Error authenticating", error.cause?.toString());
}
return false;
}
const email = response?.data?.data?.email;
const name = response?.data?.data?.name ?? email;
// If the session check API succeeds & the email/name is anonymousUser, then the user is not authenticated
// and we should not allow them to join any rooms
if (email == null || email === "anonymousUser" || name === "anonymousUser") {
return false;
}
socket.data.email = email;
socket.data.name = name;
return true;
}

View File

@ -1,18 +1,16 @@
import "./instrumentation"; import "./instrumentation";
import http from "http"; import http from "http";
import express from "express"; import express from "express";
import { Server } from "socket.io";
import type { LogLevelDesc } from "loglevel"; import type { LogLevelDesc } from "loglevel";
import log from "loglevel"; import log from "loglevel";
import { VERSION as buildVersion } from "./version"; // release version of the api import { VERSION as buildVersion } from "./version"; // release version of the api
import { initializeSockets } from "./sockets";
// routes // routes
import ast_routes from "./routes/ast_routes"; import ast_routes from "./routes/ast_routes";
import dsl_routes from "./routes/dsl_routes"; import dsl_routes from "./routes/dsl_routes";
import health_check_routes from "./routes/health_check_routes"; import health_check_routes from "./routes/health_check_routes";
import { RTS_BASE_PATH, RTS_BASE_API_PATH } from "@constants/routes"; import { RTS_BASE_API_PATH } from "@constants/routes";
// Setting the logLevel for all log messages // Setting the logLevel for all log messages
const logLevel: LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL || const logLevel: LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL ||
@ -27,11 +25,6 @@ const app = express();
app.disable("x-powered-by"); app.disable("x-powered-by");
const server = new http.Server(app); const server = new http.Server(app);
const io = new Server(server, {
path: RTS_BASE_PATH,
});
initializeSockets(io);
// parse incoming json requests // parse incoming json requests
app.use(express.json({ limit: "5mb" })); app.use(express.json({ limit: "5mb" }));

View File

@ -1,82 +0,0 @@
import type { Server, Socket } from "socket.io";
import log from "loglevel";
import {
APP_ROOM_PREFIX,
RELEASE_VERSION_EVENT_NAME,
LEAVE_EDIT_EVENT_NAME,
PAGE_EDIT_NAMESPACE,
PAGE_ROOM_PREFIX,
ROOT_NAMESPACE,
PAGE_VISIBILITY_EVENT_NAME,
} from "@constants/socket";
import { VERSION as buildVersion } from "../version";
import {
subscribeToEditEvents,
onAppSocketConnected,
onPageSocketConnected,
sendCurrentUsers,
} from "@controllers/socket";
export function watchEvents(io: Server) {
io.on("connection", (socket: Socket) => {
socket.emit(RELEASE_VERSION_EVENT_NAME, buildVersion);
subscribeToEditEvents(socket, APP_ROOM_PREFIX);
onAppSocketConnected(socket).catch((error) =>
log.error("Error in socket connected handler", error),
);
});
/** When we get the page visibility event, it means the page/tab
* is visible on the client after navigating away from it.
* We will respond back with the current version to
* so that the client can confirm if they are
* on the latest version of the client
*/
io.on(PAGE_VISIBILITY_EVENT_NAME, (socket: Socket) => {
socket.emit(RELEASE_VERSION_EVENT_NAME, buildVersion);
});
io.of(PAGE_EDIT_NAMESPACE).on("connection", (socket: Socket) => {
subscribeToEditEvents(socket, PAGE_ROOM_PREFIX);
onPageSocketConnected(socket, io).catch((error) =>
log.error("Error in socket connected handler", error),
);
});
io.of(ROOT_NAMESPACE).adapter.on("leave-room", (room, id) => {
if (room.startsWith(APP_ROOM_PREFIX)) {
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} left the room ${room}`);
}
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
});
io.of(ROOT_NAMESPACE).adapter.on("join-room", (room, id) => {
if (room.startsWith(APP_ROOM_PREFIX)) {
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} joined the room ${room}`);
}
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
});
io.of(PAGE_EDIT_NAMESPACE).adapter.on("leave-room", (room, id) => {
if (room.startsWith(PAGE_ROOM_PREFIX)) {
// someone left the page edit, notify others
log.debug(
`ns:${PAGE_EDIT_NAMESPACE} # socket ${id} left the room ${room}`,
);
io.of(PAGE_EDIT_NAMESPACE).to(room).emit(LEAVE_EDIT_EVENT_NAME, id);
}
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
});
io.of(PAGE_EDIT_NAMESPACE).adapter.on("join-room", (room, id) => {
if (room.startsWith(PAGE_ROOM_PREFIX)) {
log.debug(
`ns:${PAGE_EDIT_NAMESPACE}# socket ${id} joined the room ${room}`,
);
}
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
});
}

View File

@ -1,7 +0,0 @@
import { watchEvents } from "./events";
import type { Server } from "socket.io";
// Initializing Multiple Sockets
export function initializeSockets(io: Server) {
watchEvents(io);
}

View File

@ -1,32 +0,0 @@
export class AppUser {
name: string;
email: string;
constructor(name: string, email: string) {
this.name = name;
this.email = email;
}
}
export class CurrentEditorsEvent {
resourceId: string;
users: AppUser[];
constructor(resourceId: string, users: AppUser[]) {
this.resourceId = resourceId;
this.users = users;
}
}
export class MousePointerEvent {
pageId: string;
socketId: string;
user: AppUser;
data: object;
}
export interface Policy {
permission: string;
users: string[];
groups: string[];
}

View File

@ -9040,13 +9040,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@socket.io/component-emitter@npm:~3.1.0":
version: 3.1.0
resolution: "@socket.io/component-emitter@npm:3.1.0"
checksum: db069d95425b419de1514dffe945cc439795f6a8ef5b9465715acf5b8b50798e2c91b8719cbf5434b3fe7de179d6cdcd503c277b7871cb3dd03febb69bdd50fa
languageName: node
linkType: hard
"@storybook/addon-a11y@npm:^8.2.7": "@storybook/addon-a11y@npm:^8.2.7":
version: 8.2.7 version: 8.2.7
resolution: "@storybook/addon-a11y@npm:8.2.7" resolution: "@storybook/addon-a11y@npm:8.2.7"
@ -10204,22 +10197,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/cookie@npm:^0.4.0, @types/cookie@npm:^0.4.1": "@types/cookie@npm:^0.4.0":
version: 0.4.1 version: 0.4.1
resolution: "@types/cookie@npm:0.4.1" resolution: "@types/cookie@npm:0.4.1"
checksum: 3275534ed69a76c68eb1a77d547d75f99fedc80befb75a3d1d03662fb08d697e6f8b1274e12af1a74c6896071b11510631ba891f64d30c78528d0ec45a9c1a18 checksum: 3275534ed69a76c68eb1a77d547d75f99fedc80befb75a3d1d03662fb08d697e6f8b1274e12af1a74c6896071b11510631ba891f64d30c78528d0ec45a9c1a18
languageName: node languageName: node
linkType: hard linkType: hard
"@types/cors@npm:^2.8.12":
version: 2.8.13
resolution: "@types/cors@npm:2.8.13"
dependencies:
"@types/node": "*"
checksum: 7ef197ea19d2e5bf1313b8416baa6f3fd6dd887fd70191da1f804f557395357dafd8bc8bed0ac60686923406489262a7c8a525b55748f7b2b8afa686700de907
languageName: node
linkType: hard
"@types/cross-spawn@npm:^6.0.2": "@types/cross-spawn@npm:^6.0.2":
version: 6.0.2 version: 6.0.2
resolution: "@types/cross-spawn@npm:6.0.2" resolution: "@types/cross-spawn@npm:6.0.2"
@ -10730,7 +10714,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=13.7.0": "@types/node@npm:*, @types/node@npm:>=13.7.0":
version: 20.8.10 version: 20.8.10
resolution: "@types/node@npm:20.8.10" resolution: "@types/node@npm:20.8.10"
dependencies: dependencies:
@ -12693,7 +12677,6 @@ __metadata:
mongodb: ^5.8.0 mongodb: ^5.8.0
nodemailer: 6.9.9 nodemailer: 6.9.9
readline-sync: 1.4.10 readline-sync: 1.4.10
socket.io: ^4.6.2
supertest: ^6.3.3 supertest: ^6.3.3
ts-jest: 29.1.0 ts-jest: 29.1.0
typescript: ^5.5.4 typescript: ^5.5.4
@ -13827,13 +13810,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"base64id@npm:2.0.0, base64id@npm:~2.0.0":
version: 2.0.0
resolution: "base64id@npm:2.0.0"
checksum: 581b1d37e6cf3738b7ccdd4d14fe2bfc5c238e696e2720ee6c44c183b838655842e22034e53ffd783f872a539915c51b0d4728a49c7cc678ac5a758e00d62168
languageName: node
linkType: hard
"batch@npm:0.6.1": "batch@npm:0.6.1":
version: 0.6.1 version: 0.6.1
resolution: "batch@npm:0.6.1" resolution: "batch@npm:0.6.1"
@ -15438,7 +15414,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cookie@npm:^0.4.1, cookie@npm:~0.4.1": "cookie@npm:^0.4.1":
version: 0.4.2 version: 0.4.2
resolution: "cookie@npm:0.4.2" resolution: "cookie@npm:0.4.2"
checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b
@ -15498,16 +15474,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cors@npm:~2.8.5":
version: 2.8.5
resolution: "cors@npm:2.8.5"
dependencies:
object-assign: ^4
vary: ^1
checksum: ced838404ccd184f61ab4fdc5847035b681c90db7ac17e428f3d81d69e2989d2b680cc254da0e2554f5ed4f8a341820a1ce3d1c16b499f6e2f47a1b9b07b5006
languageName: node
linkType: hard
"cosmiconfig-typescript-loader@npm:^1.0.0": "cosmiconfig-typescript-loader@npm:^1.0.0":
version: 1.0.9 version: 1.0.9
resolution: "cosmiconfig-typescript-loader@npm:1.0.9" resolution: "cosmiconfig-typescript-loader@npm:1.0.9"
@ -16384,7 +16350,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.1, debug@npm:~4.3.2": "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4":
version: 4.3.7 version: 4.3.7
resolution: "debug@npm:4.3.7" resolution: "debug@npm:4.3.7"
dependencies: dependencies:
@ -17397,31 +17363,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"engine.io-parser@npm:~5.2.1":
version: 5.2.2
resolution: "engine.io-parser@npm:5.2.2"
checksum: 470231215f3136a9259efb1268bc9a71f789af4e8c74da8d3b49ceb149fe3cd5c315bf0cd13d2d8d9c8f0f051c6f93b68e8fa9c89a3b612b9217bf33765c943a
languageName: node
linkType: hard
"engine.io@npm:~6.5.2":
version: 6.5.5
resolution: "engine.io@npm:6.5.5"
dependencies:
"@types/cookie": ^0.4.1
"@types/cors": ^2.8.12
"@types/node": ">=10.0.0"
accepts: ~1.3.4
base64id: 2.0.0
cookie: ~0.4.1
cors: ~2.8.5
debug: ~4.3.1
engine.io-parser: ~5.2.1
ws: ~8.17.1
checksum: 358d337dd007b81cd6d7f39d0161ec8ec3a86097f0fbb0e10240eace51f836741f93c3e6bd69322b9ce0ad0fd89253a41e09335b6eb412d13e5357a054a90c4a
languageName: node
linkType: hard
"enhanced-resolve@npm:^2.2.2": "enhanced-resolve@npm:^2.2.2":
version: 2.3.0 version: 2.3.0
resolution: "enhanced-resolve@npm:2.3.0" resolution: "enhanced-resolve@npm:2.3.0"
@ -25715,7 +25656,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": "object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
version: 4.1.1 version: 4.1.1
resolution: "object-assign@npm:4.1.1" resolution: "object-assign@npm:4.1.1"
checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
@ -31107,40 +31048,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"socket.io-adapter@npm:~2.5.2":
version: 2.5.2
resolution: "socket.io-adapter@npm:2.5.2"
dependencies:
ws: ~8.11.0
checksum: 481251c3547221e57eb5cb247d0b1a3cde4d152a4c1c9051cc887345a7770e59f3b47f1011cac4499e833f01fcfc301ed13c4ec6e72f7dbb48a476375a6344cd
languageName: node
linkType: hard
"socket.io-parser@npm:~4.2.4":
version: 4.2.4
resolution: "socket.io-parser@npm:4.2.4"
dependencies:
"@socket.io/component-emitter": ~3.1.0
debug: ~4.3.1
checksum: 61540ef99af33e6a562b9effe0fad769bcb7ec6a301aba5a64b3a8bccb611a0abdbe25f469933ab80072582006a78ca136bf0ad8adff9c77c9953581285e2263
languageName: node
linkType: hard
"socket.io@npm:^4.6.2":
version: 4.7.5
resolution: "socket.io@npm:4.7.5"
dependencies:
accepts: ~1.3.4
base64id: ~2.0.0
cors: ~2.8.5
debug: ~4.3.2
engine.io: ~6.5.2
socket.io-adapter: ~2.5.2
socket.io-parser: ~4.2.4
checksum: b8b57216152cf230bdcb77b5450e124ebe1fee7482eeb50a6ef760b69f2f5a064e9b8640ce9c1efc5c9e081f5d797d3f6ff3f81606e19ddaf5d4114aad9ec7d3
languageName: node
linkType: hard
"sockjs@npm:^0.3.24": "sockjs@npm:^0.3.24":
version: 0.3.24 version: 0.3.24
resolution: "sockjs@npm:0.3.24" resolution: "sockjs@npm:0.3.24"
@ -33729,7 +33636,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vary@npm:^1, vary@npm:~1.1.2": "vary@npm:~1.1.2":
version: 1.1.2 version: 1.1.2
resolution: "vary@npm:1.1.2" resolution: "vary@npm:1.1.2"
checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b
@ -34776,36 +34683,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ws@npm:~8.11.0":
version: 8.11.0
resolution: "ws@npm:8.11.0"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
checksum: 316b33aba32f317cd217df66dbfc5b281a2f09ff36815de222bc859e3424d83766d9eb2bd4d667de658b6ab7be151f258318fb1da812416b30be13103e5b5c67
languageName: node
linkType: hard
"ws@npm:~8.17.1":
version: 8.17.1
resolution: "ws@npm:8.17.1"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2"
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf
languageName: node
linkType: hard
"xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz": "xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz":
version: 0.19.3 version: 0.19.3
resolution: "xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz" resolution: "xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz"