@hoardodile/i18n 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.d.ts CHANGED
@@ -19,6 +19,19 @@
19
19
  declare const SUPPORTED_LANGUAGES: readonly ["en", "zh", "ja", "de", "es"];
20
20
  type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number];
21
21
  declare function isSupportedLanguage(value: string): value is SupportedLanguage;
22
+ /**
23
+ * Catalog key for each supported language's display name in its own
24
+ * script (`language.english` → "English", `language.chinese` → "中文", …).
25
+ * The `language.*` catalog keys are named (not BCP-47 codes), so build the
26
+ * `t()` key through this map rather than interpolating the code.
27
+ */
28
+ declare const LANGUAGE_LABEL_KEYS: {
29
+ readonly en: "language.english";
30
+ readonly zh: "language.chinese";
31
+ readonly ja: "language.japanese";
32
+ readonly de: "language.german";
33
+ readonly es: "language.spanish";
34
+ };
22
35
  /**
23
36
  * Map a BCP-47 locale string (e.g. `navigator.language`,
24
37
  * `app.getLocale()`, a stored pref) onto the supported set, taking the
@@ -29,4 +42,4 @@ declare function isSupportedLanguage(value: string): value is SupportedLanguage;
29
42
  */
30
43
  declare function resolveSystemLanguage(raw: string | undefined): SupportedLanguage;
31
44
 
32
- export { SUPPORTED_LANGUAGES, type SupportedLanguage, isSupportedLanguage, resolveSystemLanguage };
45
+ export { LANGUAGE_LABEL_KEYS, SUPPORTED_LANGUAGES, type SupportedLanguage, isSupportedLanguage, resolveSystemLanguage };
package/dist/core.js CHANGED
@@ -3,12 +3,19 @@ var SUPPORTED_LANGUAGES = ["en", "zh", "ja", "de", "es"];
3
3
  function isSupportedLanguage(value) {
4
4
  return SUPPORTED_LANGUAGES.includes(value);
5
5
  }
6
+ var LANGUAGE_LABEL_KEYS = {
7
+ en: "language.english",
8
+ zh: "language.chinese",
9
+ ja: "language.japanese",
10
+ de: "language.german",
11
+ es: "language.spanish"
12
+ };
6
13
  function resolveSystemLanguage(raw) {
7
14
  const base = raw?.toLowerCase().split("-")[0];
8
15
  if (base !== void 0 && isSupportedLanguage(base)) return base;
9
16
  return "en";
10
17
  }
11
18
 
12
- export { SUPPORTED_LANGUAGES, isSupportedLanguage, resolveSystemLanguage };
19
+ export { LANGUAGE_LABEL_KEYS, SUPPORTED_LANGUAGES, isSupportedLanguage, resolveSystemLanguage };
13
20
  //# sourceMappingURL=core.js.map
14
21
  //# sourceMappingURL=core.js.map
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts"],"names":[],"mappings":";AAkBO,IAAM,sBAAsB,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI;AAGzD,SAAS,oBAAoB,KAAA,EAA2C;AAC9E,EAAA,OAAQ,mBAAA,CAA0C,SAAS,KAAK,CAAA;AACjE;AAUO,SAAS,sBACf,GAAA,EACoB;AACpB,EAAA,MAAM,OAAO,GAAA,EAAK,WAAA,GAAc,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC5C,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,mBAAA,CAAoB,IAAI,GAAG,OAAO,IAAA;AAC5D,EAAA,OAAO,IAAA;AACR","file":"core.js","sourcesContent":["/**\n * Locale plumbing shared by the web SPA, the Electron shell and the plugin\n * SDK: the supported-language set and pure helpers. **This module must\n * stay free of catalog imports** — the sandboxed preload imports\n * `isSupportedLanguage` from here, and the catalogs (which weigh far\n * more than this file) live in `./catalogs.ts` (`CATALOGS`,\n * `catalogFor`), `./catalogs/ui.ts` (`UI_CATALOGS`, `uiCatalogFor`) plus\n * the per-language JSON modules.\n *\n * `catalogs/*.json` (the app `translation` namespace) and `ui/*.json`\n * (the shared `ui` namespace consumed by `@hoardodile/ui` and the plugin\n * SDK iframes) must stay in lockstep internally: identical flat key\n * sets, matching interpolation placeholders, and complete `_one`/`_other`\n * pairs. `src/parity.test.ts` enforces this — run it after touching any\n * catalog. `CATALOGS: Record<SupportedLanguage, typeof en>` and\n * `UI_CATALOGS: Record<SupportedLanguage, typeof uiEn>` additionally\n * make any key drift a compile error in `tsc`.\n */\nexport const SUPPORTED_LANGUAGES = [\"en\", \"zh\", \"ja\", \"de\", \"es\"] as const\nexport type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]\n\nexport function isSupportedLanguage(value: string): value is SupportedLanguage {\n\treturn (SUPPORTED_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * Map a BCP-47 locale string (e.g. `navigator.language`,\n * `app.getLocale()`, a stored pref) onto the supported set, taking the\n * base code: `\"ja-JP\"` → `\"ja\"`, `\"de-DE\"` → `\"de\"`, `\"es-MX\"` → `\"es\"`,\n * `\"zh-CN\"`/`\"zh-TW\"` → `\"zh\"` (any Chinese base maps to the `zh`\n * catalog, preserving historical behavior). Unknown or missing values\n * fall back to `\"en\"`.\n */\nexport function resolveSystemLanguage(\n\traw: string | undefined,\n): SupportedLanguage {\n\tconst base = raw?.toLowerCase().split(\"-\")[0]\n\tif (base !== undefined && isSupportedLanguage(base)) return base\n\treturn \"en\"\n}\n"]}
1
+ {"version":3,"sources":["../src/core.ts"],"names":[],"mappings":";AAkBO,IAAM,sBAAsB,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI;AAGzD,SAAS,oBAAoB,KAAA,EAA2C;AAC9E,EAAA,OAAQ,mBAAA,CAA0C,SAAS,KAAK,CAAA;AACjE;AAQO,IAAM,mBAAA,GAAsB;AAAA,EAClC,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,mBAAA;AAAA,EACJ,EAAA,EAAI,iBAAA;AAAA,EACJ,EAAA,EAAI;AACL;AAUO,SAAS,sBACf,GAAA,EACoB;AACpB,EAAA,MAAM,OAAO,GAAA,EAAK,WAAA,GAAc,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC5C,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,mBAAA,CAAoB,IAAI,GAAG,OAAO,IAAA;AAC5D,EAAA,OAAO,IAAA;AACR","file":"core.js","sourcesContent":["/**\n * Locale plumbing shared by the web SPA, the Electron shell and the plugin\n * SDK: the supported-language set and pure helpers. **This module must\n * stay free of catalog imports** — the sandboxed preload imports\n * `isSupportedLanguage` from here, and the catalogs (which weigh far\n * more than this file) live in `./catalogs.ts` (`CATALOGS`,\n * `catalogFor`), `./catalogs/ui.ts` (`UI_CATALOGS`, `uiCatalogFor`) plus\n * the per-language JSON modules.\n *\n * `catalogs/*.json` (the app `translation` namespace) and `ui/*.json`\n * (the shared `ui` namespace consumed by `@hoardodile/ui` and the plugin\n * SDK iframes) must stay in lockstep internally: identical flat key\n * sets, matching interpolation placeholders, and complete `_one`/`_other`\n * pairs. `src/parity.test.ts` enforces this — run it after touching any\n * catalog. `CATALOGS: Record<SupportedLanguage, typeof en>` and\n * `UI_CATALOGS: Record<SupportedLanguage, typeof uiEn>` additionally\n * make any key drift a compile error in `tsc`.\n */\nexport const SUPPORTED_LANGUAGES = [\"en\", \"zh\", \"ja\", \"de\", \"es\"] as const\nexport type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]\n\nexport function isSupportedLanguage(value: string): value is SupportedLanguage {\n\treturn (SUPPORTED_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * Catalog key for each supported language's display name in its own\n * script (`language.english` → \"English\", `language.chinese` → \"中文\", …).\n * The `language.*` catalog keys are named (not BCP-47 codes), so build the\n * `t()` key through this map rather than interpolating the code.\n */\nexport const LANGUAGE_LABEL_KEYS = {\n\ten: \"language.english\",\n\tzh: \"language.chinese\",\n\tja: \"language.japanese\",\n\tde: \"language.german\",\n\tes: \"language.spanish\",\n} as const satisfies Record<SupportedLanguage, string>\n\n/**\n * Map a BCP-47 locale string (e.g. `navigator.language`,\n * `app.getLocale()`, a stored pref) onto the supported set, taking the\n * base code: `\"ja-JP\"` → `\"ja\"`, `\"de-DE\"` → `\"de\"`, `\"es-MX\"` → `\"es\"`,\n * `\"zh-CN\"`/`\"zh-TW\"` → `\"zh\"` (any Chinese base maps to the `zh`\n * catalog, preserving historical behavior). Unknown or missing values\n * fall back to `\"en\"`.\n */\nexport function resolveSystemLanguage(\n\traw: string | undefined,\n): SupportedLanguage {\n\tconst base = raw?.toLowerCase().split(\"-\")[0]\n\tif (base !== undefined && isSupportedLanguage(base)) return base\n\treturn \"en\"\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/create-i18n.ts"],"names":[],"mappings":";;;;;AAkBO,IAAM,sBAAsB,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;;;ACgBzD,SAAS,WAAW,OAAA,EAA0C;AACpE,EAAA,MAAM,EAAE,GAAA,EAAK,SAAA,EAAW,GAAG,MAAK,GAAI,OAAA;AACpC,EAAA,MAAM,QAAA,GAAW,QAAQ,cAAA,EAAe;AACxC,EAAA,KAAK,SAAS,IAAA,CAAK;AAAA,IAClB,SAAA;AAAA,IACA,GAAA;AAAA,IACA,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,CAAC,GAAG,mBAAmB,CAAA;AAAA,IACtC,wBAAA,EAA0B,IAAA;AAAA,IAC1B,aAAA,EAAe,EAAE,WAAA,EAAa,KAAA,EAAM;AAAA,IACpC,UAAA,EAAY,KAAA;AAAA,IACZ,iBAAA,EAAmB,KAAA;AAAA,IACnB,iBAAA,EAAmB,IAAA;AAAA,IACnB,eAAA,EAAiB,GAAA;AAAA,IACjB,GAAG;AAAA,GACmB,CAAA;AACvB,EAAA,OAAO,QAAA;AACR","file":"create-i18n.js","sourcesContent":["/**\n * Locale plumbing shared by the web SPA, the Electron shell and the plugin\n * SDK: the supported-language set and pure helpers. **This module must\n * stay free of catalog imports** — the sandboxed preload imports\n * `isSupportedLanguage` from here, and the catalogs (which weigh far\n * more than this file) live in `./catalogs.ts` (`CATALOGS`,\n * `catalogFor`), `./catalogs/ui.ts` (`UI_CATALOGS`, `uiCatalogFor`) plus\n * the per-language JSON modules.\n *\n * `catalogs/*.json` (the app `translation` namespace) and `ui/*.json`\n * (the shared `ui` namespace consumed by `@hoardodile/ui` and the plugin\n * SDK iframes) must stay in lockstep internally: identical flat key\n * sets, matching interpolation placeholders, and complete `_one`/`_other`\n * pairs. `src/parity.test.ts` enforces this — run it after touching any\n * catalog. `CATALOGS: Record<SupportedLanguage, typeof en>` and\n * `UI_CATALOGS: Record<SupportedLanguage, typeof uiEn>` additionally\n * make any key drift a compile error in `tsc`.\n */\nexport const SUPPORTED_LANGUAGES = [\"en\", \"zh\", \"ja\", \"de\", \"es\"] as const\nexport type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]\n\nexport function isSupportedLanguage(value: string): value is SupportedLanguage {\n\treturn (SUPPORTED_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * Map a BCP-47 locale string (e.g. `navigator.language`,\n * `app.getLocale()`, a stored pref) onto the supported set, taking the\n * base code: `\"ja-JP\"` → `\"ja\"`, `\"de-DE\"` → `\"de\"`, `\"es-MX\"` → `\"es\"`,\n * `\"zh-CN\"`/`\"zh-TW\"` → `\"zh\"` (any Chinese base maps to the `zh`\n * catalog, preserving historical behavior). Unknown or missing values\n * fall back to `\"en\"`.\n */\nexport function resolveSystemLanguage(\n\traw: string | undefined,\n): SupportedLanguage {\n\tconst base = raw?.toLowerCase().split(\"-\")[0]\n\tif (base !== undefined && isSupportedLanguage(base)) return base\n\treturn \"en\"\n}\n","/**\n * The i18next instance factory every React root uses: the web SPA, the\n * desktop wizard/shell pages, the workbench and the plugin SDK iframes\n * all boot their instance with the same options so catalog behavior\n * (fallback, plurals, interpolation, type safety) never diverges between\n * surfaces.\n *\n * This module is deliberately free of catalog imports — plugin iframe\n * bundles import the factory through this subpath and ship only the\n * small `ui`/`plugin` namespaces (the full app catalog would otherwise\n * be pulled into every bundle). Host surfaces use `createI18n` from\n * `@hoardodile/i18n`, which wraps this factory with the shared catalogs.\n *\n * React-free on purpose: the Electron main process and the sandboxed\n * preload keep using `catalogFor` / `uiCatalogFor` directly, and each\n * React root adds its own `react-i18next` binding (e.g.\n * `setI18n(instance)`).\n */\n\nimport i18next, { type i18n as I18nInstance, type InitOptions } from \"i18next\"\nimport { SUPPORTED_LANGUAGES } from \"./core.ts\"\n\nexport type CreateI18nOptions = Omit<InitOptions, \"lng\" | \"resources\"> & {\n\t/** Initial language; undefined lets i18next resolve its default (fallback → \"en\"). */\n\treadonly lng?: string\n\t/** Resource map — the shared catalogs (or the smaller ui/plugin set). */\n\treadonly resources: InitOptions[\"resources\"]\n}\n\n/**\n * Create an i18next instance with the canonical option set. Callers\n * supply the resources explicitly (hosts via the `@hoardodile/i18n`\n * wrapper, plugins via the SDK).\n */\nexport function createI18n(options: CreateI18nOptions): I18nInstance {\n\tconst { lng, resources, ...rest } = options\n\tconst instance = i18next.createInstance()\n\tvoid instance.init({\n\t\tresources,\n\t\tlng,\n\t\tfallbackLng: \"en\",\n\t\tsupportedLngs: [...SUPPORTED_LANGUAGES],\n\t\tnonExplicitSupportedLngs: true,\n\t\tinterpolation: { escapeValue: false },\n\t\treturnNull: false,\n\t\treturnEmptyString: false,\n\t\tcompatibilityJSON: \"v4\",\n\t\tpluralSeparator: \"_\",\n\t\t...rest,\n\t} satisfies InitOptions)\n\treturn instance\n}\n"]}
1
+ {"version":3,"sources":["../src/core.ts","../src/create-i18n.ts"],"names":[],"mappings":";;;;;AAkBO,IAAM,sBAAsB,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;;;ACgBzD,SAAS,WAAW,OAAA,EAA0C;AACpE,EAAA,MAAM,EAAE,GAAA,EAAK,SAAA,EAAW,GAAG,MAAK,GAAI,OAAA;AACpC,EAAA,MAAM,QAAA,GAAW,QAAQ,cAAA,EAAe;AACxC,EAAA,KAAK,SAAS,IAAA,CAAK;AAAA,IAClB,SAAA;AAAA,IACA,GAAA;AAAA,IACA,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,CAAC,GAAG,mBAAmB,CAAA;AAAA,IACtC,wBAAA,EAA0B,IAAA;AAAA,IAC1B,aAAA,EAAe,EAAE,WAAA,EAAa,KAAA,EAAM;AAAA,IACpC,UAAA,EAAY,KAAA;AAAA,IACZ,iBAAA,EAAmB,KAAA;AAAA,IACnB,iBAAA,EAAmB,IAAA;AAAA,IACnB,eAAA,EAAiB,GAAA;AAAA,IACjB,GAAG;AAAA,GACmB,CAAA;AACvB,EAAA,OAAO,QAAA;AACR","file":"create-i18n.js","sourcesContent":["/**\n * Locale plumbing shared by the web SPA, the Electron shell and the plugin\n * SDK: the supported-language set and pure helpers. **This module must\n * stay free of catalog imports** — the sandboxed preload imports\n * `isSupportedLanguage` from here, and the catalogs (which weigh far\n * more than this file) live in `./catalogs.ts` (`CATALOGS`,\n * `catalogFor`), `./catalogs/ui.ts` (`UI_CATALOGS`, `uiCatalogFor`) plus\n * the per-language JSON modules.\n *\n * `catalogs/*.json` (the app `translation` namespace) and `ui/*.json`\n * (the shared `ui` namespace consumed by `@hoardodile/ui` and the plugin\n * SDK iframes) must stay in lockstep internally: identical flat key\n * sets, matching interpolation placeholders, and complete `_one`/`_other`\n * pairs. `src/parity.test.ts` enforces this — run it after touching any\n * catalog. `CATALOGS: Record<SupportedLanguage, typeof en>` and\n * `UI_CATALOGS: Record<SupportedLanguage, typeof uiEn>` additionally\n * make any key drift a compile error in `tsc`.\n */\nexport const SUPPORTED_LANGUAGES = [\"en\", \"zh\", \"ja\", \"de\", \"es\"] as const\nexport type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]\n\nexport function isSupportedLanguage(value: string): value is SupportedLanguage {\n\treturn (SUPPORTED_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * Catalog key for each supported language's display name in its own\n * script (`language.english` → \"English\", `language.chinese` → \"中文\", …).\n * The `language.*` catalog keys are named (not BCP-47 codes), so build the\n * `t()` key through this map rather than interpolating the code.\n */\nexport const LANGUAGE_LABEL_KEYS = {\n\ten: \"language.english\",\n\tzh: \"language.chinese\",\n\tja: \"language.japanese\",\n\tde: \"language.german\",\n\tes: \"language.spanish\",\n} as const satisfies Record<SupportedLanguage, string>\n\n/**\n * Map a BCP-47 locale string (e.g. `navigator.language`,\n * `app.getLocale()`, a stored pref) onto the supported set, taking the\n * base code: `\"ja-JP\"` → `\"ja\"`, `\"de-DE\"` → `\"de\"`, `\"es-MX\"` → `\"es\"`,\n * `\"zh-CN\"`/`\"zh-TW\"` → `\"zh\"` (any Chinese base maps to the `zh`\n * catalog, preserving historical behavior). Unknown or missing values\n * fall back to `\"en\"`.\n */\nexport function resolveSystemLanguage(\n\traw: string | undefined,\n): SupportedLanguage {\n\tconst base = raw?.toLowerCase().split(\"-\")[0]\n\tif (base !== undefined && isSupportedLanguage(base)) return base\n\treturn \"en\"\n}\n","/**\n * The i18next instance factory every React root uses: the web SPA, the\n * desktop wizard/shell pages, the workbench and the plugin SDK iframes\n * all boot their instance with the same options so catalog behavior\n * (fallback, plurals, interpolation, type safety) never diverges between\n * surfaces.\n *\n * This module is deliberately free of catalog imports — plugin iframe\n * bundles import the factory through this subpath and ship only the\n * small `ui`/`plugin` namespaces (the full app catalog would otherwise\n * be pulled into every bundle). Host surfaces use `createI18n` from\n * `@hoardodile/i18n`, which wraps this factory with the shared catalogs.\n *\n * React-free on purpose: the Electron main process and the sandboxed\n * preload keep using `catalogFor` / `uiCatalogFor` directly, and each\n * React root adds its own `react-i18next` binding (e.g.\n * `setI18n(instance)`).\n */\n\nimport i18next, { type i18n as I18nInstance, type InitOptions } from \"i18next\"\nimport { SUPPORTED_LANGUAGES } from \"./core.ts\"\n\nexport type CreateI18nOptions = Omit<InitOptions, \"lng\" | \"resources\"> & {\n\t/** Initial language; undefined lets i18next resolve its default (fallback → \"en\"). */\n\treadonly lng?: string\n\t/** Resource map — the shared catalogs (or the smaller ui/plugin set). */\n\treadonly resources: InitOptions[\"resources\"]\n}\n\n/**\n * Create an i18next instance with the canonical option set. Callers\n * supply the resources explicitly (hosts via the `@hoardodile/i18n`\n * wrapper, plugins via the SDK).\n */\nexport function createI18n(options: CreateI18nOptions): I18nInstance {\n\tconst { lng, resources, ...rest } = options\n\tconst instance = i18next.createInstance()\n\tvoid instance.init({\n\t\tresources,\n\t\tlng,\n\t\tfallbackLng: \"en\",\n\t\tsupportedLngs: [...SUPPORTED_LANGUAGES],\n\t\tnonExplicitSupportedLngs: true,\n\t\tinterpolation: { escapeValue: false },\n\t\treturnNull: false,\n\t\treturnEmptyString: false,\n\t\tcompatibilityJSON: \"v4\",\n\t\tpluralSeparator: \"_\",\n\t\t...rest,\n\t} satisfies InitOptions)\n\treturn instance\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { e as en } from './catalogs-P15rGrmg.js';
2
- export { C as CATALOGS, c as catalogFor } from './catalogs-P15rGrmg.js';
1
+ import { e as en } from './catalogs-DkcPbpdW.js';
2
+ export { C as CATALOGS, c as catalogFor } from './catalogs-DkcPbpdW.js';
3
3
  import { u as uiEn } from './ui-DYXLhqSV.js';
4
4
  export { U as UI_CATALOGS, a as uiCatalogFor } from './ui-DYXLhqSV.js';
5
5
  import { i18n } from 'i18next';
6
6
  import { CreateI18nOptions } from './create-i18n.js';
7
- export { SUPPORTED_LANGUAGES, SupportedLanguage, isSupportedLanguage, resolveSystemLanguage } from './core.js';
7
+ export { LANGUAGE_LABEL_KEYS, SUPPORTED_LANGUAGES, SupportedLanguage, isSupportedLanguage, resolveSystemLanguage } from './core.js';
8
8
 
9
9
  /**
10
10
  * Type the `t()` keys of every consumer against the catalogs: a wrong key