@levo-so/next-middleware 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/geoIp.d.ts +10 -0
- package/dist/geoIp.js +21 -1
- package/package.json +1 -1
package/dist/geoIp.d.ts
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
* Traefik GeoIP2. Only surfaces `bestCountry` + `languageData` — the helpers
|
|
7
7
|
* that were historically exported (client IPs, provider-specific getters,
|
|
8
8
|
* raw header maps) are no longer used by any consumer.
|
|
9
|
+
*
|
|
10
|
+
* DELIBERATE DUPLICATE of `external/site-runtime/src/locale/geoIp.ts` (the Studio v3 copy).
|
|
11
|
+
* Not merged on purpose: this package is Next-only and serves V2 slate apps, and coupling
|
|
12
|
+
* a V2 app to the V3 site runtime would tie two independent release trains together. A
|
|
13
|
+
* header added to ONE copy is a silent gap in the other — change both.
|
|
14
|
+
*
|
|
15
|
+
* REVIEW-SKIP: no automated parity check between the two copies, by decision. This package is
|
|
16
|
+
* slated for deprecation, so the drift window is short and bounded; investing in a shared
|
|
17
|
+
* fixture or a generated header table would outlive the thing it protects. Everything below
|
|
18
|
+
* the header is byte-identical to the V3 copy today.
|
|
9
19
|
*/
|
|
10
20
|
export interface ICountryInfo {
|
|
11
21
|
countryCode: string;
|
package/dist/geoIp.js
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
* Traefik GeoIP2. Only surfaces `bestCountry` + `languageData` — the helpers
|
|
7
7
|
* that were historically exported (client IPs, provider-specific getters,
|
|
8
8
|
* raw header maps) are no longer used by any consumer.
|
|
9
|
+
*
|
|
10
|
+
* DELIBERATE DUPLICATE of `external/site-runtime/src/locale/geoIp.ts` (the Studio v3 copy).
|
|
11
|
+
* Not merged on purpose: this package is Next-only and serves V2 slate apps, and coupling
|
|
12
|
+
* a V2 app to the V3 site runtime would tie two independent release trains together. A
|
|
13
|
+
* header added to ONE copy is a silent gap in the other — change both.
|
|
14
|
+
*
|
|
15
|
+
* REVIEW-SKIP: no automated parity check between the two copies, by decision. This package is
|
|
16
|
+
* slated for deprecation, so the drift window is short and bounded; investing in a shared
|
|
17
|
+
* fixture or a generated header table would outlive the thing it protects. Everything below
|
|
18
|
+
* the header is byte-identical to the V3 copy today.
|
|
9
19
|
*/
|
|
10
20
|
const safeDecode = (value) => {
|
|
11
21
|
try {
|
|
@@ -78,11 +88,15 @@ const parseAcceptLanguage = (acceptLanguage) => {
|
|
|
78
88
|
.map((lang) => {
|
|
79
89
|
const [locale, quality] = lang.trim().split(";q=");
|
|
80
90
|
const [language, region] = (locale || "").split("-");
|
|
91
|
+
// A malformed q ("de;q=abc") parses to NaN, and NaN loses every comparison in the sort
|
|
92
|
+
// below — which scrambles the order of the WHOLE list, not just that entry. Callers take
|
|
93
|
+
// the first match, so one bad entry would hand the visitor the wrong language.
|
|
94
|
+
const parsed = Number.parseFloat(quality ?? "");
|
|
81
95
|
return {
|
|
82
96
|
locale: locale?.trim() || "",
|
|
83
97
|
language: language?.trim() || "",
|
|
84
98
|
region: region?.trim().toUpperCase(),
|
|
85
|
-
quality:
|
|
99
|
+
quality: Number.isFinite(parsed) ? parsed : 1.0,
|
|
86
100
|
};
|
|
87
101
|
})
|
|
88
102
|
.filter((l) => l.locale)
|
|
@@ -112,6 +126,12 @@ const headersToObject = (headers) => {
|
|
|
112
126
|
}
|
|
113
127
|
const obj = {};
|
|
114
128
|
for (const [k, v] of Object.entries(headers)) {
|
|
129
|
+
// Skip absent values. Node types `req.headers` as `string | string[] | undefined`, and
|
|
130
|
+
// `String(undefined)` is the truthy string "undefined" — which `extractCountry` would then
|
|
131
|
+
// report as `countryCode: "undefined"`, sending locale resolution down the geo branch with
|
|
132
|
+
// a country that does not exist.
|
|
133
|
+
if (v === undefined || v === null)
|
|
134
|
+
continue;
|
|
115
135
|
obj[k.toLowerCase()] = Array.isArray(v) ? v.join(", ") : String(v);
|
|
116
136
|
}
|
|
117
137
|
return obj;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@levo-so/next-middleware",
|
|
3
3
|
"description": "Next middleware to add a proxy for levo integration in apps",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.9",
|
|
5
5
|
"author": "Levo Engineering <devs@theinternetfolks.com>",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@types/react": "19.2.14",
|