Files
Cli-Proxy-API-Management-Ce…/src/features/plugins/pluginResources.ts
T

72 lines
2.3 KiB
TypeScript

import type { PluginListEntry, PluginMenu } from '@/types';
import { normalizeApiBase } from '@/utils/connection';
export const PLUGIN_RESOURCES_REFRESH_EVENT = 'plugin-resources-refresh';
export const notifyPluginResourcesChanged = () => {
window.dispatchEvent(new Event(PLUGIN_RESOURCES_REFRESH_EVENT));
};
export interface PluginResourceEntry {
pluginID: string;
pluginTitle: string;
pluginLogo: string;
menuIndex: number;
menu: PluginMenu;
label: string;
description: string;
route: string;
}
export const getPluginTitle = (plugin: PluginListEntry) =>
plugin.metadata?.name.trim() || plugin.id;
export const buildPluginResourceRoute = (pluginID: string, menuIndex: number) =>
`/plugin-pages/${encodeURIComponent(pluginID)}/${menuIndex}`;
export const resolvePluginAssetURL = (value: string, apiBase: string) => {
const trimmed = value.trim();
if (!trimmed) return '';
if (/^(https?:|data:|blob:)/i.test(trimmed)) return trimmed;
if (!trimmed.startsWith('/')) return trimmed;
const base = normalizeApiBase(apiBase);
return base ? `${base}${trimmed}` : trimmed;
};
// Registry entries usually carry an "owner/repo" slug rather than a full URL.
export const buildRepositoryURL = (repository: string) => {
const trimmed = repository.trim();
if (!trimmed) return '';
if (/^https?:\/\//i.test(trimmed)) return trimmed;
return `https://github.com/${trimmed.replace(/^\/+/, '')}`;
};
export const collectPluginResourceEntries = (
plugins: PluginListEntry[]
): PluginResourceEntry[] =>
plugins.flatMap((plugin) => {
if (!plugin.effectiveEnabled) return [];
const pluginTitle = getPluginTitle(plugin);
const pluginLogo = plugin.logo || plugin.metadata?.logo || '';
return plugin.menus
.map((menu, menuIndex): PluginResourceEntry | null => {
const path = menu.path.trim();
if (!path) return null;
const menuLabel = menu.menu.trim();
return {
pluginID: plugin.id,
pluginTitle,
pluginLogo,
menuIndex,
menu: { ...menu, path },
label: menuLabel || pluginTitle,
description: menu.description.trim() || pluginTitle,
route: buildPluginResourceRoute(plugin.id, menuIndex),
};
})
.filter((entry): entry is PluginResourceEntry => Boolean(entry));
});