// 组件橱窗发布(REQ-012):生成的四件套进 Registry,页面路径立刻可访问。 // // 橱窗页在 Registry 里就是普通页面——有版本、能回滚、能归档。它不需要第二套 // 存储与第二条发布链路,这也是「展示能力属于框架」的具体含义:Host 接一行, // 得到的是与业务页面同一条链路上的一批页面。 // // 归档而不是删除:橱窗页带 `showcase` 标签,关掉橱窗时按标签一次性归档, // 历史版本仍在 Registry 里可查。直接删会让「这个组件上周长什么样」永远查不到。 import { getPageRegistryStore, type PageVersionRecord, } from 'soma-core/server/registry'; import { generateShowcasePages, type GenerateShowcaseOptions, type ShowcasePage, } from './ShowcaseGenerator'; import type { ShowcaseCatalogEntry } from './ShowcaseBlueprint'; /** 橱窗页在 Registry 里的标签:按它归档,按它排除出业务页面清单 */ export const SHOWCASE_TAG = 'showcase'; export interface PublishShowcaseOptions extends GenerateShowcaseOptions { /** 写进版本记录的操作者,缺省 soma-showcase */ operator?: string; /** Registry 应用分区(可选) */ app?: string; } export interface PublishShowcaseResult { published: Array<{ slug: string; pack: string; version: PageVersionRecord }>; skipped: Array<{ name: string; reason: string }>; } function toDeclaration(page: ShowcasePage): Record { return { html: page.html, uiYaml: page.uiYaml, eventYaml: page.eventYaml, ...(page.styleYaml ? { styleYaml: page.styleYaml } : {}), notes: `组件橱窗(REQ-012):${page.pack} · ${page.components.length} 个组件。` + '由组件目录程序生成,不要手改——改契约的 example,重新生成。', }; } /** * 生成并发布全部橱窗页。 * * 生产环境闸门在 generateShowcasePages 里(assertShowcaseAllowed), * 这里不重复判断:一处判定、一处报错,才不会出现「两个开关一个开一个关」。 */ export function publishShowcasePages( entries: readonly ShowcaseCatalogEntry[], options: PublishShowcaseOptions = {}, ): PublishShowcaseResult { const { pages, skipped } = generateShowcasePages(entries, options); const store = getPageRegistryStore(); const operator = options.operator ?? 'soma-showcase'; const published = pages.map((page) => ({ slug: page.slug, pack: page.pack, version: store.publish(page.slug, toDeclaration(page), { status: 'published', operator, tags: [SHOWCASE_TAG, `pack:${page.pack}`], ...(options.app ? { app: options.app } : {}), meta: { title: page.title, description: `${page.pack} 组件橱窗:${page.components.join('、')}`, }, }), })); return { published, skipped }; }