@better-i18n/core 0.2.4 → 0.3.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/dist/cdn.d.ts.map +1 -1
- package/dist/cdn.js +48 -11
- package/dist/cdn.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/locale-ui.d.ts +67 -0
- package/dist/utils/locale-ui.d.ts.map +1 -0
- package/dist/utils/locale-ui.js +114 -0
- package/dist/utils/locale-ui.js.map +1 -0
- package/package.json +1 -1
package/dist/cdn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAMf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAMf,MAAM,YAAY,CAAC;AAkVpB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,cAAc,KAAG,QAmCvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAC"}
|
package/dist/cdn.js
CHANGED
|
@@ -7,6 +7,8 @@ const STORAGE_PREFIX = "@better-i18n";
|
|
|
7
7
|
// Global caches (shared across instances)
|
|
8
8
|
const manifestCache = new TtlCache();
|
|
9
9
|
const messagesCache = new TtlCache();
|
|
10
|
+
// ETag cache — keyed same as messagesCache, stores last ETag for If-None-Match
|
|
11
|
+
const messagesETagCache = new TtlCache();
|
|
10
12
|
// ─── Storage helpers ────────────────────────────────────────────────
|
|
11
13
|
const buildManifestStorageKey = (project) => `${STORAGE_PREFIX}:manifest:${project}`;
|
|
12
14
|
const buildMessagesStorageKey = (project, locale) => `${STORAGE_PREFIX}:messages:${project}:${locale}`;
|
|
@@ -144,23 +146,33 @@ const getManifestWithCache = async (config, fetchFn, forceRefresh = false) => {
|
|
|
144
146
|
throw cdnError;
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
|
-
// ─── Messages fetching with fallback ────────────────────────────────
|
|
148
149
|
/**
|
|
149
|
-
* Fetch messages from CDN (raw, no cache)
|
|
150
|
+
* Fetch messages from CDN (raw, no cache).
|
|
151
|
+
* Passes If-None-Match when an ETag is known — returns { notModified: true } on 304.
|
|
150
152
|
*/
|
|
151
|
-
const fetchMessagesFromCdn = async (config, locale, fetchFn) => {
|
|
153
|
+
const fetchMessagesFromCdn = async (config, locale, fetchFn, ifNoneMatch) => {
|
|
152
154
|
const logger = createLogger(config, "messages");
|
|
153
155
|
const url = `${getProjectBaseUrl(config)}/${locale}/translations.json`;
|
|
154
156
|
logger.debug("fetching", url);
|
|
155
|
-
const
|
|
157
|
+
const headers = { "Cache-Control": "no-store" };
|
|
158
|
+
if (ifNoneMatch) {
|
|
159
|
+
headers["If-None-Match"] = ifNoneMatch;
|
|
160
|
+
}
|
|
161
|
+
const response = await fetchWithRetry(fetchFn, url, { headers }, config.fetchTimeout, config.retryCount);
|
|
162
|
+
// 304 Not Modified — cached content is still fresh
|
|
163
|
+
if (response.status === 304) {
|
|
164
|
+
logger.debug("304 Not Modified", { locale });
|
|
165
|
+
return { notModified: true };
|
|
166
|
+
}
|
|
156
167
|
if (!response.ok) {
|
|
157
168
|
const message = `Messages fetch failed for locale "${locale}" (${response.status})`;
|
|
158
169
|
logger.error(message);
|
|
159
170
|
throw new Error(`[better-i18n] ${message}`);
|
|
160
171
|
}
|
|
161
172
|
const data = (await response.json());
|
|
173
|
+
const etag = response.headers?.get?.("etag") ?? null;
|
|
162
174
|
logger.debug("fetched", { locale, keys: Object.keys(data).length });
|
|
163
|
-
return data;
|
|
175
|
+
return { notModified: false, messages: data, etag };
|
|
164
176
|
};
|
|
165
177
|
/**
|
|
166
178
|
* Get messages with full fallback chain:
|
|
@@ -179,13 +191,38 @@ const getMessagesWithFallback = async (config, locale, fetchFn) => {
|
|
|
179
191
|
const memoryCached = messagesCache.get(cacheKey);
|
|
180
192
|
if (memoryCached)
|
|
181
193
|
return memoryCached;
|
|
182
|
-
// 2. CDN fetch
|
|
194
|
+
// 2. CDN fetch (with ETag If-None-Match when available)
|
|
183
195
|
try {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
196
|
+
const cachedETag = messagesETagCache.get(cacheKey);
|
|
197
|
+
const result = await fetchMessagesFromCdn(config, safeLng, fetchFn, cachedETag);
|
|
198
|
+
// 304 Not Modified — CDN confirmed content unchanged; refresh TTL with stored data
|
|
199
|
+
if (result.notModified) {
|
|
200
|
+
const stored = await readFromStorage(config.storage, storageKey);
|
|
201
|
+
if (stored) {
|
|
202
|
+
logger.debug(`304: refreshing TTL for "${safeLng}" from storage`);
|
|
203
|
+
messagesCache.set(cacheKey, stored, config.manifestCacheTtlMs);
|
|
204
|
+
return stored;
|
|
205
|
+
}
|
|
206
|
+
// No storage fallback — re-fetch without ETag to get fresh data
|
|
207
|
+
const freshResult = await fetchMessagesFromCdn(config, safeLng, fetchFn);
|
|
208
|
+
if (!freshResult.notModified) {
|
|
209
|
+
messagesCache.set(cacheKey, freshResult.messages, config.manifestCacheTtlMs);
|
|
210
|
+
if (freshResult.etag)
|
|
211
|
+
messagesETagCache.set(cacheKey, freshResult.etag, config.manifestCacheTtlMs);
|
|
212
|
+
writeToStorage(config.storage, storageKey, freshResult.messages);
|
|
213
|
+
return freshResult.messages;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// 200 OK — new or changed content
|
|
217
|
+
if (!result.notModified) {
|
|
218
|
+
messagesCache.set(cacheKey, result.messages, config.manifestCacheTtlMs);
|
|
219
|
+
if (result.etag)
|
|
220
|
+
messagesETagCache.set(cacheKey, result.etag, config.manifestCacheTtlMs);
|
|
221
|
+
writeToStorage(config.storage, storageKey, result.messages);
|
|
222
|
+
return result.messages;
|
|
223
|
+
}
|
|
224
|
+
// Shouldn't reach here, but satisfy TypeScript
|
|
225
|
+
throw new Error("[better-i18n] Unexpected 304 without storage fallback");
|
|
189
226
|
}
|
|
190
227
|
catch (cdnError) {
|
|
191
228
|
logger.warn(`CDN fetch failed for locale "${safeLng}", trying fallback sources`, cdnError);
|
package/dist/cdn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdn.js","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAUjD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC,0CAA0C;AAC1C,MAAM,aAAa,GAAG,IAAI,QAAQ,EAAoB,CAAC;AACvD,MAAM,aAAa,GAAG,IAAI,QAAQ,EAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cdn.js","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { extractLanguages } from "./manifest.js";
|
|
|
5
5
|
export { createLogger } from "./logger.js";
|
|
6
6
|
export { detectLocale } from "./i18n/detection.js";
|
|
7
7
|
export { TtlCache, buildCacheKey } from "./cache.js";
|
|
8
|
+
export { LANGUAGE_TO_COUNTRY, getCountryCodeFromLocale, getFlagEmoji, getLanguageLabel, resolveFlag, type ResolvedFlag, } from "./utils/locale-ui.js";
|
|
8
9
|
export { normalizeLocale, extractLocale, getLocaleFromPath, hasLocalePrefix, removeLocalePrefix, addLocalePrefix, replaceLocaleInPath, createLocalePath, type LocaleConfig, } from "./utils/locale.js";
|
|
9
10
|
export type { I18nCoreConfig, NormalizedConfig, ParsedProject, ManifestResponse, ManifestLanguage, ManifestFile, LanguageOption, Messages, Locale, I18nCore, TranslationStorage, Logger, LogLevel, CacheEntry, } from "./types.js";
|
|
10
11
|
export type { I18nMiddlewareConfig, LocaleDetectionOptions, LocaleDetectionResult, LocalePrefix, } from "./i18n/types.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGlF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGhG,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAEV,cAAc,EACd,gBAAgB,EAChB,aAAa,EAGb,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EAGd,QAAQ,EACR,MAAM,EAGN,QAAQ,EAGR,kBAAkB,EAGlB,MAAM,EACN,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,GACb,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGlF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGhG,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAEV,cAAc,EACd,gBAAgB,EAChB,aAAa,EAGb,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EAGd,QAAQ,EACR,MAAM,EAGN,QAAQ,EAGR,kBAAkB,EAGlB,MAAM,EACN,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,GACb,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,8 @@ export { createLogger } from "./logger.js";
|
|
|
12
12
|
export { detectLocale } from "./i18n/detection.js";
|
|
13
13
|
// Cache utilities
|
|
14
14
|
export { TtlCache, buildCacheKey } from "./cache.js";
|
|
15
|
+
// Locale UI utilities (flags, labels, country codes)
|
|
16
|
+
export { LANGUAGE_TO_COUNTRY, getCountryCodeFromLocale, getFlagEmoji, getLanguageLabel, resolveFlag, } from "./utils/locale-ui.js";
|
|
15
17
|
// Locale utilities
|
|
16
18
|
export { normalizeLocale, extractLocale, getLocaleFromPath, hasLocalePrefix, removeLocalePrefix, addLocalePrefix, replaceLocaleInPath, createLocalePath, } from "./utils/locale.js";
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAElF,mBAAmB;AACnB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEhG,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/E,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,kBAAkB;AAClB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAErD,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GAEjB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAElF,mBAAmB;AACnB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEhG,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/E,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,kBAAkB;AAClB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAErD,qDAAqD;AACrD,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,gBAAgB,EAChB,WAAW,GAEZ,MAAM,sBAAsB,CAAC;AAE9B,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GAEjB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI utilities for locale display: flag resolution, country codes, and labels.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the platform's LanguageSwitcher for use across all OSS packages.
|
|
5
|
+
* Zero dependencies — works in any React environment.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Maps primary language codes to their most commonly associated country codes.
|
|
9
|
+
* Used as a fallback when no explicit `countryCode` or regional subtag is available.
|
|
10
|
+
*/
|
|
11
|
+
export declare const LANGUAGE_TO_COUNTRY: Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Derives a two-letter country code from a locale string.
|
|
14
|
+
*
|
|
15
|
+
* Resolution order:
|
|
16
|
+
* 1. Regional subtag (e.g., "pt-BR" → "br")
|
|
17
|
+
* 2. LANGUAGE_TO_COUNTRY map (e.g., "ja" → "jp")
|
|
18
|
+
* 3. null if no mapping exists
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCountryCodeFromLocale(locale: string): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Converts a two-letter country code to its flag emoji using regional indicator symbols.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* getFlagEmoji("us") // "🇺🇸"
|
|
26
|
+
* getFlagEmoji("tr") // "🇹🇷"
|
|
27
|
+
* getFlagEmoji(null) // null
|
|
28
|
+
*/
|
|
29
|
+
export declare function getFlagEmoji(countryCode?: string | null): string | null;
|
|
30
|
+
/** Minimal language shape for UI utilities — compatible with `LanguageOption`. */
|
|
31
|
+
interface LanguageLike {
|
|
32
|
+
code: string;
|
|
33
|
+
name?: string;
|
|
34
|
+
nativeName?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the best display label for a language.
|
|
38
|
+
* Priority: nativeName → name → uppercased code.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getLanguageLabel(language: LanguageLike): string;
|
|
41
|
+
/** Resolved flag info for rendering. */
|
|
42
|
+
export type ResolvedFlag = {
|
|
43
|
+
type: "url";
|
|
44
|
+
url: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: "emoji";
|
|
47
|
+
emoji: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: "none";
|
|
50
|
+
};
|
|
51
|
+
/** Minimal shape needed for flag resolution. */
|
|
52
|
+
interface FlagResolvable {
|
|
53
|
+
code: string;
|
|
54
|
+
countryCode?: string | null;
|
|
55
|
+
flagUrl?: string | null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolves the best available flag representation for a language.
|
|
59
|
+
*
|
|
60
|
+
* Resolution order:
|
|
61
|
+
* 1. `flagUrl` → image URL (custom flag from CDN manifest)
|
|
62
|
+
* 2. Emoji flag derived from country code or locale
|
|
63
|
+
* 3. `{ type: "none" }` — caller should render a globe icon
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveFlag(language: FlagResolvable): ResolvedFlag;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=locale-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-ui.d.ts","sourceRoot":"","sources":["../../src/utils/locale-ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuCtD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CActE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAQvE;AAED,kFAAkF;AAClF,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAE/D;AAED,wCAAwC;AACxC,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,gDAAgD;AAChD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY,CAclE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI utilities for locale display: flag resolution, country codes, and labels.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the platform's LanguageSwitcher for use across all OSS packages.
|
|
5
|
+
* Zero dependencies — works in any React environment.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Maps primary language codes to their most commonly associated country codes.
|
|
9
|
+
* Used as a fallback when no explicit `countryCode` or regional subtag is available.
|
|
10
|
+
*/
|
|
11
|
+
export const LANGUAGE_TO_COUNTRY = {
|
|
12
|
+
ar: "sa",
|
|
13
|
+
bg: "bg",
|
|
14
|
+
bn: "bd",
|
|
15
|
+
cs: "cz",
|
|
16
|
+
da: "dk",
|
|
17
|
+
de: "de",
|
|
18
|
+
el: "gr",
|
|
19
|
+
en: "gb",
|
|
20
|
+
es: "es",
|
|
21
|
+
et: "ee",
|
|
22
|
+
fi: "fi",
|
|
23
|
+
fr: "fr",
|
|
24
|
+
he: "il",
|
|
25
|
+
hi: "in",
|
|
26
|
+
hr: "hr",
|
|
27
|
+
hu: "hu",
|
|
28
|
+
id: "id",
|
|
29
|
+
it: "it",
|
|
30
|
+
ja: "jp",
|
|
31
|
+
ko: "kr",
|
|
32
|
+
lt: "lt",
|
|
33
|
+
lv: "lv",
|
|
34
|
+
ms: "my",
|
|
35
|
+
nl: "nl",
|
|
36
|
+
no: "no",
|
|
37
|
+
pl: "pl",
|
|
38
|
+
pt: "pt",
|
|
39
|
+
ro: "ro",
|
|
40
|
+
ru: "ru",
|
|
41
|
+
sk: "sk",
|
|
42
|
+
sl: "si",
|
|
43
|
+
sr: "rs",
|
|
44
|
+
sv: "se",
|
|
45
|
+
th: "th",
|
|
46
|
+
tr: "tr",
|
|
47
|
+
uk: "ua",
|
|
48
|
+
vi: "vn",
|
|
49
|
+
zh: "cn",
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Derives a two-letter country code from a locale string.
|
|
53
|
+
*
|
|
54
|
+
* Resolution order:
|
|
55
|
+
* 1. Regional subtag (e.g., "pt-BR" → "br")
|
|
56
|
+
* 2. LANGUAGE_TO_COUNTRY map (e.g., "ja" → "jp")
|
|
57
|
+
* 3. null if no mapping exists
|
|
58
|
+
*/
|
|
59
|
+
export function getCountryCodeFromLocale(locale) {
|
|
60
|
+
const normalizedLocale = locale.trim().toLowerCase();
|
|
61
|
+
if (!normalizedLocale)
|
|
62
|
+
return null;
|
|
63
|
+
const [, regionOrScript] = normalizedLocale.split("-");
|
|
64
|
+
if (regionOrScript && /^[a-z]{2}$/i.test(regionOrScript)) {
|
|
65
|
+
return regionOrScript.toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
return (LANGUAGE_TO_COUNTRY[normalizedLocale] ||
|
|
68
|
+
LANGUAGE_TO_COUNTRY[normalizedLocale.split("-")[0]] ||
|
|
69
|
+
null);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Converts a two-letter country code to its flag emoji using regional indicator symbols.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* getFlagEmoji("us") // "🇺🇸"
|
|
76
|
+
* getFlagEmoji("tr") // "🇹🇷"
|
|
77
|
+
* getFlagEmoji(null) // null
|
|
78
|
+
*/
|
|
79
|
+
export function getFlagEmoji(countryCode) {
|
|
80
|
+
if (!countryCode || !/^[a-z]{2}$/i.test(countryCode))
|
|
81
|
+
return null;
|
|
82
|
+
return countryCode
|
|
83
|
+
.toUpperCase()
|
|
84
|
+
.split("")
|
|
85
|
+
.map((char) => String.fromCodePoint(127397 + char.charCodeAt(0)))
|
|
86
|
+
.join("");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns the best display label for a language.
|
|
90
|
+
* Priority: nativeName → name → uppercased code.
|
|
91
|
+
*/
|
|
92
|
+
export function getLanguageLabel(language) {
|
|
93
|
+
return language.nativeName || language.name || language.code.toUpperCase();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resolves the best available flag representation for a language.
|
|
97
|
+
*
|
|
98
|
+
* Resolution order:
|
|
99
|
+
* 1. `flagUrl` → image URL (custom flag from CDN manifest)
|
|
100
|
+
* 2. Emoji flag derived from country code or locale
|
|
101
|
+
* 3. `{ type: "none" }` — caller should render a globe icon
|
|
102
|
+
*/
|
|
103
|
+
export function resolveFlag(language) {
|
|
104
|
+
if (language.flagUrl) {
|
|
105
|
+
return { type: "url", url: language.flagUrl };
|
|
106
|
+
}
|
|
107
|
+
const countryCode = language.countryCode || getCountryCodeFromLocale(language.code);
|
|
108
|
+
const emoji = getFlagEmoji(countryCode);
|
|
109
|
+
if (emoji) {
|
|
110
|
+
return { type: "emoji", emoji };
|
|
111
|
+
}
|
|
112
|
+
return { type: "none" };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=locale-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-ui.js","sourceRoot":"","sources":["../../src/utils/locale-ui.ts"],"names":[],"mappings":"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"}
|