|
10 | 10 | */ |
11 | 11 | import { defineCollection, reference, z } from 'astro:content' |
12 | 12 | import { glob, file } from 'astro/loaders' |
13 | | -import { isProd } from '@lib/config/environmentServer' |
14 | 13 | import { validTags } from '@content/_tagList' |
| 14 | +/** Wraps a collection schema with a refinement that enforces breadcrumb title length limits */ |
| 15 | +import { withBreadcrumbTitleWarning } from '@lib/helpers/breadcrumbTitleLengthRefinement' |
15 | 16 |
|
16 | 17 | const pattern = '**\/[^_]*.{md,mdx}' |
17 | 18 |
|
18 | | -const MAX_BREADCRUMB_TITLE_LENGTH = 50 |
19 | | -const loggedBreadcrumbTitleWarnings = new Set<string>() |
20 | | - |
21 | | -const warnOnBreadcrumbTitleLength = (title: string, collectionName: string): void => { |
22 | | - if (!isProd()) return |
23 | | - if (title.length <= MAX_BREADCRUMB_TITLE_LENGTH) return |
24 | | - |
25 | | - const warningKey = `${collectionName}:${title}` |
26 | | - if (loggedBreadcrumbTitleWarnings.has(warningKey)) return |
27 | | - |
28 | | - loggedBreadcrumbTitleWarnings.add(warningKey) |
29 | | - console.warn( |
30 | | - `[Breadcrumb Warning] ${collectionName} title "${title}" is ${title.length} characters long. Titles longer than ${MAX_BREADCRUMB_TITLE_LENGTH} characters will truncate in breadcrumbs.` |
31 | | - ) |
32 | | -} |
33 | | - |
34 | | -const withBreadcrumbTitleWarning = <T extends z.ZodRawShape>( |
35 | | - schema: z.ZodObject<T>, |
36 | | - collectionName: string |
37 | | -) => |
38 | | - schema.superRefine(data => { |
39 | | - const candidateTitle = (data as { title?: string }).title |
40 | | - if (typeof candidateTitle === 'string') { |
41 | | - warnOnBreadcrumbTitleLength(candidateTitle, collectionName) |
42 | | - } |
43 | | - }) |
44 | | - |
45 | | -// export type AboutSchema = z.infer<typeof aboutSchema> |
46 | | - |
47 | 19 | /** |
48 | 20 | * About |
49 | 21 | */ |
@@ -182,6 +154,36 @@ const contactDataCollection = defineCollection({ |
182 | 154 | schema: contactDataSchema, |
183 | 155 | }) |
184 | 156 |
|
| 157 | +/** |
| 158 | + * Downloads |
| 159 | + */ |
| 160 | +const downloadsSchema = withBreadcrumbTitleWarning( |
| 161 | + z.object({ |
| 162 | + title: z.string(), |
| 163 | + description: z.string(), |
| 164 | + author: reference('authors').optional(), |
| 165 | + tags: z.array(z.enum(validTags)), |
| 166 | + image: z.object({ |
| 167 | + src: z.string(), |
| 168 | + alt: z.string(), |
| 169 | + }), |
| 170 | + publishDate: z.date(), |
| 171 | + isDraft: z.boolean().default(false), |
| 172 | + featured: z.boolean().default(false), |
| 173 | + fileType: z.enum(['PDF', 'eBook', 'Whitepaper', 'Guide', 'Report', 'Template']), |
| 174 | + fileSize: z.string().optional(), |
| 175 | + pages: z.number().optional(), |
| 176 | + readingTime: z.string().optional(), |
| 177 | + fileName: z.string(), // Filename in public/downloads directory |
| 178 | + }), |
| 179 | + 'downloads' |
| 180 | +) |
| 181 | + |
| 182 | +const downloadsCollection = defineCollection({ |
| 183 | + loader: glob({ pattern, base: './src/content/downloads' }), |
| 184 | + schema: () => downloadsSchema, |
| 185 | +}) |
| 186 | + |
185 | 187 | /** |
186 | 188 | * Services |
187 | 189 | */ |
@@ -238,40 +240,6 @@ const testimonialCollection = defineCollection({ |
238 | 240 | * content system, but there's also a lack of good logical places to add such a data file. |
239 | 241 | */ |
240 | 242 |
|
241 | | -/** |
242 | | - * Downloads |
243 | | - */ |
244 | | -const downloadsSchema = withBreadcrumbTitleWarning( |
245 | | - z.object({ |
246 | | - title: z.string(), |
247 | | - description: z.string(), |
248 | | - author: reference('authors').optional(), |
249 | | - tags: z.array(z.enum(validTags)), |
250 | | - image: z.object({ |
251 | | - src: z.string(), |
252 | | - alt: z.string(), |
253 | | - }), |
254 | | - publishDate: z.date(), |
255 | | - isDraft: z.boolean().default(false), |
256 | | - featured: z.boolean().default(false), |
257 | | - fileType: z.enum(['PDF', 'eBook', 'Whitepaper', 'Guide', 'Report', 'Template']), |
258 | | - fileSize: z.string().optional(), |
259 | | - pages: z.number().optional(), |
260 | | - readingTime: z.string().optional(), |
261 | | - fileName: z.string(), // Filename in public/downloads directory |
262 | | - }), |
263 | | - 'downloads' |
264 | | -) |
265 | | - |
266 | | -const downloadsCollection = defineCollection({ |
267 | | - loader: glob({ pattern, base: './src/content/downloads' }), |
268 | | - schema: () => downloadsSchema, |
269 | | -}) |
270 | | - |
271 | | -/** |
272 | | - * Contact data |
273 | | - */ |
274 | | - |
275 | 243 | export const collections = { |
276 | 244 | about: aboutCollection, |
277 | 245 | articles: articlesCollection, |
|
0 commit comments