astro-ghostcms/.pnpm-store/v3/files/91/b42ad6d0efdab3db8169c67c1cd...

167 lines
5.5 KiB
Plaintext

import { appendForwardSlash, joinPaths } from "@astrojs/internal-helpers/path";
import { getPathByLocale, normalizeTheLocale } from "./index.js";
import { shouldAppendForwardSlash } from "../core/build/util.js";
import { ROUTE_DATA_SYMBOL } from "../core/constants.js";
const routeDataSymbol = Symbol.for(ROUTE_DATA_SYMBOL);
function pathnameHasLocale(pathname, locales) {
const segments = pathname.split("/");
for (const segment of segments) {
for (const locale of locales) {
if (typeof locale === "string") {
if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) {
return true;
}
} else if (segment === locale.path) {
return true;
}
}
}
return false;
}
function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
if (!i18n)
return (_, next) => next();
const prefixAlways = (url, response, context) => {
if (url.pathname === base + "/" || url.pathname === base) {
if (shouldAppendForwardSlash(trailingSlash, buildFormat)) {
return context.redirect(`${appendForwardSlash(joinPaths(base, i18n.defaultLocale))}`);
} else {
return context.redirect(`${joinPaths(base, i18n.defaultLocale)}`);
}
} else if (!pathnameHasLocale(url.pathname, i18n.locales)) {
return new Response(null, {
status: 404,
headers: response.headers
});
}
return void 0;
};
const prefixOtherLocales = (url, response) => {
const pathnameContainsDefaultLocale = url.pathname.includes(`/${i18n.defaultLocale}`);
if (pathnameContainsDefaultLocale) {
const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, "");
response.headers.set("Location", newLocation);
return new Response(null, {
status: 404,
headers: response.headers
});
}
return void 0;
};
const prefixAlwaysNoRedirect = (url, response) => {
const isRoot = url.pathname === base + "/" || url.pathname === base;
if (!(isRoot || pathnameHasLocale(url.pathname, i18n.locales))) {
return new Response(null, {
status: 404,
headers: response.headers
});
}
return void 0;
};
return async (context, next) => {
const routeData = Reflect.get(context.request, routeDataSymbol);
if (routeData?.type !== "page" && routeData?.type !== "fallback") {
return await next();
}
const currentLocale = context.currentLocale;
const url = context.url;
const { locales, defaultLocale, fallback, routing } = i18n;
const response = await next();
if (response instanceof Response) {
switch (i18n.routing) {
case "domains-prefix-other-locales": {
if (localeHasntDomain(i18n, currentLocale)) {
const result = prefixOtherLocales(url, response);
if (result) {
return result;
}
}
break;
}
case "pathname-prefix-other-locales": {
const result = prefixOtherLocales(url, response);
if (result) {
return result;
}
break;
}
case "domains-prefix-other-no-redirect": {
if (localeHasntDomain(i18n, currentLocale)) {
const result = prefixAlwaysNoRedirect(url, response);
if (result) {
return result;
}
}
break;
}
case "pathname-prefix-always-no-redirect": {
const result = prefixAlwaysNoRedirect(url, response);
if (result) {
return result;
}
break;
}
case "pathname-prefix-always": {
const result = prefixAlways(url, response, context);
if (result) {
return result;
}
break;
}
case "domains-prefix-always": {
if (localeHasntDomain(i18n, currentLocale)) {
const result = prefixAlways(url, response, context);
if (result) {
return result;
}
}
break;
}
}
if (response.status >= 300 && fallback) {
const fallbackKeys = i18n.fallback ? Object.keys(i18n.fallback) : [];
const segments = url.pathname.split("/");
const urlLocale = segments.find((segment) => {
for (const locale of locales) {
if (typeof locale === "string") {
if (locale === segment) {
return true;
}
} else if (locale.path === segment) {
return true;
}
}
return false;
});
if (urlLocale && fallbackKeys.includes(urlLocale)) {
const fallbackLocale = fallback[urlLocale];
const pathFallbackLocale = getPathByLocale(fallbackLocale, locales);
let newPathname;
if (pathFallbackLocale === defaultLocale && routing === "pathname-prefix-other-locales") {
newPathname = url.pathname.replace(`/${urlLocale}`, ``);
} else {
newPathname = url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`);
}
return context.redirect(newPathname);
}
}
}
return response;
};
}
const i18nPipelineHook = (ctx) => {
Reflect.set(ctx.request, routeDataSymbol, ctx.route);
};
function localeHasntDomain(i18n, currentLocale) {
for (const domainLocale of Object.values(i18n.domainLookupTable)) {
if (domainLocale === currentLocale) {
return false;
}
}
return true;
}
export {
createI18nMiddleware,
i18nPipelineHook
};