@adminiumjs/i18n 0.1.0-rc.1
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/LICENSE +661 -0
- package/dist/create-i18n.d.ts +48 -0
- package/dist/create-i18n.d.ts.map +1 -0
- package/dist/create-i18n.js +98 -0
- package/dist/create-i18n.js.map +1 -0
- package/dist/format/index.d.ts +70 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +217 -0
- package/dist/format/index.js.map +1 -0
- package/dist/icu-format.d.ts +17 -0
- package/dist/icu-format.d.ts.map +1 -0
- package/dist/icu-format.js +52 -0
- package/dist/icu-format.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/locales.d.ts +99 -0
- package/dist/locales.d.ts.map +1 -0
- package/dist/locales.js +55 -0
- package/dist/locales.js.map +1 -0
- package/dist/react.d.ts +26 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +61 -0
- package/dist/react.js.map +1 -0
- package/dist/resources/ar-eg/common.d.ts +1964 -0
- package/dist/resources/ar-eg/common.d.ts.map +1 -0
- package/dist/resources/ar-eg/common.js +1963 -0
- package/dist/resources/ar-eg/common.js.map +1 -0
- package/dist/resources/ar-eg/errors.d.ts +45 -0
- package/dist/resources/ar-eg/errors.d.ts.map +1 -0
- package/dist/resources/ar-eg/errors.js +44 -0
- package/dist/resources/ar-eg/errors.js.map +1 -0
- package/dist/resources/ar-eg/generated.d.ts +20 -0
- package/dist/resources/ar-eg/generated.d.ts.map +1 -0
- package/dist/resources/ar-eg/generated.js +19 -0
- package/dist/resources/ar-eg/generated.js.map +1 -0
- package/dist/resources/ar-eg/studio.d.ts +18 -0
- package/dist/resources/ar-eg/studio.d.ts.map +1 -0
- package/dist/resources/ar-eg/studio.js +17 -0
- package/dist/resources/ar-eg/studio.js.map +1 -0
- package/dist/resources/ar-eg/ui.d.ts +996 -0
- package/dist/resources/ar-eg/ui.d.ts.map +1 -0
- package/dist/resources/ar-eg/ui.js +995 -0
- package/dist/resources/ar-eg/ui.js.map +1 -0
- package/dist/resources/cs-cz/common.d.ts +1964 -0
- package/dist/resources/cs-cz/common.d.ts.map +1 -0
- package/dist/resources/cs-cz/common.js +1963 -0
- package/dist/resources/cs-cz/common.js.map +1 -0
- package/dist/resources/cs-cz/errors.d.ts +45 -0
- package/dist/resources/cs-cz/errors.d.ts.map +1 -0
- package/dist/resources/cs-cz/errors.js +44 -0
- package/dist/resources/cs-cz/errors.js.map +1 -0
- package/dist/resources/cs-cz/generated.d.ts +20 -0
- package/dist/resources/cs-cz/generated.d.ts.map +1 -0
- package/dist/resources/cs-cz/generated.js +19 -0
- package/dist/resources/cs-cz/generated.js.map +1 -0
- package/dist/resources/cs-cz/studio.d.ts +18 -0
- package/dist/resources/cs-cz/studio.d.ts.map +1 -0
- package/dist/resources/cs-cz/studio.js +17 -0
- package/dist/resources/cs-cz/studio.js.map +1 -0
- package/dist/resources/cs-cz/ui.d.ts +996 -0
- package/dist/resources/cs-cz/ui.d.ts.map +1 -0
- package/dist/resources/cs-cz/ui.js +995 -0
- package/dist/resources/cs-cz/ui.js.map +1 -0
- package/dist/resources/da-dk/common.d.ts +1964 -0
- package/dist/resources/da-dk/common.d.ts.map +1 -0
- package/dist/resources/da-dk/common.js +1963 -0
- package/dist/resources/da-dk/common.js.map +1 -0
- package/dist/resources/da-dk/errors.d.ts +45 -0
- package/dist/resources/da-dk/errors.d.ts.map +1 -0
- package/dist/resources/da-dk/errors.js +44 -0
- package/dist/resources/da-dk/errors.js.map +1 -0
- package/dist/resources/da-dk/generated.d.ts +20 -0
- package/dist/resources/da-dk/generated.d.ts.map +1 -0
- package/dist/resources/da-dk/generated.js +19 -0
- package/dist/resources/da-dk/generated.js.map +1 -0
- package/dist/resources/da-dk/studio.d.ts +18 -0
- package/dist/resources/da-dk/studio.d.ts.map +1 -0
- package/dist/resources/da-dk/studio.js +17 -0
- package/dist/resources/da-dk/studio.js.map +1 -0
- package/dist/resources/da-dk/ui.d.ts +996 -0
- package/dist/resources/da-dk/ui.d.ts.map +1 -0
- package/dist/resources/da-dk/ui.js +995 -0
- package/dist/resources/da-dk/ui.js.map +1 -0
- package/dist/resources/de-de/common.d.ts +1964 -0
- package/dist/resources/de-de/common.d.ts.map +1 -0
- package/dist/resources/de-de/common.js +1963 -0
- package/dist/resources/de-de/common.js.map +1 -0
- package/dist/resources/de-de/errors.d.ts +45 -0
- package/dist/resources/de-de/errors.d.ts.map +1 -0
- package/dist/resources/de-de/errors.js +44 -0
- package/dist/resources/de-de/errors.js.map +1 -0
- package/dist/resources/de-de/generated.d.ts +20 -0
- package/dist/resources/de-de/generated.d.ts.map +1 -0
- package/dist/resources/de-de/generated.js +19 -0
- package/dist/resources/de-de/generated.js.map +1 -0
- package/dist/resources/de-de/studio.d.ts +18 -0
- package/dist/resources/de-de/studio.d.ts.map +1 -0
- package/dist/resources/de-de/studio.js +17 -0
- package/dist/resources/de-de/studio.js.map +1 -0
- package/dist/resources/de-de/ui.d.ts +996 -0
- package/dist/resources/de-de/ui.d.ts.map +1 -0
- package/dist/resources/de-de/ui.js +995 -0
- package/dist/resources/de-de/ui.js.map +1 -0
- package/dist/resources/en-us/common.d.ts +1964 -0
- package/dist/resources/en-us/common.d.ts.map +1 -0
- package/dist/resources/en-us/common.js +1963 -0
- package/dist/resources/en-us/common.js.map +1 -0
- package/dist/resources/en-us/errors.d.ts +45 -0
- package/dist/resources/en-us/errors.d.ts.map +1 -0
- package/dist/resources/en-us/errors.js +44 -0
- package/dist/resources/en-us/errors.js.map +1 -0
- package/dist/resources/en-us/generated.d.ts +20 -0
- package/dist/resources/en-us/generated.d.ts.map +1 -0
- package/dist/resources/en-us/generated.js +19 -0
- package/dist/resources/en-us/generated.js.map +1 -0
- package/dist/resources/en-us/studio.d.ts +18 -0
- package/dist/resources/en-us/studio.d.ts.map +1 -0
- package/dist/resources/en-us/studio.js +17 -0
- package/dist/resources/en-us/studio.js.map +1 -0
- package/dist/resources/en-us/ui.d.ts +996 -0
- package/dist/resources/en-us/ui.d.ts.map +1 -0
- package/dist/resources/en-us/ui.js +995 -0
- package/dist/resources/en-us/ui.js.map +1 -0
- package/dist/resources/fr-fr/common.d.ts +1964 -0
- package/dist/resources/fr-fr/common.d.ts.map +1 -0
- package/dist/resources/fr-fr/common.js +1963 -0
- package/dist/resources/fr-fr/common.js.map +1 -0
- package/dist/resources/fr-fr/errors.d.ts +45 -0
- package/dist/resources/fr-fr/errors.d.ts.map +1 -0
- package/dist/resources/fr-fr/errors.js +44 -0
- package/dist/resources/fr-fr/errors.js.map +1 -0
- package/dist/resources/fr-fr/generated.d.ts +20 -0
- package/dist/resources/fr-fr/generated.d.ts.map +1 -0
- package/dist/resources/fr-fr/generated.js +19 -0
- package/dist/resources/fr-fr/generated.js.map +1 -0
- package/dist/resources/fr-fr/studio.d.ts +18 -0
- package/dist/resources/fr-fr/studio.d.ts.map +1 -0
- package/dist/resources/fr-fr/studio.js +17 -0
- package/dist/resources/fr-fr/studio.js.map +1 -0
- package/dist/resources/fr-fr/ui.d.ts +996 -0
- package/dist/resources/fr-fr/ui.d.ts.map +1 -0
- package/dist/resources/fr-fr/ui.js +995 -0
- package/dist/resources/fr-fr/ui.js.map +1 -0
- package/dist/resources/index.d.ts +8 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +21 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/lazy.d.ts +20 -0
- package/dist/resources/lazy.d.ts.map +1 -0
- package/dist/resources/lazy.js +49 -0
- package/dist/resources/lazy.js.map +1 -0
- package/dist/resources/zh-cn/common.d.ts +1964 -0
- package/dist/resources/zh-cn/common.d.ts.map +1 -0
- package/dist/resources/zh-cn/common.js +1963 -0
- package/dist/resources/zh-cn/common.js.map +1 -0
- package/dist/resources/zh-cn/errors.d.ts +45 -0
- package/dist/resources/zh-cn/errors.d.ts.map +1 -0
- package/dist/resources/zh-cn/errors.js +44 -0
- package/dist/resources/zh-cn/errors.js.map +1 -0
- package/dist/resources/zh-cn/generated.d.ts +20 -0
- package/dist/resources/zh-cn/generated.d.ts.map +1 -0
- package/dist/resources/zh-cn/generated.js +19 -0
- package/dist/resources/zh-cn/generated.js.map +1 -0
- package/dist/resources/zh-cn/studio.d.ts +18 -0
- package/dist/resources/zh-cn/studio.d.ts.map +1 -0
- package/dist/resources/zh-cn/studio.js +17 -0
- package/dist/resources/zh-cn/studio.js.map +1 -0
- package/dist/resources/zh-cn/ui.d.ts +996 -0
- package/dist/resources/zh-cn/ui.d.ts.map +1 -0
- package/dist/resources/zh-cn/ui.js +995 -0
- package/dist/resources/zh-cn/ui.js.map +1 -0
- package/dist/resources/zh-tw/common.d.ts +1964 -0
- package/dist/resources/zh-tw/common.d.ts.map +1 -0
- package/dist/resources/zh-tw/common.js +1963 -0
- package/dist/resources/zh-tw/common.js.map +1 -0
- package/dist/resources/zh-tw/errors.d.ts +45 -0
- package/dist/resources/zh-tw/errors.d.ts.map +1 -0
- package/dist/resources/zh-tw/errors.js +44 -0
- package/dist/resources/zh-tw/errors.js.map +1 -0
- package/dist/resources/zh-tw/generated.d.ts +20 -0
- package/dist/resources/zh-tw/generated.d.ts.map +1 -0
- package/dist/resources/zh-tw/generated.js +19 -0
- package/dist/resources/zh-tw/generated.js.map +1 -0
- package/dist/resources/zh-tw/studio.d.ts +18 -0
- package/dist/resources/zh-tw/studio.d.ts.map +1 -0
- package/dist/resources/zh-tw/studio.js +17 -0
- package/dist/resources/zh-tw/studio.js.map +1 -0
- package/dist/resources/zh-tw/ui.d.ts +996 -0
- package/dist/resources/zh-tw/ui.d.ts.map +1 -0
- package/dist/resources/zh-tw/ui.js +995 -0
- package/dist/resources/zh-tw/ui.js.map +1 -0
- package/locales/ar-EG/common.json +1954 -0
- package/locales/ar-EG/errors.json +35 -0
- package/locales/ar-EG/generated.json +10 -0
- package/locales/ar-EG/studio.json +8 -0
- package/locales/ar-EG/ui.json +986 -0
- package/locales/cs-CZ/common.json +1954 -0
- package/locales/cs-CZ/errors.json +35 -0
- package/locales/cs-CZ/generated.json +10 -0
- package/locales/cs-CZ/studio.json +8 -0
- package/locales/cs-CZ/ui.json +986 -0
- package/locales/da-DK/common.json +1954 -0
- package/locales/da-DK/errors.json +35 -0
- package/locales/da-DK/generated.json +10 -0
- package/locales/da-DK/studio.json +8 -0
- package/locales/da-DK/ui.json +986 -0
- package/locales/de-DE/common.json +1954 -0
- package/locales/de-DE/errors.json +35 -0
- package/locales/de-DE/generated.json +10 -0
- package/locales/de-DE/studio.json +8 -0
- package/locales/de-DE/ui.json +986 -0
- package/locales/en-US/common.json +1954 -0
- package/locales/en-US/errors.json +35 -0
- package/locales/en-US/generated.json +10 -0
- package/locales/en-US/studio.json +8 -0
- package/locales/en-US/ui.json +986 -0
- package/locales/fr-FR/common.json +1954 -0
- package/locales/fr-FR/errors.json +35 -0
- package/locales/fr-FR/generated.json +10 -0
- package/locales/fr-FR/studio.json +8 -0
- package/locales/fr-FR/ui.json +986 -0
- package/locales/zh-CN/common.json +1954 -0
- package/locales/zh-CN/errors.json +35 -0
- package/locales/zh-CN/generated.json +10 -0
- package/locales/zh-CN/studio.json +8 -0
- package/locales/zh-CN/ui.json +986 -0
- package/locales/zh-TW/common.json +1954 -0
- package/locales/zh-TW/errors.json +35 -0
- package/locales/zh-TW/generated.json +10 -0
- package/locales/zh-TW/studio.json +8 -0
- package/locales/zh-TW/ui.json +986 -0
- package/package.json +51 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18next factory (10-i18n-theming.md §2.3): i18next + IcuFormat (ICU
|
|
3
|
+
* MessageFormat for every message — i18next's own plural-suffix system is
|
|
4
|
+
* disabled by the ICU format plugin) + an inline lazy backend. The bundled
|
|
5
|
+
* en-US namespaces ship synchronously (they are the fallback text and must
|
|
6
|
+
* never be async); every other locale/namespace pair is fetched through
|
|
7
|
+
* `loadBundle` — the dashboard passes a Vite dynamic-import loader so each
|
|
8
|
+
* locale becomes its own chunk.
|
|
9
|
+
*/
|
|
10
|
+
import { type i18n } from 'i18next';
|
|
11
|
+
import { type LocaleId } from './locales.js';
|
|
12
|
+
import { type Namespace, type ResourceBundle } from './resources/index.js';
|
|
13
|
+
/** The concrete i18next instance type consumers hold (re-exported so callers never import i18next directly). */
|
|
14
|
+
export type I18nInstance = i18n;
|
|
15
|
+
export type BundleLoader = (tag: string, ns: Namespace) => Promise<ResourceBundle | {
|
|
16
|
+
default: ResourceBundle;
|
|
17
|
+
} | null>;
|
|
18
|
+
export interface CreateI18nOptions {
|
|
19
|
+
/** Canonical locale id (`en_US` … `ar_EG`) the instance starts in. */
|
|
20
|
+
locale: LocaleId;
|
|
21
|
+
/**
|
|
22
|
+
* Extra/override resource bundles, keyed by BCP-47 tag then namespace.
|
|
23
|
+
* Merged over the bundled en-US resources (tests, Electron packaging).
|
|
24
|
+
*/
|
|
25
|
+
resources?: Partial<Record<string, Partial<Record<Namespace, ResourceBundle>>>> | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Lazy loader for non-bundled locale/namespace pairs. Return `null` (or
|
|
28
|
+
* reject) for a missing bundle — the key then resolves through the en-US
|
|
29
|
+
* fallback chain instead of failing.
|
|
30
|
+
*/
|
|
31
|
+
loadBundle?: BundleLoader | undefined;
|
|
32
|
+
/** Missing-key hook (dev overlay / CI missing-key guard, §8.2). */
|
|
33
|
+
onMissingKey?: ((lng: string, ns: string, key: string) => void) | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Builds a ready (initialized) i18next instance for `locale`. For `en_US`
|
|
37
|
+
* initialization is effectively synchronous (bundled resources); other
|
|
38
|
+
* locales resolve once their bundles load (or immediately, falling back to
|
|
39
|
+
* en-US, when no loader/bundle exists yet).
|
|
40
|
+
*/
|
|
41
|
+
export declare function createI18n(opts: CreateI18nOptions): Promise<I18nInstance>;
|
|
42
|
+
/**
|
|
43
|
+
* Preloaded live locale switch (§7.4): the target locale's namespaces load
|
|
44
|
+
* BEFORE `changeLanguage` fires, so the UI never renders a half-translated
|
|
45
|
+
* frame while `dir`/`lang` flip.
|
|
46
|
+
*/
|
|
47
|
+
export declare function switchLocale(instance: I18nInstance, locale: LocaleId): Promise<void>;
|
|
48
|
+
//# sourceMappingURL=create-i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-i18n.d.ts","sourceRoot":"","sources":["../src/create-i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAgB,EAAsB,KAAK,IAAI,EAAoC,MAAM,SAAS,CAAC;AAGnG,OAAO,EAA6B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExG,gHAAgH;AAChH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;AAEhC,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,SAAS,KACV,OAAO,CAAC,cAAc,GAAG;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,MAAM,EAAE,QAAQ,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC5F;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACtC,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7E;AA8BD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAyC/E;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18next factory (10-i18n-theming.md §2.3): i18next + IcuFormat (ICU
|
|
3
|
+
* MessageFormat for every message — i18next's own plural-suffix system is
|
|
4
|
+
* disabled by the ICU format plugin) + an inline lazy backend. The bundled
|
|
5
|
+
* en-US namespaces ship synchronously (they are the fallback text and must
|
|
6
|
+
* never be async); every other locale/namespace pair is fetched through
|
|
7
|
+
* `loadBundle` — the dashboard passes a Vite dynamic-import loader so each
|
|
8
|
+
* locale becomes its own chunk.
|
|
9
|
+
*/
|
|
10
|
+
import i18next, {} from 'i18next';
|
|
11
|
+
import { IcuFormat } from './icu-format.js';
|
|
12
|
+
import { localeEntry, tagForLocale } from './locales.js';
|
|
13
|
+
import { EN_US_RESOURCES, NAMESPACES } from './resources/index.js';
|
|
14
|
+
function lazyBackend(load) {
|
|
15
|
+
return {
|
|
16
|
+
type: 'backend',
|
|
17
|
+
init() {
|
|
18
|
+
// Options come through the closure — nothing to do.
|
|
19
|
+
},
|
|
20
|
+
read(language, namespace, callback) {
|
|
21
|
+
void Promise.resolve()
|
|
22
|
+
.then(async () => await load(language, namespace))
|
|
23
|
+
.then((bundle) => {
|
|
24
|
+
if (bundle === null) {
|
|
25
|
+
callback(null, {});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const data = 'default' in bundle ? bundle.default : bundle;
|
|
29
|
+
callback(null, data);
|
|
30
|
+
}, () => {
|
|
31
|
+
// Missing/failed chunk: resolve empty so the fallback chain applies
|
|
32
|
+
// (degraded network beats a blank screen, §7.5).
|
|
33
|
+
callback(null, {});
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds a ready (initialized) i18next instance for `locale`. For `en_US`
|
|
40
|
+
* initialization is effectively synchronous (bundled resources); other
|
|
41
|
+
* locales resolve once their bundles load (or immediately, falling back to
|
|
42
|
+
* en-US, when no loader/bundle exists yet).
|
|
43
|
+
*/
|
|
44
|
+
export async function createI18n(opts) {
|
|
45
|
+
const tag = tagForLocale(opts.locale);
|
|
46
|
+
const resources = {
|
|
47
|
+
'en-US': { ...EN_US_RESOURCES },
|
|
48
|
+
};
|
|
49
|
+
for (const [resourceTag, byNs] of Object.entries(opts.resources ?? {})) {
|
|
50
|
+
if (byNs === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
const target = (resources[resourceTag] ??= {});
|
|
53
|
+
for (const [ns, bundle] of Object.entries(byNs)) {
|
|
54
|
+
if (bundle !== undefined)
|
|
55
|
+
target[ns] = bundle;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const instance = i18next.createInstance();
|
|
59
|
+
instance.use(new IcuFormat());
|
|
60
|
+
if (opts.loadBundle !== undefined)
|
|
61
|
+
instance.use(lazyBackend(opts.loadBundle));
|
|
62
|
+
await instance.init({
|
|
63
|
+
lng: tag,
|
|
64
|
+
fallbackLng: 'en-US',
|
|
65
|
+
ns: [...NAMESPACES],
|
|
66
|
+
defaultNS: 'common',
|
|
67
|
+
resources,
|
|
68
|
+
// Bundled en-US coexists with the lazy backend for other locales.
|
|
69
|
+
partialBundledLanguages: true,
|
|
70
|
+
// React escapes; ICU handles placeables (§2.3).
|
|
71
|
+
interpolation: { escapeValue: false },
|
|
72
|
+
returnNull: false,
|
|
73
|
+
returnEmptyString: false,
|
|
74
|
+
...(opts.onMissingKey === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: {
|
|
77
|
+
saveMissing: true,
|
|
78
|
+
missingKeyHandler: (lngs, ns, key) => {
|
|
79
|
+
for (const lng of lngs)
|
|
80
|
+
opts.onMissingKey?.(lng, ns, key);
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
return instance;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Preloaded live locale switch (§7.4): the target locale's namespaces load
|
|
88
|
+
* BEFORE `changeLanguage` fires, so the UI never renders a half-translated
|
|
89
|
+
* frame while `dir`/`lang` flip.
|
|
90
|
+
*/
|
|
91
|
+
export async function switchLocale(instance, locale) {
|
|
92
|
+
const { tag } = localeEntry(locale);
|
|
93
|
+
if (instance.language === tag)
|
|
94
|
+
return;
|
|
95
|
+
await instance.loadLanguages(tag);
|
|
96
|
+
await instance.changeLanguage(tag);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=create-i18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-i18n.js","sourceRoot":"","sources":["../src/create-i18n.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intl formatting layer (10-i18n-theming.md §4). All numbers, dates,
|
|
3
|
+
* currencies, relative times, and lists render through here — never through
|
|
4
|
+
* hand-rolled helpers or `toLocaleString('en-US')`.
|
|
5
|
+
*
|
|
6
|
+
* Numeral policy (§4.2, normative): `ctx: "data"` (the default) forces Latin
|
|
7
|
+
* digits (`-u-nu-latn`) and the gregorian calendar (`-ca-gregory`) so mono
|
|
8
|
+
* data cells stay `tabular-nums`-aligned in every locale, including `ar_EG`;
|
|
9
|
+
* `ctx: "prose"` uses the locale's default numbering system, so Arabic prose
|
|
10
|
+
* renders Arabic-Indic digits. `Intl.*` instances are expensive — memoized
|
|
11
|
+
* per `(tag, options, context)`.
|
|
12
|
+
*/
|
|
13
|
+
export type FmtContext = 'data' | 'prose';
|
|
14
|
+
export interface Formatters {
|
|
15
|
+
number(v: number, o?: Intl.NumberFormatOptions & {
|
|
16
|
+
ctx?: FmtContext;
|
|
17
|
+
}): string;
|
|
18
|
+
/** 24500 → "24.5K" / "24 500" per locale. */
|
|
19
|
+
compact(v: number, o?: {
|
|
20
|
+
ctx?: FmtContext;
|
|
21
|
+
}): string;
|
|
22
|
+
percent(v: number, o?: {
|
|
23
|
+
fractionDigits?: number;
|
|
24
|
+
ctx?: FmtContext;
|
|
25
|
+
}): string;
|
|
26
|
+
/** Currency code comes from column metadata, never from the viewer's locale (§4.4). */
|
|
27
|
+
currency(v: number, currency: string, o?: {
|
|
28
|
+
ctx?: FmtContext;
|
|
29
|
+
}): string;
|
|
30
|
+
/** Intl unit style, "1.2 MB". Data context (mono cells). */
|
|
31
|
+
bytes(v: number): string;
|
|
32
|
+
date(d: Date | string | number, style?: 'short' | 'medium' | 'long', o?: {
|
|
33
|
+
ctx?: FmtContext;
|
|
34
|
+
timeZone?: string;
|
|
35
|
+
}): string;
|
|
36
|
+
time(d: Date | string | number, o?: {
|
|
37
|
+
ctx?: FmtContext;
|
|
38
|
+
timeZone?: string;
|
|
39
|
+
}): string;
|
|
40
|
+
dateTime(d: Date | string | number, o?: {
|
|
41
|
+
ctx?: FmtContext;
|
|
42
|
+
timeZone?: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/** `formatRange`, collapses shared parts. */
|
|
45
|
+
dateRange(a: Date | string | number, b: Date | string | number): string;
|
|
46
|
+
/** "3 hours ago" — auto unit, prose context; absolute date past ~26 days (§4.5). */
|
|
47
|
+
relative(d: Date | string | number, o?: {
|
|
48
|
+
now?: number;
|
|
49
|
+
}): string;
|
|
50
|
+
list(items: string[], type?: 'conjunction' | 'disjunction'): string;
|
|
51
|
+
/** Client-side sorts (in-memory widget sorts, ⌘K ordering) — `numeric: true`. */
|
|
52
|
+
collator(): Intl.Collator;
|
|
53
|
+
}
|
|
54
|
+
/** Static week-info fallback for the 8 locales (§4.5). ISO-8601 day numbers (1 = Monday … 7 = Sunday). */
|
|
55
|
+
export interface WeekInfo {
|
|
56
|
+
firstDay: number;
|
|
57
|
+
weekend: readonly number[];
|
|
58
|
+
}
|
|
59
|
+
/** `Intl.Locale#getWeekInfo()` where available, else the static table. */
|
|
60
|
+
export declare function weekInfo(tag: string): WeekInfo;
|
|
61
|
+
/**
|
|
62
|
+
* The data-context BCP-47 tag (latn digits + gregorian calendar, §4.2) for
|
|
63
|
+
* callers that must build an `Intl.*` instance this layer does not expose —
|
|
64
|
+
* e.g. a narrow-style relative-time formatter for a mono grid cell. Keeps the
|
|
65
|
+
* numeral policy in one place instead of hand-rolling the `-u-nu-latn` suffix.
|
|
66
|
+
*/
|
|
67
|
+
export declare function latnDataTag(tag: string): string;
|
|
68
|
+
/** Memoized per BCP-47 tag. Framework-free — the React binding is `useFmt()` (./react.js entry). */
|
|
69
|
+
export declare function getFormatters(tag: string): Formatters;
|
|
70
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/format/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,mBAAmB,GAAG;QAAE,GAAG,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,MAAM,CAAC;IAC/E,6CAA6C;IAC7C,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,MAAM,CAAC;IACrD,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,MAAM,CAAC;IAC9E,uFAAuF;IACvF,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,MAAM,CAAC;IACxE,4DAA4D;IAC5D,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC1H,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACrF,QAAQ,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACzF,6CAA6C;IAC7C,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACxE,oFAAoF;IACpF,QAAQ,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAClE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,MAAM,CAAC;IACpE,iFAAiF;IACjF,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;CAC3B;AAED,0GAA0G;AAC1G,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAaD,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAY9C;AAYD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AA2KD,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAQrD"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intl formatting layer (10-i18n-theming.md §4). All numbers, dates,
|
|
3
|
+
* currencies, relative times, and lists render through here — never through
|
|
4
|
+
* hand-rolled helpers or `toLocaleString('en-US')`.
|
|
5
|
+
*
|
|
6
|
+
* Numeral policy (§4.2, normative): `ctx: "data"` (the default) forces Latin
|
|
7
|
+
* digits (`-u-nu-latn`) and the gregorian calendar (`-ca-gregory`) so mono
|
|
8
|
+
* data cells stay `tabular-nums`-aligned in every locale, including `ar_EG`;
|
|
9
|
+
* `ctx: "prose"` uses the locale's default numbering system, so Arabic prose
|
|
10
|
+
* renders Arabic-Indic digits. `Intl.*` instances are expensive — memoized
|
|
11
|
+
* per `(tag, options, context)`.
|
|
12
|
+
*/
|
|
13
|
+
const WEEK_INFO_FALLBACK = {
|
|
14
|
+
'en-US': { firstDay: 7, weekend: [6, 7] },
|
|
15
|
+
'de-DE': { firstDay: 1, weekend: [6, 7] },
|
|
16
|
+
'fr-FR': { firstDay: 1, weekend: [6, 7] },
|
|
17
|
+
'cs-CZ': { firstDay: 1, weekend: [6, 7] },
|
|
18
|
+
'da-DK': { firstDay: 1, weekend: [6, 7] },
|
|
19
|
+
'zh-CN': { firstDay: 1, weekend: [6, 7] },
|
|
20
|
+
'zh-TW': { firstDay: 1, weekend: [6, 7] },
|
|
21
|
+
'ar-EG': { firstDay: 6, weekend: [5, 6] },
|
|
22
|
+
};
|
|
23
|
+
/** `Intl.Locale#getWeekInfo()` where available, else the static table. */
|
|
24
|
+
export function weekInfo(tag) {
|
|
25
|
+
try {
|
|
26
|
+
const locale = new Intl.Locale(tag);
|
|
27
|
+
const info = locale.getWeekInfo?.() ?? locale.weekInfo;
|
|
28
|
+
if (info !== undefined)
|
|
29
|
+
return { firstDay: info.firstDay, weekend: info.weekend };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Fall through to the static table.
|
|
33
|
+
}
|
|
34
|
+
return WEEK_INFO_FALLBACK[tag] ?? { firstDay: 1, weekend: [6, 7] };
|
|
35
|
+
}
|
|
36
|
+
/** §4.2/§4.3: latn digits + gregorian calendar pinned for data context. */
|
|
37
|
+
function tagFor(tag, ctx) {
|
|
38
|
+
// Coalesce empty/invalid tags (see `normalizeTag`) before appending the
|
|
39
|
+
// `-u-...` extension, so `latnDataTag('')` and direct `Intl.*` builds off it
|
|
40
|
+
// don't produce an invalid `"-u-nu-latn-…"` tag that throws.
|
|
41
|
+
const base = normalizeTag(tag);
|
|
42
|
+
if (ctx === 'prose')
|
|
43
|
+
return base;
|
|
44
|
+
return base.includes('-u-') ? `${base}-nu-latn-ca-gregory` : `${base}-u-nu-latn-ca-gregory`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The data-context BCP-47 tag (latn digits + gregorian calendar, §4.2) for
|
|
48
|
+
* callers that must build an `Intl.*` instance this layer does not expose —
|
|
49
|
+
* e.g. a narrow-style relative-time formatter for a mono grid cell. Keeps the
|
|
50
|
+
* numeral policy in one place instead of hand-rolling the `-u-nu-latn` suffix.
|
|
51
|
+
*/
|
|
52
|
+
export function latnDataTag(tag) {
|
|
53
|
+
return tagFor(tag, 'data');
|
|
54
|
+
}
|
|
55
|
+
const numberFormats = new Map();
|
|
56
|
+
const dateFormats = new Map();
|
|
57
|
+
const listFormats = new Map();
|
|
58
|
+
const relativeFormats = new Map();
|
|
59
|
+
const collators = new Map();
|
|
60
|
+
function numberFormat(tag, ctx, options) {
|
|
61
|
+
const resolved = tagFor(tag, ctx);
|
|
62
|
+
const key = `${resolved}|${JSON.stringify(options)}`;
|
|
63
|
+
let fmt = numberFormats.get(key);
|
|
64
|
+
if (fmt === undefined) {
|
|
65
|
+
fmt = new Intl.NumberFormat(resolved, options);
|
|
66
|
+
numberFormats.set(key, fmt);
|
|
67
|
+
}
|
|
68
|
+
return fmt;
|
|
69
|
+
}
|
|
70
|
+
function dateFormat(tag, ctx, options) {
|
|
71
|
+
const resolved = tagFor(tag, ctx);
|
|
72
|
+
const key = `${resolved}|${JSON.stringify(options)}`;
|
|
73
|
+
let fmt = dateFormats.get(key);
|
|
74
|
+
if (fmt === undefined) {
|
|
75
|
+
fmt = new Intl.DateTimeFormat(resolved, options);
|
|
76
|
+
dateFormats.set(key, fmt);
|
|
77
|
+
}
|
|
78
|
+
return fmt;
|
|
79
|
+
}
|
|
80
|
+
function toDate(d) {
|
|
81
|
+
return d instanceof Date ? d : new Date(d);
|
|
82
|
+
}
|
|
83
|
+
const BYTE_UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'];
|
|
84
|
+
const DATE_STYLES = {
|
|
85
|
+
short: { dateStyle: 'short' },
|
|
86
|
+
medium: { dateStyle: 'medium' },
|
|
87
|
+
long: { dateStyle: 'long' },
|
|
88
|
+
};
|
|
89
|
+
const MINUTE = 60_000;
|
|
90
|
+
const HOUR = 3_600_000;
|
|
91
|
+
const DAY = 86_400_000;
|
|
92
|
+
const formattersByTag = new Map();
|
|
93
|
+
function buildFormatters(tag) {
|
|
94
|
+
const relativeFor = (t) => {
|
|
95
|
+
let fmt = relativeFormats.get(t);
|
|
96
|
+
if (fmt === undefined) {
|
|
97
|
+
fmt = new Intl.RelativeTimeFormat(t, { numeric: 'auto' });
|
|
98
|
+
relativeFormats.set(t, fmt);
|
|
99
|
+
}
|
|
100
|
+
return fmt;
|
|
101
|
+
};
|
|
102
|
+
const fmt = {
|
|
103
|
+
number(v, o = {}) {
|
|
104
|
+
const { ctx = 'data', ...options } = o;
|
|
105
|
+
return numberFormat(tag, ctx, options).format(v);
|
|
106
|
+
},
|
|
107
|
+
compact(v, o = {}) {
|
|
108
|
+
return numberFormat(tag, o.ctx ?? 'data', { notation: 'compact', maximumFractionDigits: 1 }).format(v);
|
|
109
|
+
},
|
|
110
|
+
percent(v, o = {}) {
|
|
111
|
+
const digits = o.fractionDigits ?? 0;
|
|
112
|
+
return numberFormat(tag, o.ctx ?? 'data', {
|
|
113
|
+
style: 'percent',
|
|
114
|
+
minimumFractionDigits: digits,
|
|
115
|
+
maximumFractionDigits: digits,
|
|
116
|
+
}).format(v);
|
|
117
|
+
},
|
|
118
|
+
currency(v, currency, o = {}) {
|
|
119
|
+
return numberFormat(tag, o.ctx ?? 'data', { style: 'currency', currency }).format(v);
|
|
120
|
+
},
|
|
121
|
+
bytes(v) {
|
|
122
|
+
const magnitude = v === 0 ? 0 : Math.floor(Math.log10(Math.abs(v)) / 3);
|
|
123
|
+
const index = Math.min(Math.max(magnitude, 0), BYTE_UNITS.length - 1);
|
|
124
|
+
const unit = BYTE_UNITS[index] ?? 'byte';
|
|
125
|
+
return numberFormat(tag, 'data', {
|
|
126
|
+
style: 'unit',
|
|
127
|
+
unit,
|
|
128
|
+
unitDisplay: 'short',
|
|
129
|
+
maximumFractionDigits: 1,
|
|
130
|
+
}).format(v / 1000 ** index);
|
|
131
|
+
},
|
|
132
|
+
date(d, style = 'medium', o = {}) {
|
|
133
|
+
return dateFormat(tag, o.ctx ?? 'data', {
|
|
134
|
+
...DATE_STYLES[style],
|
|
135
|
+
...(o.timeZone === undefined ? {} : { timeZone: o.timeZone }),
|
|
136
|
+
}).format(toDate(d));
|
|
137
|
+
},
|
|
138
|
+
time(d, o = {}) {
|
|
139
|
+
return dateFormat(tag, o.ctx ?? 'data', {
|
|
140
|
+
timeStyle: 'short',
|
|
141
|
+
...(o.timeZone === undefined ? {} : { timeZone: o.timeZone }),
|
|
142
|
+
}).format(toDate(d));
|
|
143
|
+
},
|
|
144
|
+
dateTime(d, o = {}) {
|
|
145
|
+
return dateFormat(tag, o.ctx ?? 'data', {
|
|
146
|
+
dateStyle: 'medium',
|
|
147
|
+
timeStyle: 'short',
|
|
148
|
+
...(o.timeZone === undefined ? {} : { timeZone: o.timeZone }),
|
|
149
|
+
}).format(toDate(d));
|
|
150
|
+
},
|
|
151
|
+
dateRange(a, b) {
|
|
152
|
+
return dateFormat(tag, 'data', { dateStyle: 'medium' }).formatRange(toDate(a), toDate(b));
|
|
153
|
+
},
|
|
154
|
+
relative(d, o = {}) {
|
|
155
|
+
const now = o.now ?? Date.now();
|
|
156
|
+
const delta = toDate(d).getTime() - now;
|
|
157
|
+
const abs = Math.abs(delta);
|
|
158
|
+
const rtf = relativeFor(tag); // prose context: relative times live in sentences (§4.2)
|
|
159
|
+
if (abs < 45_000)
|
|
160
|
+
return rtf.format(0, 'second'); // "now" via numeric: 'auto'
|
|
161
|
+
if (abs < 90 * MINUTE)
|
|
162
|
+
return rtf.format(Math.round(delta / MINUTE), 'minute');
|
|
163
|
+
if (abs < 22 * HOUR)
|
|
164
|
+
return rtf.format(Math.round(delta / HOUR), 'hour');
|
|
165
|
+
if (abs < 26 * DAY)
|
|
166
|
+
return rtf.format(Math.round(delta / DAY), 'day');
|
|
167
|
+
return fmt.date(d);
|
|
168
|
+
},
|
|
169
|
+
list(items, type = 'conjunction') {
|
|
170
|
+
const key = `${tag}|${type}`;
|
|
171
|
+
let lf = listFormats.get(key);
|
|
172
|
+
if (lf === undefined) {
|
|
173
|
+
lf = new Intl.ListFormat(tag, { type });
|
|
174
|
+
listFormats.set(key, lf);
|
|
175
|
+
}
|
|
176
|
+
return lf.format(items);
|
|
177
|
+
},
|
|
178
|
+
collator() {
|
|
179
|
+
let c = collators.get(tag);
|
|
180
|
+
if (c === undefined) {
|
|
181
|
+
c = new Intl.Collator(tag, { numeric: true });
|
|
182
|
+
collators.set(tag, c);
|
|
183
|
+
}
|
|
184
|
+
return c;
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
return fmt;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Coalesce an empty/whitespace/structurally-invalid tag to `en-US`. Callers
|
|
191
|
+
* often pass `config.locale ?? 'en-US'`, which lets an empty string `''` slip
|
|
192
|
+
* through (`??` only catches null/undefined) — and `new Intl.NumberFormat('')`
|
|
193
|
+
* throws `RangeError`. Normalizing here makes every formatter safe against a
|
|
194
|
+
* schema-valid empty locale, so no widget crashes on it.
|
|
195
|
+
*/
|
|
196
|
+
function normalizeTag(tag) {
|
|
197
|
+
if (typeof tag !== 'string' || tag.trim() === '')
|
|
198
|
+
return 'en-US';
|
|
199
|
+
try {
|
|
200
|
+
Intl.getCanonicalLocales(tag); // throws RangeError on an invalid tag
|
|
201
|
+
return tag;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return 'en-US';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/** Memoized per BCP-47 tag. Framework-free — the React binding is `useFmt()` (./react.js entry). */
|
|
208
|
+
export function getFormatters(tag) {
|
|
209
|
+
const normalized = normalizeTag(tag);
|
|
210
|
+
let fmt = formattersByTag.get(normalized);
|
|
211
|
+
if (fmt === undefined) {
|
|
212
|
+
fmt = buildFormatters(normalized);
|
|
213
|
+
formattersByTag.set(normalized, fmt);
|
|
214
|
+
}
|
|
215
|
+
return fmt;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/format/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type FormatValues = Record<string, unknown> | undefined;
|
|
2
|
+
export declare class IcuFormat {
|
|
3
|
+
#private;
|
|
4
|
+
static readonly type = "i18nFormat";
|
|
5
|
+
readonly type: "i18nFormat";
|
|
6
|
+
constructor(opts?: {
|
|
7
|
+
onError?: (key: string, error: unknown) => void;
|
|
8
|
+
});
|
|
9
|
+
/** i18next module hook (called by i18next during init; extra args ignored). */
|
|
10
|
+
init(): void;
|
|
11
|
+
/** i18next i18nFormat contract: format the resolved resource string (trailing `info` arg unused). */
|
|
12
|
+
parse(res: string, options: FormatValues, lng: string, _ns: string, key: string): string;
|
|
13
|
+
/** i18next asks the format plugin whether to add ordinal/plural key suffixes — ICU handles plurals itself. */
|
|
14
|
+
getSuffixes(): string[];
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=icu-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icu-format.d.ts","sourceRoot":"","sources":["../src/icu-format.ts"],"names":[],"mappings":"AAYA,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;AAExD,qBAAa,SAAS;;IACpB,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB;IACpC,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAU;gBAK1B,IAAI,GAAE;QAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAO;IAS1E,+EAA+E;IAC/E,IAAI,IAAI,IAAI;IAIZ,qGAAqG;IACrG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAgBxF,8GAA8G;IAC9G,WAAW,IAAI,MAAM,EAAE;CAGxB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ICU i18nFormat module for i18next, built directly on intl-messageformat's
|
|
3
|
+
* NAMED export (10-i18n-theming.md §2.3).
|
|
4
|
+
*
|
|
5
|
+
* Replaces `i18next-icu`, whose ESM build does `import IntlMessageFormat from
|
|
6
|
+
* 'intl-messageformat'` — under Node ESM that default resolves to the CJS
|
|
7
|
+
* namespace object (not the class), the internal `new` throws, the error is
|
|
8
|
+
* swallowed, and every message silently renders raw. Owning these ~40 lines
|
|
9
|
+
* removes the interop landmine and gives us explicit error surfacing.
|
|
10
|
+
*/
|
|
11
|
+
import { IntlMessageFormat } from 'intl-messageformat';
|
|
12
|
+
export class IcuFormat {
|
|
13
|
+
static type = 'i18nFormat';
|
|
14
|
+
type = 'i18nFormat';
|
|
15
|
+
#cache = new Map();
|
|
16
|
+
#onError;
|
|
17
|
+
constructor(opts = {}) {
|
|
18
|
+
this.#onError =
|
|
19
|
+
opts.onError ??
|
|
20
|
+
((key, error) => {
|
|
21
|
+
// One structured warning per failure — never throw at render time.
|
|
22
|
+
console.warn(`[adminium/i18n] ICU parse failed for "${key}":`, error);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** i18next module hook (called by i18next during init; extra args ignored). */
|
|
26
|
+
init() {
|
|
27
|
+
/* no service wiring needed */
|
|
28
|
+
}
|
|
29
|
+
/** i18next i18nFormat contract: format the resolved resource string (trailing `info` arg unused). */
|
|
30
|
+
parse(res, options, lng, _ns, key) {
|
|
31
|
+
if (typeof res !== 'string' || !res.includes('{'))
|
|
32
|
+
return res;
|
|
33
|
+
try {
|
|
34
|
+
const cacheKey = `${lng}\x00${key}\x00${res}`;
|
|
35
|
+
let message = this.#cache.get(cacheKey);
|
|
36
|
+
if (message === undefined) {
|
|
37
|
+
message = new IntlMessageFormat(res, lng, undefined, { ignoreTag: true });
|
|
38
|
+
this.#cache.set(cacheKey, message);
|
|
39
|
+
}
|
|
40
|
+
return String(message.format(options));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.#onError(key, error);
|
|
44
|
+
return res;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** i18next asks the format plugin whether to add ordinal/plural key suffixes — ICU handles plurals itself. */
|
|
48
|
+
getSuffixes() {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=icu-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icu-format.js","sourceRoot":"","sources":["../src/icu-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD,MAAM,OAAO,SAAS;IACpB,MAAM,CAAU,IAAI,GAAG,YAAY,CAAC;IAC3B,IAAI,GAAG,YAAqB,CAAC;IAEtC,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC9C,QAAQ,CAAwC;IAEhD,YAAY,OAA4D,EAAE;QACxE,IAAI,CAAC,QAAQ;YACX,IAAI,CAAC,OAAO;gBACZ,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;oBACd,mEAAmE;oBACnE,OAAO,CAAC,IAAI,CAAC,yCAAyC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC;gBACxE,CAAC,CAAC,CAAC;IACP,CAAC;IAED,+EAA+E;IAC/E,IAAI;QACF,8BAA8B;IAChC,CAAC;IAED,qGAAqG;IACrG,KAAK,CAAC,GAAW,EAAE,OAAqB,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW;QAC7E,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,GAAG,GAAG,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC;YAC9C,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,GAAG,IAAI,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC1E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrC,CAAC;YACD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAsD,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC1B,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,8GAA8G;IAC9G,WAAW;QACT,OAAO,EAAE,CAAC;IACZ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adminium/i18n — 8-locale registry, i18next+ICU runtime factory, Intl
|
|
3
|
+
* formatter layer, RTL utils (workplan/10-i18n-theming.md). Framework-free;
|
|
4
|
+
* React bindings live in the `@adminium/i18n/react` entry.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PACKAGE_NAME = "@adminium/i18n";
|
|
7
|
+
export { LOCALES, LOCALE_IDS, dirForLocale, isLocaleId, isRtlLocale, localeEntry, localeFromTag, tagForLocale, } from './locales.js';
|
|
8
|
+
export type { LocaleEntry, LocaleId } from './locales.js';
|
|
9
|
+
export { createI18n, switchLocale } from './create-i18n.js';
|
|
10
|
+
export type { BundleLoader, CreateI18nOptions, I18nInstance } from './create-i18n.js';
|
|
11
|
+
export { EN_US_RESOURCES, NAMESPACES } from './resources/index.js';
|
|
12
|
+
export type { Namespace, ResourceBundle } from './resources/index.js';
|
|
13
|
+
export { loadLocaleBundle } from './resources/lazy.js';
|
|
14
|
+
export { getFormatters, latnDataTag, weekInfo } from './format/index.js';
|
|
15
|
+
export type { FmtContext, Formatters, WeekInfo } from './format/index.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAE7C,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEtF,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adminium/i18n — 8-locale registry, i18next+ICU runtime factory, Intl
|
|
3
|
+
* formatter layer, RTL utils (workplan/10-i18n-theming.md). Framework-free;
|
|
4
|
+
* React bindings live in the `@adminium/i18n/react` entry.
|
|
5
|
+
*/
|
|
6
|
+
export const PACKAGE_NAME = '@adminium/i18n';
|
|
7
|
+
export { LOCALES, LOCALE_IDS, dirForLocale, isLocaleId, isRtlLocale, localeEntry, localeFromTag, tagForLocale, } from './locales.js';
|
|
8
|
+
export { createI18n, switchLocale } from './create-i18n.js';
|
|
9
|
+
export { EN_US_RESOURCES, NAMESPACES } from './resources/index.js';
|
|
10
|
+
export { loadLocaleBundle } from './resources/lazy.js';
|
|
11
|
+
export { getFormatters, latnDataTag, weekInfo } from './format/index.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
|