UNPKG

kodi-api

Version:

A complete implementation of Kodi JSON-RPC calls in an easy-to-use Javascript/TypeScript client.

118 lines (117 loc) 5.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KodiClient = void 0; const promise_1 = require("jayson/promise"); const uuid_1 = require("uuid"); const KodiIntrospect_1 = require("./KodiIntrospect"); const KodiMethodNamespace_1 = require("./KodiMethodNamespace"); const WebSocketClient_1 = require("./WebSocketClient"); const numeric = /^\d+$/gu; /** Class for dynamically calling the Kodi JSON-RPC api, regardless of api version. */ class KodiClient { constructor(options) { this.throwValidationError = typeof options.throwValidationError === 'undefined' ? false : options.throwValidationError; this.clientType = options.clientType; // Initialize as undefined so that key can be looked up, like `key in this`. this.introspectionCache = undefined; switch (options.clientType) { case 'http': this.jsonRpcClient = promise_1.Client.http({ port: 8080, ...options.clientOptions }); break; case 'https': this.jsonRpcClient = promise_1.Client.https({ ...options.clientOptions }); break; case 'ws': this.jsonRpcClient = new WebSocketClient_1.WebSocketClient({ ...options.clientOptions }); break; case 'tcp': default: this.jsonRpcClient = promise_1.Client.tcp({ ...{ port: 9090 }, ...options.clientOptions }); break; } return new Proxy(this, KodiProxyHandler); } /** Method to manually connect to the defined web socket; silently returns for any other client type. */ async connect() { if (this.jsonRpcClient instanceof WebSocketClient_1.WebSocketClient) { await this.jsonRpcClient.connect(); } } /** Method to manually disconnect from the defined web socket; silently returns for any other client type. */ async disconnect() { if (this.jsonRpcClient instanceof WebSocketClient_1.WebSocketClient) { await this.jsonRpcClient.disconnect(); } } /** Method to get and cache the introspection result on this instance. */ async getIntrospectionCache(refresh = false) { if (typeof this.introspectionCache === 'undefined' || refresh) { const result = await this.jsonRpcClient.request('JSONRPC.Introspect', null, uuid_1.v4()); this.introspectionCache = new KodiIntrospect_1.KodiIntrospect(result); } return this.introspectionCache; } async listMethods(group = false) { await this.getIntrospectionCache(); return this.introspectionCache.listMethods(group); } /** Construct an HTTP instance with Kodi defaults. */ static http() { return new KodiClient({ clientType: 'http' }); } /** Construct an HTTPS instance with Kodi defaults. __NOTE:__ _Kodi does not natively or officially support HTTPS; some users have unofficially found a way, though._ */ static https() { return new KodiClient({ clientType: 'https' }); } /** Construct a TCP instance with Kodi defaults. */ static tcp() { return new KodiClient({ clientType: 'tcp' }); } /** Construct a WebSocket instance with Kodi defaults. */ static ws() { return new KodiClient({ clientType: 'ws' }); } } exports.KodiClient = KodiClient; /** @hidden */ const KodiProxyHandler = { get(target, nameSpace, r) { // Short-circuit if namespace already exists on target. if (nameSpace in target) return target[nameSpace]; if (typeof nameSpace !== 'string' || (/^\d+$/gu).test(nameSpace)) return void 0; const listMethods = async function listMethods() { await target.getIntrospectionCache(); const groups = await target.listMethods(true); return groups[nameSpace]; }; return new Proxy({ ListMethods: listMethods, listMethods }, { get(subTarget, methodName, r) { if (methodName in subTarget) return subTarget[methodName]; if (typeof methodName !== 'string' || numeric.test(methodName)) return void 0; // Construct a namespace object as a caching mechanism. const newNameSpace = new KodiMethodNamespace_1.KodiMethodNamespace(nameSpace, methodName, target); // Store the namespace on the original `this`. target[nameSpace] = newNameSpace; // Return the requested method from the namespace. return newNameSpace[methodName]; } }); } };