diff --git a/server/src/plugin/media.ts b/server/src/plugin/media.ts index 628901a13..2ef42b3cc 100644 --- a/server/src/plugin/media.ts +++ b/server/src/plugin/media.ts @@ -348,7 +348,7 @@ export abstract class MediaManagerBase implements MediaManager { fromMimeType: mediaObject.mimeType, toMimeType, convert: async (data, fromMimeType, toMimeType) => { - return mediaObject.convert(toMimeType); + return mediaObject.convert!(toMimeType); } }); @@ -366,10 +366,10 @@ export abstract class MediaManagerBase implements MediaManager { // connect the intrinsic converter to other converters for (const candidate of converters) { try { - const candidateMime = new MimeType(candidate.fromMimeType); + const candidateMime = new MimeType(candidate.fromMimeType!); if (!mimeMatches(convertedMime, candidateMime)) continue; - const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')) || (candidateMime.essence === '*/*' ? 1000 : 1); + const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')!) || (candidateMime.essence === '*/*' ? 1000 : 1); const candidateId = candidate.id; node[candidateId] = outputWeight; } @@ -381,10 +381,10 @@ export abstract class MediaManagerBase implements MediaManager { for (const converter of converters) { try { - const inputMime = new MimeType(converter.fromMimeType); - const convertedMime = new MimeType(converter.toMimeType); + const inputMime = new MimeType(converter.fromMimeType!); + const convertedMime = new MimeType(converter.toMimeType!); // catch all converters should be heavily weighted so as not to use them. - const inputWeight = parseFloat(inputMime.parameters.get('converter-weight')) || (inputMime.essence === '*/*' ? 1000 : 1); + const inputWeight = parseFloat(inputMime.parameters.get('converter-weight')!) || (inputMime.essence === '*/*' ? 1000 : 1); // const convertedWeight = parseFloat(convertedMime.parameters.get('converter-weight')) || (convertedMime.essence === ScryptedMimeTypes.MediaObject ? 1000 : 1); // const conversionWeight = inputWeight + convertedWeight; const targetId = converter.id; @@ -393,10 +393,10 @@ export abstract class MediaManagerBase implements MediaManager { // edge matches for (const candidate of converters) { try { - const candidateMime = new MimeType(candidate.fromMimeType); + const candidateMime = new MimeType(candidate.fromMimeType!); if (!mimeMatches(convertedMime, candidateMime)) continue; - const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')) || (candidateMime.essence === '*/*' ? 1000 : 1); + const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')!) || (candidateMime.essence === '*/*' ? 1000 : 1); const candidateId = candidate.id; node[candidateId] = inputWeight + outputWeight; } @@ -436,23 +436,23 @@ export abstract class MediaManagerBase implements MediaManager { let valueMime = new MimeType(mediaObject.mimeType); while (route.length) { - const node = route.shift(); - const converter = converterMap.get(node); - const converterToMimeType = new MimeType(converter.toMimeType); - const converterFromMimeType = new MimeType(converter.fromMimeType); + const node = route.shift()!; + const converter = converterMap.get(node)!; + const converterToMimeType = new MimeType(converter.toMimeType!); + const converterFromMimeType = new MimeType(converter.fromMimeType!); const type = converterToMimeType.type === '*' ? valueMime.type : converterToMimeType.type; const subtype = converterToMimeType.subtype === '*' ? valueMime.subtype : converterToMimeType.subtype; let targetMimeType = `${type}/${subtype}`; if (!route.length && outputMime.parameters.size) { const withParameters = new MimeType(targetMimeType); for (const k of outputMime.parameters.keys()) { - withParameters.parameters.set(k, outputMime.parameters.get(k)); + withParameters.parameters.set(k, outputMime.parameters.get(k)!); } targetMimeType = outputMime.toString(); } if (converter.toMimeType === ScryptedMimeTypes.MediaObject) { - const mo = await converter.convert(value, valueMime.essence, toMimeType, { sourceId }) as MediaObjectInterface; + const mo = await converter.convert!(value, valueMime.essence, toMimeType, { sourceId }) as MediaObjectInterface; const found = await this.convertMediaObject(mo, toMimeType); return { data: found, @@ -460,7 +460,7 @@ export abstract class MediaManagerBase implements MediaManager { }; } - value = await converter.convert(value, valueMime.essence, targetMimeType, { sourceId }) as string | Buffer; + value = await converter.convert!(value, valueMime.essence, targetMimeType, { sourceId }) as string | Buffer; valueMime = new MimeType(targetMimeType); } diff --git a/server/src/plugin/plugin-host.ts b/server/src/plugin/plugin-host.ts index eb404226e..12b876fd2 100644 --- a/server/src/plugin/plugin-host.ts +++ b/server/src/plugin/plugin-host.ts @@ -36,8 +36,8 @@ export class UnsupportedRuntimeError extends Error { } export class PluginHost { - worker: RuntimeWorker; - peer: RpcPeer; + worker!: RuntimeWorker; + peer!: RpcPeer; pluginId: string; module: Promise; scrypted: ScryptedRuntime; @@ -50,7 +50,7 @@ export class PluginHost { perMessageDeflate: true, cors: (req, callback) => { const header = this.scrypted.getAccessControlAllowOrigin(req.headers); - callback(undefined, { + callback(undefined!, { origin: header, credentials: true, }) @@ -61,11 +61,11 @@ export class PluginHost { pluginName: string; packageJson: any; killed = false; - consoleServer: Promise; + consoleServer!: Promise; zipHash: string; zipFile: string; unzippedPath: string; - clusterWorkerId: Promise; + clusterWorkerId!: Promise; kill() { this.killed = true; @@ -103,10 +103,11 @@ export class PluginHost { if (!needInvalidate) { // may also need to invalidate if the the plugin did not previously return a device // because it had not yet completed the discovery process. - const device = this.scrypted.devices[pi._id]; + const device = this.scrypted.devices[pi._id]!; try { - if (device.handler?.mixinTable) - needInvalidate = !(await device.handler.mixinTable?.[device.handler.mixinTable.length - 1].entry).proxy; + const handler = device.handler; + if (handler?.mixinTable) + needInvalidate = !(await handler.mixinTable?.[handler.mixinTable.length - 1]!.entry).proxy; } catch (e) { // device retrieval had previously failed, fetch again. @@ -125,16 +126,16 @@ export class PluginHost { this.pluginName = plugin.packageJson?.name; this.packageJson = plugin.packageJson; - const pluginDeviceId = scrypted.findPluginDevice(this.pluginId)._id; - const logger = scrypted.getDeviceLogger(scrypted.findPluginDevice(this.pluginId)); + const pluginDeviceId = scrypted.findPluginDevice(this.pluginId)!._id; + const logger = scrypted.getDeviceLogger(scrypted.findPluginDevice(this.pluginId)!)!; const volume = getScryptedVolume(); const pluginVolume = ensurePluginVolume(this.pluginId); { - const zipBuffer = Buffer.from(plugin.zip, 'base64'); + const zipBuffer = Buffer.from(plugin.zip!, 'base64'); // allow garbage collection of the base 64 contents - plugin = undefined; + (plugin as any) = undefined; const hash = crypto.createHash('md5').update(zipBuffer).digest().toString('hex'); this.zipHash = hash; @@ -146,7 +147,7 @@ export class PluginHost { const peerPromise = this.startPluginHost(logger, { SCRYPTED_VOLUME: volume, SCRYPTED_PLUGIN_VOLUME: pluginVolume, - }, pluginDebug); + }, pluginDebug!); this.io.on('connection', async (socket) => { try { @@ -157,8 +158,8 @@ export class PluginHost { } = (socket.request as any).scrypted; try { - if (socket.request.url.indexOf('/engine.io/api') !== -1) { - if (socket.request.url.indexOf('/public') !== -1) { + if (socket.request.url!.indexOf('/engine.io/api') !== -1) { + if (socket.request.url!.indexOf('/public') !== -1) { socket.close(); return; } @@ -205,13 +206,13 @@ export class PluginHost { ? new MediaManagerHostImpl(pluginDeviceId, () => scrypted.stateManager.getSystemState(), console, id => scrypted.getDevice(id)) : undefined; - this.api = new PluginHostAPI(scrypted, this.pluginId, this, mediaManager); + this.api = new PluginHostAPI(scrypted, this.pluginId, this, mediaManager!); logger.log('i', `loading ${this.pluginName}`); logger.log('i', 'pid ' + this.worker?.pid); - const remotePromise = this.prepareRemote(peerPromise, logger, pluginDebug); - const init = this.initializeRemote(remotePromise, logger, pluginDebug); + const remotePromise = this.prepareRemote(peerPromise, logger, pluginDebug!); + const init = this.initializeRemote(remotePromise, logger, pluginDebug!); init.catch(e => { console.error('plugin failed to load', e); @@ -280,7 +281,7 @@ export class PluginHost { } catch (e) { logger.log('e', 'plugin failed to start ' + e); - throw new RPCResultError(this.peer, 'cluster plugin start failed', e); + throw new RPCResultError(this.peer, 'cluster plugin start failed', e as Error | undefined); } const startupTime = Date.now(); @@ -333,8 +334,8 @@ export class PluginHost { let { runtime } = this.packageJson.scrypted; runtime ||= 'node'; - const pluginDevice = this.scrypted.findPluginDevice(this.pluginId); - const customRuntime = pluginDevice.state.interfaces.value.includes(ScryptedInterface.ScryptedPluginRuntime); + const pluginDevice = this.scrypted.findPluginDevice(this.pluginId)!; + const customRuntime = pluginDevice.state.interfaces!.value.includes(ScryptedInterface.ScryptedPluginRuntime); if (customRuntime) { runtime = 'custom'; } @@ -375,7 +376,7 @@ export class PluginHost { this.worker.stdout.on('data', data => console.log(data.toString())); this.worker.stderr.on('data', data => console.error(data.toString())); - this.clusterWorkerId = Promise.resolve(undefined); + this.clusterWorkerId = Promise.resolve(undefined!); } else { const scrypted: ClusterForkOptions = JSON.parse(JSON.stringify(this.packageJson.scrypted)); @@ -414,7 +415,7 @@ export class PluginHost { peer.killedSafe.finally(() => originalPeer.kill()); }).catch(() => { }); - this.clusterWorkerId = clusterWorkerId; + this.clusterWorkerId = clusterWorkerId as Promise; clusterWorkerId.then(clusterWorkerId => { console.log('cluster worker id', clusterWorkerId); }).catch(() => { @@ -483,7 +484,7 @@ export class PluginHost { serializer.sendMessage(message, reject, serializationContext); } catch (e) { - reject?.(e); + reject?.(e as Error); } }); rpcPeer.tags.acl = accessControls; @@ -500,6 +501,6 @@ export class PluginHost { socket.on('close', kill); socket.on('error', kill); - return setupPluginRemote(rpcPeer, api, null, { serverVersion }, () => this.scrypted.stateManager.getSystemState()); + return setupPluginRemote(rpcPeer, api, null!, { serverVersion }, () => this.scrypted.stateManager.getSystemState()); } }