You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.8 KiB
77 lines
1.8 KiB
import { Video } from "./typings/video";
|
|
|
|
import InvidiousAdapter from "./adapters/invidious";
|
|
import PipedAdapter from "./adapters/piped";
|
|
|
|
import Adapter, { ApiType, ConnectedAdapter } from "./adapters";
|
|
import { Suggestions } from "./typings/search/suggestions";
|
|
import { SearchResults } from "./typings/search";
|
|
import { SearchOptions } from "./typings/search/options";
|
|
|
|
export interface RemoteApi {
|
|
type: ApiType;
|
|
baseUrl: string;
|
|
score: number;
|
|
}
|
|
|
|
export default class Client {
|
|
private apis: RemoteApi[];
|
|
private adapters: Adapter[] = [InvidiousAdapter, PipedAdapter];
|
|
|
|
constructor(
|
|
apis: {
|
|
type: ApiType;
|
|
baseUrl: string;
|
|
}[]
|
|
) {
|
|
this.apis = apis.map((api) => ({ ...api, score: 0 }));
|
|
}
|
|
|
|
private findAdapterForApiType(apiType: ApiType): Adapter {
|
|
const adapter = this.adapters.find((adapter) => adapter.apiType == apiType);
|
|
|
|
if (adapter === undefined)
|
|
throw new Error(`Could not find an adapter with api type ${apiType}`);
|
|
|
|
return adapter;
|
|
}
|
|
|
|
private getBestApi(): RemoteApi {
|
|
const randomIndex = Math.floor(Math.random() * this.apis.length);
|
|
|
|
return this.apis[randomIndex];
|
|
}
|
|
|
|
private getBestAdapter(): ConnectedAdapter {
|
|
const api = this.getBestApi();
|
|
|
|
const adapter = this.findAdapterForApiType(api.type);
|
|
|
|
return adapter.connect(api.baseUrl);
|
|
}
|
|
|
|
public async getTrending(region: string): Promise<Video[]> {
|
|
const adapter = this.getBestAdapter();
|
|
|
|
return await adapter.getTrending(region);
|
|
}
|
|
|
|
public async getSearchSuggestions(query: string): Promise<Suggestions> {
|
|
const adapter = this.getBestAdapter();
|
|
|
|
return await adapter.getSearchSuggestions(query);
|
|
}
|
|
|
|
public async getSearch(
|
|
query: string,
|
|
options?: SearchOptions
|
|
): Promise<SearchResults> {
|
|
const adapter = this.getBestAdapter();
|
|
|
|
return await adapter.getSearch(query, {
|
|
page: options?.page ?? 1,
|
|
type: options?.type ?? "all"
|
|
});
|
|
}
|
|
}
|