@jellyfin/sdk
Version:
A TypeScript SDK for Jellyfin.
111 lines (108 loc) • 4.63 kB
JavaScript
import { RecommendedServerInfoScore } from '../models/recommended-server-info.js';
import { SystemInfoIssue, ProductNameIssue, VersionMissingIssue, VersionUnsupportedIssue, VersionOutdatedIssue, SlowResponseIssue } from '../models/recommended-server-issue.js';
import { getSystemApi } from '../utils/api/system-api.js';
import { isVersionLess } from '../utils/versioning.js';
import { MINIMUM_VERSION, API_VERSION } from '../versions.js';
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/** The expected product name in system info. */
const PRODUCT_NAME = 'Jellyfin Server';
/** Requests taking longer than 3s are considered slow. */
const SLOW_RESPONSE_TIME = 3000;
/** System info request timeout. */
const HTTP_TIMEOUT = 5000;
/** Get the minimum RecommendedServerInfoScore from an array. */
function getMinScore(scores, defaultScore = RecommendedServerInfoScore.GREAT) {
return scores.length > 0 ? Math.min(...scores) : defaultScore;
}
/** Builds a RecommendedServerInfo from a SystemInfoResult. */
function toRecommendedServerInfo(result) {
var _a, _b, _c;
const issues = [];
const scores = [];
if (!((_a = result.response) === null || _a === void 0 ? void 0 : _a.data) || result.error) {
// The response did not return valid data or returned an error
issues.push(new SystemInfoIssue(result.error));
scores.push(RecommendedServerInfoScore.BAD);
}
else if (result.response.data.ProductName !== PRODUCT_NAME) {
// The product name returned was invalid
issues.push(new ProductNameIssue(result.response.data.ProductName));
scores.push(RecommendedServerInfoScore.BAD);
}
const version = (_b = result.response) === null || _b === void 0 ? void 0 : _b.data.Version;
try {
if (!version) {
// No version was returned
issues.push(new VersionMissingIssue());
scores.push(RecommendedServerInfoScore.BAD);
}
else if (isVersionLess(version, MINIMUM_VERSION)) {
// Version is less than the minimum supported
issues.push(new VersionUnsupportedIssue(version));
scores.push(RecommendedServerInfoScore.OK);
}
else if (isVersionLess(version, API_VERSION)) {
// Version is less than the generated client, but above the minimum
issues.push(new VersionOutdatedIssue(version));
scores.push(RecommendedServerInfoScore.GOOD);
}
}
catch (error) {
if (error instanceof TypeError) {
issues.push(new VersionMissingIssue());
scores.push(RecommendedServerInfoScore.BAD);
}
}
if (result.responseTime > SLOW_RESPONSE_TIME) {
// Response was slow
issues.push(new SlowResponseIssue(result.responseTime));
scores.push(RecommendedServerInfoScore.GOOD);
}
return {
address: result.address,
responseTime: result.responseTime,
score: getMinScore(scores),
issues,
systemInfo: (_c = result.response) === null || _c === void 0 ? void 0 : _c.data
};
}
/** Class to discover and evaluate potential servers. */
class RecommendedServerDiscovery {
constructor(jellyfin) {
this.jellyfin = jellyfin;
}
/**
* Fetches the RecommendedServerInfo for a single server address.
* @param address The server address.
* @returns The resulting RecommendedServerInfo.
*/
async fetchRecommendedServerInfo(address) {
const api = this.jellyfin.createApi(address);
const startTime = Date.now();
return getSystemApi(api).getPublicSystemInfo({ timeout: HTTP_TIMEOUT })
.then(response => ({
address,
response,
responseTime: Date.now() - startTime
}))
.catch(error => ({
address,
error,
responseTime: Date.now() - startTime
}))
.then(result => toRecommendedServerInfo(result));
}
/**
* Fetches the RecommendedServerInfo for multiple server addresses.
* @param servers An array of server addresses.
* @returns The RecommendedServerInfo for each address.
*/
async discover(servers, minimumScore = RecommendedServerInfoScore.BAD) {
return (await Promise.all(servers.map(server => this.fetchRecommendedServerInfo(server)))).filter(serverInfo => serverInfo.score >= minimumScore);
}
}
export { RecommendedServerDiscovery };