refactor: share channel manifest metadata mapping

This commit is contained in:
Peter Steinberger
2026-04-20 13:44:41 +01:00
parent 91f1f881bb
commit ff414f5870
3 changed files with 78 additions and 67 deletions

View File

@@ -2,7 +2,7 @@ import type { PluginPackageChannel } from "../plugins/manifest.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { listBundledChannelCatalogEntries } from "./bundled-channel-catalog-read.js";
import { CHAT_CHANNEL_ORDER, type ChatChannelId } from "./ids.js";
import { resolveChannelExposure } from "./plugins/exposure.js";
import { buildManifestChannelMeta } from "./plugins/channel-meta.js";
import type { ChannelMeta } from "./plugins/types.core.js";
export type ChatChannelMeta = ChannelMeta;
@@ -17,49 +17,20 @@ function toChatChannelMeta(params: {
if (!label) {
throw new Error(`Missing label for bundled chat channel "${params.id}"`);
}
const exposure = resolveChannelExposure(params.channel);
return {
return buildManifestChannelMeta({
id: params.id,
channel: params.channel,
label,
selectionLabel: normalizeOptionalString(params.channel.selectionLabel) || label,
docsPath: normalizeOptionalString(params.channel.docsPath) || `/channels/${params.id}`,
docsLabel: normalizeOptionalString(params.channel.docsLabel),
blurb: normalizeOptionalString(params.channel.blurb) || "",
...(params.channel.aliases?.length ? { aliases: params.channel.aliases } : {}),
...(params.channel.order !== undefined ? { order: params.channel.order } : {}),
...(params.channel.selectionDocsPrefix !== undefined
? { selectionDocsPrefix: params.channel.selectionDocsPrefix }
: {}),
...(params.channel.selectionDocsOmitLabel !== undefined
? { selectionDocsOmitLabel: params.channel.selectionDocsOmitLabel }
: {}),
...(params.channel.selectionExtras?.length
? { selectionExtras: params.channel.selectionExtras }
: {}),
...(normalizeOptionalString(params.channel.detailLabel)
? { detailLabel: normalizeOptionalString(params.channel.detailLabel)! }
: {}),
...(normalizeOptionalString(params.channel.systemImage)
? { systemImage: normalizeOptionalString(params.channel.systemImage)! }
: {}),
...(params.channel.markdownCapable !== undefined
? { markdownCapable: params.channel.markdownCapable }
: {}),
exposure,
...(params.channel.quickstartAllowFrom !== undefined
? { quickstartAllowFrom: params.channel.quickstartAllowFrom }
: {}),
...(params.channel.forceAccountBinding !== undefined
? { forceAccountBinding: params.channel.forceAccountBinding }
: {}),
...(params.channel.preferSessionLookupForAnnounceTarget !== undefined
? {
preferSessionLookupForAnnounceTarget: params.channel.preferSessionLookupForAnnounceTarget,
}
: {}),
...(params.channel.preferOver?.length ? { preferOver: params.channel.preferOver } : {}),
};
detailLabel: normalizeOptionalString(params.channel.detailLabel),
systemImage: normalizeOptionalString(params.channel.systemImage),
arrayFieldMode: "non-empty",
selectionDocsPrefixMode: "defined",
});
}
export function buildChatChannelMetaById(): Record<ChatChannelId, ChatChannelMeta> {

View File

@@ -8,7 +8,7 @@ import type { PluginPackageChannel, PluginPackageInstall } from "../../plugins/m
import type { PluginOrigin } from "../../plugins/plugin-origin.types.js";
import { normalizeOptionalString } from "../../shared/string-coerce.js";
import { isRecord, resolveConfigDir, resolveUserPath } from "../../utils.js";
import { resolveChannelExposure } from "./exposure.js";
import { buildManifestChannelMeta } from "./channel-meta.js";
import type { ChannelMeta } from "./types.public.js";
export type ChannelUiMetaEntry = {
@@ -182,43 +182,20 @@ function toChannelMeta(params: {
const docsPath = params.channel.docsPath?.trim() || `/channels/${params.id}`;
const blurb = params.channel.blurb?.trim() || "";
const systemImage = params.channel.systemImage?.trim();
const exposure = resolveChannelExposure(params.channel);
return {
return buildManifestChannelMeta({
id: params.id,
channel: params.channel,
label,
selectionLabel,
...(detailLabel ? { detailLabel } : {}),
docsPath,
docsLabel: normalizeOptionalString(params.channel.docsLabel),
blurb,
...(params.channel.aliases ? { aliases: params.channel.aliases } : {}),
...(params.channel.preferOver ? { preferOver: params.channel.preferOver } : {}),
...(params.channel.order !== undefined ? { order: params.channel.order } : {}),
...(params.channel.selectionDocsPrefix
? { selectionDocsPrefix: params.channel.selectionDocsPrefix }
: {}),
...(params.channel.selectionDocsOmitLabel !== undefined
? { selectionDocsOmitLabel: params.channel.selectionDocsOmitLabel }
: {}),
...(params.channel.selectionExtras ? { selectionExtras: params.channel.selectionExtras } : {}),
detailLabel,
...(systemImage ? { systemImage } : {}),
...(params.channel.markdownCapable !== undefined
? { markdownCapable: params.channel.markdownCapable }
: {}),
exposure,
...(params.channel.quickstartAllowFrom !== undefined
? { quickstartAllowFrom: params.channel.quickstartAllowFrom }
: {}),
...(params.channel.forceAccountBinding !== undefined
? { forceAccountBinding: params.channel.forceAccountBinding }
: {}),
...(params.channel.preferSessionLookupForAnnounceTarget !== undefined
? {
preferSessionLookupForAnnounceTarget: params.channel.preferSessionLookupForAnnounceTarget,
}
: {}),
};
arrayFieldMode: "defined",
selectionDocsPrefixMode: "truthy",
});
}
function resolveInstallInfo(params: {

View File

@@ -0,0 +1,63 @@
import type { PluginPackageChannel } from "../../plugins/manifest.js";
import { resolveChannelExposure } from "./exposure.js";
import type { ChannelMeta } from "./types.core.js";
type ArrayFieldMode = "defined" | "non-empty";
type OptionalStringMode = "defined" | "truthy";
export function buildManifestChannelMeta(params: {
id: string;
channel: PluginPackageChannel;
label: string;
selectionLabel: string;
docsPath: string;
docsLabel?: string;
blurb: string;
detailLabel?: string;
systemImage?: string;
arrayFieldMode: ArrayFieldMode;
selectionDocsPrefixMode: OptionalStringMode;
}): ChannelMeta {
const hasArrayField = (value: readonly string[] | undefined) =>
params.arrayFieldMode === "defined" ? value !== undefined : Boolean(value?.length);
const hasSelectionDocsPrefix =
params.selectionDocsPrefixMode === "defined"
? params.channel.selectionDocsPrefix !== undefined
: Boolean(params.channel.selectionDocsPrefix);
return {
id: params.id,
label: params.label,
selectionLabel: params.selectionLabel,
docsPath: params.docsPath,
docsLabel: params.docsLabel,
blurb: params.blurb,
...(hasArrayField(params.channel.aliases) ? { aliases: params.channel.aliases } : {}),
...(params.channel.order !== undefined ? { order: params.channel.order } : {}),
...(hasSelectionDocsPrefix ? { selectionDocsPrefix: params.channel.selectionDocsPrefix } : {}),
...(params.channel.selectionDocsOmitLabel !== undefined
? { selectionDocsOmitLabel: params.channel.selectionDocsOmitLabel }
: {}),
...(hasArrayField(params.channel.selectionExtras)
? { selectionExtras: params.channel.selectionExtras }
: {}),
...(params.detailLabel ? { detailLabel: params.detailLabel } : {}),
...(params.systemImage ? { systemImage: params.systemImage } : {}),
...(params.channel.markdownCapable !== undefined
? { markdownCapable: params.channel.markdownCapable }
: {}),
exposure: resolveChannelExposure(params.channel),
...(params.channel.quickstartAllowFrom !== undefined
? { quickstartAllowFrom: params.channel.quickstartAllowFrom }
: {}),
...(params.channel.forceAccountBinding !== undefined
? { forceAccountBinding: params.channel.forceAccountBinding }
: {}),
...(params.channel.preferSessionLookupForAnnounceTarget !== undefined
? {
preferSessionLookupForAnnounceTarget: params.channel.preferSessionLookupForAnnounceTarget,
}
: {}),
...(hasArrayField(params.channel.preferOver) ? { preferOver: params.channel.preferOver } : {}),
};
}