feat(contracts): Route/Render/Theme Manifest 契约 v1 冻结

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-20 18:36:45 +08:00
parent 33517065f6
commit c8c4336da7
5 changed files with 220 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
export const THEME_MANIFEST_VERSION = 1
export interface ThemeManifest {
key: string
version: string
renderContractVersion: string
supportedContentTypes: string[]
requiredSiteConfig: string[]
templates: Array<{ key: string; appliesTo: string }>
}
const SEMVER = /^\d+\.\d+\.\d+$/
// 守卫查值类型(不只查键存在):semver 格式、字符串字段、数组元素类型全部校验
export function isThemeManifest(v: unknown): v is ThemeManifest {
if (typeof v !== 'object' || v === null) return false
const m = v as ThemeManifest
return typeof m.key === 'string'
&& typeof m.version === 'string' && SEMVER.test(m.version)
&& typeof m.renderContractVersion === 'string'
&& Array.isArray(m.supportedContentTypes)
&& m.supportedContentTypes.every((t) => typeof t === 'string')
&& Array.isArray(m.requiredSiteConfig)
&& m.requiredSiteConfig.every((t) => typeof t === 'string')
&& Array.isArray(m.templates)
&& m.templates.every((t) => typeof t === 'object' && t !== null
&& typeof (t as { key: unknown }).key === 'string'
&& typeof (t as { appliesTo: unknown }).appliesTo === 'string')
}