UNPKG

@gibme/tablo.tv

Version:

API interface for interacting with a Tablo TV device

308 lines 12.5 kB
"use strict"; // Copyright (c) 2025, Brandon Lehmann <brandonlehmann@gmail.com> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Lighthouse = void 0; const fetch_1 = __importDefault(require("@gibme/fetch")); const logger_1 = __importDefault(require("@gibme/logger")); class Lighthouse { // eslint-disable-next-line no-useless-constructor constructor(email, password, timeout = 2000, request_logging = false) { this.email = email; this.password = password; this.timeout = timeout; this.request_logging = request_logging; this.context_token = ''; } get authenticated() { return !!this.token; } get base_uri() { return Lighthouse.base_uri; } static execute(method_1, endpoint_1) { return __awaiter(this, arguments, void 0, function* (method, endpoint, params = {}, payload, timeout = 2000) { const qs = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { qs.set(key, value); } const url = endpoint.includes('://') ? `${endpoint}?${qs.toString()}` : `${this.base_uri}${endpoint}?${qs.toString()}`; const response = yield (0, fetch_1.default)(url, { json: (method === 'PATCH' || method === 'POST' || method === 'PUT') ? payload : undefined, method, timeout }); if (!response.ok) { throw new Error(`${response.url} [${response.status}] ${response.statusText}`); } return yield response.json(); }); } /** * Retrieves a list of devices associated with the network from which this API call is made. * @param timeout */ static listAvailableDevices() { return __awaiter(this, arguments, void 0, function* (timeout = 2000) { var _a; try { return ((_a = yield this.get('/devices/', undefined, timeout)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Retrieves a list of virtual devices associated with the network from which this API call is made. * @param timeout */ static listVirtualDevices() { return __awaiter(this, arguments, void 0, function* (timeout = 2000) { var _a; try { return ((_a = yield this.get('/devices/virtual/', undefined, timeout)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Attempts to retrieve the specified virtual device associated with the network from which this API call is made. * @param server_id * @param timeout */ static virtualDevice(server_id_1) { return __awaiter(this, arguments, void 0, function* (server_id, timeout = 2000) { try { return yield this.get(`/devices/virtual/${server_id}/`, undefined, timeout); } catch (_a) { } }); } static get(endpoint_1) { return __awaiter(this, arguments, void 0, function* (endpoint, params = {}, timeout = 2000) { return this.execute('GET', endpoint, params, undefined, timeout); }); } /** * Retrieves the account information */ accountInfo() { return __awaiter(this, arguments, void 0, function* (timeout = this.timeout) { try { return yield this.get('/account/', undefined, timeout); } catch (_a) { } }); } /** * Retrieves the current airing information for the specified channel within the specified device context * @param channel_id * @param context_token * @param timeout */ channelAirings(channel_id_1) { return __awaiter(this, arguments, void 0, function* (channel_id, context_token = this.context_token, timeout = this.timeout) { var _a; try { return ((_a = yield this.get(`/account/guide/channels/${channel_id}/live/`, undefined, timeout, context_token)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Retrieves the list of live airings for the specified device context * @param context_token * @param timeout */ currentLiveAirings() { return __awaiter(this, arguments, void 0, function* (context_token = this.context_token, timeout = this.timeout) { var _a; try { return ((_a = yield this.get(`/account/${context_token}/guide/channels/live/`, undefined, timeout, context_token)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Retrieves a list of the devices associated with the account */ devices() { return __awaiter(this, arguments, void 0, function* (timeout = this.timeout) { var _a; try { return ((_a = yield this.get('/account/devices/', undefined, timeout)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Retrieves the list of channels available within the specified device context * @param context_token * @param timeout */ guideChannels() { return __awaiter(this, arguments, void 0, function* (context_token = this.context_token, timeout = this.timeout) { var _a; try { return ((_a = yield this.get(`/account/${context_token}/guide/channels/`, undefined, timeout, context_token)) !== null && _a !== void 0 ? _a : []); } catch (_b) { return []; } }); } /** * Attempts to retrieve information regarding a specific device associated with the account * @param server_id * @param timeout */ resolveDevice(server_id_1) { return __awaiter(this, arguments, void 0, function* (server_id, timeout = this.timeout) { try { return yield this.get(`/account/devices/${server_id}/resolve/`, undefined, timeout); } catch (_a) { } }); } /** * Selects the device context based upon the specified `profile_id` and `server_id`. * @param profile_id * @param server_id * @param timeout */ selectDeviceContext(profile_id_1, server_id_1) { return __awaiter(this, arguments, void 0, function* (profile_id, server_id, timeout = this.timeout) { try { const { token } = yield this.post('/account/select/', { pid: profile_id, sid: server_id }, timeout); if (token) { this.context_token = token; } return token; } catch (_a) { } }); } get(endpoint_1) { return __awaiter(this, arguments, void 0, function* (endpoint, params = {}, timeout = this.timeout, token) { return this.execute('GET', endpoint, params, undefined, timeout, token); }); } post(endpoint_1, payload_1) { return __awaiter(this, arguments, void 0, function* (endpoint, payload, timeout = this.timeout, token) { return this.execute('POST', endpoint, {}, payload, timeout, token); }); } authenticate() { return __awaiter(this, arguments, void 0, function* (timeout = this.timeout) { try { const response = yield (0, fetch_1.default)(`${this.base_uri}/login/`, { method: 'POST', json: { email: this.email, password: this.password }, timeout }); if (response.ok) { this.token = yield response.json(); return true; } delete this.token; return false; } catch (_a) { return false; } }); } execute(method_1, endpoint_1) { return __awaiter(this, arguments, void 0, function* (method, endpoint, params = {}, payload, timeout = this.timeout, token, is_retry = false) { var _a, _b; if (!this.token && !(yield this.authenticate(timeout))) { throw new Error('Failed to authenticate with Lighthouse API'); } const headers = { Accept: 'application/json', Authorization: `${(_a = this.token) === null || _a === void 0 ? void 0 : _a.token_type} ${(_b = this.token) === null || _b === void 0 ? void 0 : _b.access_token}` }; if (token) { headers.Lighthouse = token; } const qs = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { qs.set(key, value); } const url = endpoint.includes('://') ? `${endpoint}?${qs.toString()}` : `${this.base_uri}${endpoint}?${qs.toString()}`; if (this.request_logging) { logger_1.default.debug('%s %s %s %s', method, JSON.stringify(headers), url, payload ? JSON.stringify(payload) : ''); } const response = yield (0, fetch_1.default)(url, { headers, json: (method === 'PATCH' || method === 'POST' || method === 'PUT') ? payload : undefined, method }); if (!response.ok) { if (response.status === 401 && !is_retry) { if (yield this.authenticate(timeout)) { return this.execute(method, endpoint, params, payload, timeout, token, true); } } throw new Error(`${response.url} [${response.status}] ${response.statusText}`); } return yield response.json(); }); } } exports.Lighthouse = Lighthouse; Lighthouse.base_uri = 'https://lighthousetv.ewscloud.com/api/v2'; exports.default = Lighthouse; //# sourceMappingURL=lighthouse.js.map