Clean-room copy of the reusable engines from comiida, with all instance data, secrets, dependencies, and build output excluded: - app/ Astro theme skeleton (no comiida blog posts; hero image -> placeholder) - api/ SeedProject PHP framework (no vendor/.env/config.php) - content-pipeline/ engine only (scripts/admin/prompts; empty runtime state) - astroagent.config.json + app/.astroagent/skills Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYHWLHihq3v9nxNwoPCKSn
35 lines
1 KiB
JavaScript
35 lines
1 KiB
JavaScript
import { defineCollection } from "astro:content";
|
|
import { glob } from "astro/loaders";
|
|
import { z } from "astro/zod";
|
|
|
|
const blog = defineCollection({
|
|
loader: glob({
|
|
pattern: "**/index.mdx",
|
|
base: "./src/content/blog",
|
|
generateId: ({ entry }) => entry.replace(/[\\/]index\.mdx$/, "").replace(/\\/g, "/"),
|
|
}),
|
|
schema: ({ image }) =>
|
|
z.object({
|
|
title: z.string(),
|
|
excerpt: z.string(),
|
|
date: z.coerce.date(),
|
|
updated: z.coerce.date().optional(),
|
|
readingTime: z.number().int().positive(),
|
|
category: z.string(),
|
|
tags: z.array(z.string()).default([]),
|
|
author: z.string(),
|
|
thumbnail: image(),
|
|
imageCredit: z
|
|
.object({
|
|
caption: z.string().optional(),
|
|
author: z.string(),
|
|
authorUrl: z.string().url(),
|
|
source: z.string().optional(),
|
|
sourceUrl: z.string().url().optional(),
|
|
})
|
|
.optional(),
|
|
featured: z.boolean().default(false),
|
|
}),
|
|
});
|
|
|
|
export const collections = { blog };
|