30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
|
|
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')
|
||
|
|
}
|