40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
// Server-side provider registry for search fan-out
|
|
// Each provider module should export an object with a `search(q, opts)` function returning Promise<Suggestion[]>
|
|
|
|
/**
|
|
* @typedef {Object} Suggestion
|
|
* @property {string} title
|
|
* @property {string} id
|
|
* @property {number=} duration
|
|
* @property {boolean=} isShort
|
|
* @property {string=} url
|
|
* @property {string=} thumbnail
|
|
* @property {string=} uploaderName
|
|
* @property {string=} type
|
|
*/
|
|
|
|
/** @typedef {'yt'|'dm'|'tw'|'pt'|'od'|'ru'} ProviderId */
|
|
|
|
/** @type {Record<ProviderId, { id: ProviderId, label: string, search: (q: string, opts: { limit: number, page?: number }) => Promise<Suggestion[]> }>} */
|
|
export const providerRegistry = {
|
|
/** @type {any} */ yt: (await import('./youtube.mjs')).default,
|
|
/** @type {any} */ dm: (await import('./dailymotion.mjs')).default,
|
|
/** @type {any} */ tw: (await import('./twitch.mjs')).default,
|
|
/** @type {any} */ pt: (await import('./peertube.mjs')).default,
|
|
/** @type {any} */ od: (await import('./odysee.mjs')).default,
|
|
/** @type {any} */ ru: (await import('./rumble.mjs')).default,
|
|
};
|
|
|
|
/**
|
|
* Validate and normalize a comma separated providers list
|
|
* @param {string} input
|
|
* @returns {ProviderId[]}
|
|
*/
|
|
export function validateProviders(input) {
|
|
const raw = String(input || '').split(',').map(s => s.trim()).filter(Boolean);
|
|
const allowed = /** @type {ProviderId[]} */(['yt','dm','tw','pt','od','ru']);
|
|
const filtered = raw.filter(p => allowed.includes(/** @type {any} */(p)));
|
|
if (filtered.length === 0) return allowed;
|
|
return /** @type {ProviderId[]} */(filtered);
|
|
}
|