import { escapeHtml, getGitHubUrl, sanitizeUrl, } from '../utils'; interface PluginAuthor { name: string; url?: string; } interface PluginSource { source: string; repo?: string; path?: string; } export interface RenderablePlugin { name: string; description?: string; path: string; tags?: string[]; itemCount: number; lastUpdated?: string | null; external?: boolean; repository?: string | null; homepage?: string | null; author?: PluginAuthor | null; source?: PluginSource | null; } export type PluginSortOption = 'title' | 'lastUpdated'; export function sortPlugins( items: T[], sort: PluginSortOption ): T[] { return [...items].sort((a, b) => { if (sort === 'lastUpdated') { const dateA = a.lastUpdated ? new Date(a.lastUpdated).getTime() : 0; const dateB = b.lastUpdated ? new Date(b.lastUpdated).getTime() : 0; return dateB - dateA; } return a.name.localeCompare(b.name); }); } function getExternalPluginUrl(plugin: RenderablePlugin): string { if (plugin.source?.source === 'github' && plugin.source.repo) { const base = `https://github.com/${plugin.source.repo}`; return plugin.source.path ? `${base}/tree/main/${plugin.source.path}` : base; } return sanitizeUrl(plugin.repository || plugin.homepage); } export function renderPluginsHtml(items: RenderablePlugin[]): string { if (items.length === 0) { return `

No plugins found

Try different tags or clear the current filters

`; } return items .map((item) => { const isExternal = item.external === true; const metaTag = isExternal ? '🔗 External' : `${item.itemCount} items`; const authorTag = isExternal && item.author?.name ? `by ${escapeHtml(item.author.name)}` : ''; const githubHref = isExternal ? escapeHtml(getExternalPluginUrl(item)) : getGitHubUrl(item.path); return `
`; }) .join(''); }