UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

205 lines (204 loc) • 6.15 kB
import { getAllCodes, normalizeTheLocale } from "./index.js"; function parseLocale(header) { if (header === "*") { return [{ locale: header, qualityValue: void 0 }]; } const result = []; const localeValues = header.split(",").map((str) => str.trim()); for (const localeValue of localeValues) { const split = localeValue.split(";").map((str) => str.trim()); const localeName = split[0]; const qualityValue = split[1]; if (!split) { continue; } if (qualityValue && qualityValue.startsWith("q=")) { const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length)); if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) { result.push({ locale: localeName, qualityValue: void 0 }); } else { result.push({ locale: localeName, qualityValue: qualityValueAsFloat }); } } else { result.push({ locale: localeName, qualityValue: void 0 }); } } return result; } function sortAndFilterLocales(browserLocaleList, locales) { const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale); return browserLocaleList.filter((browserLocale) => { if (browserLocale.locale !== "*") { return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale)); } return true; }).sort((a, b) => { if (a.qualityValue && b.qualityValue) { return Math.sign(b.qualityValue - a.qualityValue); } return 0; }); } function computePreferredLocale(request, locales) { const acceptHeader = request.headers.get("Accept-Language"); let result = void 0; if (acceptHeader) { const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); const firstResult = browserLocaleList.at(0); if (firstResult && firstResult.locale !== "*") { for (const currentLocale of locales) { if (typeof currentLocale === "string") { if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) { result = currentLocale; break; } } else { for (const currentCode of currentLocale.codes) { if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) { result = currentCode; break; } } } } } } return result; } function computePreferredLocaleList(request, locales) { const acceptHeader = request.headers.get("Accept-Language"); let result = []; if (acceptHeader) { const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") { return getAllCodes(locales); } else if (browserLocaleList.length > 0) { for (const browserLocale of browserLocaleList) { for (const loopLocale of locales) { if (typeof loopLocale === "string") { if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) { result.push(loopLocale); } } else { for (const code of loopLocale.codes) { if (code === browserLocale.locale) { result.push(code); } } } } } } } return result; } function computeCurrentLocale(pathname, locales, defaultLocale) { for (const segment of pathname.split("/")) { for (const locale of locales) { if (typeof locale === "string") { if (!segment.includes(locale)) continue; if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { return locale; } } else { if (locale.path === segment) { return locale.codes.at(0); } else { for (const code of locale.codes) { if (normalizeTheLocale(code) === normalizeTheLocale(segment)) { return code; } } } } } } for (const locale of locales) { if (typeof locale === "string") { if (locale === defaultLocale) { return locale; } } else { if (locale.path === defaultLocale) { return locale.codes.at(0); } } } } function toRoutingStrategy(routing, domains) { let strategy; const hasDomains = domains ? Object.keys(domains).length > 0 : false; if (routing === "manual") { strategy = "manual"; } else { if (!hasDomains) { if (routing?.prefixDefaultLocale === true) { if (routing.redirectToDefaultLocale) { strategy = "pathname-prefix-always"; } else { strategy = "pathname-prefix-always-no-redirect"; } } else { strategy = "pathname-prefix-other-locales"; } } else { if (routing?.prefixDefaultLocale === true) { if (routing.redirectToDefaultLocale) { strategy = "domains-prefix-always"; } else { strategy = "domains-prefix-always-no-redirect"; } } else { strategy = "domains-prefix-other-locales"; } } } return strategy; } const PREFIX_DEFAULT_LOCALE = /* @__PURE__ */ new Set([ "pathname-prefix-always", "domains-prefix-always", "pathname-prefix-always-no-redirect", "domains-prefix-always-no-redirect" ]); const REDIRECT_TO_DEFAULT_LOCALE = /* @__PURE__ */ new Set([ "pathname-prefix-always-no-redirect", "domains-prefix-always-no-redirect" ]); function fromRoutingStrategy(strategy, fallbackType) { let routing; if (strategy === "manual") { routing = "manual"; } else { routing = { prefixDefaultLocale: PREFIX_DEFAULT_LOCALE.has(strategy), redirectToDefaultLocale: !REDIRECT_TO_DEFAULT_LOCALE.has(strategy), fallbackType }; } return routing; } function toFallbackType(routing) { if (routing === "manual") { return "rewrite"; } return routing.fallbackType; } export { computeCurrentLocale, computePreferredLocale, computePreferredLocaleList, fromRoutingStrategy, parseLocale, toFallbackType, toRoutingStrategy };