mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-24 23:51:48 +00:00
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
|
|
import type { PluginOrigin } from "../plugins/types.js";
|
|
import type { ChannelUiMetadata, PluginUiMetadata } from "./schema.js";
|
|
|
|
type ChannelMetadataRecord = ChannelUiMetadata & {
|
|
originRank: number;
|
|
};
|
|
|
|
const PLUGIN_ORIGIN_RANK: Readonly<Record<PluginOrigin, number>> = {
|
|
config: 0,
|
|
workspace: 1,
|
|
global: 2,
|
|
bundled: 3,
|
|
};
|
|
|
|
export function collectPluginSchemaMetadata(registry: PluginManifestRegistry): PluginUiMetadata[] {
|
|
const deduped = new Map<
|
|
string,
|
|
PluginUiMetadata & {
|
|
originRank: number;
|
|
}
|
|
>();
|
|
|
|
for (const record of registry.plugins) {
|
|
const current = deduped.get(record.id);
|
|
const nextRank = PLUGIN_ORIGIN_RANK[record.origin] ?? Number.MAX_SAFE_INTEGER;
|
|
if (current && current.originRank <= nextRank) {
|
|
continue;
|
|
}
|
|
deduped.set(record.id, {
|
|
id: record.id,
|
|
name: record.name,
|
|
description: record.description,
|
|
configUiHints: record.configUiHints,
|
|
configSchema: record.configSchema,
|
|
originRank: nextRank,
|
|
});
|
|
}
|
|
|
|
return [...deduped.values()]
|
|
.toSorted((left, right) => left.id.localeCompare(right.id))
|
|
.map(({ originRank: _originRank, ...record }) => record);
|
|
}
|
|
|
|
export function collectChannelSchemaMetadata(
|
|
registry: PluginManifestRegistry,
|
|
): ChannelUiMetadata[] {
|
|
const byChannelId = new Map<string, ChannelMetadataRecord>();
|
|
|
|
for (const record of registry.plugins) {
|
|
const originRank = PLUGIN_ORIGIN_RANK[record.origin] ?? Number.MAX_SAFE_INTEGER;
|
|
const rootLabel = record.channelCatalogMeta?.label;
|
|
const rootDescription = record.channelCatalogMeta?.blurb;
|
|
|
|
for (const channelId of record.channels) {
|
|
const current = byChannelId.get(channelId);
|
|
if (!current || originRank <= current.originRank) {
|
|
byChannelId.set(channelId, {
|
|
id: channelId,
|
|
label: rootLabel ?? current?.label,
|
|
description: rootDescription ?? current?.description,
|
|
configSchema: current?.configSchema,
|
|
configUiHints: current?.configUiHints,
|
|
originRank,
|
|
});
|
|
}
|
|
}
|
|
|
|
for (const [channelId, channelConfig] of Object.entries(record.channelConfigs ?? {})) {
|
|
const current = byChannelId.get(channelId);
|
|
if (
|
|
current &&
|
|
current.originRank < originRank &&
|
|
(current.configSchema !== undefined || current.configUiHints !== undefined)
|
|
) {
|
|
continue;
|
|
}
|
|
byChannelId.set(channelId, {
|
|
id: channelId,
|
|
label: channelConfig.label ?? rootLabel ?? current?.label,
|
|
description: channelConfig.description ?? rootDescription ?? current?.description,
|
|
configSchema: channelConfig.schema,
|
|
configUiHints: channelConfig.uiHints as ChannelUiMetadata["configUiHints"],
|
|
originRank,
|
|
});
|
|
}
|
|
}
|
|
|
|
return [...byChannelId.values()]
|
|
.toSorted((left, right) => left.id.localeCompare(right.id))
|
|
.map(({ originRank: _originRank, ...entry }) => entry);
|
|
}
|