Add syndication links and start blog collection

This commit is contained in:
Bad Manners 2024-09-13 10:56:42 -03:00
parent 09934a9f8e
commit 9ff1986adc
No known key found for this signature in database
GPG key ID: 8C88292CCB075609
80 changed files with 415 additions and 33 deletions

View file

@ -78,6 +78,14 @@ const websiteLinks = z.object({
return { link, username };
}),
),
sofurrybeta: z.object({ link: z.string().url(), username: z.string() }).or(
z.string().transform((link, ctx) => {
const { username } = parseRegex<{ username: string }>(
/^(?:https?:\/\/)?sofurrybeta.com\/u\/(?<username>[^\/]+)\/?$/,
)(link, ctx);
return { link, username };
}),
),
mastodon: z
.object({ link: z.string().url(), username: z.string().regex(/^[^@]+@[^@]+$/) })
.or(
@ -144,7 +152,6 @@ const publishedContent = z.object({
// Required parameters
title: z.string(),
authors: userList,
contentWarning: z.string().trim(),
// Required parameters, but optional for drafts (isDraft === true)
pubDate: z
.date()
@ -154,10 +161,10 @@ const publishedContent = z.object({
tags: z.array(z.string()),
// Optional parameters
isDraft: z.boolean().default(false),
isAgeRestricted: z.boolean().default(true),
relatedStories: z.array(reference("stories")).default([]),
relatedGames: z.array(reference("games")).default([]),
lang: lang,
copyrightedCharacters: copyrightedCharacters,
series: reference("series").optional(),
posts: z
.object({
@ -191,6 +198,18 @@ const publishedContent = z.object({
)(link, ctx);
return { link, postId };
}),
sofurrybeta: z.string().transform((link, ctx) => {
const { postId } = parseRegex<{ postId: string }>(
/^(?:https?:\/\/)sofurrybeta\.com\/s\/(?<postId>[a-zA-Z0-9]+)\/?$/,
)(link, ctx);
return { link, postId };
}),
itch: z.string().transform((link, ctx) => {
const { user, postId } = parseRegex<{ user: string; postId: string }>(
/^(?:https?:\/\/)(?<user>[a-z-]+)\.itch\.io\/(?<postId>[a-z0-9_-]+)\/?$/,
)(link, ctx);
return { link, user, postId };
}),
twitter: z.string().transform((link, ctx) => {
const { user, postId } = parseRegex<{ user: string; postId: string }>(
/^(?:https?:\/\/)(?:www\.)?(?:twitter\.com|x\.com)\/(?<user>[a-zA-Z0-9_-]+)\/status\/(?<postId>[1-9]\d*)\/?$/,
@ -212,6 +231,7 @@ const publishedContent = z.object({
})
.partial()
.default({}),
blacklistedMastodonComments: z.array(z.string()).default([]),
});
// Types
@ -232,17 +252,19 @@ const storiesCollection = defineCollection({
z
.object({
// Required parameters, but optional for drafts (isDraft === true)
contentWarning: z.string().trim(),
wordCount: z.number().int().optional(),
thumbnail: image().optional(),
// Optional parameters
shortTitle: z.string().optional(),
commissioners: userList.optional(),
requesters: userList.optional(),
summary: z.string().trim().optional(),
thumbnailWidth: z.number().int().optional(),
thumbnailHeight: z.number().int().optional(),
prev: reference("stories").nullish(),
next: reference("stories").nullish(),
copyrightedCharacters: copyrightedCharacters,
shortTitle: z.string().optional(),
commissioners: userList.optional(),
requesters: userList.optional(),
summary: z.string().trim().optional(),
})
.and(publishedContent)
.refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published story`)
@ -253,7 +275,11 @@ const storiesCollection = defineCollection({
.refine(({ isDraft, wordCount }) => isDraft || wordCount, `Missing "wordCount" for published story`)
.refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published story`)
.refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published story`)
.refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`),
.refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`)
.refine(
({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon,
`Cannot include "blacklistedMastodonComments" without a Mastodon post`,
),
});
const gamesCollection = defineCollection({
@ -262,6 +288,7 @@ const gamesCollection = defineCollection({
z
.object({
// Required parameters, but optional for drafts (isDraft === true)
contentWarning: z.string().trim(),
platforms: z.array(platform).default([]),
thumbnail: image().optional(),
// Optional parameters
@ -269,6 +296,7 @@ const gamesCollection = defineCollection({
thumbnailHeight: z.number().int().optional(),
prev: reference("games").nullish(),
next: reference("games").nullish(),
copyrightedCharacters: copyrightedCharacters,
})
.and(publishedContent)
.refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published game`)
@ -276,7 +304,36 @@ const gamesCollection = defineCollection({
.refine(({ isDraft, platforms }) => isDraft || platforms.length, `Missing "platforms" for published game`)
.refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published game`)
.refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published game`)
.refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published game`),
.refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published game`)
.refine(
({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon,
`Cannot include "blacklistedMastodonComments" without a Mastodon post`,
),
});
const blogCollection = defineCollection({
type: "content",
schema: ({ image }) =>
z
.object({
// Required parameters, but optional for drafts (isDraft === true)
thumbnail: image().optional(),
// Optional parameters
summary: z.string().trim().optional(),
thumbnailWidth: z.number().int().optional(),
thumbnailHeight: z.number().int().optional(),
prev: reference("blog").nullish(),
next: reference("blog").nullish(),
})
.and(publishedContent)
.refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published story`)
.refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published story`)
.refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published story`)
.refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`)
.refine(
({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon,
`Cannot include "blacklistedMastodonComments" without a Mastodon post`,
),
});
// Data collections
@ -332,6 +389,7 @@ const tagCategoriesCollection = defineCollection({
export const collections = {
stories: storiesCollection,
games: gamesCollection,
blog: blogCollection,
users: usersCollection,
series: seriesCollection,
"tag-categories": tagCategoriesCollection,