added /dist
This commit is contained in:
Vendored
+68
@@ -0,0 +1,68 @@
|
||||
import { getLocaleCodes, isValidLocale } from './helpers.js';
|
||||
/** Cookie name the template uses to persist a visitor's locale choice. */ export const LOCALE_COOKIE_NAME = 'ipal-locale';
|
||||
/**
|
||||
* Resolves which locale to serve, in priority order:
|
||||
* 1. Cookie (explicit prior choice)
|
||||
* 2. Accept-Language header (best match against configured locales)
|
||||
* 3. Configured default locale
|
||||
*
|
||||
* Pure function — the template feeds it request data and acts on the result
|
||||
* (redirect, cookie set). No Next.js or request objects here.
|
||||
*/ export function negotiateLocale({ acceptLanguage, config, cookieLocale }) {
|
||||
// 1. Explicit prior choice wins
|
||||
if (cookieLocale && isValidLocale(cookieLocale, config)) {
|
||||
return cookieLocale;
|
||||
}
|
||||
// 2. Best match from Accept-Language
|
||||
const fromHeader = matchAcceptLanguage(acceptLanguage, config);
|
||||
if (fromHeader) {
|
||||
return fromHeader;
|
||||
}
|
||||
// 3. Fall back to configured default
|
||||
return config.defaultLocale;
|
||||
}
|
||||
/**
|
||||
* Parses an Accept-Language header and returns the best-matching configured
|
||||
* locale, or undefined if none match.
|
||||
*
|
||||
* Matches on the primary subtag (e.g. "en-US" matches configured "en"),
|
||||
* respecting the header's quality-value ordering.
|
||||
*/ export function matchAcceptLanguage(acceptLanguage, config) {
|
||||
if (!acceptLanguage) {
|
||||
return undefined;
|
||||
}
|
||||
const available = getLocaleCodes(config);
|
||||
const ranked = parseAcceptLanguage(acceptLanguage);
|
||||
for (const tag of ranked){
|
||||
// Exact match (e.g. "pt-BR" === "pt-BR")
|
||||
const exact = available.find((code)=>code.toLowerCase() === tag);
|
||||
if (exact) {
|
||||
return exact;
|
||||
}
|
||||
// Primary-subtag match (e.g. "en-us" → "en")
|
||||
const primary = tag.split('-')[0];
|
||||
const partial = available.find((code)=>code.toLowerCase().split('-')[0] === primary);
|
||||
if (partial) {
|
||||
return partial;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Parses an Accept-Language header into locale tags ordered by descending
|
||||
* quality value. Tags are lowercased for comparison.
|
||||
*
|
||||
* "en-US,en;q=0.9,pl;q=0.8" → ["en-us", "en", "pl"]
|
||||
*/ function parseAcceptLanguage(header) {
|
||||
return header.split(',').map((part)=>{
|
||||
const [tag, ...params] = part.trim().split(';');
|
||||
const qParam = params.find((p)=>p.trim().startsWith('q='));
|
||||
const quality = qParam ? parseFloat(qParam.split('=')[1]) : 1;
|
||||
return {
|
||||
quality: Number.isNaN(quality) ? 0 : quality,
|
||||
tag: tag.trim().toLowerCase()
|
||||
};
|
||||
}).filter((entry)=>entry.tag && entry.tag !== '*').sort((a, b)=>b.quality - a.quality).map((entry)=>entry.tag);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=negotiateLocale.js.map
|
||||
Reference in New Issue
Block a user