Improve i18n support and config validation
This commit is contained in:
parent
4f83ae8802
commit
37db38b613
9 changed files with 152 additions and 152 deletions
|
|
@ -17,6 +17,8 @@ export const WEBSITE_LIST = [
|
|||
] as const;
|
||||
|
||||
const localUrlRegex = /^((\/?\.\.(?=\/))+|(\.(?=\/)))?\/?[a-z0-9_-]+(\/[a-z0-9_-]+)*\/?$/;
|
||||
const refineAuthors = (value: { id: any } | any[]) => "id" in value || value.length > 0;
|
||||
const refineCopyrightedCharacters = (value: Record<string, any>) => !("" in value) || Object.keys(value).length == 1;
|
||||
|
||||
const lang = z.enum(["eng", "tok"]).default("eng");
|
||||
const website = z.enum(WEBSITE_LIST);
|
||||
|
|
@ -43,7 +45,10 @@ const storiesCollection = defineCollection({
|
|||
// Optional
|
||||
isDraft: z.boolean().default(false),
|
||||
shortTitle: z.string().optional(),
|
||||
authors: z.union([reference("users"), z.array(reference("users"))]).default("bad-manners"),
|
||||
authors: z
|
||||
.union([reference("users"), z.array(reference("users"))])
|
||||
.default("bad-manners")
|
||||
.refine(refineAuthors, "authors cannot be empty"),
|
||||
descriptionPlaintext: z.string().optional(),
|
||||
summary: z.string().optional(),
|
||||
thumbnail: image().optional(),
|
||||
|
|
@ -52,7 +57,13 @@ const storiesCollection = defineCollection({
|
|||
series: reference("series").optional(),
|
||||
commissioner: reference("users").optional(),
|
||||
requester: reference("users").optional(),
|
||||
copyrightedCharacters: z.record(z.string(), reference("users")).default({}),
|
||||
copyrightedCharacters: z
|
||||
.record(z.string(), reference("users"))
|
||||
.default({})
|
||||
.refine(
|
||||
refineCopyrightedCharacters,
|
||||
"copyrightedCharacters cannot have an empty catch-all key with other keys",
|
||||
),
|
||||
lang,
|
||||
prev: reference("stories").nullish(),
|
||||
next: reference("stories").nullish(),
|
||||
|
|
@ -74,13 +85,22 @@ const gamesCollection = defineCollection({
|
|||
tags: z.array(z.string()),
|
||||
// Optional
|
||||
isDraft: z.boolean().default(false),
|
||||
authors: z.union([reference("users"), z.array(reference("users"))]).default("bad-manners"),
|
||||
authors: z
|
||||
.union([reference("users"), z.array(reference("users"))])
|
||||
.default("bad-manners")
|
||||
.refine(refineAuthors, "authors cannot be empty"),
|
||||
descriptionPlaintext: z.string().optional(),
|
||||
thumbnail: image().optional(),
|
||||
thumbnailWidth: z.number().int().optional(),
|
||||
thumbnailHeight: z.number().int().optional(),
|
||||
series: reference("series").optional(),
|
||||
copyrightedCharacters: z.record(z.string(), reference("users")).default({}),
|
||||
copyrightedCharacters: z
|
||||
.record(z.string(), reference("users"))
|
||||
.default({})
|
||||
.refine(
|
||||
refineCopyrightedCharacters,
|
||||
"copyrightedCharacters cannot have an empty catch-all key with other keys",
|
||||
),
|
||||
lang,
|
||||
relatedStories: z.array(reference("stories")).default([]),
|
||||
relatedGames: z.array(reference("games")).default([]),
|
||||
|
|
@ -91,16 +111,24 @@ const gamesCollection = defineCollection({
|
|||
const usersCollection = defineCollection({
|
||||
type: "data",
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
// Required
|
||||
name: z.string(),
|
||||
links: z.record(website, z.union([z.string().url(), z.tuple([z.string().url(), z.string()])])),
|
||||
// Optional
|
||||
preferredLink: website.nullish(),
|
||||
nameLang: z.record(lang, z.string()).default({}),
|
||||
avatar: image().optional(),
|
||||
isAnonymous: z.boolean().default(false),
|
||||
}),
|
||||
z
|
||||
.object({
|
||||
// Required
|
||||
name: z.string(),
|
||||
links: z.record(website, z.union([z.string().url(), z.tuple([z.string().url(), z.string()])])),
|
||||
// Optional
|
||||
preferredLink: website.nullish(),
|
||||
nameLang: z.record(lang, z.string()).default({}),
|
||||
avatar: image().optional(),
|
||||
isAnonymous: z.boolean().default(false),
|
||||
})
|
||||
.refine(
|
||||
({ links, preferredLink }) => !preferredLink || preferredLink in links,
|
||||
({ preferredLink }) => ({
|
||||
message: `"${preferredLink}" not defined in links`,
|
||||
path: ["preferredLink"],
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const seriesCollection = defineCollection({
|
||||
|
|
@ -118,7 +146,12 @@ const tagCategoriesCollection = defineCollection({
|
|||
// Required
|
||||
name: z.string(),
|
||||
index: z.number().int(),
|
||||
tags: z.array(z.union([z.string(), z.record(lang, z.string())])),
|
||||
tags: z.array(
|
||||
z.union([
|
||||
z.string(),
|
||||
z.record(lang, z.string()).refine((tag) => "eng" in tag, 'Object-formatted tag must have an "eng" key'),
|
||||
]),
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue