@nxgt/i18n 1.0.0 → 1.0.2

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 CHANGED
@@ -1,39 +1,19 @@
1
1
  # @nxgt/i18n
2
2
 
3
- Backend-side i18n primitives shared by the Hono/GraphQL services: a tiny ICU
4
- translator (`createTranslator`, `translate`, `getLanguage`), the language
5
- constants (`LANGUAGE_KEY`, `FALLBACK_LANGUAGE`, `SUPPORTED_LANGUAGES`), the
6
- `LocaleKey`/`FlatObject`/`Path` types, and the base resource bundle
7
- (`common`, `errors`, `validation`, `zod`) that every service merges into its own.
3
+ Message catalogues and ICU formatting (`intl-messageformat`) for every service,
4
+ plus the `LocaleKey` type that `@nxgt/shared-exceptions` uses to type the
5
+ message of a thrown error.
8
6
 
9
- ## Scope: backend only
7
+ An error message is a **key**, not a sentence: `CustomException` carries
8
+ `'users.errors.not-found'` and the boundary that renders it decides the
9
+ language. That is why `LocaleKey` lives this low in the layering.
10
10
 
11
- The UI apps (`apps/oauth/oauth`, `apps/oauth/oauth-admin`,
12
- `apps/storex/storex-ui`) do **not** use this package. They share their i18n
13
- mechanism through `@nxgt/material/i18n`, which adds the React side this package
14
- deliberately has none of: an `I18nProvider` holding the language in one context
15
- so a `changeLanguage()` re-renders every consumer, and `createTypedTranslation`
16
- to build each app's typed `useTranslation()`. Do not add a frontend consumer
17
- here — extend `@nxgt/material/i18n` instead.
11
+ ## Install
18
12
 
19
- ## Consumers
20
-
21
- - `apps/gateway`
22
- - `apps/oauth/oauth-api`, `apps/storex/storex-api`
23
- - `apps/services/core`, `apps/services/locations`, `apps/services/notifications`
24
- - `packages/shared-exceptions`, `packages/shared-hono`, `packages/shared-mongo`,
25
- `packages/shared-storage`
26
-
27
- A service builds its own translator over its own resources merged with this
28
- package's base bundle:
29
-
30
- ```ts
31
- import { createTranslator, resources as shared } from '@nxgt/i18n';
32
-
33
- export const resources = {
34
- en: { ...en, ...shared.en },
35
- fr: { ...fr, ...shared.fr },
36
- };
37
-
38
- export const translate = createTranslator<LocaleKey>(resources);
13
+ ```bash
14
+ bun add @nxgt/i18n
39
15
  ```
16
+
17
+ Public on npmjs; no token needed to install. TypeScript is a peer, pinned to
18
+ `^6.0.3` across every `@nxgt/*` package — the set is unsatisfiable if one of
19
+ them widens it.
package/dist/index.js CHANGED
@@ -474,10 +474,10 @@ function getLanguage() {
474
474
  }
475
475
  return FALLBACK_LANGUAGE;
476
476
  }
477
- function createTranslator(resources2 = {}, localeProvider = getLanguage) {
477
+ function createTranslator(resources = {}, localeProvider = getLanguage) {
478
478
  return (key, context = undefined, provideLanguage = localeProvider) => {
479
479
  const language = typeof provideLanguage === "function" ? provideLanguage() : provideLanguage;
480
- let message = _.get(resources2[language], key) ?? key;
480
+ let message = _.get(resources[language], key) ?? key;
481
481
  try {
482
482
  message = new IntlMessageFormat(message, language).format(context);
483
483
  } catch (e) {
@@ -497,5 +497,5 @@ export {
497
497
  translate
498
498
  };
499
499
 
500
- //# debugId=629CBE18E4850F3E64756E2164756E21
500
+ //# debugId=9824428B699DC6DF64756E2164756E21
501
501
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -8,7 +8,7 @@
8
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
9
  "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"
10
10
  ],
11
- "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,YAAY;AAAA,EACxB;AAAA,EACA;AACD;;;ACHO,IAAM,eAAe;AAErB,IAAM,sBAAsB,OAAO,KAAK,SAAS;AAEjD,IAAM,oBAA8B;;ACP3C;AACA;AACA;AAsBO,SAAS,WAAW,GAAa;AAAA,EACvC,MAAM,cAAuB,cAAc,GAAG,IAAI,YAAqB;AAAA,EACvE,IACC,OAAO,gBAAgB,YACvB,oBAAoB,SAAS,WAAuB,GACnD;AAAA,IACD,OAAO;AAAA,EACR;AAAA,EACA,IAAI,OAAO,iBAAiB,aAAa;AAAA,IACxC,MAAM,SAAS,aAAa,QAAQ,YAAY;AAAA,IAChD,IAAI,oBAAoB,SAAS,MAAkB,GAAG;AAAA,MACrD,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGD,SAAS,gBAA8C,CAC7D,aAAiC,CAAC,GAClC,iBAAmC,aAClC;AAAA,EACD,OAAO,CACN,KACA,UAA8B,WAC9B,kBAAoC,mBACxB;AAAA,IACZ,MAAM,WACL,OAAO,oBAAoB,aACxB,gBAAgB,IAChB;AAAA,IACJ,IAAI,UAAkB,EAAE,IAAI,WAAU,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,YAAY,iBAAiB,SAAS;",
12
- "debugId": "629CBE18E4850F3E64756E2164756E21",
11
+ "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,YAAY;AAAA,EACxB;AAAA,EACA;AACD;;;ACHO,IAAM,eAAe;AAErB,IAAM,sBAAsB,OAAO,KAAK,SAAS;AAEjD,IAAM,oBAA8B;;ACP3C;AACA;AACA;AAsBO,SAAS,WAAW,GAAa;AAAA,EACvC,MAAM,cAAuB,cAAc,GAAG,IAAI,YAAqB;AAAA,EACvE,IACC,OAAO,gBAAgB,YACvB,oBAAoB,SAAS,WAAuB,GACnD;AAAA,IACD,OAAO;AAAA,EACR;AAAA,EACA,IAAI,OAAO,iBAAiB,aAAa;AAAA,IACxC,MAAM,SAAS,aAAa,QAAQ,YAAY;AAAA,IAChD,IAAI,oBAAoB,SAAS,MAAkB,GAAG;AAAA,MACrD,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGD,SAAS,gBAA8C,CAC7D,YAAiC,CAAC,GAClC,iBAAmC,aAClC;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,YAAY,iBAAiB,SAAS;",
12
+ "debugId": "9824428B699DC6DF64756E2164756E21",
13
13
  "names": []
14
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/i18n",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "scripts": {
31
31
  "build": "bun run ../../build.ts",
32
+ "test": "bun test src",
32
33
  "typecheck": "tsc --noEmit"
33
34
  },
34
35
  "nxgt": {