NewTube/server/providers/registry.mjs

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);
}