mirror of
https://github.com/koush/scrypted.git
synced 2026-09-17 09:10:38 +01:00
server: use unzipped plugin path where possible
This commit is contained in:
@@ -4,7 +4,7 @@ import { SystemManager, DeviceManager, ScryptedNativeId, Device, EventListenerRe
|
||||
import { ScryptedRuntime } from '../runtime';
|
||||
import { Plugin } from '../db-types';
|
||||
import io, { Socket } from 'engine.io';
|
||||
import { attachPluginRemote, setupPluginRemote } from './plugin-remote';
|
||||
import { attachPluginRemote, PluginReader, setupPluginRemote } from './plugin-remote';
|
||||
import { PluginAPI, PluginAPIProxy, PluginRemote, PluginRemoteLoadZipOptions } from './plugin-api';
|
||||
import { Logger } from '../logger';
|
||||
import { MediaManagerHostImpl, MediaManagerImpl } from './media';
|
||||
@@ -560,9 +560,9 @@ export function startPluginRemote() {
|
||||
}
|
||||
throw new Error(`unknown service ${name}`);
|
||||
},
|
||||
async onLoadZip(zip: AdmZip, packageJson: any) {
|
||||
const entry = zip.getEntry('main.nodejs.js.map')
|
||||
const map = entry?.getData().toString();
|
||||
async onLoadZip(pluginReader: PluginReader, packageJson: any) {
|
||||
const entry = pluginReader('main.nodejs.js.map')
|
||||
const map = entry?.toString();
|
||||
|
||||
installSourceMapSupport({
|
||||
environment: 'node',
|
||||
|
||||
@@ -28,8 +28,8 @@ export abstract class PluginHttp<T> {
|
||||
});
|
||||
}
|
||||
|
||||
abstract handleEngineIOEndpoint(req: Request, res: ServerResponse, endpointRequest: HttpRequest, pluginData: T): Promise<void>;
|
||||
abstract handleRequestEndpoint(req: Request, res: Response, endpointRequest: HttpRequest, pluginData: T): Promise<void>;
|
||||
abstract handleEngineIOEndpoint(req: Request, res: ServerResponse, endpointRequest: HttpRequest, pluginData: T): void;
|
||||
abstract handleRequestEndpoint(req: Request, res: Response, endpointRequest: HttpRequest, pluginData: T): void;
|
||||
abstract getEndpointPluginData(endpoint: string, isUpgrade: boolean, isEngineIOEndpoint: boolean): Promise<T>;
|
||||
abstract handleWebSocket(endpoint: string, httpRequest: HttpRequest, ws: WebSocket, pluginData: T): Promise<void>;
|
||||
|
||||
|
||||
@@ -308,13 +308,15 @@ export interface WebSocketCustomHandler {
|
||||
methods: WebSocketMethods;
|
||||
}
|
||||
|
||||
export type PluginReader = (name: string) => Buffer;
|
||||
|
||||
export interface PluginRemoteAttachOptions {
|
||||
createMediaManager?: (systemManager: SystemManager) => Promise<MediaManager>;
|
||||
getServicePort?: (name: string, ...args: any[]) => Promise<number>;
|
||||
getDeviceConsole?: (nativeId?: ScryptedNativeId) => Console;
|
||||
getPluginConsole?: () => Console;
|
||||
getMixinConsole?: (id: string, nativeId?: ScryptedNativeId) => Console;
|
||||
onLoadZip?: (zip: AdmZip, packageJson: any) => Promise<void>;
|
||||
onLoadZip?: (pluginReader: PluginReader, packageJson: any) => Promise<void>;
|
||||
onGetRemote?: (api: PluginAPI, pluginId: string) => Promise<void>;
|
||||
onPluginReady?: (scrypted: ScryptedStatic, params: any, plugin: any) => Promise<void>;
|
||||
}
|
||||
@@ -438,21 +440,22 @@ export function attachPluginRemote(peer: RpcPeer, options?: PluginRemoteAttachOp
|
||||
|
||||
async loadZip(packageJson: any, zipData: Buffer | string, zipOptions?: PluginRemoteLoadZipOptions) {
|
||||
const pluginConsole = getPluginConsole?.();
|
||||
let zip = new AdmZip(zipData);
|
||||
zipData = undefined;
|
||||
await options?.onLoadZip?.(zip, packageJson);
|
||||
const main = zip.getEntry('main.nodejs.js');
|
||||
const script = main.getData().toString();
|
||||
const window: any = {};
|
||||
const exports: any = window;
|
||||
window.exports = exports;
|
||||
|
||||
let volume: any;
|
||||
if (zipOptions?.unzippedPath && fs.existsSync(path.join(zipOptions.unzippedPath, 'fs'))) {
|
||||
let pluginReader: PluginReader;
|
||||
if (zipOptions?.unzippedPath && fs.existsSync(zipOptions?.unzippedPath)) {
|
||||
volume = link(fs, ['', path.join(zipOptions.unzippedPath, 'fs')]);
|
||||
pluginReader = name => {
|
||||
const filename = path.join(zipOptions.unzippedPath, name);
|
||||
if (!fs.existsSync(filename))
|
||||
return;
|
||||
return fs.readFileSync(filename);
|
||||
};
|
||||
}
|
||||
else {
|
||||
for (const entry of zip.getEntries()) {
|
||||
const admZip = new AdmZip(zipData);
|
||||
volume = new Volume();
|
||||
for (const entry of admZip.getEntries()) {
|
||||
if (entry.isDirectory)
|
||||
continue;
|
||||
if (!entry.entryName.startsWith('fs/'))
|
||||
@@ -462,8 +465,24 @@ export function attachPluginRemote(peer: RpcPeer, options?: PluginRemoteAttachOp
|
||||
const data = entry.getData();
|
||||
volume.writeFileSync(name, data);
|
||||
}
|
||||
|
||||
pluginReader = name => {
|
||||
const entry = admZip.getEntry(name);
|
||||
if (!entry)
|
||||
return;
|
||||
return entry.getData();
|
||||
}
|
||||
}
|
||||
zip = undefined;
|
||||
zipData = undefined;
|
||||
|
||||
await options?.onLoadZip?.(pluginReader, packageJson);
|
||||
const main = pluginReader('main.nodejs.js');
|
||||
pluginReader = undefined;
|
||||
const script = main.toString();
|
||||
const window: any = {};
|
||||
const exports: any = window;
|
||||
window.exports = exports;
|
||||
|
||||
|
||||
function websocketConnect(url: string, protocols: any, callbacks: WebSocketConnectCallbacks) {
|
||||
if (url.startsWith('io://') || url.startsWith('ws://')) {
|
||||
|
||||
@@ -313,7 +313,7 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
|
||||
}
|
||||
}
|
||||
|
||||
async handleEngineIOEndpoint(req: Request, res: ServerResponse, endpointRequest: HttpRequest, pluginData: HttpPluginData) {
|
||||
handleEngineIOEndpoint(req: Request, res: ServerResponse, endpointRequest: HttpRequest, pluginData: HttpPluginData) {
|
||||
const { pluginHost, pluginDevice } = pluginData;
|
||||
|
||||
(req as any).scrypted = {
|
||||
@@ -326,7 +326,7 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
|
||||
pluginHost.io.handleRequest(req, res);
|
||||
}
|
||||
|
||||
async handleRequestEndpoint(req: Request, res: Response, endpointRequest: HttpRequest, pluginData: HttpPluginData) {
|
||||
handleRequestEndpoint(req: Request, res: Response, endpointRequest: HttpRequest, pluginData: HttpPluginData) {
|
||||
const { pluginHost, pluginDevice } = pluginData;
|
||||
const handler = this.getDevice<HttpRequestHandler>(pluginDevice._id);
|
||||
if (handler.interfaces.includes(ScryptedInterface.EngineIOHandler) && req.headers.connection === 'upgrade' && req.headers.upgrade?.toLowerCase() === 'websocket') {
|
||||
|
||||
Reference in New Issue
Block a user