import { defineCollection, defineConfig } from "@content-collections/core"; import { parsePostDate } from "@/lib/blog"; const italianDateRegex = /^\d{1,2} (gennaio|febbraio|marzo|aprile|maggio|giugno|luglio|agosto|settembre|ottobre|novembre|dicembre) \d{4}$/i; // Regex per "8 min", "12 min", ecc. const readTimeRegex = /^\d{1,3} min$/; const authors = defineCollection({ name: "authors", directory: "src/authors", include: "*.yml", parser: "yaml", schema: (z) => ({ name: z.string().min(1, "Nome obbligatorio"), ref: z.string().min(1, "Riferimento obbligatorio"), avatar: z.string(), title: z.string().min(1, "Titolo obbligatorio"), description: z.string().min(1, "Descrizione obbligatoria"), socialLinks: z.object({ twitter: z.string().url("URL non valido").optional(), github: z.string().url("URL non valido").optional(), linkedin: z.string().url("URL non valido").optional(), }).optional(), }), transform(data, context) { return { ...data, avatar: `${data.avatar}?height=80&width=80`, } }, }); const posts = defineCollection({ name: "posts", directory: "src/posts", include: "**/*.md", schema: (z) => ({ title: z.string().min(1, "Titolo obbligatorio"), excerpt: z.string().min(1, "Excerpt obbligatorio"), content: z.string().min(1), author: z.string().min(1, "Autore obbligatorio"), date: z.string().regex(italianDateRegex, "La data deve essere nel formato 'dd mmm yyyy'"), readTime: z.string().regex(readTimeRegex, "readTime deve essere nel formato 'X min'").optional(), category: z.string().min(1, "Categoria obbligatoria"), tags: z.array(z.string().min(1)).min(1, "Almeno un tag è richiesto"), coverImage: z.string(), hidden: z.null().optional(), }), transform(data, context) { const date = parsePostDate(data.date); const prefix = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`; const authorObj = context.documents(authors).find((author) => author.ref === data.author); if (authorObj == null) throw new Error(`Autore non trovato: ${data.author}`); if (data.readTime == null) { const words = data.content.trim().split(/\s+/).length; const wpm = 180; const minutes = Math.ceil(words / wpm); data.readTime = `${minutes} min`; } return { ...data, slug: `${prefix}-${data._meta.path}`, dateObject: date, author: authorObj, } } }); const portfolio = defineCollection({ name: "portfolio", directory: "src/portfolio", include: "**/*.md", schema: (z) => ({ title: z.string().min(1, "Nome obbligatorio"), description: z.string().min(1, "Descrizione obbligatoria"), content: z.string().min(1), image: z.string(), tags: z.array(z.string().min(1)).min(1, "Almeno un tag è richiesto"), year: z.number().min(2000, "L'anno deve essere maggiore di 2000"), links: z.object({ apple: z.string().url().or(z.null()), play: z.string().url().or(z.null()), }).or(z.null()), }), }); export default defineConfig({ collections: [authors, posts, portfolio], });