@byline/i18n 4.11.2 → 4.13.0
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/README.md +13 -13
- package/dist/admin/index.d.ts +4 -3
- package/dist/admin/index.js +5 -2
- package/dist/admin/th.js +535 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/resolve.d.ts +4 -4
- package/dist/resolve.js +2 -2
- package/dist/types.d.ts +2 -2
- package/package.json +8 -8
- package/src/admin/index.test.node.ts +3 -1
- package/src/admin/index.ts +6 -3
- package/src/admin/th.json +534 -0
- package/src/index.ts +2 -2
- package/src/resolve.test.node.ts +16 -16
- package/src/resolve.ts +4 -4
- package/src/types.ts +2 -2
package/src/resolve.test.node.ts
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
import { describe, expect, it } from 'vitest'
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { resolveAdminLocale } from './resolve.js'
|
|
12
12
|
|
|
13
13
|
const locales = ['en', 'fr', 'es']
|
|
14
14
|
const defaultLocale = 'en'
|
|
15
15
|
|
|
16
|
-
describe('
|
|
16
|
+
describe('resolveAdminLocale — tier 1 (preferred)', () => {
|
|
17
17
|
it('wins over every other signal when set and valid', () => {
|
|
18
|
-
const out =
|
|
18
|
+
const out = resolveAdminLocale({
|
|
19
19
|
locales,
|
|
20
20
|
defaultLocale,
|
|
21
21
|
preferred: 'fr',
|
|
@@ -26,7 +26,7 @@ describe('resolveInterfaceLocale — tier 1 (preferred)', () => {
|
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
it('falls through when preferred is not in the permitted set', () => {
|
|
29
|
-
const out =
|
|
29
|
+
const out = resolveAdminLocale({
|
|
30
30
|
locales,
|
|
31
31
|
defaultLocale,
|
|
32
32
|
preferred: 'de',
|
|
@@ -36,7 +36,7 @@ describe('resolveInterfaceLocale — tier 1 (preferred)', () => {
|
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
it('falls through when preferred is null', () => {
|
|
39
|
-
const out =
|
|
39
|
+
const out = resolveAdminLocale({
|
|
40
40
|
locales,
|
|
41
41
|
defaultLocale,
|
|
42
42
|
preferred: null,
|
|
@@ -46,9 +46,9 @@ describe('resolveInterfaceLocale — tier 1 (preferred)', () => {
|
|
|
46
46
|
})
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
describe('
|
|
49
|
+
describe('resolveAdminLocale — tier 2 (cookie)', () => {
|
|
50
50
|
it('wins over Accept-Language', () => {
|
|
51
|
-
const out =
|
|
51
|
+
const out = resolveAdminLocale({
|
|
52
52
|
locales,
|
|
53
53
|
defaultLocale,
|
|
54
54
|
cookie: 'es',
|
|
@@ -58,7 +58,7 @@ describe('resolveInterfaceLocale — tier 2 (cookie)', () => {
|
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
it('falls through when cookie points at a removed locale', () => {
|
|
61
|
-
const out =
|
|
61
|
+
const out = resolveAdminLocale({
|
|
62
62
|
locales,
|
|
63
63
|
defaultLocale,
|
|
64
64
|
cookie: 'de',
|
|
@@ -68,7 +68,7 @@ describe('resolveInterfaceLocale — tier 2 (cookie)', () => {
|
|
|
68
68
|
})
|
|
69
69
|
|
|
70
70
|
it('falls through when cookie is null', () => {
|
|
71
|
-
const out =
|
|
71
|
+
const out = resolveAdminLocale({
|
|
72
72
|
locales,
|
|
73
73
|
defaultLocale,
|
|
74
74
|
cookie: null,
|
|
@@ -78,9 +78,9 @@ describe('resolveInterfaceLocale — tier 2 (cookie)', () => {
|
|
|
78
78
|
})
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
-
describe('
|
|
81
|
+
describe('resolveAdminLocale — tier 3 (Accept-Language)', () => {
|
|
82
82
|
it('picks the best match from the header', () => {
|
|
83
|
-
const out =
|
|
83
|
+
const out = resolveAdminLocale({
|
|
84
84
|
locales,
|
|
85
85
|
defaultLocale,
|
|
86
86
|
acceptLanguage: 'fr-CA;q=0.9, fr;q=0.8, en;q=0.5',
|
|
@@ -89,7 +89,7 @@ describe('resolveInterfaceLocale — tier 3 (Accept-Language)', () => {
|
|
|
89
89
|
})
|
|
90
90
|
|
|
91
91
|
it('falls back to default when no header language is in the permitted set', () => {
|
|
92
|
-
const out =
|
|
92
|
+
const out = resolveAdminLocale({
|
|
93
93
|
locales,
|
|
94
94
|
defaultLocale,
|
|
95
95
|
acceptLanguage: 'de;q=0.9, ja;q=0.5',
|
|
@@ -98,7 +98,7 @@ describe('resolveInterfaceLocale — tier 3 (Accept-Language)', () => {
|
|
|
98
98
|
})
|
|
99
99
|
|
|
100
100
|
it('handles malformed headers gracefully', () => {
|
|
101
|
-
const out =
|
|
101
|
+
const out = resolveAdminLocale({
|
|
102
102
|
locales,
|
|
103
103
|
defaultLocale,
|
|
104
104
|
acceptLanguage: 'this-is-not-a-valid-header',
|
|
@@ -109,14 +109,14 @@ describe('resolveInterfaceLocale — tier 3 (Accept-Language)', () => {
|
|
|
109
109
|
})
|
|
110
110
|
})
|
|
111
111
|
|
|
112
|
-
describe('
|
|
112
|
+
describe('resolveAdminLocale — tier 4 (default)', () => {
|
|
113
113
|
it('returns defaultLocale when every other tier produces nothing', () => {
|
|
114
|
-
const out =
|
|
114
|
+
const out = resolveAdminLocale({ locales, defaultLocale })
|
|
115
115
|
expect(out).toBe('en')
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
it('returns defaultLocale when every signal is empty', () => {
|
|
119
|
-
const out =
|
|
119
|
+
const out = resolveAdminLocale({
|
|
120
120
|
locales,
|
|
121
121
|
defaultLocale,
|
|
122
122
|
preferred: null,
|
package/src/resolve.ts
CHANGED
|
@@ -29,10 +29,10 @@ import Negotiator from 'negotiator'
|
|
|
29
29
|
|
|
30
30
|
import type { LocaleCode } from './types.js'
|
|
31
31
|
|
|
32
|
-
export interface
|
|
33
|
-
/** Permitted locale set — from `i18n.
|
|
32
|
+
export interface ResolveAdminLocaleOptions {
|
|
33
|
+
/** Permitted locale set — from `i18n.admin.locales`. */
|
|
34
34
|
locales: readonly LocaleCode[]
|
|
35
|
-
/** Last-resort fallback — from `i18n.
|
|
35
|
+
/** Last-resort fallback — from `i18n.admin.defaultLocale`. */
|
|
36
36
|
defaultLocale: LocaleCode
|
|
37
37
|
/** `admin_users.preferred_locale` for the authenticated request, if any. */
|
|
38
38
|
preferred?: LocaleCode | null
|
|
@@ -42,7 +42,7 @@ export interface ResolveInterfaceLocaleOptions {
|
|
|
42
42
|
acceptLanguage?: string | null
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export function
|
|
45
|
+
export function resolveAdminLocale(options: ResolveAdminLocaleOptions): LocaleCode {
|
|
46
46
|
const { locales, defaultLocale, preferred, cookie, acceptLanguage } = options
|
|
47
47
|
|
|
48
48
|
// Tier 1 — admin user preference.
|
package/src/types.ts
CHANGED
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* Locale code — kept as a plain `string` so the package stays open to
|
|
11
11
|
* any BCP 47 tag (`en`, `pt-BR`, `zh-Hans-CN`). The host's
|
|
12
|
-
* `i18n.
|
|
12
|
+
* `i18n.admin.locales` config is the canonical allow-list at
|
|
13
13
|
* runtime; the resolver / validator narrow against it.
|
|
14
14
|
*/
|
|
15
15
|
export type LocaleCode = string
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Lightweight locale definition used by `<LanguageMenu>` to render the
|
|
19
|
-
* dropdown. The `code` matches a string in `i18n.
|
|
19
|
+
* dropdown. The `code` matches a string in `i18n.admin.locales`;
|
|
20
20
|
* the `nativeName` is what the user sees ("English", "Español",
|
|
21
21
|
* "Français", "Deutsch", "日本語").
|
|
22
22
|
*/
|