mirror of
https://github.com/koush/scrypted.git
synced 2026-02-12 18:12:04 +00:00
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { EventEmitter } from 'ws';
|
|
import { listenZero } from './listen-zero';
|
|
import { Server } from 'net';
|
|
import { once } from 'events';
|
|
import repl from 'repl';
|
|
import { ScryptedStatic } from '@scrypted/sdk';
|
|
|
|
export async function createREPLServer(scrypted: ScryptedStatic, params: any, plugin: any): Promise<number> {
|
|
const { deviceManager, systemManager } = scrypted;
|
|
const server = new Server(async (socket) => {
|
|
let [filter] = await once(socket, 'data');
|
|
filter = filter.toString().trim();
|
|
if (filter === 'undefined')
|
|
filter = undefined;
|
|
|
|
const chain: string[] = [];
|
|
const nativeIds: Map<string, any> = (deviceManager as any).nativeIds;
|
|
const reversed = new Map<string, string>();
|
|
for (const nativeId of nativeIds.keys()) {
|
|
reversed.set(nativeIds.get(nativeId).id, nativeId);
|
|
}
|
|
|
|
while (filter) {
|
|
const { id } = nativeIds.get(filter);
|
|
const d = await systemManager.getDeviceById(id);
|
|
chain.push(filter);
|
|
filter = reversed.get(d.providerId);
|
|
}
|
|
|
|
chain.reverse();
|
|
let device = plugin;
|
|
for (const c of chain) {
|
|
device = await device.getDevice(c);
|
|
}
|
|
|
|
const ctx = Object.assign(params, {
|
|
device
|
|
});
|
|
delete ctx.console;
|
|
delete ctx.window;
|
|
delete ctx.WebSocket;
|
|
delete ctx.pluginHostAPI;
|
|
|
|
const replFilter = new Set<string>(['require', 'localStorage'])
|
|
const replVariables = Object.keys(ctx).filter(key => !replFilter.has(key));
|
|
|
|
const welcome = `JavaScript REPL variables:\n${replVariables.map(key => ' ' + key).join('\n')}\n\n`;
|
|
socket.write(welcome);
|
|
|
|
const r = repl.start({
|
|
terminal: true,
|
|
input: socket,
|
|
output: socket,
|
|
// writer(this: REPLServer, obj: any) {
|
|
// const ret = util.inspect(obj, {
|
|
// colors: true,
|
|
// });
|
|
// return ret;//.replaceAll('\n', '\r\n');
|
|
// },
|
|
preview: false,
|
|
});
|
|
|
|
Object.assign(r.context, ctx);
|
|
|
|
const cleanup = () => {
|
|
r.close();
|
|
};
|
|
|
|
socket.on('close', cleanup);
|
|
socket.on('error', cleanup);
|
|
socket.on('end', cleanup);
|
|
});
|
|
return listenZero(server);
|
|
}
|