113 lines
1.9 KiB
JavaScript
113 lines
1.9 KiB
JavaScript
class API {
|
|
|
|
/**
|
|
* @type {!string}
|
|
*/
|
|
apiURL;
|
|
|
|
/**
|
|
* @param {!string} apiURL
|
|
*/
|
|
constructor(apiURL) {
|
|
this.apiURL = apiURL;
|
|
}
|
|
|
|
/**
|
|
* @param {"GET" | "POST" | "PUT"} method
|
|
* @param {!string} path
|
|
* @param {?Object.<string, string>} query
|
|
* @param {?any} body
|
|
* @returns {?any}
|
|
* @throws {APIError}
|
|
*/
|
|
async call(method, path, query, body) {
|
|
let params = new URLSearchParams();
|
|
if (query != null) {
|
|
for (let key in query) {
|
|
let value = query[key];
|
|
if (value == null) continue;
|
|
params.set(key, value);
|
|
}
|
|
}
|
|
|
|
let response = await fetch(this.apiURL + path + (params.size > 0 ? "?" + params : ""),
|
|
{
|
|
method,
|
|
headers: (body != null ? { "Content-Type": "application/json" } : undefined),
|
|
body
|
|
}
|
|
);
|
|
|
|
let json = null;
|
|
try {
|
|
json = await response.json();
|
|
} catch (e) {
|
|
throw "Failed to decode response";
|
|
}
|
|
|
|
if (!response.ok) {
|
|
throw json?.error || "Request failed: " + response.status + " " + response.statusText;
|
|
}
|
|
|
|
return json
|
|
}
|
|
|
|
/**
|
|
* @param {?("series" | "author")} groupBy
|
|
* @returns {Library}
|
|
* @throws {APIError}
|
|
*/
|
|
async getLibrary(groupBy) {
|
|
return await this.call("GET", "/library", { 'groupBy': groupBy }, null);
|
|
}
|
|
|
|
/**
|
|
* @param {!string} id
|
|
* @returns {Video}
|
|
* @throws {APIError}
|
|
*/
|
|
async getVideo(id) {
|
|
return await this.call("GET", "/library/video/" + encodeURIComponent(id), null, null);
|
|
}
|
|
|
|
}
|
|
|
|
class APIError {
|
|
|
|
/**
|
|
* @type {string}
|
|
*/
|
|
errorMessage;
|
|
|
|
/**
|
|
* @param {!string} errorMessage
|
|
*/
|
|
constructor(errorMessage) {
|
|
this.errorMessage = errorMessage
|
|
}
|
|
|
|
}
|
|
|
|
class Library {
|
|
/**
|
|
* @type {Object<string, Video[]>}
|
|
*/
|
|
videos;
|
|
}
|
|
|
|
class Video {
|
|
/**
|
|
* @type {string}
|
|
*/
|
|
id;
|
|
|
|
/**
|
|
* @type {VideoMetadata}
|
|
*/
|
|
metadata;
|
|
}
|
|
|
|
/**
|
|
* @typedef {{series:string, title: string, author: string, index: number, [key: string]: any}} VideoMetadata
|
|
*/
|