@nxgt/i18n 1.1.0 → 2.0.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/README.md +38 -7
- package/dist/chunks/{index-86mgj3nf.js → index-jscbtbek.js} +68 -5
- package/dist/chunks/index-jscbtbek.js.map +15 -0
- package/dist/i18n.browser.d.ts +6 -12
- package/dist/i18n.browser.d.ts.map +1 -1
- package/dist/i18n.d.ts +13 -8
- package/dist/i18n.d.ts.map +1 -1
- package/dist/index.browser.d.ts +1 -0
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +13 -31
- package/dist/index.browser.js.map +3 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -36
- package/dist/index.js.map +3 -4
- package/dist/resources/en/index.d.ts +1 -0
- package/dist/resources/en/index.d.ts.map +1 -1
- package/dist/resources/fr/index.d.ts +1 -0
- package/dist/resources/fr/index.d.ts.map +1 -1
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/sources.d.ts +21 -0
- package/dist/sources.d.ts.map +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/dist/chunks/index-86mgj3nf.js.map +0 -13
- package/dist/types/hono.d.ts +0 -7
package/README.md
CHANGED
|
@@ -51,10 +51,31 @@ and `errors.service-unavailable`.
|
|
|
51
51
|
|
|
52
52
|
`getLanguage()` asks, most specific first:
|
|
53
53
|
|
|
54
|
-
1.
|
|
54
|
+
1. every registered **language source**, in the order registered
|
|
55
55
|
2. `localStorage.language`, when that object exists
|
|
56
56
|
3. `FALLBACK_LANGUAGE` (`'en'`)
|
|
57
57
|
|
|
58
|
+
A source is a function answering the current request's language, or nothing.
|
|
59
|
+
This package knows no server; the server says where its request keeps the
|
|
60
|
+
language:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { registerLanguageSource } from '@nxgt/i18n';
|
|
64
|
+
|
|
65
|
+
const remove = registerLanguageSource(() => currentRequest()?.language);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| server | its source |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| Hono | `@nxgt/shared-hono` registers `honoLanguageSource` when imported: the `language` variable `languageDetector()` sets, read through `contextStorage()` |
|
|
71
|
+
| GraphQL Yoga on Hono | `@nxgt/shared-graphql`'s `createYogaHono()` registers the same |
|
|
72
|
+
| alxia | `@alxia/i18n`'s `createI18n()` registers the request's language |
|
|
73
|
+
|
|
74
|
+
A source that answers nothing, a language no catalogue has, or throws is
|
|
75
|
+
skipped. Registering one twice keeps one. The registry is on `globalThis`, so
|
|
76
|
+
two copies of this package in one app — one a dependency of
|
|
77
|
+
`@nxgt/shared-hono`, one the app's own — share it.
|
|
78
|
+
|
|
58
79
|
The two consuming monorepos had forked exactly this — one read the request, the
|
|
59
80
|
other read `localStorage` — and neither could run where the other did. Asking
|
|
60
81
|
both serves either without a caller changing anything. Pass a provider (a
|
|
@@ -63,19 +84,29 @@ and not the other.
|
|
|
63
84
|
|
|
64
85
|
`SUPPORTED_LANGUAGES` is derived from the catalogue keys, not typed out.
|
|
65
86
|
|
|
87
|
+
### Since 2.0
|
|
88
|
+
|
|
89
|
+
Until 2.0, `getLanguage()` read the Hono request context itself, through
|
|
90
|
+
`hono/context-storage`: every consumer depended on Hono, and a server on
|
|
91
|
+
anything else got the fallback. The Hono part lives in `@nxgt/shared-hono`
|
|
92
|
+
now, with the `ContextVariableMap` augmentation that types `c.get('language')`.
|
|
93
|
+
An app that imports `@nxgt/shared-hono` sees no difference; one that used
|
|
94
|
+
`@nxgt/i18n` beside Hono without it calls `useHonoLanguage()` from
|
|
95
|
+
`@nxgt/shared-hono` once, or registers its own source.
|
|
96
|
+
|
|
66
97
|
## In a browser bundle
|
|
67
98
|
|
|
68
99
|
Nothing to change: `import { translate } from '@nxgt/i18n'` is the same import
|
|
69
100
|
whether the code runs in Node, Bun, or a bundler that resolves the `browser`
|
|
70
|
-
export condition (Vite, Nuxt's client build).
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
including `translate` and `createTranslator`, behaves the same. The point of
|
|
74
|
-
the condition is what it leaves out of the bundle: no `hono/context-storage`,
|
|
75
|
-
and nothing Node-only, ships to the client.
|
|
101
|
+
export condition (Vite, Nuxt's client build). Since 2.0 nothing in the package
|
|
102
|
+
is Node-only, and the `browser` entry is the same code; a client app registers
|
|
103
|
+
a source as a server does, or relies on `localStorage`.
|
|
76
104
|
|
|
77
105
|
## Things that bite
|
|
78
106
|
|
|
107
|
+
- **A server's language is a registered source.** Without one, every
|
|
108
|
+
request is translated in `localStorage`'s language — none, on a server — or
|
|
109
|
+
the fallback.
|
|
79
110
|
- **Messages are keys.** Rendering at the throw site (or translating in a
|
|
80
111
|
service) freezes the language of whoever threw, not of whoever reads.
|
|
81
112
|
- **ICU formatting failures are swallowed** (`console.error`) and the
|
|
@@ -45,7 +45,8 @@ var errors_default = {
|
|
|
45
45
|
"persisted-query-not-supported": "Persisted queries are not supported on this server.",
|
|
46
46
|
"bad-user-input": "Invalid input provided. Please check your data and try again.",
|
|
47
47
|
"operation-resolution-failure": "Failed to resolve the GraphQL operation.",
|
|
48
|
-
"bad-request": "The request is invalid or malformed. Please verify the request format."
|
|
48
|
+
"bad-request": "The request is invalid or malformed. Please verify the request format.",
|
|
49
|
+
"list-patch-one-operation-per-path": "Only one of ''replace'', ''add'' and ''remove'' can change ''{path}'' in one update. Send them as separate updates."
|
|
49
50
|
};
|
|
50
51
|
// src/resources/en/validation.json
|
|
51
52
|
var validation_default = {
|
|
@@ -269,7 +270,8 @@ var errors_default2 = {
|
|
|
269
270
|
"persisted-query-not-supported": "Les requêtes persistantes ne sont pas prises en charge sur ce serveur.",
|
|
270
271
|
"bad-user-input": "Données saisies invalides. Veuillez vérifier vos informations et réessayer.",
|
|
271
272
|
"operation-resolution-failure": "Échec de la résolution de l'opération GraphQL.",
|
|
272
|
-
"bad-request": "La requête est invalide ou mal formée. Veuillez vérifier le format de la requête."
|
|
273
|
+
"bad-request": "La requête est invalide ou mal formée. Veuillez vérifier le format de la requête.",
|
|
274
|
+
"list-patch-one-operation-per-path": "Une seule des opérations ''replace'', ''add'' et ''remove'' peut modifier ''{path}'' dans une même mise à jour. Envoyez-les dans des mises à jour distinctes."
|
|
273
275
|
};
|
|
274
276
|
// src/resources/fr/validation.json
|
|
275
277
|
var validation_default2 = {
|
|
@@ -457,7 +459,68 @@ var resources2 = {
|
|
|
457
459
|
var LANGUAGE_KEY2 = "language";
|
|
458
460
|
var SUPPORTED_LANGUAGES2 = Object.keys(resources2);
|
|
459
461
|
var FALLBACK_LANGUAGE2 = "en";
|
|
460
|
-
export { resources2, LANGUAGE_KEY2, SUPPORTED_LANGUAGES2, FALLBACK_LANGUAGE2 };
|
|
461
462
|
|
|
462
|
-
|
|
463
|
-
|
|
463
|
+
// src/sources.ts
|
|
464
|
+
var REGISTRY = Symbol.for("@nxgt/i18n/language-sources");
|
|
465
|
+
function registry() {
|
|
466
|
+
const global = globalThis;
|
|
467
|
+
global[REGISTRY] ??= [];
|
|
468
|
+
return global[REGISTRY];
|
|
469
|
+
}
|
|
470
|
+
function registerLanguageSource2(source) {
|
|
471
|
+
const sources = registry();
|
|
472
|
+
if (!sources.includes(source))
|
|
473
|
+
sources.push(source);
|
|
474
|
+
return () => {
|
|
475
|
+
const index = sources.indexOf(source);
|
|
476
|
+
if (index !== -1)
|
|
477
|
+
sources.splice(index, 1);
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
function languageFromSources2() {
|
|
481
|
+
for (const source of registry()) {
|
|
482
|
+
let answer;
|
|
483
|
+
try {
|
|
484
|
+
answer = source();
|
|
485
|
+
} catch {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
if (SUPPORTED_LANGUAGES2.includes(answer)) {
|
|
489
|
+
return answer;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/i18n.ts
|
|
496
|
+
import { IntlMessageFormat } from "intl-messageformat";
|
|
497
|
+
import _ from "lodash";
|
|
498
|
+
function getLanguage2() {
|
|
499
|
+
const fromSource = languageFromSources2();
|
|
500
|
+
if (fromSource !== undefined)
|
|
501
|
+
return fromSource;
|
|
502
|
+
if (typeof localStorage !== "undefined") {
|
|
503
|
+
const stored = localStorage.getItem(LANGUAGE_KEY2);
|
|
504
|
+
if (SUPPORTED_LANGUAGES2.includes(stored)) {
|
|
505
|
+
return stored;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return FALLBACK_LANGUAGE2;
|
|
509
|
+
}
|
|
510
|
+
function createTranslator2(resources = {}, localeProvider = getLanguage2) {
|
|
511
|
+
return (key, context = undefined, provideLanguage = localeProvider) => {
|
|
512
|
+
const language = typeof provideLanguage === "function" ? provideLanguage() : provideLanguage;
|
|
513
|
+
let message = _.get(resources[language], key) ?? key;
|
|
514
|
+
try {
|
|
515
|
+
message = new IntlMessageFormat(message, language).format(context);
|
|
516
|
+
} catch (e) {
|
|
517
|
+
console.error(e);
|
|
518
|
+
}
|
|
519
|
+
return message;
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
var translate2 = createTranslator2(resources2);
|
|
523
|
+
export { resources2, LANGUAGE_KEY2, SUPPORTED_LANGUAGES2, FALLBACK_LANGUAGE2, registerLanguageSource2, languageFromSources2, getLanguage2, createTranslator2, translate2 };
|
|
524
|
+
|
|
525
|
+
//# debugId=2FA53BAC7C0D362464756E2164756E21
|
|
526
|
+
//# sourceMappingURL=index-jscbtbek.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/resources/en/index.ts", "../src/resources/fr/index.ts", "../src/resources/index.ts", "../src/consts.ts", "../src/sources.ts", "../src/i18n.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import common from './common.json';\nimport errors from './errors.json';\nimport validation from './validation.json';\nimport zod from './zod.json';\n\nexport const en = {\n\t...common,\n\terrors,\n\tvalidation,\n\tzod,\n};\n",
|
|
6
|
+
"import common from './common.json';\nimport errors from './errors.json';\nimport validation from './validation.json';\nimport zod from './zod.json';\n\nexport const fr = {\n\t...common,\n\terrors,\n\tvalidation,\n\tzod,\n};\n",
|
|
7
|
+
"import { en } from './en';\nimport { fr } from './fr';\n\nexport const resources = {\n\ten,\n\tfr,\n};\n",
|
|
8
|
+
"import { resources } from './resources';\nimport type { Language } from './types';\n\nexport const LANGUAGE_KEY = 'language';\n\nexport const SUPPORTED_LANGUAGES = Object.keys(resources) as Language[];\n\nexport const FALLBACK_LANGUAGE: Language = 'en';\n",
|
|
9
|
+
"import { SUPPORTED_LANGUAGES } from './consts';\nimport type { Language } from './types';\n\n/**\n * Where a language may come from: a server's request context, a framework's\n * state. It answers the request's language, or nothing — `undefined`, `null`,\n * a language no catalogue has — and the next source is asked.\n */\nexport type LanguageSource = () => string | null | undefined;\n\n/**\n * One registry for the process, on `globalThis`: an app can hold two copies\n * of this package — one a dependency of `@nxgt/shared-hono`, one its own —\n * and a source registered through either must answer both.\n */\nconst REGISTRY = Symbol.for('@nxgt/i18n/language-sources');\n\nfunction registry(): LanguageSource[] {\n\tconst global = globalThis as { [REGISTRY]?: LanguageSource[] };\n\tglobal[REGISTRY] ??= [];\n\treturn global[REGISTRY];\n}\n\n/**\n * Adds a source `getLanguage()` asks, after those registered before it.\n * Registering one twice keeps one. Answers the function that removes it.\n *\n * This package knows no server: `@nxgt/shared-hono` registers the Hono\n * request context's `language`, `@alxia/i18n` the alxia request's.\n */\nexport function registerLanguageSource(source: LanguageSource): () => void {\n\tconst sources = registry();\n\tif (!sources.includes(source)) sources.push(source);\n\treturn () => {\n\t\tconst index = sources.indexOf(source);\n\t\tif (index !== -1) sources.splice(index, 1);\n\t};\n}\n\n/**\n * The first supported language a registered source answers. A source that\n * throws is skipped: a language is never worth a failed request.\n */\nexport function languageFromSources(): Language | undefined {\n\tfor (const source of registry()) {\n\t\tlet answer: string | null | undefined;\n\t\ttry {\n\t\t\tanswer = source();\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (SUPPORTED_LANGUAGES.includes(answer as Language)) {\n\t\t\treturn answer as Language;\n\t\t}\n\t}\n\treturn undefined;\n}\n",
|
|
10
|
+
"import { IntlMessageFormat } from 'intl-messageformat';\nimport _ from 'lodash';\nimport { FALLBACK_LANGUAGE, LANGUAGE_KEY, SUPPORTED_LANGUAGES } from './consts';\nimport { resources } from './resources';\nimport { languageFromSources } from './sources';\nimport type {\n\tLanguage,\n\tLanguageProvider,\n\tLocaleKey,\n\tTranslationContext,\n} from './types';\n\n/**\n * Where the language comes from when the caller does not say, most specific\n * first:\n *\n * 1. a registered source — `registerLanguageSource()`: a server's request\n * context, which `@nxgt/shared-hono` registers for Hono and\n * `@alxia/i18n` for alxia;\n * 2. `localStorage`, when that object exists;\n * 3. the fallback language.\n *\n * Until 2.0 this read Hono's request context itself, through\n * `hono/context-storage`, which tied every consumer — a browser bundle, an\n * alxia server — to Hono. The Hono part lives in `@nxgt/shared-hono` now.\n *\n * `createTranslator` still takes a provider, so a caller that wants one source\n * and not the others passes it.\n */\nexport function getLanguage(): Language {\n\tconst fromSource = languageFromSources();\n\tif (fromSource !== undefined) return fromSource;\n\tif (typeof localStorage !== 'undefined') {\n\t\tconst stored = localStorage.getItem(LANGUAGE_KEY);\n\t\tif (SUPPORTED_LANGUAGES.includes(stored as Language)) {\n\t\t\treturn stored as Language;\n\t\t}\n\t}\n\treturn FALLBACK_LANGUAGE;\n}\n\nexport function createTranslator<K extends string = LocaleKey>(\n\tresources: Record<string, any> = {},\n\tlocaleProvider: LanguageProvider = getLanguage,\n) {\n\treturn (\n\t\tkey: K,\n\t\tcontext: TranslationContext = undefined,\n\t\tprovideLanguage: LanguageProvider = localeProvider,\n\t): string => {\n\t\tconst language =\n\t\t\ttypeof provideLanguage === 'function'\n\t\t\t\t? provideLanguage()\n\t\t\t\t: provideLanguage;\n\t\tlet message: string = _.get(resources[language], key) ?? key;\n\t\ttry {\n\t\t\tmessage = new IntlMessageFormat(message, language).format(context);\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t}\n\n\t\treturn message;\n\t};\n}\n\nexport const translate = createTranslator(resources);\n"
|
|
11
|
+
],
|
|
12
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,IAAM,KAAK;AAAA,KACd;AAAA,EACH;AAAA,EACA;AAAA,EACA;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLO,IAAM,KAAK;AAAA,KACd;AAAA,EACH;AAAA,EACA;AAAA,EACA;AACD;;;ACPO,IAAM,aAAY;AAAA,EACxB;AAAA,EACA;AACD;;;ACHO,IAAM,gBAAe;AAErB,IAAM,uBAAsB,OAAO,KAAK,UAAS;AAEjD,IAAM,qBAA8B;;;ACQ3C,IAAM,WAAW,OAAO,IAAI,6BAA6B;AAEzD,SAAS,QAAQ,GAAqB;AAAA,EACrC,MAAM,SAAS;AAAA,EACf,OAAO,cAAc,CAAC;AAAA,EACtB,OAAO,OAAO;AAAA;AAUR,SAAS,uBAAsB,CAAC,QAAoC;AAAA,EAC1E,MAAM,UAAU,SAAS;AAAA,EACzB,IAAI,CAAC,QAAQ,SAAS,MAAM;AAAA,IAAG,QAAQ,KAAK,MAAM;AAAA,EAClD,OAAO,MAAM;AAAA,IACZ,MAAM,QAAQ,QAAQ,QAAQ,MAAM;AAAA,IACpC,IAAI,UAAU;AAAA,MAAI,QAAQ,OAAO,OAAO,CAAC;AAAA;AAAA;AAQpC,SAAS,oBAAmB,GAAyB;AAAA,EAC3D,WAAW,UAAU,SAAS,GAAG;AAAA,IAChC,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,SAAS,OAAO;AAAA,MACf,MAAM;AAAA,MACP;AAAA;AAAA,IAED,IAAI,qBAAoB,SAAS,MAAkB,GAAG;AAAA,MACrD,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EACA;AAAA;;;ACvDD;AACA;AA4BO,SAAS,YAAW,GAAa;AAAA,EACvC,MAAM,aAAa,qBAAoB;AAAA,EACvC,IAAI,eAAe;AAAA,IAAW,OAAO;AAAA,EACrC,IAAI,OAAO,iBAAiB,aAAa;AAAA,IACxC,MAAM,SAAS,aAAa,QAAQ,aAAY;AAAA,IAChD,IAAI,qBAAoB,SAAS,MAAkB,GAAG;AAAA,MACrD,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGD,SAAS,iBAA8C,CAC7D,YAAiC,CAAC,GAClC,iBAAmC,cAClC;AAAA,EACD,OAAO,CACN,KACA,UAA8B,WAC9B,kBAAoC,mBACxB;AAAA,IACZ,MAAM,WACL,OAAO,oBAAoB,aACxB,gBAAgB,IAChB;AAAA,IACJ,IAAI,UAAkB,EAAE,IAAI,UAAU,WAAW,GAAG,KAAK;AAAA,IACzD,IAAI;AAAA,MACH,UAAU,IAAI,kBAAkB,SAAS,QAAQ,EAAE,OAAO,OAAO;AAAA,MAChE,OAAO,GAAG;AAAA,MACX,QAAQ,MAAM,CAAC;AAAA;AAAA,IAGhB,OAAO;AAAA;AAAA;AAIF,IAAM,aAAY,kBAAiB,UAAS;",
|
|
13
|
+
"debugId": "2FA53BAC7C0D362464756E2164756E21",
|
|
14
|
+
"names": []
|
|
15
|
+
}
|
package/dist/i18n.browser.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import type { Language, LanguageProvider, LocaleKey, TranslationContext } from './types';
|
|
2
1
|
/**
|
|
3
|
-
* The browser build of
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* a client bundle that never runs inside a Hono request. There is no request
|
|
9
|
-
* context to ask in a browser anyway, so the behaviour a consumer sees is the
|
|
10
|
-
* same: `localStorage`, then the fallback language.
|
|
2
|
+
* The `browser` condition's build of `./i18n`. They were two files while
|
|
3
|
+
* `./i18n` imported `hono/context-storage`, which pulls in `node:async_hooks`;
|
|
4
|
+
* since 2.0 neither imports anything Node-only, and a browser registers its
|
|
5
|
+
* own language sources as a server does. The entry point stays, so a bundler
|
|
6
|
+
* that resolves the `browser` condition keeps resolving it.
|
|
11
7
|
*/
|
|
12
|
-
export
|
|
13
|
-
export declare function createTranslator<K extends string = LocaleKey>(resources?: Record<string, any>, localeProvider?: LanguageProvider): (key: K, context?: TranslationContext, provideLanguage?: LanguageProvider) => string;
|
|
14
|
-
export declare const translate: (key: "errors.not-found" | "errors.unauthenticated" | "errors.duplicate-key" | "errors.something-went-wrong" | "errors.insufficient-permissions" | "errors.cast-failed" | "errors.server-connection-failed" | "errors.forbidden" | "errors.optimistic-lock-failed" | "errors.internal-server-error" | "errors.validation-failed" | "errors.address-blocked" | "errors.could-not-use-first-and-last-together" | "errors.invalid-cursor" | "errors.invalid-status-transition" | "errors.service-unavailable" | "errors.graphql-parse-failed" | "errors.graphql-validation-failed" | "errors.persisted-query-not-found" | "errors.persisted-query-not-supported" | "errors.bad-user-input" | "errors.operation-resolution-failure" | "errors.bad-request" | "validation.errors.time" | "validation.errors.invalid-account-number" | "validation.errors.invalid-big-int" | "validation.errors.invalid-country-code" | "validation.errors.invalid-country-name" | "validation.errors.invalid-cuid" | "validation.errors.invalid-currency" | "validation.errors.invalid-date" | "validation.errors.invalid-date-time" | "validation.errors.invalid-duration" | "validation.errors.invalid-email-address" | "validation.errors.invalid-geo-json" | "validation.errors.invalid-guid" | "validation.errors.invalid-hex-color-code" | "validation.errors.invalid-hexadecimal" | "validation.errors.invalid-hsl" | "validation.errors.invalid-hsla" | "validation.errors.invalid-iban" | "validation.errors.invalid-ip" | "validation.errors.invalid-ipv4" | "validation.errors.invalid-ipv6" | "validation.errors.invalid-isbn" | "validation.errors.invalid-json" | "validation.errors.invalid-json-object" | "validation.errors.invalid-jwt" | "validation.errors.invalid-latitude" | "validation.errors.invalid-locale" | "validation.errors.invalid-longitude" | "validation.errors.invalid-long" | "validation.errors.invalid-mac" | "validation.errors.invalid-negative-float" | "validation.errors.invalid-negative-int" | "validation.errors.invalid-non-empty-string" | "validation.errors.invalid-non-negative-float" | "validation.errors.invalid-non-negative-int" | "validation.errors.invalid-non-positive-float" | "validation.errors.invalid-non-positive-int" | "validation.errors.invalid-object-id" | "validation.errors.invalid-phone-number" | "validation.errors.invalid-port" | "validation.errors.invalid-positive-float" | "validation.errors.invalid-positive-int" | "validation.errors.invalid-postal-code" | "validation.errors.invalid-rgb" | "validation.errors.invalid-rgba" | "validation.errors.invalid-sessn" | "validation.errors.invalid-time" | "validation.errors.invalid-timestamp" | "validation.errors.invalid-url" | "validation.errors.invalid-us-currency" | "validation.errors.invalid-utc-offset" | "validation.errors.invalid-uuid" | "validation.errors.invalid-void" | "validation.errors.min" | "validation.errors.max" | "validation.errors.min-length" | "validation.errors.max-length" | "validation.errors.range" | "validation.errors.size" | "validation.errors.past" | "validation.errors.future" | "validation.errors.email" | "validation.errors.ip" | "validation.errors.ipv4" | "validation.errors.ipv6" | "validation.errors.mac" | "validation.errors.url" | "validation.errors.uuid" | "validation.errors.guid" | "validation.errors.ssn" | "validation.errors.phone" | "validation.errors.street" | "validation.errors.zip-code" | "validation.errors.object-id" | "validation.errors.pattern" | "validation.errors.not-blank" | "validation.errors.not-empty" | "validation.errors.positive" | "validation.errors.negative" | "validation.errors.no-scalars" | "validation.errors.not-null" | "validation.errors.required" | "zod.required" | "zod.invalid_value_single" | "zod.invalid_value_multiple" | "zod.too_big_inclusive" | "zod.too_big_exclusive" | "zod.too_big_no_unit_inclusive" | "zod.too_big_no_unit_exclusive" | "zod.too_small_inclusive" | "zod.too_small_exclusive" | "zod.too_small_no_unit_inclusive" | "zod.too_small_no_unit_exclusive" | "zod.not_multiple_of" | "zod.unrecognized_keys_single" | "zod.unrecognized_keys_multiple" | "zod.invalid_key" | "zod.invalid_union" | "zod.invalid_element" | "zod.default" | "zod.invalid_type.string" | "zod.invalid_type.number" | "zod.invalid_type.bigint" | "zod.invalid_type.boolean" | "zod.invalid_type.symbol" | "zod.invalid_type.undefined" | "zod.invalid_type.object" | "zod.invalid_type.function" | "zod.invalid_type.date" | "zod.invalid_type.default" | "zod.invalid_type.array" | "zod.invalid_type.null" | "zod.invalid_type.enum" | "zod.invalid_format.includes" | "zod.invalid_format.default" | "zod.invalid_format.starts_with" | "zod.invalid_format.ends_with" | "zod.invalid_format.regex" | "zod.nouns.emoji" | "zod.nouns.nanoid" | "zod.nouns.cuid" | "zod.nouns.cuid2" | "zod.nouns.date" | "zod.nouns.time" | "zod.nouns.duration" | "zod.nouns.email" | "zod.nouns.ipv4" | "zod.nouns.ipv6" | "zod.nouns.mac" | "zod.nouns.url" | "zod.nouns.uuid" | "zod.nouns.guid" | "zod.nouns.regex" | "zod.nouns.uuidv4" | "zod.nouns.uuidv6" | "zod.nouns.ulid" | "zod.nouns.xid" | "zod.nouns.ksuid" | "zod.nouns.datetime" | "zod.nouns.cidrv4" | "zod.nouns.cidrv6" | "zod.nouns.base64" | "zod.nouns.base64url" | "zod.nouns.json_string" | "zod.nouns.e164" | "zod.nouns.jwt" | "zod.nouns.template_literal" | "zod.sizing.string.unit" | "zod.sizing.string.verb" | "zod.sizing.array.unit" | "zod.sizing.array.verb" | "zod.sizing.file.unit" | "zod.sizing.file.verb" | "zod.sizing.set.unit" | "zod.sizing.set.verb" | "mail.common.thanks" | "mail.common.greeting" | "mail.common.copyright" | "mail.templates.verification.message" | "mail.templates.verification.verify" | "mail.templates.verification.notes" | "opening-hours.errors.invalid-start-time-format" | "opening-hours.errors.invalid-end-time-format", context?: TranslationContext, provideLanguage?: LanguageProvider) => string;
|
|
8
|
+
export * from './i18n';
|
|
15
9
|
//# sourceMappingURL=i18n.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.browser.d.ts","sourceRoot":"","sources":["../src/i18n.browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"i18n.browser.d.ts","sourceRoot":"","sources":["../src/i18n.browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,QAAQ,CAAC"}
|
package/dist/i18n.d.ts
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import type { Language, LanguageProvider, LocaleKey, TranslationContext } from './types';
|
|
2
2
|
/**
|
|
3
|
-
* Where the language comes from when the caller does not say
|
|
3
|
+
* Where the language comes from when the caller does not say, most specific
|
|
4
|
+
* first:
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* 1. a registered source — `registerLanguageSource()`: a server's request
|
|
7
|
+
* context, which `@nxgt/shared-hono` registers for Hono and
|
|
8
|
+
* `@alxia/i18n` for alxia;
|
|
9
|
+
* 2. `localStorage`, when that object exists;
|
|
10
|
+
* 3. the fallback language.
|
|
11
|
+
*
|
|
12
|
+
* Until 2.0 this read Hono's request context itself, through
|
|
13
|
+
* `hono/context-storage`, which tied every consumer — a browser bundle, an
|
|
14
|
+
* alxia server — to Hono. The Hono part lives in `@nxgt/shared-hono` now.
|
|
10
15
|
*
|
|
11
16
|
* `createTranslator` still takes a provider, so a caller that wants one source
|
|
12
|
-
* and not the
|
|
17
|
+
* and not the others passes it.
|
|
13
18
|
*/
|
|
14
19
|
export declare function getLanguage(): Language;
|
|
15
20
|
export declare function createTranslator<K extends string = LocaleKey>(resources?: Record<string, any>, localeProvider?: LanguageProvider): (key: K, context?: TranslationContext, provideLanguage?: LanguageProvider) => string;
|
|
16
|
-
export declare const translate: (key: "errors.not-found" | "errors.unauthenticated" | "errors.duplicate-key" | "errors.something-went-wrong" | "errors.insufficient-permissions" | "errors.cast-failed" | "errors.server-connection-failed" | "errors.forbidden" | "errors.optimistic-lock-failed" | "errors.internal-server-error" | "errors.validation-failed" | "errors.address-blocked" | "errors.could-not-use-first-and-last-together" | "errors.invalid-cursor" | "errors.invalid-status-transition" | "errors.service-unavailable" | "errors.graphql-parse-failed" | "errors.graphql-validation-failed" | "errors.persisted-query-not-found" | "errors.persisted-query-not-supported" | "errors.bad-user-input" | "errors.operation-resolution-failure" | "errors.bad-request" | "validation.errors.time" | "validation.errors.invalid-account-number" | "validation.errors.invalid-big-int" | "validation.errors.invalid-country-code" | "validation.errors.invalid-country-name" | "validation.errors.invalid-cuid" | "validation.errors.invalid-currency" | "validation.errors.invalid-date" | "validation.errors.invalid-date-time" | "validation.errors.invalid-duration" | "validation.errors.invalid-email-address" | "validation.errors.invalid-geo-json" | "validation.errors.invalid-guid" | "validation.errors.invalid-hex-color-code" | "validation.errors.invalid-hexadecimal" | "validation.errors.invalid-hsl" | "validation.errors.invalid-hsla" | "validation.errors.invalid-iban" | "validation.errors.invalid-ip" | "validation.errors.invalid-ipv4" | "validation.errors.invalid-ipv6" | "validation.errors.invalid-isbn" | "validation.errors.invalid-json" | "validation.errors.invalid-json-object" | "validation.errors.invalid-jwt" | "validation.errors.invalid-latitude" | "validation.errors.invalid-locale" | "validation.errors.invalid-longitude" | "validation.errors.invalid-long" | "validation.errors.invalid-mac" | "validation.errors.invalid-negative-float" | "validation.errors.invalid-negative-int" | "validation.errors.invalid-non-empty-string" | "validation.errors.invalid-non-negative-float" | "validation.errors.invalid-non-negative-int" | "validation.errors.invalid-non-positive-float" | "validation.errors.invalid-non-positive-int" | "validation.errors.invalid-object-id" | "validation.errors.invalid-phone-number" | "validation.errors.invalid-port" | "validation.errors.invalid-positive-float" | "validation.errors.invalid-positive-int" | "validation.errors.invalid-postal-code" | "validation.errors.invalid-rgb" | "validation.errors.invalid-rgba" | "validation.errors.invalid-sessn" | "validation.errors.invalid-time" | "validation.errors.invalid-timestamp" | "validation.errors.invalid-url" | "validation.errors.invalid-us-currency" | "validation.errors.invalid-utc-offset" | "validation.errors.invalid-uuid" | "validation.errors.invalid-void" | "validation.errors.min" | "validation.errors.max" | "validation.errors.min-length" | "validation.errors.max-length" | "validation.errors.range" | "validation.errors.size" | "validation.errors.past" | "validation.errors.future" | "validation.errors.email" | "validation.errors.ip" | "validation.errors.ipv4" | "validation.errors.ipv6" | "validation.errors.mac" | "validation.errors.url" | "validation.errors.uuid" | "validation.errors.guid" | "validation.errors.ssn" | "validation.errors.phone" | "validation.errors.street" | "validation.errors.zip-code" | "validation.errors.object-id" | "validation.errors.pattern" | "validation.errors.not-blank" | "validation.errors.not-empty" | "validation.errors.positive" | "validation.errors.negative" | "validation.errors.no-scalars" | "validation.errors.not-null" | "validation.errors.required" | "zod.required" | "zod.invalid_value_single" | "zod.invalid_value_multiple" | "zod.too_big_inclusive" | "zod.too_big_exclusive" | "zod.too_big_no_unit_inclusive" | "zod.too_big_no_unit_exclusive" | "zod.too_small_inclusive" | "zod.too_small_exclusive" | "zod.too_small_no_unit_inclusive" | "zod.too_small_no_unit_exclusive" | "zod.not_multiple_of" | "zod.unrecognized_keys_single" | "zod.unrecognized_keys_multiple" | "zod.invalid_key" | "zod.invalid_union" | "zod.invalid_element" | "zod.default" | "zod.invalid_type.string" | "zod.invalid_type.number" | "zod.invalid_type.bigint" | "zod.invalid_type.boolean" | "zod.invalid_type.symbol" | "zod.invalid_type.undefined" | "zod.invalid_type.object" | "zod.invalid_type.function" | "zod.invalid_type.date" | "zod.invalid_type.default" | "zod.invalid_type.array" | "zod.invalid_type.null" | "zod.invalid_type.enum" | "zod.invalid_format.includes" | "zod.invalid_format.default" | "zod.invalid_format.starts_with" | "zod.invalid_format.ends_with" | "zod.invalid_format.regex" | "zod.nouns.emoji" | "zod.nouns.nanoid" | "zod.nouns.cuid" | "zod.nouns.cuid2" | "zod.nouns.date" | "zod.nouns.time" | "zod.nouns.duration" | "zod.nouns.email" | "zod.nouns.ipv4" | "zod.nouns.ipv6" | "zod.nouns.mac" | "zod.nouns.url" | "zod.nouns.uuid" | "zod.nouns.guid" | "zod.nouns.regex" | "zod.nouns.uuidv4" | "zod.nouns.uuidv6" | "zod.nouns.ulid" | "zod.nouns.xid" | "zod.nouns.ksuid" | "zod.nouns.datetime" | "zod.nouns.cidrv4" | "zod.nouns.cidrv6" | "zod.nouns.base64" | "zod.nouns.base64url" | "zod.nouns.json_string" | "zod.nouns.e164" | "zod.nouns.jwt" | "zod.nouns.template_literal" | "zod.sizing.string.unit" | "zod.sizing.string.verb" | "zod.sizing.array.unit" | "zod.sizing.array.verb" | "zod.sizing.file.unit" | "zod.sizing.file.verb" | "zod.sizing.set.unit" | "zod.sizing.set.verb" | "mail.common.thanks" | "mail.common.greeting" | "mail.common.copyright" | "mail.templates.verification.message" | "mail.templates.verification.verify" | "mail.templates.verification.notes" | "opening-hours.errors.invalid-start-time-format" | "opening-hours.errors.invalid-end-time-format", context?: TranslationContext, provideLanguage?: LanguageProvider) => string;
|
|
21
|
+
export declare const translate: (key: "errors.not-found" | "errors.unauthenticated" | "errors.duplicate-key" | "errors.something-went-wrong" | "errors.insufficient-permissions" | "errors.cast-failed" | "errors.server-connection-failed" | "errors.forbidden" | "errors.optimistic-lock-failed" | "errors.internal-server-error" | "errors.validation-failed" | "errors.address-blocked" | "errors.could-not-use-first-and-last-together" | "errors.invalid-cursor" | "errors.invalid-status-transition" | "errors.service-unavailable" | "errors.graphql-parse-failed" | "errors.graphql-validation-failed" | "errors.persisted-query-not-found" | "errors.persisted-query-not-supported" | "errors.bad-user-input" | "errors.operation-resolution-failure" | "errors.bad-request" | "errors.list-patch-one-operation-per-path" | "validation.errors.time" | "validation.errors.invalid-account-number" | "validation.errors.invalid-big-int" | "validation.errors.invalid-country-code" | "validation.errors.invalid-country-name" | "validation.errors.invalid-cuid" | "validation.errors.invalid-currency" | "validation.errors.invalid-date" | "validation.errors.invalid-date-time" | "validation.errors.invalid-duration" | "validation.errors.invalid-email-address" | "validation.errors.invalid-geo-json" | "validation.errors.invalid-guid" | "validation.errors.invalid-hex-color-code" | "validation.errors.invalid-hexadecimal" | "validation.errors.invalid-hsl" | "validation.errors.invalid-hsla" | "validation.errors.invalid-iban" | "validation.errors.invalid-ip" | "validation.errors.invalid-ipv4" | "validation.errors.invalid-ipv6" | "validation.errors.invalid-isbn" | "validation.errors.invalid-json" | "validation.errors.invalid-json-object" | "validation.errors.invalid-jwt" | "validation.errors.invalid-latitude" | "validation.errors.invalid-locale" | "validation.errors.invalid-longitude" | "validation.errors.invalid-long" | "validation.errors.invalid-mac" | "validation.errors.invalid-negative-float" | "validation.errors.invalid-negative-int" | "validation.errors.invalid-non-empty-string" | "validation.errors.invalid-non-negative-float" | "validation.errors.invalid-non-negative-int" | "validation.errors.invalid-non-positive-float" | "validation.errors.invalid-non-positive-int" | "validation.errors.invalid-object-id" | "validation.errors.invalid-phone-number" | "validation.errors.invalid-port" | "validation.errors.invalid-positive-float" | "validation.errors.invalid-positive-int" | "validation.errors.invalid-postal-code" | "validation.errors.invalid-rgb" | "validation.errors.invalid-rgba" | "validation.errors.invalid-sessn" | "validation.errors.invalid-time" | "validation.errors.invalid-timestamp" | "validation.errors.invalid-url" | "validation.errors.invalid-us-currency" | "validation.errors.invalid-utc-offset" | "validation.errors.invalid-uuid" | "validation.errors.invalid-void" | "validation.errors.min" | "validation.errors.max" | "validation.errors.min-length" | "validation.errors.max-length" | "validation.errors.range" | "validation.errors.size" | "validation.errors.past" | "validation.errors.future" | "validation.errors.email" | "validation.errors.ip" | "validation.errors.ipv4" | "validation.errors.ipv6" | "validation.errors.mac" | "validation.errors.url" | "validation.errors.uuid" | "validation.errors.guid" | "validation.errors.ssn" | "validation.errors.phone" | "validation.errors.street" | "validation.errors.zip-code" | "validation.errors.object-id" | "validation.errors.pattern" | "validation.errors.not-blank" | "validation.errors.not-empty" | "validation.errors.positive" | "validation.errors.negative" | "validation.errors.no-scalars" | "validation.errors.not-null" | "validation.errors.required" | "zod.required" | "zod.invalid_value_single" | "zod.invalid_value_multiple" | "zod.too_big_inclusive" | "zod.too_big_exclusive" | "zod.too_big_no_unit_inclusive" | "zod.too_big_no_unit_exclusive" | "zod.too_small_inclusive" | "zod.too_small_exclusive" | "zod.too_small_no_unit_inclusive" | "zod.too_small_no_unit_exclusive" | "zod.not_multiple_of" | "zod.unrecognized_keys_single" | "zod.unrecognized_keys_multiple" | "zod.invalid_key" | "zod.invalid_union" | "zod.invalid_element" | "zod.default" | "zod.invalid_type.string" | "zod.invalid_type.number" | "zod.invalid_type.bigint" | "zod.invalid_type.boolean" | "zod.invalid_type.symbol" | "zod.invalid_type.undefined" | "zod.invalid_type.object" | "zod.invalid_type.function" | "zod.invalid_type.date" | "zod.invalid_type.default" | "zod.invalid_type.array" | "zod.invalid_type.null" | "zod.invalid_type.enum" | "zod.invalid_format.includes" | "zod.invalid_format.default" | "zod.invalid_format.starts_with" | "zod.invalid_format.ends_with" | "zod.invalid_format.regex" | "zod.nouns.emoji" | "zod.nouns.nanoid" | "zod.nouns.cuid" | "zod.nouns.cuid2" | "zod.nouns.date" | "zod.nouns.time" | "zod.nouns.duration" | "zod.nouns.email" | "zod.nouns.ipv4" | "zod.nouns.ipv6" | "zod.nouns.mac" | "zod.nouns.url" | "zod.nouns.uuid" | "zod.nouns.guid" | "zod.nouns.regex" | "zod.nouns.uuidv4" | "zod.nouns.uuidv6" | "zod.nouns.ulid" | "zod.nouns.xid" | "zod.nouns.ksuid" | "zod.nouns.datetime" | "zod.nouns.cidrv4" | "zod.nouns.cidrv6" | "zod.nouns.base64" | "zod.nouns.base64url" | "zod.nouns.json_string" | "zod.nouns.e164" | "zod.nouns.jwt" | "zod.nouns.template_literal" | "zod.sizing.string.unit" | "zod.sizing.string.verb" | "zod.sizing.array.unit" | "zod.sizing.array.verb" | "zod.sizing.file.unit" | "zod.sizing.file.verb" | "zod.sizing.set.unit" | "zod.sizing.set.verb" | "mail.common.thanks" | "mail.common.greeting" | "mail.common.copyright" | "mail.templates.verification.message" | "mail.templates.verification.verify" | "mail.templates.verification.notes" | "opening-hours.errors.invalid-start-time-format" | "opening-hours.errors.invalid-end-time-format", context?: TranslationContext, provideLanguage?: LanguageProvider) => string;
|
|
17
22
|
//# sourceMappingURL=i18n.d.ts.map
|
package/dist/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,MAAM,SAAS,CAAC;AAEjB
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAUtC;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EAC5D,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EACnC,cAAc,GAAE,gBAA8B,IAG7C,KAAK,CAAC,EACN,UAAS,kBAA8B,EACvC,kBAAiB,gBAAiC,KAChD,MAAM,CAcT;AAED,eAAO,MAAM,SAAS,+qLAlBX,kBAAkB,oBACV,gBAAgB,KAC/B,MAgBgD,CAAC"}
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/dist/index.browser.js
CHANGED
|
@@ -2,42 +2,24 @@ import {
|
|
|
2
2
|
resources2,
|
|
3
3
|
LANGUAGE_KEY2,
|
|
4
4
|
SUPPORTED_LANGUAGES2,
|
|
5
|
-
FALLBACK_LANGUAGE2
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const stored = localStorage.getItem(LANGUAGE_KEY2);
|
|
13
|
-
if (SUPPORTED_LANGUAGES2.includes(stored)) {
|
|
14
|
-
return stored;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return FALLBACK_LANGUAGE2;
|
|
18
|
-
}
|
|
19
|
-
function createTranslator(resources = {}, localeProvider = getLanguage) {
|
|
20
|
-
return (key, context = undefined, provideLanguage = localeProvider) => {
|
|
21
|
-
const language = typeof provideLanguage === "function" ? provideLanguage() : provideLanguage;
|
|
22
|
-
let message = _.get(resources[language], key) ?? key;
|
|
23
|
-
try {
|
|
24
|
-
message = new IntlMessageFormat(message, language).format(context);
|
|
25
|
-
} catch (e) {
|
|
26
|
-
console.error(e);
|
|
27
|
-
}
|
|
28
|
-
return message;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
var translate = createTranslator(resources2);
|
|
5
|
+
FALLBACK_LANGUAGE2,
|
|
6
|
+
registerLanguageSource2,
|
|
7
|
+
languageFromSources2,
|
|
8
|
+
getLanguage2,
|
|
9
|
+
createTranslator2,
|
|
10
|
+
translate2
|
|
11
|
+
} from "./chunks/index-jscbtbek.js";
|
|
32
12
|
export {
|
|
33
13
|
FALLBACK_LANGUAGE2 as FALLBACK_LANGUAGE,
|
|
34
14
|
LANGUAGE_KEY2 as LANGUAGE_KEY,
|
|
35
15
|
SUPPORTED_LANGUAGES2 as SUPPORTED_LANGUAGES,
|
|
36
|
-
createTranslator,
|
|
37
|
-
getLanguage,
|
|
16
|
+
createTranslator2 as createTranslator,
|
|
17
|
+
getLanguage2 as getLanguage,
|
|
18
|
+
languageFromSources2 as languageFromSources,
|
|
19
|
+
registerLanguageSource2 as registerLanguageSource,
|
|
38
20
|
resources2 as resources,
|
|
39
|
-
translate
|
|
21
|
+
translate2 as translate
|
|
40
22
|
};
|
|
41
23
|
|
|
42
|
-
//# debugId=
|
|
24
|
+
//# debugId=56C1E29CC90F7A3164756E2164756E21
|
|
43
25
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": [
|
|
3
|
+
"sources": [],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { IntlMessageFormat } from 'intl-messageformat';\nimport _ from 'lodash';\nimport { FALLBACK_LANGUAGE, LANGUAGE_KEY, SUPPORTED_LANGUAGES } from './consts';\nimport { resources } from './resources';\nimport type {\n\tLanguage,\n\tLanguageProvider,\n\tLocaleKey,\n\tTranslationContext,\n} from './types';\n\n/**\n * The browser build of {@link getLanguage} from `./i18n`.\n *\n * A bundler that resolves the `browser` export condition (Vite, Nuxt's client\n * build) gets this file instead: it never imports `hono/context-storage`,\n * which pulls in `node:async_hooks` — absent in a browser and dead weight in\n * a client bundle that never runs inside a Hono request. There is no request\n * context to ask in a browser anyway, so the behaviour a consumer sees is the\n * same: `localStorage`, then the fallback language.\n */\nexport function getLanguage(): Language {\n\tif (typeof localStorage !== 'undefined') {\n\t\tconst stored = localStorage.getItem(LANGUAGE_KEY);\n\t\tif (SUPPORTED_LANGUAGES.includes(stored as Language)) {\n\t\t\treturn stored as Language;\n\t\t}\n\t}\n\treturn FALLBACK_LANGUAGE;\n}\n\nexport function createTranslator<K extends string = LocaleKey>(\n\tresources: Record<string, any> = {},\n\tlocaleProvider: LanguageProvider = getLanguage,\n) {\n\treturn (\n\t\tkey: K,\n\t\tcontext: TranslationContext = undefined,\n\t\tprovideLanguage: LanguageProvider = localeProvider,\n\t): string => {\n\t\tconst language =\n\t\t\ttypeof provideLanguage === 'function'\n\t\t\t\t? provideLanguage()\n\t\t\t\t: provideLanguage;\n\t\tlet message: string = _.get(resources[language], key) ?? key;\n\t\ttry {\n\t\t\tmessage = new IntlMessageFormat(message, language).format(context);\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t}\n\n\t\treturn message;\n\t};\n}\n\nexport const translate = createTranslator(resources);\n"
|
|
6
5
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
6
|
+
"mappings": "",
|
|
7
|
+
"debugId": "56C1E29CC90F7A3164756E2164756E21",
|
|
9
8
|
"names": []
|
|
10
9
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,47 +2,24 @@ import {
|
|
|
2
2
|
resources2,
|
|
3
3
|
LANGUAGE_KEY2,
|
|
4
4
|
SUPPORTED_LANGUAGES2,
|
|
5
|
-
FALLBACK_LANGUAGE2
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const fromRequest = tryGetContext()?.get(LANGUAGE_KEY2);
|
|
13
|
-
if (typeof fromRequest === "string" && SUPPORTED_LANGUAGES2.includes(fromRequest)) {
|
|
14
|
-
return fromRequest;
|
|
15
|
-
}
|
|
16
|
-
if (typeof localStorage !== "undefined") {
|
|
17
|
-
const stored = localStorage.getItem(LANGUAGE_KEY2);
|
|
18
|
-
if (SUPPORTED_LANGUAGES2.includes(stored)) {
|
|
19
|
-
return stored;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return FALLBACK_LANGUAGE2;
|
|
23
|
-
}
|
|
24
|
-
function createTranslator(resources = {}, localeProvider = getLanguage) {
|
|
25
|
-
return (key, context = undefined, provideLanguage = localeProvider) => {
|
|
26
|
-
const language = typeof provideLanguage === "function" ? provideLanguage() : provideLanguage;
|
|
27
|
-
let message = _.get(resources[language], key) ?? key;
|
|
28
|
-
try {
|
|
29
|
-
message = new IntlMessageFormat(message, language).format(context);
|
|
30
|
-
} catch (e) {
|
|
31
|
-
console.error(e);
|
|
32
|
-
}
|
|
33
|
-
return message;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
var translate = createTranslator(resources2);
|
|
5
|
+
FALLBACK_LANGUAGE2,
|
|
6
|
+
registerLanguageSource2,
|
|
7
|
+
languageFromSources2,
|
|
8
|
+
getLanguage2,
|
|
9
|
+
createTranslator2,
|
|
10
|
+
translate2
|
|
11
|
+
} from "./chunks/index-jscbtbek.js";
|
|
37
12
|
export {
|
|
38
13
|
FALLBACK_LANGUAGE2 as FALLBACK_LANGUAGE,
|
|
39
14
|
LANGUAGE_KEY2 as LANGUAGE_KEY,
|
|
40
15
|
SUPPORTED_LANGUAGES2 as SUPPORTED_LANGUAGES,
|
|
41
|
-
createTranslator,
|
|
42
|
-
getLanguage,
|
|
16
|
+
createTranslator2 as createTranslator,
|
|
17
|
+
getLanguage2 as getLanguage,
|
|
18
|
+
languageFromSources2 as languageFromSources,
|
|
19
|
+
registerLanguageSource2 as registerLanguageSource,
|
|
43
20
|
resources2 as resources,
|
|
44
|
-
translate
|
|
21
|
+
translate2 as translate
|
|
45
22
|
};
|
|
46
23
|
|
|
47
|
-
//# debugId=
|
|
24
|
+
//# debugId=B6438B8D81267DD164756E2164756E21
|
|
48
25
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": [
|
|
3
|
+
"sources": [],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { tryGetContext } from 'hono/context-storage';\nimport { IntlMessageFormat } from 'intl-messageformat';\nimport _ from 'lodash';\nimport { FALLBACK_LANGUAGE, LANGUAGE_KEY, SUPPORTED_LANGUAGES } from './consts';\nimport { resources } from './resources';\nimport type {\n\tLanguage,\n\tLanguageProvider,\n\tLocaleKey,\n\tTranslationContext,\n} from './types';\n\n/**\n * Where the language comes from when the caller does not say.\n *\n * The two repositories had forked exactly this: sellix-monorepo read\n * `localStorage`, nxgt-federation read the Hono request context, and neither\n * could run where the other did — federation's fell back to `'en'` outside a\n * request, sellix's knew nothing about one. Asking both, most specific first,\n * serves either without a caller changing anything.\n *\n * `createTranslator` still takes a provider, so a caller that wants one source\n * and not the other passes it.\n */\nexport function getLanguage(): Language {\n\tconst fromRequest: unknown = tryGetContext()?.get(LANGUAGE_KEY as never);\n\tif (\n\t\ttypeof fromRequest === 'string' &&\n\t\tSUPPORTED_LANGUAGES.includes(fromRequest as Language)\n\t) {\n\t\treturn fromRequest as Language;\n\t}\n\tif (typeof localStorage !== 'undefined') {\n\t\tconst stored = localStorage.getItem(LANGUAGE_KEY);\n\t\tif (SUPPORTED_LANGUAGES.includes(stored as Language)) {\n\t\t\treturn stored as Language;\n\t\t}\n\t}\n\treturn FALLBACK_LANGUAGE;\n}\n\nexport function createTranslator<K extends string = LocaleKey>(\n\tresources: Record<string, any> = {},\n\tlocaleProvider: LanguageProvider = getLanguage,\n) {\n\treturn (\n\t\tkey: K,\n\t\tcontext: TranslationContext = undefined,\n\t\tprovideLanguage: LanguageProvider = localeProvider,\n\t): string => {\n\t\tconst language =\n\t\t\ttypeof provideLanguage === 'function'\n\t\t\t\t? provideLanguage()\n\t\t\t\t: provideLanguage;\n\t\tlet message: string = _.get(resources[language], key) ?? key;\n\t\ttry {\n\t\t\tmessage = new IntlMessageFormat(message, language).format(context);\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t}\n\n\t\treturn message;\n\t};\n}\n\nexport const translate = createTranslator(resources);\n"
|
|
6
5
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
6
|
+
"mappings": "",
|
|
7
|
+
"debugId": "B6438B8D81267DD164756E2164756E21",
|
|
9
8
|
"names": []
|
|
10
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/en/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/en/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/fr/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/fr/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKd,CAAC"}
|
|
@@ -24,6 +24,7 @@ export declare const resources: {
|
|
|
24
24
|
"bad-user-input": string;
|
|
25
25
|
"operation-resolution-failure": string;
|
|
26
26
|
"bad-request": string;
|
|
27
|
+
"list-patch-one-operation-per-path": string;
|
|
27
28
|
};
|
|
28
29
|
validation: {
|
|
29
30
|
errors: {
|
|
@@ -248,6 +249,7 @@ export declare const resources: {
|
|
|
248
249
|
"bad-user-input": string;
|
|
249
250
|
"operation-resolution-failure": string;
|
|
250
251
|
"bad-request": string;
|
|
252
|
+
"list-patch-one-operation-per-path": string;
|
|
251
253
|
};
|
|
252
254
|
validation: {
|
|
253
255
|
errors: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Language } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Where a language may come from: a server's request context, a framework's
|
|
4
|
+
* state. It answers the request's language, or nothing — `undefined`, `null`,
|
|
5
|
+
* a language no catalogue has — and the next source is asked.
|
|
6
|
+
*/
|
|
7
|
+
export type LanguageSource = () => string | null | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Adds a source `getLanguage()` asks, after those registered before it.
|
|
10
|
+
* Registering one twice keeps one. Answers the function that removes it.
|
|
11
|
+
*
|
|
12
|
+
* This package knows no server: `@nxgt/shared-hono` registers the Hono
|
|
13
|
+
* request context's `language`, `@alxia/i18n` the alxia request's.
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerLanguageSource(source: LanguageSource): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* The first supported language a registered source answers. A source that
|
|
18
|
+
* throws is skipped: a language is never worth a failed request.
|
|
19
|
+
*/
|
|
20
|
+
export declare function languageFromSources(): Language | undefined;
|
|
21
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAe7D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,IAAI,CAOzE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,GAAG,SAAS,CAa1D"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/i18n",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"hono": "^4.13.4",
|
|
45
44
|
"intl-messageformat": "^12.1.2",
|
|
46
45
|
"lodash": "^4.18.1"
|
|
47
46
|
},
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/resources/en/index.ts", "../src/resources/fr/index.ts", "../src/resources/index.ts", "../src/consts.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import common from './common.json';\nimport errors from './errors.json';\nimport validation from './validation.json';\nimport zod from './zod.json';\n\nexport const en = {\n\t...common,\n\terrors,\n\tvalidation,\n\tzod,\n};\n",
|
|
6
|
-
"import common from './common.json';\nimport errors from './errors.json';\nimport validation from './validation.json';\nimport zod from './zod.json';\n\nexport const fr = {\n\t...common,\n\terrors,\n\tvalidation,\n\tzod,\n};\n",
|
|
7
|
-
"import { en } from './en';\nimport { fr } from './fr';\n\nexport const resources = {\n\ten,\n\tfr,\n};\n",
|
|
8
|
-
"import { resources } from './resources';\nimport type { Language } from './types';\n\nexport const LANGUAGE_KEY = 'language';\n\nexport const SUPPORTED_LANGUAGES = Object.keys(resources) as Language[];\n\nexport const FALLBACK_LANGUAGE: Language = 'en';\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,IAAM,KAAK;AAAA,KACd;AAAA,EACH;AAAA,EACA;AAAA,EACA;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLO,IAAM,KAAK;AAAA,KACd;AAAA,EACH;AAAA,EACA;AAAA,EACA;AACD;;;ACPO,IAAM,aAAY;AAAA,EACxB;AAAA,EACA;AACD;;;ACHO,IAAM,gBAAe;AAErB,IAAM,uBAAsB,OAAO,KAAK,UAAS;AAEjD,IAAM,qBAA8B;",
|
|
11
|
-
"debugId": "9B74B0DCF0FC1D0A64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|