Add remote console capabilities
This commit is contained in:
96
remote_console/application/index.js
Normal file
96
remote_console/application/index.js
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const winston = require("winston");
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: "debug",
|
||||
format: winston.format.combine(
|
||||
winston.format.splat(),
|
||||
winston.format.colorize(),
|
||||
winston.format.simple()
|
||||
),
|
||||
transports: [new winston.transports.Console()],
|
||||
});
|
||||
|
||||
/**
|
||||
* Generator function to stream responses from fetch calls.
|
||||
*
|
||||
* @param {Function} fetchcall - The fetch call to make. Should return a response with a readable body stream.
|
||||
* @returns {AsyncGenerator<string>} An async generator that yields strings from the response stream.
|
||||
*/
|
||||
async function* streamingFetch(fetchcall) {
|
||||
const response = await fetchcall();
|
||||
// Attach Reader
|
||||
const reader = response.body.getReader();
|
||||
while (true) {
|
||||
// wait for next encoded chunk
|
||||
const { done, value } = await reader.read();
|
||||
// check if stream is done
|
||||
if (done) break;
|
||||
// Decodes data chunk and yields it
|
||||
yield new TextDecoder().decode(value);
|
||||
}
|
||||
}
|
||||
|
||||
function splitByBraces(str) {
|
||||
const matches = [];
|
||||
const regex = /\{[^}]*\}/g;
|
||||
let match;
|
||||
while ((match = regex.exec(str)) !== null) {
|
||||
matches.push(match[0]); // Includes the braces
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
for await (let chunk of streamingFetch(() =>
|
||||
fetch(
|
||||
"https://iva.mortons.site/webdis/SUBSCRIBE/67bca862210071627d32ef12.console"
|
||||
)
|
||||
)) {
|
||||
try {
|
||||
messages = splitByBraces(chunk);
|
||||
if (messages.length === 0) {
|
||||
logger.warn("No messages found in chunk: %s", chunk);
|
||||
continue;
|
||||
}
|
||||
|
||||
messages.forEach((rawMessage) => {
|
||||
const message = JSON.parse(rawMessage);
|
||||
|
||||
if (
|
||||
message["SUBSCRIBE"] &&
|
||||
message["SUBSCRIBE"][0] === "message" &&
|
||||
message["SUBSCRIBE"].length >= 3
|
||||
) {
|
||||
// Decode the base64 string
|
||||
const decodedString = Buffer.from(
|
||||
message["SUBSCRIBE"][2],
|
||||
"base64"
|
||||
).toString("utf-8");
|
||||
const messageObject = JSON.parse(decodedString);
|
||||
|
||||
const logMessage = JSON.parse(messageObject.data)[0][0][0];
|
||||
|
||||
switch (messageObject.level) {
|
||||
case "INFO":
|
||||
logger.info("%O", logMessage);
|
||||
break;
|
||||
case "DEBUG":
|
||||
logger.debug(logMessage);
|
||||
break;
|
||||
case "WARN":
|
||||
logger.warn(logMessage);
|
||||
break;
|
||||
case "ERROR":
|
||||
logger.error(logMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("Error parsing message: %O", error);
|
||||
logger.error("Original chunk: %s", chunk);
|
||||
}
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user