@chipmobilesdk/rn-i18n 0.1.2 → 0.1.3
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/CHANGELOG.md +70 -57
- package/README.md +218 -218
- package/package.json +46 -49
- package/skills/sdk-rn-i18n/SKILL.md +61 -62
- package/src/config/types.ts +144 -152
- package/src/config/validateConfig.ts +156 -174
- package/src/format/currency.ts +27 -27
- package/src/format/date.ts +26 -26
- package/src/format/invalid.ts +13 -16
- package/src/format/number.ts +23 -25
- package/src/format/units.ts +141 -151
- package/src/i18n.ts +196 -222
- package/src/index.ts +50 -50
- package/src/locale/activeLocale.ts +46 -45
- package/src/locale/deviceLocale.ts +50 -54
- package/src/locale/persistence.ts +31 -37
- package/src/react/I18nProvider.tsx +31 -35
- package/src/react/hooks.ts +57 -61
- package/src/tooling/cli.ts +76 -78
- package/src/tooling/generateKeys.ts +62 -68
- package/src/tooling/index.ts +27 -32
- package/src/tooling/report.ts +109 -117
- package/src/tooling/runner.ts +111 -126
- package/src/tooling/scan.ts +193 -210
- package/src/tooling/sync.ts +193 -198
- package/src/tooling/types.ts +119 -119
- package/src/translation/interpolate.ts +23 -23
- package/src/translation/plurals.ts +62 -69
- package/src/translation/resolver.ts +140 -146
- package/src/translation/runtimeKeys.ts +27 -27
package/package.json
CHANGED
|
@@ -1,49 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@chipmobilesdk/rn-i18n",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"private": false,
|
|
5
|
-
"license": "UNLICENSED",
|
|
6
|
-
"main": "src/index.ts",
|
|
7
|
-
"types": "src/index.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./src/index.ts",
|
|
11
|
-
"react-native": "./src/index.ts",
|
|
12
|
-
"default": "./src/index.ts"
|
|
13
|
-
},
|
|
14
|
-
"./tooling": {
|
|
15
|
-
"types": "./src/tooling/index.ts",
|
|
16
|
-
"node": "./src/tooling/index.ts",
|
|
17
|
-
"default": "./src/tooling/index.ts"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"src/index.ts",
|
|
22
|
-
"src/i18n.ts",
|
|
23
|
-
"src/config",
|
|
24
|
-
"src/translation",
|
|
25
|
-
"src/locale",
|
|
26
|
-
"src/format",
|
|
27
|
-
"src/react",
|
|
28
|
-
"src/tooling",
|
|
29
|
-
"skills",
|
|
30
|
-
"README.md",
|
|
31
|
-
"CHANGELOG.md"
|
|
32
|
-
],
|
|
33
|
-
"sideEffects": false,
|
|
34
|
-
"scripts": {
|
|
35
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
|
-
"pack:
|
|
37
|
-
},
|
|
38
|
-
"peerDependencies": {
|
|
39
|
-
"react": ">=19",
|
|
40
|
-
"react-native": ">=0.85"
|
|
41
|
-
},
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"registry": "https://registry.npmjs.org/"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@chipmobilesdk/rn-i18n",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"private": false,
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.ts",
|
|
11
|
+
"react-native": "./src/index.ts",
|
|
12
|
+
"default": "./src/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"./tooling": {
|
|
15
|
+
"types": "./src/tooling/index.ts",
|
|
16
|
+
"node": "./src/tooling/index.ts",
|
|
17
|
+
"default": "./src/tooling/index.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"src/index.ts",
|
|
22
|
+
"src/i18n.ts",
|
|
23
|
+
"src/config",
|
|
24
|
+
"src/translation",
|
|
25
|
+
"src/locale",
|
|
26
|
+
"src/format",
|
|
27
|
+
"src/react",
|
|
28
|
+
"src/tooling",
|
|
29
|
+
"skills",
|
|
30
|
+
"README.md",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
],
|
|
33
|
+
"sideEffects": false,
|
|
34
|
+
"scripts": {
|
|
35
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
|
+
"pack:check": "npm pack --dry-run"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=19",
|
|
40
|
+
"react-native": ">=0.85"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public",
|
|
44
|
+
"registry": "https://registry.npmjs.org/"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,62 +1,61 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sdk-rn-i18n
|
|
3
|
-
description: "Localization via @chipmobilesdk/rn-i18n: createI18n, useTranslation, useLocale, locale persistence, unit formatting, and the extraction/sync CLI. Use when adding translated strings, switching locale, formatting units, or syncing translation keys."
|
|
4
|
-
metadata:
|
|
5
|
-
package: "@chipmobilesdk/rn-i18n"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- `
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `
|
|
42
|
-
- `
|
|
43
|
-
- `
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
| Version/peer constraints | `## Compatibility` |
|
|
1
|
+
---
|
|
2
|
+
name: sdk-rn-i18n
|
|
3
|
+
description: "Localization via @chipmobilesdk/rn-i18n: createI18n, useTranslation, useLocale, locale persistence, unit formatting, and the extraction/sync CLI. Use when adding translated strings, switching locale, formatting units, or syncing translation keys."
|
|
4
|
+
metadata:
|
|
5
|
+
package: "@chipmobilesdk/rn-i18n"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
disable-model-invocation: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# @chipmobilesdk/rn-i18n
|
|
11
|
+
|
|
12
|
+
Localization with device-locale detection, persisted locale choice, typed translation
|
|
13
|
+
access, unit/number formatting, and a CLI that extracts and synchronizes keys.
|
|
14
|
+
|
|
15
|
+
## Use this when
|
|
16
|
+
|
|
17
|
+
- Adding or changing any user-facing string
|
|
18
|
+
- Reading or switching the active locale
|
|
19
|
+
- Formatting numbers, dates or units for a locale
|
|
20
|
+
- Translation keys are missing, stale, or out of sync across locale files
|
|
21
|
+
|
|
22
|
+
## Never hardcode a user-facing string
|
|
23
|
+
|
|
24
|
+
Every string rendered to a user goes through `useTranslation`. A literal in a component
|
|
25
|
+
is a defect — it cannot be translated and will not appear in extraction output.
|
|
26
|
+
|
|
27
|
+
## Keys are generated, not hand-maintained
|
|
28
|
+
|
|
29
|
+
Do not hand-edit locale JSON to add a key. Run the extraction/sync CLI so every locale
|
|
30
|
+
file stays aligned. The monorepo exposes it as `npm run i18n:sync`. See
|
|
31
|
+
`## Extraction & synchronization CLI`.
|
|
32
|
+
|
|
33
|
+
## Public API
|
|
34
|
+
|
|
35
|
+
Runtime:
|
|
36
|
+
|
|
37
|
+
- `createI18n(...)` → `I18n`
|
|
38
|
+
- `I18nProvider` (+ `I18nProviderProps`)
|
|
39
|
+
- `useTranslation()` → `UseTranslationResult`
|
|
40
|
+
- `useLocale()` → `UseLocaleResult`
|
|
41
|
+
- `defaultDeviceLocaleProvider` — device locale detection
|
|
42
|
+
- `LOCALE_STORAGE_KEY` — where the chosen locale persists
|
|
43
|
+
- `I18nConfigError` — thrown on invalid configuration at startup
|
|
44
|
+
|
|
45
|
+
Types: `I18n`, `UnitFormatOptions`, `I18nProviderProps`, `UseLocaleResult`,
|
|
46
|
+
`UseTranslationResult`
|
|
47
|
+
|
|
48
|
+
`I18nConfigError` throws at startup by design — a misconfigured i18n setup should fail
|
|
49
|
+
loudly, not silently render keys.
|
|
50
|
+
|
|
51
|
+
## Where the detail lives
|
|
52
|
+
|
|
53
|
+
Read one section of `node_modules/@chipmobilesdk/rn-i18n/README.md`:
|
|
54
|
+
|
|
55
|
+
| Need | Section |
|
|
56
|
+
|---|---|
|
|
57
|
+
| First integration | `## Installation`, `## Quick start` |
|
|
58
|
+
| Full export list | `## Public API` |
|
|
59
|
+
| Locale file layout, plurals | `## Translations` |
|
|
60
|
+
| Adding/syncing keys | `## Extraction & synchronization CLI` |
|
|
61
|
+
| Version/peer constraints | `## Compatibility` |
|
package/src/config/types.ts
CHANGED
|
@@ -1,152 +1,144 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public configuration and contract types for @chipmobilesdk/rn-i18n.
|
|
3
|
-
*
|
|
4
|
-
* The package has zero runtime dependencies: formatting uses the Intl APIs
|
|
5
|
-
* built into Hermes (Intl.NumberFormat, Intl.DateTimeFormat), while plural
|
|
6
|
-
* rules and unit conversion are package-owned because Intl.PluralRules and
|
|
7
|
-
* Intl unit-style formatting are not reliably available in Hermes.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export type LocaleDirection = 'ltr' | 'rtl';
|
|
11
|
-
|
|
12
|
-
export type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
|
|
13
|
-
|
|
14
|
-
export type PluralRule = (count: number) => PluralCategory;
|
|
15
|
-
|
|
16
|
-
export type UnitDimension = 'length' | 'mass' | 'volume' | 'temperature';
|
|
17
|
-
|
|
18
|
-
export type UnitId =
|
|
19
|
-
| 'millimeter'
|
|
20
|
-
| 'centimeter'
|
|
21
|
-
| 'meter'
|
|
22
|
-
| 'kilometer'
|
|
23
|
-
| 'inch'
|
|
24
|
-
| 'foot'
|
|
25
|
-
| 'mile'
|
|
26
|
-
| 'gram'
|
|
27
|
-
| 'kilogram'
|
|
28
|
-
| 'ounce'
|
|
29
|
-
| 'pound'
|
|
30
|
-
| 'milliliter'
|
|
31
|
-
| 'liter'
|
|
32
|
-
| 'gallon'
|
|
33
|
-
| 'celsius'
|
|
34
|
-
| 'fahrenheit'
|
|
35
|
-
| 'kelvin';
|
|
36
|
-
|
|
37
|
-
export interface LocaleConfig {
|
|
38
|
-
/** BCP-47 language-region code, e.g. `vi-VN`, `en-US`, `ja-JP`. */
|
|
39
|
-
code: string;
|
|
40
|
-
displayName: string;
|
|
41
|
-
direction: LocaleDirection;
|
|
42
|
-
/**
|
|
43
|
-
* Ordered locale codes consulted when a key is missing from this locale.
|
|
44
|
-
* Every entry must be another supported locale; cycles, duplicates, and
|
|
45
|
-
* self-references are rejected during setup validation.
|
|
46
|
-
*/
|
|
47
|
-
fallbackChain: string[];
|
|
48
|
-
/** ISO-4217 currency code used when no explicit currency is requested. */
|
|
49
|
-
defaultCurrency: string;
|
|
50
|
-
defaultUnit: UnitId;
|
|
51
|
-
/**
|
|
52
|
-
* Default Intl.DateTimeFormat options for this locale. Restricted to the
|
|
53
|
-
* component options supported by Hermes on both Android and iOS.
|
|
54
|
-
*/
|
|
55
|
-
defaultDateFormat: Intl.DateTimeFormatOptions;
|
|
56
|
-
/** Default Intl.NumberFormat options for this locale. */
|
|
57
|
-
defaultNumberFormat: Intl.NumberFormatOptions;
|
|
58
|
-
/** Optional plural rule override; defaults to the built-in language rule. */
|
|
59
|
-
pluralRule?: PluralRule;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export type TranslationNode = string | { [key: string]: TranslationNode };
|
|
63
|
-
|
|
64
|
-
export type TranslationNamespace = { [key: string]: TranslationNode };
|
|
65
|
-
|
|
66
|
-
/** App-owned translation resources keyed by locale code. */
|
|
67
|
-
export type TranslationResources = { [localeCode: string]: TranslationNamespace };
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* A translation key intentionally resolved at runtime and therefore not
|
|
71
|
-
* discoverable by static source scanning. Declared entries are protected
|
|
72
|
-
* from removal during locale JSON synchronization.
|
|
73
|
-
*/
|
|
74
|
-
export interface RuntimeTranslationEntry {
|
|
75
|
-
key: string;
|
|
76
|
-
/** Template text used when no locale resource provides a value. */
|
|
77
|
-
defaultText: string;
|
|
78
|
-
/**
|
|
79
|
-
* Synchronization policy when the key is missing from a locale file:
|
|
80
|
-
* `add` writes the default text, `report` only lists it. Default: `report`.
|
|
81
|
-
*/
|
|
82
|
-
policy?: 'add' | 'report';
|
|
83
|
-
/** Owning feature note surfaced in the extraction report. */
|
|
84
|
-
description?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export type MissingTranslationPolicy =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
export
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
readonly issues: readonly string[];
|
|
146
|
-
|
|
147
|
-
constructor(issues: readonly string[]) {
|
|
148
|
-
super(`Invalid i18n configuration:\n- ${issues.join('\n- ')}`);
|
|
149
|
-
this.name = 'I18nConfigError';
|
|
150
|
-
this.issues = issues;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Public configuration and contract types for @chipmobilesdk/rn-i18n.
|
|
3
|
+
*
|
|
4
|
+
* The package has zero runtime dependencies: formatting uses the Intl APIs
|
|
5
|
+
* built into Hermes (Intl.NumberFormat, Intl.DateTimeFormat), while plural
|
|
6
|
+
* rules and unit conversion are package-owned because Intl.PluralRules and
|
|
7
|
+
* Intl unit-style formatting are not reliably available in Hermes.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type LocaleDirection = 'ltr' | 'rtl';
|
|
11
|
+
|
|
12
|
+
export type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
|
|
13
|
+
|
|
14
|
+
export type PluralRule = (count: number) => PluralCategory;
|
|
15
|
+
|
|
16
|
+
export type UnitDimension = 'length' | 'mass' | 'volume' | 'temperature';
|
|
17
|
+
|
|
18
|
+
export type UnitId =
|
|
19
|
+
| 'millimeter'
|
|
20
|
+
| 'centimeter'
|
|
21
|
+
| 'meter'
|
|
22
|
+
| 'kilometer'
|
|
23
|
+
| 'inch'
|
|
24
|
+
| 'foot'
|
|
25
|
+
| 'mile'
|
|
26
|
+
| 'gram'
|
|
27
|
+
| 'kilogram'
|
|
28
|
+
| 'ounce'
|
|
29
|
+
| 'pound'
|
|
30
|
+
| 'milliliter'
|
|
31
|
+
| 'liter'
|
|
32
|
+
| 'gallon'
|
|
33
|
+
| 'celsius'
|
|
34
|
+
| 'fahrenheit'
|
|
35
|
+
| 'kelvin';
|
|
36
|
+
|
|
37
|
+
export interface LocaleConfig {
|
|
38
|
+
/** BCP-47 language-region code, e.g. `vi-VN`, `en-US`, `ja-JP`. */
|
|
39
|
+
code: string;
|
|
40
|
+
displayName: string;
|
|
41
|
+
direction: LocaleDirection;
|
|
42
|
+
/**
|
|
43
|
+
* Ordered locale codes consulted when a key is missing from this locale.
|
|
44
|
+
* Every entry must be another supported locale; cycles, duplicates, and
|
|
45
|
+
* self-references are rejected during setup validation.
|
|
46
|
+
*/
|
|
47
|
+
fallbackChain: string[];
|
|
48
|
+
/** ISO-4217 currency code used when no explicit currency is requested. */
|
|
49
|
+
defaultCurrency: string;
|
|
50
|
+
defaultUnit: UnitId;
|
|
51
|
+
/**
|
|
52
|
+
* Default Intl.DateTimeFormat options for this locale. Restricted to the
|
|
53
|
+
* component options supported by Hermes on both Android and iOS.
|
|
54
|
+
*/
|
|
55
|
+
defaultDateFormat: Intl.DateTimeFormatOptions;
|
|
56
|
+
/** Default Intl.NumberFormat options for this locale. */
|
|
57
|
+
defaultNumberFormat: Intl.NumberFormatOptions;
|
|
58
|
+
/** Optional plural rule override; defaults to the built-in language rule. */
|
|
59
|
+
pluralRule?: PluralRule;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type TranslationNode = string | { [key: string]: TranslationNode };
|
|
63
|
+
|
|
64
|
+
export type TranslationNamespace = { [key: string]: TranslationNode };
|
|
65
|
+
|
|
66
|
+
/** App-owned translation resources keyed by locale code. */
|
|
67
|
+
export type TranslationResources = { [localeCode: string]: TranslationNamespace };
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A translation key intentionally resolved at runtime and therefore not
|
|
71
|
+
* discoverable by static source scanning. Declared entries are protected
|
|
72
|
+
* from removal during locale JSON synchronization.
|
|
73
|
+
*/
|
|
74
|
+
export interface RuntimeTranslationEntry {
|
|
75
|
+
key: string;
|
|
76
|
+
/** Template text used when no locale resource provides a value. */
|
|
77
|
+
defaultText: string;
|
|
78
|
+
/**
|
|
79
|
+
* Synchronization policy when the key is missing from a locale file:
|
|
80
|
+
* `add` writes the default text, `report` only lists it. Default: `report`.
|
|
81
|
+
*/
|
|
82
|
+
policy?: 'add' | 'report';
|
|
83
|
+
/** Owning feature note surfaced in the extraction report. */
|
|
84
|
+
description?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type MissingTranslationPolicy = { mode: 'key' } | { mode: 'placeholder'; text: string };
|
|
88
|
+
|
|
89
|
+
export type InvalidFormatPolicy = { mode: 'placeholder'; text: string } | { mode: 'error' };
|
|
90
|
+
|
|
91
|
+
/** App-injected persistence contract. The package never bundles a backend. */
|
|
92
|
+
export interface LocaleStorageAdapter {
|
|
93
|
+
getItem(key: string): Promise<string | null>;
|
|
94
|
+
setItem(key: string, value: string): Promise<void>;
|
|
95
|
+
removeItem(key: string): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Returns the device locale, or undefined when detection is unavailable. */
|
|
99
|
+
export type DeviceLocaleProvider = () => string | undefined;
|
|
100
|
+
|
|
101
|
+
export interface I18nConfig {
|
|
102
|
+
locales: LocaleConfig[];
|
|
103
|
+
/** Recovery locale when persistence or device detection cannot decide. */
|
|
104
|
+
primaryLocale: string;
|
|
105
|
+
resources: TranslationResources;
|
|
106
|
+
runtimeEntries?: RuntimeTranslationEntry[];
|
|
107
|
+
/** Persist the selected locale across launches. Default: true. */
|
|
108
|
+
persistLocale?: boolean;
|
|
109
|
+
/** Required when `persistLocale` is not disabled. */
|
|
110
|
+
storage?: LocaleStorageAdapter;
|
|
111
|
+
deviceLocale?: DeviceLocaleProvider;
|
|
112
|
+
/** Default: `{ mode: 'key' }`. */
|
|
113
|
+
missingTranslation?: MissingTranslationPolicy;
|
|
114
|
+
/** Default: `{ mode: 'placeholder', text: '—' }`. */
|
|
115
|
+
invalidFormat?: InvalidFormatPolicy;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type LocaleSelectionSource =
|
|
119
|
+
'persisted' | 'device' | 'languageMatch' | 'primaryFallback' | 'runtimeSwitch';
|
|
120
|
+
|
|
121
|
+
export interface ActiveLocalePreference {
|
|
122
|
+
code: string;
|
|
123
|
+
source: LocaleSelectionSource;
|
|
124
|
+
/** True when an unsupported persisted locale was discarded. */
|
|
125
|
+
recovered: boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type TranslateVars = Record<string, string | number>;
|
|
129
|
+
|
|
130
|
+
export interface TranslateOptions {
|
|
131
|
+
/** Selects the plural variant and is exposed as the `count` variable. */
|
|
132
|
+
count?: number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Configuration error listing every detected violation. */
|
|
136
|
+
export class I18nConfigError extends Error {
|
|
137
|
+
readonly issues: readonly string[];
|
|
138
|
+
|
|
139
|
+
constructor(issues: readonly string[]) {
|
|
140
|
+
super(`Invalid i18n configuration:\n- ${issues.join('\n- ')}`);
|
|
141
|
+
this.name = 'I18nConfigError';
|
|
142
|
+
this.issues = issues;
|
|
143
|
+
}
|
|
144
|
+
}
|