| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { defineMiddleware } from "astro:middleware"
- import { exactLocale, matchLocale } from "./i18n/locales"
- function docsAlias(pathname: string) {
- const hit = /^\/docs\/([^/]+)(\/.*)?$/.exec(pathname)
- if (!hit) return null
- const value = hit[1] ?? ""
- const tail = hit[2] ?? ""
- const locale = exactLocale(value)
- if (!locale) return null
- const next = locale === "root" ? `/docs${tail}` : `/docs/${locale}${tail}`
- if (next === pathname) return null
- return {
- path: next,
- locale,
- }
- }
- function cookie(locale: string) {
- const value = locale === "root" ? "en" : locale
- return `oc_locale=${encodeURIComponent(value)}; Path=/; Max-Age=31536000; SameSite=Lax`
- }
- function redirect(url: URL, path: string, locale?: string) {
- const next = new URL(url.toString())
- next.pathname = path
- const headers = new Headers({
- Location: next.toString(),
- })
- if (locale) headers.set("Set-Cookie", cookie(locale))
- return new Response(null, {
- status: 302,
- headers,
- })
- }
- function localeFromCookie(header: string | null) {
- if (!header) return null
- const raw = header
- .split(";")
- .map((x) => x.trim())
- .find((x) => x.startsWith("oc_locale="))
- ?.slice("oc_locale=".length)
- if (!raw) return null
- return matchLocale(raw)
- }
- function localeFromAcceptLanguage(header: string | null) {
- if (!header) return "root"
- const items = header
- .split(",")
- .map((raw) => raw.trim())
- .filter(Boolean)
- .map((raw) => {
- const parts = raw.split(";").map((x) => x.trim())
- const lang = parts[0] ?? ""
- const q = parts
- .slice(1)
- .find((x) => x.startsWith("q="))
- ?.slice(2)
- return {
- lang,
- q: q ? Number.parseFloat(q) : 1,
- }
- })
- .sort((a, b) => b.q - a.q)
- const locale = items
- .map((item) => item.lang)
- .filter((lang) => lang && lang !== "*")
- .map((lang) => matchLocale(lang))
- .find((lang) => lang)
- return locale ?? "root"
- }
- export const onRequest = defineMiddleware((ctx, next) => {
- const alias = docsAlias(ctx.url.pathname)
- if (alias) {
- return redirect(ctx.url, alias.path, alias.locale)
- }
- if (ctx.url.pathname !== "/docs" && ctx.url.pathname !== "/docs/") return next()
- const locale =
- localeFromCookie(ctx.request.headers.get("cookie")) ??
- localeFromAcceptLanguage(ctx.request.headers.get("accept-language"))
- if (!locale || locale === "root") return next()
- return redirect(ctx.url, `/docs/${locale}/`)
- })
|