first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
# acceptLanguageDetector
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`acceptLanguageDetector` is a server-only `LocaleDetector` that parses
the inbound `Accept-Language` header per RFC 9110 §5.3.5 and returns
the highest-priority entry. It is the canonical fallback when nothing
else (querystring, user preference, cookie, geo lookup) has produced a
match — every browser submits an `Accept-Language` header so this
detector almost always returns _something_ on a real request.
The detector returns the _raw_ highest-q entry; supported-locale
negotiation is the chain runner's responsibility (it calls
`LocaleResolver.negotiate(raw, supported)` to perform BCP-47 fallback).
## Features
- Full RFC 9110 q-value parsing (default 1.0, range `[0, 1]`)
- Stable sort: ties keep insertion order
- Wildcard `*` skipped (no useful locale information)
- Malformed entries silently skipped
- `environment: "server"`
## Usage: Basic Example
```ts
import { acceptLanguageDetector } from "@suaveplan/react-i18n/detector/accept-language/accept-language";
import { createDetectorChain } from "@suaveplan/i18n/detector";
const chain = createDetectorChain([acceptLanguageDetector()]);
```
## Usage: Advanced Example
```ts
import { parseAcceptLanguage } from "@suaveplan/react-i18n/detector/accept-language/accept-language";
// Build a custom detector that biases language groups using the
// canonical RFC 9110 parser exposed by this module.
const groups = parseAcceptLanguage("fr-FR;q=0.5, de-DE;q=0.9, en;q=0.8");
// → [{ locale: "de-DE", q: 0.9 }, { locale: "en", q: 0.8 }, ...]
```
## API Reference
### `acceptLanguageDetector(): LocaleDetector`
Returns a `LocaleDetector` with `name: "acceptLanguage"` and
`environment: "server"`. Only `detect(ctx)` is implemented.
### `parseAcceptLanguage(header: string): AcceptLanguageEntry[]`
Parses an `Accept-Language` header into a sorted descending-by-q array
of `{ locale, q }` entries. Exposed for tests and as a building block
for advanced consumers building custom detectors.
### `AcceptLanguageEntry`
```ts
interface AcceptLanguageEntry {
readonly locale: string;
readonly q: number;
}
```
## Implementation Notes
- The parser uses `Array.prototype.sort` with a tie-breaking
insertion-index because the JavaScript spec only guarantees a
stable sort in modern engines; the explicit index keeps the
behaviour deterministic across older runtimes too.
- Wildcards are skipped at parse time — they never appear in the
returned array. The chain runner still has the option of
consulting `ctx.fallbackLocale` once every detector returns null.
- An entry whose q-value is unparseable, negative, or > 1 is treated
as a malformed entry per RFC 9110 ("the recipient SHOULD discard")
rather than coerced to the documented default — this keeps the
parser strict at the field level while staying liberal at the
header level.