- astro 7.0.7, @astrojs/mdx 7, sitemap 3.7, rss 4.0.19, check 0.9.9 - trailingSlash 'always' → 'ignore': Astro 7 generates prerender paths for dynamic extension endpoints (/categories/<c>/rss.xml) with a trailing slash under 'always' but builds their route patterns without one, so the build fails with "Missing parameter"; directory-format output is identical either way. Also removes the now-unneeded dev feed-slash shim. - compressHTML: true pinned to keep pre-v7 whitespace behavior - zod 4: import z from 'astro/zod' (astro:content re-export deprecated), z.string().url() → z.url() - npm audit fix (fast-uri, fast-xml-builder, yaml) Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
import { defineCollection } from 'astro:content';
|
|
import { z } from 'astro/zod';
|
|
import { glob } from 'astro/loaders';
|
|
import { TOPICS } from './lib/topics';
|
|
|
|
const stripIndex = ({ entry }: { entry: string }) =>
|
|
entry.replace(/\/index\.mdx$/, '');
|
|
|
|
const leafSlug = ({ entry }: { entry: string }) =>
|
|
entry.replace(/\/index\.mdx$/, '').split('/').pop()!;
|
|
|
|
const reviews = defineCollection({
|
|
loader: glob({
|
|
pattern: '**/index.mdx',
|
|
base: './src/content/reviews',
|
|
generateId: stripIndex,
|
|
}),
|
|
schema: z.object({
|
|
name: z.string(),
|
|
subtitle: z.string(),
|
|
date: z.coerce.date(),
|
|
category: z.string(),
|
|
topics: z.array(z.enum(TOPICS)).default([]),
|
|
tags: z.array(z.string()).default([]),
|
|
link: z.url().optional(),
|
|
linkText: z.string().optional(),
|
|
amazonLink: z.url().optional(),
|
|
description: z.string().optional(),
|
|
source: z.string().optional(),
|
|
fromFind: z.string().optional(),
|
|
}),
|
|
});
|
|
|
|
const posts = defineCollection({
|
|
loader: glob({
|
|
pattern: '**/index.mdx',
|
|
base: './src/content/posts',
|
|
generateId: stripIndex,
|
|
}),
|
|
schema: z.object({
|
|
title: z.string(),
|
|
date: z.coerce.date(),
|
|
category: z.string(),
|
|
tags: z.array(z.string()).default([]),
|
|
description: z.string().optional(),
|
|
}),
|
|
});
|
|
|
|
const find = defineCollection({
|
|
loader: glob({
|
|
pattern: '**/index.mdx',
|
|
base: './src/content/find',
|
|
generateId: leafSlug,
|
|
}),
|
|
schema: z.object({
|
|
name: z.string(),
|
|
subtitle: z.string().optional(),
|
|
date: z.coerce.date(),
|
|
link: z.url(),
|
|
linkText: z.string().optional(),
|
|
amazonLink: z.url().optional(),
|
|
source: z.string(),
|
|
topics: z.array(z.enum(TOPICS)).default([]),
|
|
tags: z.array(z.string()).default([]),
|
|
description: z.string().optional(),
|
|
promotedTo: z.string().optional(),
|
|
shortlist: z.boolean().default(false),
|
|
editorialTags: z.array(z.string()).default([]),
|
|
}),
|
|
});
|
|
|
|
const bundles = defineCollection({
|
|
loader: glob({
|
|
pattern: '**/index.mdx',
|
|
base: './src/content/bundles',
|
|
generateId: stripIndex,
|
|
}),
|
|
schema: z.object({
|
|
title: z.string(),
|
|
date: z.coerce.date(),
|
|
category: z.string().default('bundles'),
|
|
tags: z.array(z.string()).default([]),
|
|
description: z.string().optional(),
|
|
blurb: z.string().optional(),
|
|
items: z.array(z.string()).min(1),
|
|
}),
|
|
});
|
|
|
|
export const collections = { reviews, posts, find, bundles };
|