import { defineCollection } from 'astro:content'; import { z } from 'astro/zod'; import { glob } from 'astro/loaders'; // Blog collection with Content Layer API const blog = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: ({ image }) => z.object({ title: z.string().max(100), description: z.string().max(200), publishedAt: z.coerce.date(), updatedAt: z.coerce.date().optional(), author: z.string().default('Team'), image: image().optional(), imageAlt: z.string().optional(), tags: z.array(z.string()).default([]), svgSlug: z.string().optional(), draft: z.boolean().default(false), featured: z.boolean().default(false), locale: z.enum(['en', 'es', 'fr']).default('en'), }), }); // Pages collection for static pages const pages = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/pages' }), schema: z.object({ title: z.string(), description: z.string(), updatedAt: z.coerce.date().optional(), locale: z.enum(['en', 'es', 'fr']).default('en'), }), }); // Authors collection const authors = defineCollection({ loader: glob({ pattern: '**/*.json', base: './src/content/authors' }), schema: ({ image }) => z.object({ name: z.string(), bio: z.string(), avatar: image().optional(), social: z .object({ twitter: z.string().optional(), github: z.string().optional(), linkedin: z.string().optional(), }) .optional(), }), }); // FAQs collection (for JSON-LD FAQ schema) const faqs = defineCollection({ loader: glob({ pattern: '**/*.json', base: './src/content/faqs' }), schema: z.object({ question: z.string(), answer: z.string(), category: z.string().optional(), order: z.number().default(0), locale: z.enum(['en', 'es', 'fr']).default('en'), }), }); // Projects collection — one MDX file per project const projects = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/projects' }), schema: ({ image }) => z.object({ title: z.string(), description: z.string(), url: z.string().url().optional(), repo: z.string().url().optional(), image: image().optional(), imageAlt: z.string().optional(), tags: z.array(z.string()).default([]), featured: z.boolean().default(false), order: z.number().default(99), year: z.number().optional(), client: z.string().optional(), role: z.string().optional(), services: z.array(z.string()).default([]), draft: z.boolean().default(false), }), }); // Stack collection — one MDX file per tool, editable like blog posts const stack = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/stack' }), schema: z.object({ name: z.string(), description: z.string(), version: z.string(), url: z.string().url(), icon: z.string(), // icon name, e.g. 'brand-astro' colorOklch: z.string(), // OKLCH params, e.g. '62.5% 0.22 38' order: z.number().default(0), }), }); export const collections = { blog, pages, authors, faqs, stack, projects, };