diff --git a/app/src/bridge/Media.ts b/app/src/bridge/Media.ts index ee2fd41..62cd603 100644 --- a/app/src/bridge/Media.ts +++ b/app/src/bridge/Media.ts @@ -46,7 +46,7 @@ export default class Media { this.sendMessageCallback = sendMessageCallback; this.session.createChannel(MEDIA_NAMESPACE); - this.channel = this.session.channelMap.get(MEDIA_NAMESPACE); + this.channel = this.session.channelMap.get(MEDIA_NAMESPACE)!; this.channel.on("message", (data: any) => { if (data && data.type === "MEDIA_STATUS" diff --git a/app/src/bridge/Session.ts b/app/src/bridge/Session.ts index 76e1bc7..85080b4 100644 --- a/app/src/bridge/Session.ts +++ b/app/src/bridge/Session.ts @@ -20,16 +20,16 @@ export default class Session { private referenceId: string; private client: Client; - private clientConnection: Channel; - private clientHeartbeat: Channel; - private clientReceiver: Channel; - private clientHeartbeatIntervalId: NodeJS.Timer; + private clientConnection?: Channel; + private clientHeartbeat?: Channel; + private clientReceiver?: Channel; + private clientHeartbeatIntervalId?: NodeJS.Timer; private isSessionCreated = false; - private clientId: string; - private transportId: string; - private transportConnection: Channel; + private clientId?: string; + private transportId?: string; + private transportConnection?: Channel; private app: any; constructor ( @@ -67,7 +67,7 @@ export default class Session { transportHeartbeat.send({ type: "PING" }); } - this.clientHeartbeat.send({ type: "PING" }); + this.clientHeartbeat!.send({ type: "PING" }); }, 5000); this.clientReceiver.send({ @@ -94,7 +94,7 @@ export default class Session { // Close session this.sendMessage("shim:/session/stopped"); this.client.close(); - clearInterval(this.clientHeartbeatIntervalId); + clearInterval(this.clientHeartbeatIntervalId!); return; } @@ -106,10 +106,10 @@ export default class Session { `client-${Math.floor(Math.random() * 10e5)}`; this.transportConnection = this.client.createChannel( - this.clientId, this.transportId + this.clientId, this.transportId! , NS_CONNECTION, "JSON"); transportHeartbeat = this.client.createChannel( - this.clientId, this.transportId + this.clientId, this.transportId! , NS_HEARTBEAT, "JSON"); this.transportConnection.send({ type: "CONNECT" }); @@ -167,12 +167,12 @@ export default class Session { if (!this.channelMap.has(namespace)) { this.channelMap.set(namespace , this.client.createChannel( - this.clientId, this.transportId, namespace, "JSON")); + this.clientId!, this.transportId!, namespace, "JSON")); } } public close () { - this.clientConnection.send({ type: "CLOSE" }); + this.clientConnection!.send({ type: "CLOSE" }); if (this.transportConnection) { this.transportConnection.send({ type: "CLOSE" }); } @@ -188,7 +188,7 @@ export default class Session { private _impl_addMessageListener (namespace: string) { this.createChannel(namespace); - this.channelMap.get(namespace).on("message", (data: any) => { + this.channelMap.get(namespace)!.on("message", (data: any) => { this.sendMessage("shim:/session/impl_addMessageListener", { namespace , data: JSON.stringify(data) @@ -205,7 +205,7 @@ export default class Session { try { this.createChannel(namespace); - this.channelMap.get(namespace).send(message); + this.channelMap.get(namespace)!.send(message); } catch (err) { error = true; } @@ -221,7 +221,7 @@ export default class Session { let error = false; try { - this.clientReceiver.send({ + this.clientReceiver!.send({ type: "SET_VOLUME" , volume: { muted } , requestId: 0 @@ -241,7 +241,7 @@ export default class Session { let error = false; try { - this.clientReceiver.send({ + this.clientReceiver!.send({ type: "SET_VOLUME" , volume: { level: newLevel } , requestId: 0 @@ -260,7 +260,7 @@ export default class Session { let error = false; try { - this.clientReceiver.send({ + this.clientReceiver!.send({ type: "STOP" , sessionId: this.sessionId , requestId: 0 @@ -271,7 +271,7 @@ export default class Session { this.client.close(); - clearInterval(this.clientHeartbeatIntervalId); + clearInterval(this.clientHeartbeatIntervalId!); this.sendMessage("shim:/session/impl_stop", { stopId diff --git a/app/src/bridge/StatusListener.ts b/app/src/bridge/StatusListener.ts index e00a7a9..f15a8b6 100644 --- a/app/src/bridge/StatusListener.ts +++ b/app/src/bridge/StatusListener.ts @@ -14,8 +14,8 @@ const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver"; */ export default class StatusListener extends EventEmitter { private client: Client; - private clientReceiver: Channel; - private clientHeartbeatIntervalId: number; + private clientReceiver?: Channel; + private clientHeartbeatIntervalId?: number; constructor ( private host: string @@ -35,7 +35,10 @@ export default class StatusListener extends EventEmitter { * Closes status listener connection. */ public deregister (): void { - this.clientReceiver.send({ type: "CLOSE" }); + if (this.clientReceiver) { + this.clientReceiver.send({ type: "CLOSE" }); + } + this.client.close(); } diff --git a/app/src/bridge/airplay/auth.ts b/app/src/bridge/airplay/auth.ts index c8e196a..bb3918f 100644 --- a/app/src/bridge/airplay/auth.ts +++ b/app/src/bridge/airplay/auth.ts @@ -26,10 +26,15 @@ export class AirPlayAuthCredentials { public clientSk: Uint8Array; public clientPk: Uint8Array; - constructor (clientId: string, clientSk: Uint8Array) { - if (clientId && clientSk) { + constructor ( + clientId?: string + , clientSk?: Uint8Array + , clientPk?: Uint8Array) { + + if (clientId && clientSk && clientPk) { this.clientId = clientId; this.clientSk = clientSk; + this.clientPk = clientPk; } else { // If specified without arguments, generate new credentials const keyPair = nacl.sign.keyPair(); @@ -190,7 +195,7 @@ export class AirPlayAuth { }); // Append Content-Type header if request has body - if (data) { + if (data && contentType) { requestHeaders.append("Content-Type", contentType); } diff --git a/app/src/bridge/index.ts b/app/src/bridge/index.ts index 3b86c36..adacc8a 100755 --- a/app/src/bridge/index.ts +++ b/app/src/bridge/index.ts @@ -82,22 +82,26 @@ let receiverSelectorApp: child_process.ChildProcess; */ async function handleMessage (message: Message) { if (message.subject.startsWith("bridge:/media/")) { - if (existingMedia.has(message._id)) { + const mediaId = message._id!; + + if (existingMedia.has(mediaId)) { // Forward message to instance message handler - existingMedia.get(message._id).messageHandler(message); + existingMedia.get(mediaId)!.messageHandler(message); } else { if (message.subject.endsWith("/initialize")) { // Get Session object media belongs to const parentSession = existingSessions.get( message.data._internalSessionId); - // Create Media - existingMedia.set(message._id, new Media( - message.data.sessionId - , message.data.mediaSessionId - , message._id - , parentSession - , sendMessage)); + if (parentSession) { + // Create Media + existingMedia.set(mediaId, new Media( + message.data.sessionId + , message.data.mediaSessionId + , mediaId + , parentSession + , sendMessage)); + } } } @@ -105,18 +109,20 @@ async function handleMessage (message: Message) { } if (message.subject.startsWith("bridge:/session/")) { - if (existingSessions.has(message._id)) { + const sessionId = message._id!; + + if (existingSessions.has(sessionId)) { // Forward message to instance message handler - existingSessions.get(message._id).messageHandler(message); + existingSessions.get(sessionId)!.messageHandler(message); } else { if (message.subject.endsWith("/initialize")) { // Create Session - existingSessions.set(message._id, new Session( + existingSessions.set(sessionId, new Session( message.data.address , message.data.port , message.data.appId , message.data.sessionId - , message._id + , sessionId , sendMessage)); } } @@ -161,8 +167,8 @@ async function handleMessage (message: Message) { path.join(process.cwd(), "selector") , [ receiverSelectorData ]); - receiverSelectorApp.stdout.setEncoding("utf8"); - receiverSelectorApp.stdout.on("data", data => { + receiverSelectorApp.stdout!.setEncoding("utf8"); + receiverSelectorApp.stdout!.on("data", data => { sendMessage({ subject: "main:/receiverSelector/selected" , data: JSON.parse(data) @@ -280,7 +286,7 @@ function initialize (options: InitializeOptions) { } }; - if ("applications" in status) { + if (status.applications && status.applications.length) { const application = status.applications[0]; receiverStatusMessage.data.status.application = { @@ -300,7 +306,7 @@ function initialize (options: InitializeOptions) { const { id } = service.txt; if (statusListeners.has(id)) { - statusListeners.get(id).deregister(); + statusListeners.get(id)!.deregister(); statusListeners.delete(id); } } diff --git a/app/src/transforms.ts b/app/src/transforms.ts index 237a0f5..0fde151 100755 --- a/app/src/transforms.ts +++ b/app/src/transforms.ts @@ -43,7 +43,7 @@ export class ResponseTransform extends Transform { export class DecodeTransform extends Transform { // Message data private _messageBuffer = Buffer.alloc(0); - private _messageLength: number = null; + private _messageLength?: number; constructor () { super({ @@ -64,7 +64,7 @@ export class DecodeTransform extends Transform { ]); for (;;) { - if (this._messageLength === null) { + if (this._messageLength === undefined) { if (this._messageBuffer.length >= 4) { // Read message length and offset buffer this._messageLength = this._messageBuffer.readUInt32LE(0); @@ -85,7 +85,7 @@ export class DecodeTransform extends Transform { // Offset buffer to start of next message this._messageBuffer = this._messageBuffer.slice( this._messageLength); - this._messageLength = null; + this._messageLength = undefined; // Next message continue; diff --git a/app/tsconfig.json b/app/tsconfig.json index 1ec6cdb..7fa281f 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -4,4 +4,7 @@ "./src/**/*" , "./@types/**/*" ] + , "compilerOptions": { + "strict": true + } }