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
JavaScript
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
};