Created
March 18, 2024 09:30
-
-
Save diboune/7b3ed1e81e1bd9ceae9efca271f04894 to your computer and use it in GitHub Desktop.
Configure website pathname
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { z } from "zod"; | |
export type Locale = z.input<typeof localeSchema>; | |
const localeSchema = z.object({ | |
name: z.string(), | |
path: z.string(), | |
default: z.boolean().optional(), | |
dir: z.enum(["ltr", "rtl"]).optional().default("ltr"), | |
metadata: z.record(z.unknown()).optional().default({}), | |
}); | |
const localesSchema = z | |
.array(localeSchema) | |
.min(1) | |
.superRefine((locales, ctx) => { | |
// check if there is a default locale | |
if (locales.every((locale) => locale.default !== true)) { | |
ctx.addIssue({ | |
code: "custom", | |
message: "Atleast one locale should be set as default", | |
path: ["default"], | |
}); | |
} | |
// check if there are no duplicate locales | |
if (locales.length !== new Set(locales.map((locale) => locale.path)).size) { | |
ctx.addIssue({ | |
code: "custom", | |
message: "You can't have duplicate locale paths", | |
path: ["path"], | |
}); | |
} | |
// check if there are no more than 1 default locale | |
if (locales.filter((locale) => locale.default === true).length > 1) { | |
ctx.addIssue({ | |
code: "custom", | |
message: "Only one locale should be default", | |
path: ["default"], | |
}); | |
} | |
}); | |
const getPathnameInfo = (locales: Locale[]) => (pathname: string) => { | |
const parsed = z | |
.enum(locales.map((p) => p.path) as [string, ...string[]]) | |
.safeParse(pathname.split("/")[1]); | |
return { | |
locale: parsed.success | |
? pathname.split("/")[1] | |
: (locales.find((locale) => locale.default)?.path as string), | |
pathname: parsed.success | |
? "/" + pathname.split("/").slice(2).join("/") | |
: pathname, | |
dir: parsed.success | |
? locales.find((locale) => locale.path === parsed.data)?.dir | |
: (locales.find((locale) => locale.default)?.dir as string), | |
...(parsed.success | |
? null | |
: /\/[a-zA-Z]{2}(-[a-zA-Z]{2})?\//.test( | |
"/" + pathname.split("/")[1] + "/" | |
) | |
? { | |
locale_hint: | |
"Looks like you're trying to access a locale that is not defined yet: " + | |
pathname.split("/")[1], | |
} | |
: null), | |
metadata: parsed.success | |
? locales.find((locale) => locale.path === parsed.data)?.metadata | |
: locales.find((locale) => locale.default)?.metadata, | |
}; | |
}; | |
export const configure = ({ locales }: { locales: Locale[] }) => { | |
const parsedLocales = localesSchema.parse(locales); | |
return { | |
getPathnameInfo: getPathnameInfo(parsedLocales), | |
locales, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment