import { appendForwardSlash } from "@astrojs/internal-helpers/path"; import { shouldAppendForwardSlash } from "../core/build/util.js"; import { REROUTE_DIRECTIVE_HEADER, ROUTE_TYPE_HEADER } from "../core/constants.js"; import { computeFallbackRoute } from "./fallback.js"; import { I18nRouter } from "./router.js"; function createI18nMiddleware(i18n, base, trailingSlash, format) { if (!i18n) return (_, next) => next(); const i18nRouter = new I18nRouter({ strategy: i18n.strategy, defaultLocale: i18n.defaultLocale, locales: i18n.locales, base, domains: i18n.domainLookupTable ? Object.keys(i18n.domainLookupTable).reduce( (acc, domain) => { const locale = i18n.domainLookupTable[domain]; if (!acc[domain]) { acc[domain] = []; } acc[domain].push(locale); return acc; }, {} ) : void 0 }); return async (context, next) => { const response = await next(); const typeHeader = response.headers.get(ROUTE_TYPE_HEADER); const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER); if (isReroute === "no" && typeof i18n.fallback === "undefined") { return response; } if (typeHeader !== "page" && typeHeader !== "fallback") { return response; } const routerContext = { currentLocale: context.currentLocale, currentDomain: context.url.hostname, routeType: typeHeader, isReroute: isReroute === "yes" }; const routeDecision = i18nRouter.match(context.url.pathname, routerContext); switch (routeDecision.type) { case "redirect": { let location = routeDecision.location; if (shouldAppendForwardSlash(trailingSlash, format)) { location = appendForwardSlash(location); } return context.redirect(location, routeDecision.status); } case "notFound": { if (context.isPrerendered) { const prerenderedRes = new Response(response.body, { status: 404, headers: response.headers }); prerenderedRes.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); if (routeDecision.location) { prerenderedRes.headers.set("Location", routeDecision.location); } return prerenderedRes; } const headers = new Headers(); if (routeDecision.location) { headers.set("Location", routeDecision.location); } return new Response(null, { status: 404, headers }); } case "continue": break; } if (i18n.fallback && i18n.fallbackType) { const fallbackDecision = computeFallbackRoute({ pathname: context.url.pathname, responseStatus: response.status, currentLocale: context.currentLocale, fallback: i18n.fallback, fallbackType: i18n.fallbackType, locales: i18n.locales, defaultLocale: i18n.defaultLocale, strategy: i18n.strategy, base }); switch (fallbackDecision.type) { case "redirect": return context.redirect(fallbackDecision.pathname + context.url.search); case "rewrite": return await context.rewrite(fallbackDecision.pathname + context.url.search); case "none": break; } } return response; }; } export { createI18nMiddleware };