import type { InstalledPluginIndex } from "./installed-plugin-index.js"; import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord, PluginManifestRegistry } from "./manifest-registry.js"; export type PluginRegistryIdNormalizerOptions = { manifestRegistry?: PluginManifestRegistry; lookUpTable?: Pick<{ manifestRegistry: PluginManifestRegistry }, "manifestRegistry">; }; function normalizePluginRegistryAlias(value: string): string { return value.trim(); } function normalizePluginRegistryAliasKey(value: string): string { return normalizePluginRegistryAlias(value).toLowerCase(); } function collectObjectKeys(value: Record | undefined): readonly string[] { return value ? Object.keys(value) : []; } function listPluginRegistryNormalizerAliases(plugin: PluginManifestRecord): readonly string[] { return [ plugin.id, ...plugin.providers, ...plugin.channels, ...(plugin.setup?.providers?.map((provider) => provider.id) ?? []), ...plugin.cliBackends, ...(plugin.setup?.cliBackends ?? []), ...collectObjectKeys(plugin.modelCatalog?.providers), ...collectObjectKeys(plugin.modelCatalog?.aliases), ...(plugin.legacyPluginIds ?? []), ]; } export function createPluginRegistryIdNormalizer( index: InstalledPluginIndex, options: PluginRegistryIdNormalizerOptions = {}, ): (pluginId: string) => string { const aliases = new Map(); for (const plugin of index.plugins) { const pluginId = normalizePluginRegistryAlias(plugin.pluginId); if (pluginId) { aliases.set(normalizePluginRegistryAliasKey(pluginId), plugin.pluginId); } } const registry = options.lookUpTable?.manifestRegistry ?? options.manifestRegistry ?? loadPluginManifestRegistryForInstalledIndex({ index, includeDisabled: true, }); for (const plugin of [...registry.plugins].toSorted((left, right) => left.id.localeCompare(right.id), )) { const pluginId = normalizePluginRegistryAlias(plugin.id); if (!pluginId) { continue; } aliases.set(normalizePluginRegistryAliasKey(pluginId), plugin.id); for (const alias of listPluginRegistryNormalizerAliases(plugin)) { const normalizedAlias = normalizePluginRegistryAlias(alias); const normalizedAliasKey = normalizePluginRegistryAliasKey(alias); if (normalizedAlias && !aliases.has(normalizedAliasKey)) { aliases.set(normalizedAliasKey, pluginId); } } } return (pluginId: string) => { const trimmed = normalizePluginRegistryAlias(pluginId); return aliases.get(normalizePluginRegistryAliasKey(trimmed)) ?? trimmed; }; }