Add "Playing It Safe" draft and improve type-checking
- Remove most type assertions and improve types - Validate wordCount property - Add "Vore Day" tag - Add licenses
This commit is contained in:
parent
17ef8c652c
commit
fe908a4989
37 changed files with 1309 additions and 841 deletions
|
|
@ -16,8 +16,8 @@ export const WEBSITE_LIST = [
|
|||
] as const;
|
||||
export const GAME_PLATFORMS = ["web", "windows", "linux", "macos", "android", "ios"] as const;
|
||||
export const DEFAULT_LANG = "eng";
|
||||
export const DEFAULT_AUTHOR = "bad-manners";
|
||||
export const ANONYMOUS_USER = "anonymous";
|
||||
export const DEFAULT_AUTHOR_ID = "bad-manners";
|
||||
export const ANONYMOUS_USER_ID = "anonymous";
|
||||
|
||||
// Validators
|
||||
|
||||
|
|
@ -40,9 +40,10 @@ const refineCopyrightedCharacters = [
|
|||
|
||||
// Transformers
|
||||
|
||||
export const adjustDateForUTCOffset = (date: Date) =>
|
||||
const trimText = (text: string) => text.trim();
|
||||
const adjustDateForUTCOffset = (date: Date) =>
|
||||
new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
|
||||
export const parseMastodonPostUrl = (url: string, ctx: z.RefinementCtx) => {
|
||||
const parseMastodonPostUrl = (url: string, ctx: z.RefinementCtx) => {
|
||||
const match = mastodonPostUrlRegex.exec(url);
|
||||
if (!match) {
|
||||
ctx.addIssue({
|
||||
|
|
@ -70,14 +71,17 @@ const mastodonPost = z
|
|||
postId: z.string(),
|
||||
})
|
||||
.or(z.string().transform(parseMastodonPostUrl));
|
||||
const authors = z
|
||||
.union([reference("users"), z.array(reference("users"))])
|
||||
.default(DEFAULT_AUTHOR)
|
||||
.refine(...refineAuthors);
|
||||
const userList = z
|
||||
.array(reference("users"))
|
||||
.or(reference("users").transform((user) => [user]))
|
||||
.refine((value) => value.length > 0, `user list cannot be empty`);
|
||||
const authors = userList.default([DEFAULT_AUTHOR_ID]);
|
||||
const copyrightedCharacters = z
|
||||
.record(z.string(), reference("users"))
|
||||
.default({})
|
||||
.refine(...refineCopyrightedCharacters);
|
||||
// { eng: string, tok?: string, ... }
|
||||
const langRecord = z.object({ [DEFAULT_LANG]: z.string() }).and(z.record(lang, z.string()));
|
||||
|
||||
export type Lang = z.output<typeof lang>;
|
||||
export type Website = z.infer<typeof website>;
|
||||
|
|
@ -93,21 +97,21 @@ const storiesCollection = defineCollection({
|
|||
// Required
|
||||
title: z.string(),
|
||||
wordCount: z.number().int().optional(),
|
||||
contentWarning: z.string(),
|
||||
description: z.string(),
|
||||
contentWarning: z.string().transform(trimText),
|
||||
description: z.string().transform(trimText),
|
||||
tags: z.array(z.string()),
|
||||
// Optional
|
||||
pubDate: z.date().transform(adjustDateForUTCOffset).optional(),
|
||||
isDraft: z.boolean().default(false),
|
||||
shortTitle: z.string().optional(),
|
||||
authors,
|
||||
summary: z.string().optional(),
|
||||
summary: z.string().transform(trimText).optional(),
|
||||
thumbnail: image().optional(),
|
||||
thumbnailWidth: z.number().int().optional(),
|
||||
thumbnailHeight: z.number().int().optional(),
|
||||
series: reference("series").optional(),
|
||||
commissioner: reference("users").optional(),
|
||||
requester: reference("users").optional(),
|
||||
commissioner: userList.optional(),
|
||||
requester: userList.optional(),
|
||||
copyrightedCharacters: copyrightedCharacters,
|
||||
lang,
|
||||
prev: reference("stories").nullish(),
|
||||
|
|
@ -134,8 +138,9 @@ const gamesCollection = defineCollection({
|
|||
z.object({
|
||||
// Required
|
||||
title: z.string(),
|
||||
contentWarning: z.string(),
|
||||
description: z.string(),
|
||||
contentWarning: z.string().transform(trimText),
|
||||
description: z.string().transform(trimText),
|
||||
platforms: z.array(platform).refine((platforms) => platforms.length > 0, `"platforms" cannot be empty`),
|
||||
tags: z.array(z.string()),
|
||||
// Optional
|
||||
pubDate: z.date().transform(adjustDateForUTCOffset).optional(),
|
||||
|
|
@ -145,7 +150,6 @@ const gamesCollection = defineCollection({
|
|||
thumbnailWidth: z.number().int().optional(),
|
||||
thumbnailHeight: z.number().int().optional(),
|
||||
series: reference("series").optional(),
|
||||
platforms: z.array(platform).refine((platforms) => platforms.length > 0, `"platforms" cannot be empty`),
|
||||
copyrightedCharacters: copyrightedCharacters,
|
||||
lang,
|
||||
relatedStories: z.array(reference("stories")).default([]),
|
||||
|
|
@ -176,7 +180,7 @@ const usersCollection = defineCollection({
|
|||
links: z.record(website, z.union([z.string().url(), z.tuple([z.string().url(), z.string()])])),
|
||||
// Optional
|
||||
preferredLink: website.nullish(),
|
||||
lang: z.record(lang, z.string()).default({}),
|
||||
lang: langRecord.optional(),
|
||||
avatar: image().optional(),
|
||||
})
|
||||
.refine(
|
||||
|
|
@ -205,7 +209,7 @@ const tagCategoriesCollection = defineCollection({
|
|||
index: z.number().int(),
|
||||
tags: z.array(
|
||||
z.object({
|
||||
name: z.union([z.string(), z.object({ [DEFAULT_LANG]: z.string() }).and(z.record(lang, z.string()))]),
|
||||
name: z.union([z.string(), langRecord]),
|
||||
description: z.string().optional(),
|
||||
related: z.array(z.string()).optional(),
|
||||
}),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue