1- //import { AstroError } from 'astro/errors'
2- import { z , type ZodLiteral , type ZodNumber , type ZodObject , type ZodString , type ZodUnion } from 'astro/zod'
31
4- // 定义博客作者 schema
2+ import { z , type ZodLiteral , type ZodNumber , type ZodObject , type ZodString , type ZodUnion } from 'astro/zod' ;
3+ import { graphConfigSchema , nodeStyleSchema } from 'starlight-site-graph/config' ; // 来自 starlight-site-graph
4+
5+ // 从 starlight-site-graph 的 schema
6+ const pageGraphConfigSchema = graphConfigSchema . extend ( {
7+ /**
8+ * Whether the graph component should be visible for this page, has precedence over global rules
9+ */
10+ visible : z . boolean ( ) . optional ( ) ,
11+
12+ /**
13+ * Custom styles for the node defined by this page
14+ * Overrides any other styles that may be applied to this node
15+ */
16+ nodeStyle : nodeStyleSchema . partial ( ) . optional ( ) ,
17+ } ) ;
18+ export type PageGraphConfig = z . infer < typeof pageGraphConfigSchema > ;
19+
20+ const pageSitemapConfigSchema = z . object ( {
21+ /**
22+ * Whether the page should be included in the sitemap, has precedence over global rules
23+ *
24+ * @optional
25+ */
26+ include : z . boolean ( ) . optional ( ) ,
27+ /**
28+ * Specifies the title of the page in the sitemap (and thus graph and backlinks). \
29+ * If not provided, either the `title` frontmatter field, the global `pageTitles` setting,
30+ * or the last part of the page's path is used as the title
31+ * Otherwise, the `pageTitle` overrides all other title sources.
32+ *
33+ * @optional
34+ */
35+ pageTitle : z . string ( ) . optional ( ) ,
36+ /**
37+ * Determine for this page which links are included in the sitemap.
38+ * The link is included/excluded if the link's target _path_ matches one of the rules.
39+ * When a rule starts with `!`, the link is _excluded_ if matched.
40+ * Rules are evaluated in order, the first matching rule determines the inclusion of the link.
41+ * These rules have precedence over global rules.
42+ *
43+ * @optional
44+ */
45+ linkInclusionRules : z . array ( z . string ( ) ) . default ( [ ] ) ,
46+ } ) ;
47+ export type PageSitemapConfig = z . infer < typeof pageSitemapConfigSchema > ;
48+
49+ const pageBacklinksConfigSchema = z . object ( {
50+ /**
51+ * Whether the backlinks component should be visible for this page, has precedence over global rules
52+ */
53+ visible : z . boolean ( ) . optional ( ) ,
54+ } ) ;
55+ export type PageBacklinksConfig = z . infer < typeof pageBacklinksConfigSchema > ;
56+
57+ // 从 starlight-blog 的 schema
558export const blogAuthorSchema = z . object ( {
659 /**
760 * The name of the author.
@@ -19,22 +72,8 @@ export const blogAuthorSchema = z.object({
1972 * The URL to the author's website.
2073 */
2174 url : z . string ( ) . url ( ) . optional ( ) ,
22- } )
75+ } ) ;
2376
24- // 定义主题 schema
25- export const topicSchema = z . object ( {
26- /**
27- * ID of the topic to associate with the current page if the page is not listed in any topic sidebar configuration.
28- *
29- * @see https://starlight-sidebar-topics.netlify.app/docs/guides/unlisted-pages/
30- */
31- topic : z . string ( ) . optional ( ) ,
32- } )
33-
34- export type TopicFrontmatterSchema = z . input < typeof topicSchema >
35- export type StarlightBlogAuthor = z . infer < typeof blogAuthorSchema >
36-
37- // 定义博客条目 schema
3877export const blogEntrySchema = ( { image } : SchemaContext ) =>
3978 z . object ( {
4079 /**
@@ -92,46 +131,80 @@ export const blogEntrySchema = ({ image }: SchemaContext) =>
92131 * Featured blog posts are displayed in a dedicated sidebar group above recent blog posts.
93132 */
94133 featured : z . boolean ( ) . optional ( ) ,
95- /**
96- * ID of the topic to associate with the current page if the page is not listed in any topic sidebar configuration.
97- *
98- * @see https://starlight-sidebar-topics.netlify.app/docs/guides/unlisted-pages/
99- */
100- topic : z . string ( ) . optional ( ) ,
101- } )
134+ } ) ;
102135
103- // 合并后的 schema 函数
136+ // 融合的 schema
104137export function combinedSchema ( context : SchemaContext ) {
105- // 检查上下文以提供更好的迁移错误消息
106- if ( ! context ) {
107- // throw new AstroError(
108- // 'Missing schema validation context.',
109- // `You may need to update your content collections configuration in the \`src/content.config.ts\` file and pass the context to the schema function:
138+ // 检查 context 是否存在
110139
111- // \`docs: defineCollection({ loader: docsLoader(), schema: docsSchema({ extend: (context) => combinedSchema(context) }) })\`
140+ // 创建 blog 部分的 schema
141+ const blogPart = blogEntrySchema ( context ) . partial ( ) ;
112142
113- // If you believe this is a bug, please file an issue at https://github.com/HiDeoo/starlight-blog/issues/new/choose`,
114- // )
115- }
143+ // 创建 site-graph 部分的 schema
144+ const siteGraphPart = z . object ( {
145+ /**
146+ * The title of the page
147+ *
148+ * @required
149+ */
150+ title : z . string ( ) . optional ( ) ,
151+ /**
152+ * Specify direct links to other pages of the site
153+ *
154+ * @optional
155+ */
156+ links : z . array ( z . string ( ) ) . optional ( ) ,
157+ /**
158+ * Tags linked to this page (重复的字段,但保留以兼容两个插件)
159+ *
160+ * @optional
161+ */
162+ tags : z . array ( z . string ( ) ) . optional ( ) ,
163+ /**
164+ * Configuration for the sitemap
165+ *
166+ * @optional
167+ */
168+ sitemap : pageSitemapConfigSchema . optional ( ) . default ( {
169+ linkInclusionRules : [ '**/*' ] ,
170+ } ) ,
171+ /**
172+ * Configuration for the graph component for this page
173+ *
174+ * Overrides global graph configuration
175+ *
176+ * @optional
177+ */
178+ graph : pageGraphConfigSchema . optional ( ) ,
179+ /**
180+ * Configuration for the backlinks component for this page
181+ *
182+ * Overrides global backlinks configuration
183+ *
184+ * @optional
185+ */
186+ backlinks : pageBacklinksConfigSchema . optional ( ) ,
187+ } ) ;
116188
117- // 返回合并了 blog 和 topic 属性的 schema
118- return blogEntrySchema ( context ) . partial ( )
189+ // 返回融合后的 schema
190+ return z . object ( {
191+ ...blogPart . shape ,
192+ ...siteGraphPart . shape ,
193+ } ) ;
119194}
120195
121- // 用于向后兼容的 blogSchema 函数
122- export function blogSchema ( context : SchemaContext ) {
123- return combinedSchema ( context )
124- }
196+ export type StarlightBlogAuthor = z . infer < typeof blogAuthorSchema > ;
197+ export type PageSiteGraphFrontmatter = z . infer < typeof pageSiteGraphSchema > ;
125198
126199interface SchemaContext {
127- image : ImageFunction
200+ image : ImageFunction ;
128201}
129202
130203// https://github.com/withastro/astro/blob/7d597506615fa5a34327304e8321be7b9c4b799d/packages/astro/src/assets/types.ts#L34-L42
131204type ImageFunction = ( ) => ZodObject < {
132- src : ZodString
133- width : ZodNumber
134- height : ZodNumber
205+ src : ZodString ;
206+ width : ZodNumber ;
207+ height : ZodNumber ;
135208 format : ZodUnion <
136209 [
137210 ZodLiteral < 'png' > ,
@@ -143,5 +216,17 @@ type ImageFunction = () => ZodObject<{
143216 ZodLiteral < 'svg' > ,
144217 ZodLiteral < 'avif' > ,
145218 ]
146- >
147- } >
219+ > ;
220+ } > ;
221+
222+ // 导出合并后的 pageSiteGraphSchema,以便向外部提供兼容性
223+ export const pageSiteGraphSchema = z . object ( {
224+ title : z . string ( ) . optional ( ) ,
225+ links : z . array ( z . string ( ) ) . optional ( ) ,
226+ tags : z . array ( z . string ( ) ) . optional ( ) ,
227+ sitemap : pageSitemapConfigSchema . optional ( ) . default ( {
228+ linkInclusionRules : [ '**/*' ] ,
229+ } ) ,
230+ graph : pageGraphConfigSchema . optional ( ) ,
231+ backlinks : pageBacklinksConfigSchema . optional ( ) ,
232+ } ) ;
0 commit comments