@intlayer/i18next 8.12.5-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createInstance.cjs","names":["ANSIColors","internationalization","resolveTranslation","getInterpolationValues"],"sources":["../../src/createInstance.ts"],"sourcesContent":["import { internationalization, log } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getIntlayer } from '@intlayer/core/interpreter';\nimport { resolveMessage } from '@intlayer/core/messageFormat';\nimport type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n createInstance as _createInstance,\n i18n as I18nInterface,\n InitOptions,\n TOptions,\n} from 'i18next';\nimport {\n getInterpolationValues,\n resolveTranslation,\n} from './resolveTranslation';\n\ntype EventHandler = (...args: unknown[]) => void;\n\nconst navigatePath = (obj: unknown, path: string): unknown => {\n if (!path) return obj;\n let current: unknown = obj;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\nconst warnIgnoredResources = (location: string) => {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize(location, ANSIColors.CYAN)}: the ${colorize('`resources`', ANSIColors.CYAN)} option is ignored when using ${colorize('@intlayer/i18next', ANSIColors.MAGENTA)} — translations are served from the compiled intlayer dictionaries instead. Remove the resource imports and the ${colorize('`resources`', ANSIColors.CYAN)} option to reduce your bundle size.`\n );\n};\n\nexport const createInstance: typeof _createInstance = (\n instanceOptions: InitOptions = {}\n): I18nInterface => {\n if ((instanceOptions as Record<string, unknown>).resources !== undefined) {\n warnIgnoredResources('createInstance');\n }\n\n const config = internationalization;\n\n let currentLanguage: string =\n (instanceOptions.lng as string) ?? config?.defaultLocale ?? 'en';\n\n let defaultNS: string =\n (instanceOptions.defaultNS as string) ??\n (Array.isArray(instanceOptions.ns)\n ? (instanceOptions.ns[0] as string)\n : (instanceOptions.ns as string)) ??\n 'translation';\n\n const listeners = new Map<string, Set<EventHandler>>();\n let initialized = false;\n\n const emit = (event: string, ...args: unknown[]) => {\n listeners.get(event)?.forEach((h) => {\n h(...args);\n });\n };\n\n const getSeparators = () => ({\n keySeparator:\n (instanceOptions.keySeparator as string | false | undefined) ?? '.',\n nsSeparator:\n (instanceOptions.nsSeparator as string | false | undefined) ?? ':',\n });\n\n /**\n * Resolves a key through the full i18next pipeline (namespace prefix,\n * `ns` option, plural/context suffixes, `$t()` nesting, interpolation).\n * Falls back to the interpolated `defaultValue`, then to the key itself.\n */\n const resolveKey = (\n lang: string,\n ns: string,\n key: string,\n opts?: TOptions | string\n ): string => {\n const options =\n typeof opts === 'string' ? { defaultValue: opts } : (opts as TOptions);\n\n const resolved = resolveTranslation({\n locale: lang as LocalesValues,\n namespace: ns,\n key,\n options,\n ...getSeparators(),\n });\n\n if (resolved !== undefined) return resolved as string;\n\n const defaultValue = (options as Record<string, unknown> | undefined)\n ?.defaultValue;\n if (typeof defaultValue === 'string') {\n return resolveMessage(\n defaultValue,\n getInterpolationValues(options),\n lang as LocalesValues,\n 'i18next'\n );\n }\n\n return key;\n };\n\n const instance = {\n get language() {\n return currentLanguage;\n },\n get languages() {\n return (config?.locales?.map(String) ?? [\n currentLanguage,\n ]) as readonly string[];\n },\n get resolvedLanguage() {\n return currentLanguage;\n },\n get isInitialized() {\n return initialized;\n },\n isInitializing: false,\n initializedStoreOnce: false,\n initializedLanguageOnce: false,\n options: instanceOptions,\n modules: {} as I18nInterface['modules'],\n services: {} as I18nInterface['services'],\n store: {} as I18nInterface['store'],\n format: ((value: unknown) => String(value)) as I18nInterface['format'],\n\n async init(optionsOrCb?: unknown, cb?: unknown) {\n const opts =\n typeof optionsOrCb === 'function'\n ? {}\n : ((optionsOrCb ?? {}) as Record<string, unknown>);\n if (opts.resources !== undefined) {\n warnIgnoredResources('i18next.init');\n }\n if (opts.lng) currentLanguage = opts.lng as string;\n if (opts.defaultNS) defaultNS = opts.defaultNS as string;\n else if (opts.ns)\n defaultNS = Array.isArray(opts.ns)\n ? (opts.ns[0] as string)\n : (opts.ns as string);\n initialized = true;\n emit('initialized', opts);\n const t = instance.t.bind(instance);\n const callback = typeof optionsOrCb === 'function' ? optionsOrCb : cb;\n (callback as ((err: unknown, t: unknown) => void) | undefined)?.(null, t);\n return t as unknown as Promise<I18nInterface['t']>;\n },\n\n t(\n key: unknown,\n optionsOrDefaultValue?: unknown,\n extraOpts?: unknown\n ): unknown {\n const options =\n typeof optionsOrDefaultValue === 'string'\n ? {\n defaultValue: optionsOrDefaultValue,\n ...((extraOpts ?? {}) as Record<string, unknown>),\n }\n : (optionsOrDefaultValue as TOptions | undefined);\n const keys: string[] = Array.isArray(key)\n ? (key as string[])\n : [String(key)];\n for (const candidateKey of keys) {\n const result = resolveTranslation({\n locale: currentLanguage as LocalesValues,\n namespace: defaultNS,\n key: candidateKey,\n options,\n ...getSeparators(),\n });\n if (result !== undefined) return result;\n }\n\n const defaultValue = (options as Record<string, unknown> | undefined)\n ?.defaultValue;\n if (typeof defaultValue === 'string') {\n return resolveMessage(\n defaultValue,\n getInterpolationValues(options),\n currentLanguage as LocalesValues,\n 'i18next'\n );\n }\n\n return defaultValue ?? (Array.isArray(key) ? key[key.length - 1] : key);\n },\n\n async changeLanguage(lng?: string, cb?: unknown) {\n const prev = currentLanguage;\n if (lng) currentLanguage = lng;\n emit('languageChanged', currentLanguage, prev);\n const t = instance.t.bind(instance);\n (cb as ((err: unknown, t: unknown) => void) | undefined)?.(null, t);\n return t as unknown as Promise<I18nInterface['t']>;\n },\n\n exists(key: string, options?: unknown): boolean {\n return (\n resolveTranslation({\n locale: currentLanguage as LocalesValues,\n namespace: defaultNS,\n key,\n options: options as TOptions,\n ...getSeparators(),\n }) !== undefined\n );\n },\n\n /**\n * Returns a `t()` function bound to a fixed locale and namespace.\n * When `ns` matches a registered intlayer dictionary key, the returned\n * function's `key` parameter is typed to only accept valid dot-notation\n * paths for that dictionary.\n *\n * @example\n * ```ts\n * const tAbout = i18n.getFixedT(null, 'about');\n * tAbout('counter.label'); // ✓ typed\n * ```\n */\n getFixedT<N extends DictionaryKeys>(\n lng: string | readonly string[] | null,\n ns?: N | null,\n keyPrefix?: string\n ): <P extends ValidDotPathsFor<N>>(key: P, opts?: TOptions) => string {\n const fixedLng = Array.isArray(lng)\n ? ((lng[0] as string) ?? currentLanguage)\n : ((lng as string) ?? currentLanguage);\n const fixedNS = (ns as string) ?? defaultNS;\n return <P extends ValidDotPathsFor<N>>(\n key: P,\n opts?: TOptions\n ): string => {\n const fullKey = keyPrefix ? `${keyPrefix}.${String(key)}` : String(key);\n return resolveKey(fixedLng, fixedNS, fullKey, opts);\n };\n },\n\n use(module: unknown) {\n (module as { init?: (i18n: I18nInterface) => void })?.init?.(\n instance as unknown as I18nInterface\n );\n return instance as unknown as I18nInterface;\n },\n\n on(event: string, handler: EventHandler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n return instance as unknown as I18nInterface;\n },\n\n once(event: string, handler: EventHandler) {\n const wrapper: EventHandler = (...args) => {\n handler(...args);\n instance.off(event, wrapper);\n };\n instance.on(event, wrapper);\n return instance as unknown as I18nInterface;\n },\n\n off(event: string, handler?: EventHandler) {\n if (!handler) listeners.delete(event);\n else listeners.get(event)?.delete(handler);\n },\n\n emit(eventName: string, ...args: unknown[]) {\n emit(eventName, ...args);\n },\n\n createInstance(opts?: InitOptions, _cb?: unknown) {\n return createInstance({ ...instanceOptions, ...opts });\n },\n\n cloneInstance(opts?: Record<string, unknown>, _cb?: unknown) {\n return createInstance({ ...instanceOptions, ...opts });\n },\n\n dir(lng?: string): 'ltr' | 'rtl' {\n const rtl = ['ar', 'he', 'fa', 'ur', 'ps', 'yi', 'dv', 'ug'];\n return rtl.some((l) => (lng ?? currentLanguage).startsWith(l))\n ? 'rtl'\n : 'ltr';\n },\n\n setDefaultNamespace(ns: string) {\n defaultNS = ns;\n },\n\n hasLoadedNamespace(ns: string | readonly string[]): boolean {\n try {\n getIntlayer(\n (Array.isArray(ns) ? ns[0] : ns) as DictionaryKeys,\n currentLanguage as LocalesValues\n );\n return true;\n } catch {\n return false;\n }\n },\n\n async loadNamespaces(_ns: unknown) {},\n async loadLanguages(_lngs: unknown) {},\n loadResources(_cb?: unknown) {},\n async reloadResources() {},\n\n getDataByLanguage(_lng: string) {\n return undefined;\n },\n\n getResource(lng: string, ns: string, key: string): unknown {\n try {\n return navigatePath(\n getIntlayer(ns as DictionaryKeys, lng as LocalesValues),\n key\n );\n } catch {\n return undefined;\n }\n },\n\n addResource: () => instance as unknown as I18nInterface,\n addResources: () => instance as unknown as I18nInterface,\n addResourceBundle: () => instance as unknown as I18nInterface,\n hasResourceBundle: () => false,\n getResourceBundle: () => undefined,\n removeResourceBundle: () => instance as unknown as I18nInterface,\n\n toJSON() {\n return {\n options: instanceOptions,\n store: {} as I18nInterface['store'],\n language: currentLanguage,\n languages: (config?.locales?.map(String) ?? [\n currentLanguage,\n ]) as readonly string[],\n resolvedLanguage: currentLanguage,\n };\n },\n };\n\n return instance as unknown as I18nInterface;\n};\n\n/** Typed variant of i18next's `getFixedT`, scoped to an intlayer dictionary namespace. */\nexport type TypedGetFixedT = <N extends DictionaryKeys>(\n lng: string | readonly string[] | null,\n ns?: N | null,\n keyPrefix?: string\n) => <P extends ValidDotPathsFor<N>>(key: P, opts?: TOptions) => string;\n"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+ const require_resolveTranslation = require('./resolveTranslation.cjs');
3
+ const require_createInstance = require('./createInstance.cjs');
4
+ let react_i18next = require("react-i18next");
5
+
6
+ //#region src/index.ts
7
+ const i18next = require_createInstance.createInstance();
8
+ const dir = i18next.dir.bind(i18next);
9
+ const init = i18next.init.bind(i18next);
10
+ const loadResources = i18next.loadResources.bind(i18next);
11
+ const reloadResources = i18next.reloadResources.bind(i18next);
12
+ const use = i18next.use.bind(i18next);
13
+ const changeLanguage = i18next.changeLanguage.bind(i18next);
14
+ /**
15
+ * Returns a `t()` function bound to a fixed locale and namespace.
16
+ * When `ns` matches a registered intlayer dictionary key, the returned
17
+ * function's `key` parameter is typed to only accept valid dot-notation
18
+ * paths for that dictionary.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const tAbout = getFixedT(null, 'about');
23
+ * tAbout('counter.label'); // ✓ typed
24
+ * ```
25
+ */
26
+ const getFixedT = i18next.getFixedT.bind(i18next);
27
+ const t = i18next.t.bind(i18next);
28
+ const exists = i18next.exists.bind(i18next);
29
+ const setDefaultNamespace = i18next.setDefaultNamespace.bind(i18next);
30
+ const hasLoadedNamespace = i18next.hasLoadedNamespace.bind(i18next);
31
+ const loadNamespaces = i18next.loadNamespaces.bind(i18next);
32
+ const loadLanguages = i18next.loadLanguages.bind(i18next);
33
+ /**
34
+ * No-op shim for i18next's `keyFromSelector`. This helper is not exposed by
35
+ * every supported i18next version, so a permissive identity function is
36
+ * provided to keep `.keyFromSelector(...)` call-sites working.
37
+ */
38
+ const keyFromSelector = (selector) => selector;
39
+
40
+ //#endregion
41
+ exports.changeLanguage = changeLanguage;
42
+ exports.createInstance = require_createInstance.createInstance;
43
+ exports.default = i18next;
44
+ exports.i18next = i18next;
45
+ exports.dir = dir;
46
+ exports.exists = exists;
47
+ exports.getFixedT = getFixedT;
48
+ exports.getInterpolationValues = require_resolveTranslation.getInterpolationValues;
49
+ exports.hasLoadedNamespace = hasLoadedNamespace;
50
+ exports.init = init;
51
+ Object.defineProperty(exports, 'initReactI18next', {
52
+ enumerable: true,
53
+ get: function () {
54
+ return react_i18next.initReactI18next;
55
+ }
56
+ });
57
+ exports.keyFromSelector = keyFromSelector;
58
+ exports.loadLanguages = loadLanguages;
59
+ exports.loadNamespaces = loadNamespaces;
60
+ exports.loadResources = loadResources;
61
+ exports.reloadResources = reloadResources;
62
+ exports.resolveTranslation = require_resolveTranslation.resolveTranslation;
63
+ exports.setDefaultNamespace = setDefaultNamespace;
64
+ exports.t = t;
65
+ exports.use = use;
66
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["createInstance"],"sources":["../../src/index.ts"],"sourcesContent":["import type {\n changeLanguage as _changeLanguage,\n dir as _dir,\n exists as _exists,\n hasLoadedNamespace as _hasLoadedNamespace,\n init as _init,\n loadLanguages as _loadLanguages,\n loadNamespaces as _loadNamespaces,\n loadResources as _loadResources,\n reloadResources as _reloadResources,\n setDefaultNamespace as _setDefaultNamespace,\n t as _t,\n use as _use,\n i18n,\n} from 'i18next';\nimport { createInstance, type TypedGetFixedT } from './createInstance';\n\nexport {\n getInterpolationValues,\n type ResolveTranslationParams,\n resolveTranslation,\n} from './resolveTranslation';\n\nconst i18next: i18n = createInstance();\n\nexport { createInstance };\nexport default i18next;\nexport { i18next };\n\nexport const dir: typeof _dir = i18next.dir.bind(i18next);\nexport const init: typeof _init = i18next.init.bind(i18next);\nexport const loadResources: typeof _loadResources =\n i18next.loadResources.bind(i18next);\nexport const reloadResources: typeof _reloadResources =\n i18next.reloadResources.bind(i18next);\nexport const use: typeof _use = i18next.use.bind(i18next);\nexport const changeLanguage: typeof _changeLanguage =\n i18next.changeLanguage.bind(i18next);\n\n/**\n * Returns a `t()` function bound to a fixed locale and namespace.\n * When `ns` matches a registered intlayer dictionary key, the returned\n * function's `key` parameter is typed to only accept valid dot-notation\n * paths for that dictionary.\n *\n * @example\n * ```ts\n * const tAbout = getFixedT(null, 'about');\n * tAbout('counter.label'); // ✓ typed\n * ```\n */\nexport const getFixedT: TypedGetFixedT = i18next.getFixedT.bind(\n i18next\n) as TypedGetFixedT;\n\nexport const t: typeof _t = i18next.t.bind(i18next);\nexport const exists: typeof _exists = i18next.exists.bind(i18next);\nexport const setDefaultNamespace: typeof _setDefaultNamespace =\n i18next.setDefaultNamespace.bind(i18next);\nexport const hasLoadedNamespace: typeof _hasLoadedNamespace =\n i18next.hasLoadedNamespace.bind(i18next);\nexport const loadNamespaces: typeof _loadNamespaces =\n i18next.loadNamespaces.bind(i18next);\nexport const loadLanguages: typeof _loadLanguages =\n i18next.loadLanguages.bind(i18next);\n\n/**\n * No-op shim for i18next's `keyFromSelector`. This helper is not exposed by\n * every supported i18next version, so a permissive identity function is\n * provided to keep `.keyFromSelector(...)` call-sites working.\n */\nexport const keyFromSelector = (selector: unknown): unknown => selector;\n\nexport type { InitOptions, i18n, TFunction, TOptions } from 'i18next';\nexport { initReactI18next } from 'react-i18next';\n"],"mappings":";;;;;;AAuBA,MAAM,UAAgBA,sCAAe;AAMrC,MAAa,MAAmB,QAAQ,IAAI,KAAK,OAAO;AACxD,MAAa,OAAqB,QAAQ,KAAK,KAAK,OAAO;AAC3D,MAAa,gBACX,QAAQ,cAAc,KAAK,OAAO;AACpC,MAAa,kBACX,QAAQ,gBAAgB,KAAK,OAAO;AACtC,MAAa,MAAmB,QAAQ,IAAI,KAAK,OAAO;AACxD,MAAa,iBACX,QAAQ,eAAe,KAAK,OAAO;;;;;;;;;;;;;AAcrC,MAAa,YAA4B,QAAQ,UAAU,KACzD,OACF;AAEA,MAAa,IAAe,QAAQ,EAAE,KAAK,OAAO;AAClD,MAAa,SAAyB,QAAQ,OAAO,KAAK,OAAO;AACjE,MAAa,sBACX,QAAQ,oBAAoB,KAAK,OAAO;AAC1C,MAAa,qBACX,QAAQ,mBAAmB,KAAK,OAAO;AACzC,MAAa,iBACX,QAAQ,eAAe,KAAK,OAAO;AACrC,MAAa,gBACX,QAAQ,cAAc,KAAK,OAAO;;;;;;AAOpC,MAAa,mBAAmB,aAA+B"}
@@ -0,0 +1,74 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let _intlayer_config_colors = require("@intlayer/config/colors");
4
+ _intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
5
+ let _intlayer_config_logger = require("@intlayer/config/logger");
6
+ let node_path = require("node:path");
7
+ let _intlayer_chokidar_utils = require("@intlayer/chokidar/utils");
8
+ let _intlayer_config_node = require("@intlayer/config/node");
9
+ let vite_intlayer = require("vite-intlayer");
10
+
11
+ //#region src/plugin/index.ts
12
+ /**
13
+ * A Vite plugin for the i18next compat adapter that wraps `vite-intlayer`
14
+ * and registers a resolve alias mapping `i18next` to `@intlayer/i18next`.
15
+ *
16
+ * This lets an existing i18next codebase migrate to intlayer without
17
+ * rewriting any `import ... from 'i18next'` statements — they are
18
+ * transparently redirected to the compat adapter at build time.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * // vite.config.ts
23
+ * import i18nextVitePlugin from '@intlayer/i18next/plugin';
24
+ *
25
+ * export default defineConfig({
26
+ * plugins: [i18nextVitePlugin()],
27
+ * });
28
+ * ```
29
+ */
30
+ /**
31
+ * Caller configurations for i18next's `getFixedT` method.
32
+ *
33
+ * Tells the intlayer field-usage analyser how to extract the dictionary key
34
+ * (namespace) and optional key prefix from `i18n.getFixedT(lng, ns, prefix)`
35
+ * call sites, enabling accurate dictionary pruning for projects using
36
+ * `@intlayer/i18next`.
37
+ */
38
+ const I18NEXT_COMPAT_CALLERS = [{
39
+ callerName: "getFixedT",
40
+ importSources: ["i18next", "@intlayer/i18next"],
41
+ matchAsMethod: true,
42
+ namespace: {
43
+ from: "argument",
44
+ index: 1
45
+ },
46
+ keyPrefix: {
47
+ from: "argument",
48
+ index: 2
49
+ },
50
+ translationFunction: "return-value"
51
+ }];
52
+ const i18nextVitePlugin = (options) => {
53
+ const intlayerConfig = (0, _intlayer_config_node.getConfiguration)();
54
+ const appLogger = (0, _intlayer_config_logger.getAppLogger)(intlayerConfig);
55
+ (0, _intlayer_chokidar_utils.runOnce)((0, node_path.join)(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
56
+ appLogger([(0, _intlayer_config_logger.colorize)("Please report any issues you met on GitHub:", _intlayer_config_colors.GREY), (0, _intlayer_config_logger.colorize)("https://github.com/aymericzip/intlayer/issues", _intlayer_config_colors.GREY_LIGHT)]);
57
+ }, { cacheTimeoutMs: 1e3 * 60 * 60 });
58
+ const basePlugins = (0, vite_intlayer.intlayer)({
59
+ ...options,
60
+ compatCallers: [...options?.compatCallers ?? [], ...I18NEXT_COMPAT_CALLERS]
61
+ });
62
+ const compatPlugin = {
63
+ name: "vite-i18next-compat-plugin",
64
+ config: () => {
65
+ return { resolve: { alias: { i18next: "@intlayer/i18next" } } };
66
+ }
67
+ };
68
+ return [...Array.isArray(basePlugins) ? basePlugins : [basePlugins], compatPlugin];
69
+ };
70
+
71
+ //#endregion
72
+ exports.default = i18nextVitePlugin;
73
+ exports.i18nextVitePlugin = i18nextVitePlugin;
74
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["ANSIColors"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { runOnce } from '@intlayer/chokidar/utils';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { PluginOption } from 'vite';\nimport { type CompatCallerConfig, intlayer } from 'vite-intlayer';\n\n/**\n * A Vite plugin for the i18next compat adapter that wraps `vite-intlayer`\n * and registers a resolve alias mapping `i18next` to `@intlayer/i18next`.\n *\n * This lets an existing i18next codebase migrate to intlayer without\n * rewriting any `import ... from 'i18next'` statements — they are\n * transparently redirected to the compat adapter at build time.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import i18nextVitePlugin from '@intlayer/i18next/plugin';\n *\n * export default defineConfig({\n * plugins: [i18nextVitePlugin()],\n * });\n * ```\n */\n\n/**\n * Caller configurations for i18next's `getFixedT` method.\n *\n * Tells the intlayer field-usage analyser how to extract the dictionary key\n * (namespace) and optional key prefix from `i18n.getFixedT(lng, ns, prefix)`\n * call sites, enabling accurate dictionary pruning for projects using\n * `@intlayer/i18next`.\n */\nconst I18NEXT_COMPAT_CALLERS: CompatCallerConfig[] = [\n {\n callerName: 'getFixedT',\n importSources: ['i18next', '@intlayer/i18next'],\n matchAsMethod: true,\n namespace: { from: 'argument', index: 1 },\n keyPrefix: { from: 'argument', index: 2 },\n translationFunction: 'return-value',\n },\n];\n\nexport const i18nextVitePlugin = (\n options?: Parameters<typeof intlayer>[0]\n): PluginOption[] => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const basePlugins = intlayer({\n ...options,\n compatCallers: [\n ...(options?.compatCallers ?? []),\n ...I18NEXT_COMPAT_CALLERS,\n ],\n });\n\n const compatPlugin: PluginOption = {\n name: 'vite-i18next-compat-plugin',\n config: () => {\n return {\n resolve: {\n alias: {\n i18next: '@intlayer/i18next',\n },\n },\n };\n },\n };\n\n return [\n ...(Array.isArray(basePlugins) ? basePlugins : [basePlugins]),\n compatPlugin,\n ];\n};\n\nexport default i18nextVitePlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAM,yBAA+C,CACnD;CACE,YAAY;CACZ,eAAe,CAAC,WAAW,mBAAmB;CAC9C,eAAe;CACf,WAAW;EAAE,MAAM;EAAY,OAAO;CAAE;CACxC,WAAW;EAAE,MAAM;EAAY,OAAO;CAAE;CACxC,qBAAqB;AACvB,CACF;AAEA,MAAa,qBACX,YACmB;CACnB,MAAM,6DAAkC;CACxC,MAAM,sDAAyB,cAAc;CAE7C,0DAEI,eAAe,OAAO,SACtB,aACA,SACA,iCACF,SACM;EACJ,UAAU,uCAEN,+CACAA,wBAAW,IACb,yCAEE,iDACAA,wBAAW,UACb,CACF,CAAC;CACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;CAEA,MAAM,0CAAuB;EAC3B,GAAG;EACH,eAAe,CACb,GAAI,SAAS,iBAAiB,CAAC,GAC/B,GAAG,sBACL;CACF,CAAC;CAED,MAAM,eAA6B;EACjC,MAAM;EACN,cAAc;GACZ,OAAO,EACL,SAAS,EACP,OAAO,EACL,SAAS,oBACX,EACF,EACF;EACF;CACF;CAEA,OAAO,CACL,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW,GAC3D,YACF;AACF"}
@@ -0,0 +1,142 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
3
+ let _intlayer_core_messageFormat = require("@intlayer/core/messageFormat");
4
+
5
+ //#region src/resolveTranslation.ts
6
+ /**
7
+ * Shared i18next-dialect translation resolution.
8
+ *
9
+ * Implements the i18next lookup pipeline on top of intlayer dictionaries:
10
+ * namespace prefix (`ns:key`), `ns` option override, plural suffixes
11
+ * (`key_one`, `key_other`, …) via `Intl.PluralRules`, context suffixes
12
+ * (`key_male`), `$t()` nesting, `defaultValue` and `{{var}}` interpolation.
13
+ *
14
+ * Used by `@intlayer/i18next` (instance `t`) and `@intlayer/react-i18next`
15
+ * (`useTranslation`, `<Trans>`).
16
+ */
17
+ /** Option keys that are control flags, never interpolation values. */
18
+ const CONTROL_OPTION_KEYS = new Set([
19
+ "defaultValue",
20
+ "ns",
21
+ "lng",
22
+ "lngs",
23
+ "fallbackLng",
24
+ "returnObjects",
25
+ "returnDetails",
26
+ "keySeparator",
27
+ "nsSeparator",
28
+ "ordinal",
29
+ "postProcess",
30
+ "postProcessPassResolved",
31
+ "interpolation",
32
+ "replace",
33
+ "joinArrays",
34
+ "nsMode",
35
+ "keyPrefix"
36
+ ]);
37
+ /** Maximum `$t()` nesting recursion depth. */
38
+ const MAX_NESTING_DEPTH = 5;
39
+ const navigatePath = (objectValue, path, keySeparator = ".") => {
40
+ if (!path) return objectValue;
41
+ const parts = keySeparator === false ? [path] : path.split(keySeparator);
42
+ let current = objectValue;
43
+ for (const part of parts) {
44
+ if (current === null || current === void 0 || typeof current !== "object") return;
45
+ current = current[part];
46
+ }
47
+ return current;
48
+ };
49
+ /**
50
+ * Builds the ordered list of key candidates following i18next's resolution
51
+ * order: context + plural → context → plural → exact key.
52
+ */
53
+ const buildKeyCandidates = (path, locale, count, context, ordinal) => {
54
+ const candidates = [];
55
+ const pluralCategory = count === void 0 ? void 0 : new Intl.PluralRules(locale, { type: ordinal ? "ordinal" : "cardinal" }).select(count);
56
+ if (context) {
57
+ if (pluralCategory) {
58
+ if (ordinal) candidates.push(`${path}_${context}_ordinal_${pluralCategory}`);
59
+ candidates.push(`${path}_${context}_${pluralCategory}`);
60
+ if (count !== 1) candidates.push(`${path}_${context}_plural`);
61
+ }
62
+ candidates.push(`${path}_${context}`);
63
+ }
64
+ if (pluralCategory) {
65
+ if (ordinal) candidates.push(`${path}_ordinal_${pluralCategory}`);
66
+ candidates.push(`${path}_${pluralCategory}`);
67
+ if (count !== 1) candidates.push(`${path}_plural`);
68
+ }
69
+ candidates.push(path);
70
+ return candidates;
71
+ };
72
+ /** Extracts interpolation values from i18next `t()` options. */
73
+ const getInterpolationValues = (options) => {
74
+ if (!options || typeof options !== "object") return {};
75
+ const replace = options.replace;
76
+ if (replace) {
77
+ const values = { ...replace };
78
+ if (options.count !== void 0) values.count ??= options.count;
79
+ if (options.context !== void 0) values.context ??= options.context;
80
+ return values;
81
+ }
82
+ const values = {};
83
+ for (const [optionKey, optionValue] of Object.entries(options)) if (!CONTROL_OPTION_KEYS.has(optionKey)) values[optionKey] = optionValue;
84
+ return values;
85
+ };
86
+ /**
87
+ * Resolves a single translation key the i18next way against intlayer
88
+ * dictionaries.
89
+ *
90
+ * Returns the resolved value: a string in the common case, or an
91
+ * object/array when `returnObjects: true`. Returns `undefined` when the key
92
+ * cannot be resolved (caller decides between `defaultValue`, fallback keys
93
+ * and key echo).
94
+ */
95
+ const resolveTranslation = ({ locale, namespace, key, options, keySeparator = ".", nsSeparator = ":", depth = 0 }) => {
96
+ let targetNamespace = namespace;
97
+ let path = key;
98
+ if (nsSeparator !== false && key.includes(nsSeparator)) {
99
+ const separatorIndex = key.indexOf(nsSeparator);
100
+ targetNamespace = key.slice(0, separatorIndex);
101
+ path = key.slice(separatorIndex + nsSeparator.length);
102
+ } else if (options?.ns) targetNamespace = Array.isArray(options.ns) ? options.ns[0] : options.ns;
103
+ const count = typeof options?.count === "number" ? options.count : void 0;
104
+ const context = options?.context !== void 0 ? String(options.context) : void 0;
105
+ const ordinal = options?.ordinal === true;
106
+ let dictionary;
107
+ try {
108
+ dictionary = (0, _intlayer_core_interpreter.getIntlayer)(targetNamespace, options?.lng ?? locale);
109
+ } catch {
110
+ return;
111
+ }
112
+ let resolvedValue;
113
+ for (const candidate of buildKeyCandidates(path, options?.lng ?? locale, count, context, ordinal)) {
114
+ const value = navigatePath(dictionary, candidate, keySeparator);
115
+ if (value !== null && value !== void 0) {
116
+ resolvedValue = value;
117
+ break;
118
+ }
119
+ }
120
+ if (resolvedValue === null || resolvedValue === void 0) return void 0;
121
+ if (options?.returnObjects && typeof resolvedValue === "object" && resolvedValue !== null) return resolvedValue;
122
+ const values = getInterpolationValues(options);
123
+ let resolved = (0, _intlayer_core_messageFormat.resolveMessage)(resolvedValue, values, options?.lng ?? locale, "i18next");
124
+ if (depth < MAX_NESTING_DEPTH && resolved.includes("$t(")) resolved = resolved.replace(/\$t\(\s*([^),]+?)\s*(?:,[^)]*)?\)/g, (match, nestedKey) => {
125
+ const nestedValue = resolveTranslation({
126
+ locale,
127
+ namespace: targetNamespace,
128
+ key: nestedKey.trim(),
129
+ options,
130
+ keySeparator,
131
+ nsSeparator,
132
+ depth: depth + 1
133
+ });
134
+ return typeof nestedValue === "string" ? nestedValue : match;
135
+ });
136
+ return resolved;
137
+ };
138
+
139
+ //#endregion
140
+ exports.getInterpolationValues = getInterpolationValues;
141
+ exports.resolveTranslation = resolveTranslation;
142
+ //# sourceMappingURL=resolveTranslation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveTranslation.cjs","names":[],"sources":["../../src/resolveTranslation.ts"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport {\n type MessageValues,\n resolveMessage,\n} from '@intlayer/core/messageFormat';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { TOptions } from 'i18next';\n\n/**\n * Shared i18next-dialect translation resolution.\n *\n * Implements the i18next lookup pipeline on top of intlayer dictionaries:\n * namespace prefix (`ns:key`), `ns` option override, plural suffixes\n * (`key_one`, `key_other`, …) via `Intl.PluralRules`, context suffixes\n * (`key_male`), `$t()` nesting, `defaultValue` and `{{var}}` interpolation.\n *\n * Used by `@intlayer/i18next` (instance `t`) and `@intlayer/react-i18next`\n * (`useTranslation`, `<Trans>`).\n */\n\n/** Option keys that are control flags, never interpolation values. */\nconst CONTROL_OPTION_KEYS = new Set([\n 'defaultValue',\n 'ns',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'returnObjects',\n 'returnDetails',\n 'keySeparator',\n 'nsSeparator',\n 'ordinal',\n 'postProcess',\n 'postProcessPassResolved',\n 'interpolation',\n 'replace',\n 'joinArrays',\n 'nsMode',\n 'keyPrefix',\n]);\n\n/** Maximum `$t()` nesting recursion depth. */\nconst MAX_NESTING_DEPTH = 5;\n\nconst navigatePath = (\n objectValue: unknown,\n path: string,\n keySeparator: string | false = '.'\n): unknown => {\n if (!path) return objectValue;\n\n const parts = keySeparator === false ? [path] : path.split(keySeparator);\n\n let current: unknown = objectValue;\n for (const part of parts) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Builds the ordered list of key candidates following i18next's resolution\n * order: context + plural → context → plural → exact key.\n */\nconst buildKeyCandidates = (\n path: string,\n locale: string,\n count: number | undefined,\n context: string | undefined,\n ordinal: boolean\n): string[] => {\n const candidates: string[] = [];\n\n const pluralCategory =\n count === undefined\n ? undefined\n : new Intl.PluralRules(locale, {\n type: ordinal ? 'ordinal' : 'cardinal',\n }).select(count);\n\n if (context) {\n if (pluralCategory) {\n if (ordinal) {\n candidates.push(`${path}_${context}_ordinal_${pluralCategory}`);\n }\n candidates.push(`${path}_${context}_${pluralCategory}`);\n if (count !== 1) candidates.push(`${path}_${context}_plural`);\n }\n candidates.push(`${path}_${context}`);\n }\n\n if (pluralCategory) {\n if (ordinal) candidates.push(`${path}_ordinal_${pluralCategory}`);\n candidates.push(`${path}_${pluralCategory}`);\n // Legacy i18next v3 JSON suffix\n if (count !== 1) candidates.push(`${path}_plural`);\n }\n\n candidates.push(path);\n\n return candidates;\n};\n\n/** Extracts interpolation values from i18next `t()` options. */\nexport const getInterpolationValues = (options?: TOptions): MessageValues => {\n if (!options || typeof options !== 'object') return {};\n\n const replace = (options as { replace?: MessageValues }).replace;\n if (replace) {\n // `count` and `context` are always interpolatable, even with `replace`\n const values: MessageValues = { ...replace };\n if (options.count !== undefined) values.count ??= options.count;\n if (options.context !== undefined) values.context ??= options.context;\n return values;\n }\n\n const values: MessageValues = {};\n for (const [optionKey, optionValue] of Object.entries(options)) {\n if (!CONTROL_OPTION_KEYS.has(optionKey)) values[optionKey] = optionValue;\n }\n return values;\n};\n\nexport type ResolveTranslationParams = {\n /** Locale to resolve against. */\n locale: LocalesValues;\n /** Default namespace (dictionary key) when the key has no `ns:` prefix. */\n namespace: string;\n /** The translation key, possibly `ns:path.to.key`. */\n key: string;\n /** i18next `t()` options (interpolation values, count, context, …). */\n options?: TOptions;\n /** Custom key separator (`init({ keySeparator })`). */\n keySeparator?: string | false;\n /** Custom namespace separator (`init({ nsSeparator })`). */\n nsSeparator?: string | false;\n /** Internal `$t()` nesting recursion depth. */\n depth?: number;\n};\n\n/**\n * Resolves a single translation key the i18next way against intlayer\n * dictionaries.\n *\n * Returns the resolved value: a string in the common case, or an\n * object/array when `returnObjects: true`. Returns `undefined` when the key\n * cannot be resolved (caller decides between `defaultValue`, fallback keys\n * and key echo).\n */\nexport const resolveTranslation = ({\n locale,\n namespace,\n key,\n options,\n keySeparator = '.',\n nsSeparator = ':',\n depth = 0,\n}: ResolveTranslationParams): unknown => {\n // Namespace resolution: `ns:` prefix > `ns` option > default namespace\n let targetNamespace = namespace;\n let path = key;\n\n if (nsSeparator !== false && key.includes(nsSeparator)) {\n const separatorIndex = key.indexOf(nsSeparator);\n targetNamespace = key.slice(0, separatorIndex);\n path = key.slice(separatorIndex + nsSeparator.length);\n } else if (options?.ns) {\n targetNamespace = Array.isArray(options.ns)\n ? (options.ns[0] as string)\n : (options.ns as string);\n }\n\n const count = typeof options?.count === 'number' ? options.count : undefined;\n const context =\n options?.context !== undefined ? String(options.context) : undefined;\n const ordinal = options?.ordinal === true;\n\n let dictionary: unknown;\n try {\n dictionary = getIntlayer(\n targetNamespace as DictionaryKeys,\n ((options?.lng as string) ?? locale) as LocalesValues\n );\n } catch {\n return undefined;\n }\n\n let resolvedValue: unknown;\n for (const candidate of buildKeyCandidates(\n path,\n (options?.lng as string) ?? (locale as string),\n count,\n context,\n ordinal\n )) {\n const value = navigatePath(dictionary, candidate, keySeparator);\n if (value !== null && value !== undefined) {\n resolvedValue = value;\n break;\n }\n }\n\n if (resolvedValue === null || resolvedValue === undefined) return undefined;\n\n // `returnObjects: true` — return the raw subtree\n if (\n options?.returnObjects &&\n typeof resolvedValue === 'object' &&\n resolvedValue !== null\n ) {\n return resolvedValue;\n }\n\n const values = getInterpolationValues(options);\n\n let resolved = resolveMessage(\n resolvedValue,\n values,\n ((options?.lng as string) ?? locale) as LocalesValues,\n 'i18next'\n );\n\n // `$t(key)` nesting\n if (depth < MAX_NESTING_DEPTH && resolved.includes('$t(')) {\n resolved = resolved.replace(\n /\\$t\\(\\s*([^),]+?)\\s*(?:,[^)]*)?\\)/g,\n (match, nestedKey: string) => {\n const nestedValue = resolveTranslation({\n locale,\n namespace: targetNamespace,\n key: nestedKey.trim(),\n options,\n keySeparator,\n nsSeparator,\n depth: depth + 1,\n });\n return typeof nestedValue === 'string' ? nestedValue : match;\n }\n );\n }\n\n return resolved;\n};\n"],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ import { getInterpolationValues, resolveTranslation } from "./resolveTranslation.mjs";
2
+ import { internationalization, log } from "@intlayer/config/built";
3
+ import * as ANSIColors from "@intlayer/config/colors";
4
+ import { colorize, getAppLogger } from "@intlayer/config/logger";
5
+ import { getIntlayer } from "@intlayer/core/interpreter";
6
+ import { resolveMessage } from "@intlayer/core/messageFormat";
7
+
8
+ //#region src/createInstance.ts
9
+ const navigatePath = (obj, path) => {
10
+ if (!path) return obj;
11
+ let current = obj;
12
+ for (const part of path.split(".")) {
13
+ if (current === null || current === void 0 || typeof current !== "object") return;
14
+ current = current[part];
15
+ }
16
+ return current;
17
+ };
18
+ const warnIgnoredResources = (location) => {
19
+ getAppLogger({ log })(`${colorize(location, ANSIColors.CYAN)}: the ${colorize("`resources`", ANSIColors.CYAN)} option is ignored when using ${colorize("@intlayer/i18next", ANSIColors.MAGENTA)} — translations are served from the compiled intlayer dictionaries instead. Remove the resource imports and the ${colorize("`resources`", ANSIColors.CYAN)} option to reduce your bundle size.`);
20
+ };
21
+ const createInstance = (instanceOptions = {}) => {
22
+ if (instanceOptions.resources !== void 0) warnIgnoredResources("createInstance");
23
+ const config = internationalization;
24
+ let currentLanguage = instanceOptions.lng ?? config?.defaultLocale ?? "en";
25
+ let defaultNS = instanceOptions.defaultNS ?? (Array.isArray(instanceOptions.ns) ? instanceOptions.ns[0] : instanceOptions.ns) ?? "translation";
26
+ const listeners = /* @__PURE__ */ new Map();
27
+ let initialized = false;
28
+ const emit = (event, ...args) => {
29
+ listeners.get(event)?.forEach((h) => {
30
+ h(...args);
31
+ });
32
+ };
33
+ const getSeparators = () => ({
34
+ keySeparator: instanceOptions.keySeparator ?? ".",
35
+ nsSeparator: instanceOptions.nsSeparator ?? ":"
36
+ });
37
+ /**
38
+ * Resolves a key through the full i18next pipeline (namespace prefix,
39
+ * `ns` option, plural/context suffixes, `$t()` nesting, interpolation).
40
+ * Falls back to the interpolated `defaultValue`, then to the key itself.
41
+ */
42
+ const resolveKey = (lang, ns, key, opts) => {
43
+ const options = typeof opts === "string" ? { defaultValue: opts } : opts;
44
+ const resolved = resolveTranslation({
45
+ locale: lang,
46
+ namespace: ns,
47
+ key,
48
+ options,
49
+ ...getSeparators()
50
+ });
51
+ if (resolved !== void 0) return resolved;
52
+ const defaultValue = options?.defaultValue;
53
+ if (typeof defaultValue === "string") return resolveMessage(defaultValue, getInterpolationValues(options), lang, "i18next");
54
+ return key;
55
+ };
56
+ const instance = {
57
+ get language() {
58
+ return currentLanguage;
59
+ },
60
+ get languages() {
61
+ return config?.locales?.map(String) ?? [currentLanguage];
62
+ },
63
+ get resolvedLanguage() {
64
+ return currentLanguage;
65
+ },
66
+ get isInitialized() {
67
+ return initialized;
68
+ },
69
+ isInitializing: false,
70
+ initializedStoreOnce: false,
71
+ initializedLanguageOnce: false,
72
+ options: instanceOptions,
73
+ modules: {},
74
+ services: {},
75
+ store: {},
76
+ format: ((value) => String(value)),
77
+ async init(optionsOrCb, cb) {
78
+ const opts = typeof optionsOrCb === "function" ? {} : optionsOrCb ?? {};
79
+ if (opts.resources !== void 0) warnIgnoredResources("i18next.init");
80
+ if (opts.lng) currentLanguage = opts.lng;
81
+ if (opts.defaultNS) defaultNS = opts.defaultNS;
82
+ else if (opts.ns) defaultNS = Array.isArray(opts.ns) ? opts.ns[0] : opts.ns;
83
+ initialized = true;
84
+ emit("initialized", opts);
85
+ const t = instance.t.bind(instance);
86
+ (typeof optionsOrCb === "function" ? optionsOrCb : cb)?.(null, t);
87
+ return t;
88
+ },
89
+ t(key, optionsOrDefaultValue, extraOpts) {
90
+ const options = typeof optionsOrDefaultValue === "string" ? {
91
+ defaultValue: optionsOrDefaultValue,
92
+ ...extraOpts ?? {}
93
+ } : optionsOrDefaultValue;
94
+ const keys = Array.isArray(key) ? key : [String(key)];
95
+ for (const candidateKey of keys) {
96
+ const result = resolveTranslation({
97
+ locale: currentLanguage,
98
+ namespace: defaultNS,
99
+ key: candidateKey,
100
+ options,
101
+ ...getSeparators()
102
+ });
103
+ if (result !== void 0) return result;
104
+ }
105
+ const defaultValue = options?.defaultValue;
106
+ if (typeof defaultValue === "string") return resolveMessage(defaultValue, getInterpolationValues(options), currentLanguage, "i18next");
107
+ return defaultValue ?? (Array.isArray(key) ? key[key.length - 1] : key);
108
+ },
109
+ async changeLanguage(lng, cb) {
110
+ const prev = currentLanguage;
111
+ if (lng) currentLanguage = lng;
112
+ emit("languageChanged", currentLanguage, prev);
113
+ const t = instance.t.bind(instance);
114
+ cb?.(null, t);
115
+ return t;
116
+ },
117
+ exists(key, options) {
118
+ return resolveTranslation({
119
+ locale: currentLanguage,
120
+ namespace: defaultNS,
121
+ key,
122
+ options,
123
+ ...getSeparators()
124
+ }) !== void 0;
125
+ },
126
+ /**
127
+ * Returns a `t()` function bound to a fixed locale and namespace.
128
+ * When `ns` matches a registered intlayer dictionary key, the returned
129
+ * function's `key` parameter is typed to only accept valid dot-notation
130
+ * paths for that dictionary.
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * const tAbout = i18n.getFixedT(null, 'about');
135
+ * tAbout('counter.label'); // ✓ typed
136
+ * ```
137
+ */
138
+ getFixedT(lng, ns, keyPrefix) {
139
+ const fixedLng = Array.isArray(lng) ? lng[0] ?? currentLanguage : lng ?? currentLanguage;
140
+ const fixedNS = ns ?? defaultNS;
141
+ return (key, opts) => {
142
+ return resolveKey(fixedLng, fixedNS, keyPrefix ? `${keyPrefix}.${String(key)}` : String(key), opts);
143
+ };
144
+ },
145
+ use(module) {
146
+ module?.init?.(instance);
147
+ return instance;
148
+ },
149
+ on(event, handler) {
150
+ if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
151
+ listeners.get(event).add(handler);
152
+ return instance;
153
+ },
154
+ once(event, handler) {
155
+ const wrapper = (...args) => {
156
+ handler(...args);
157
+ instance.off(event, wrapper);
158
+ };
159
+ instance.on(event, wrapper);
160
+ return instance;
161
+ },
162
+ off(event, handler) {
163
+ if (!handler) listeners.delete(event);
164
+ else listeners.get(event)?.delete(handler);
165
+ },
166
+ emit(eventName, ...args) {
167
+ emit(eventName, ...args);
168
+ },
169
+ createInstance(opts, _cb) {
170
+ return createInstance({
171
+ ...instanceOptions,
172
+ ...opts
173
+ });
174
+ },
175
+ cloneInstance(opts, _cb) {
176
+ return createInstance({
177
+ ...instanceOptions,
178
+ ...opts
179
+ });
180
+ },
181
+ dir(lng) {
182
+ return [
183
+ "ar",
184
+ "he",
185
+ "fa",
186
+ "ur",
187
+ "ps",
188
+ "yi",
189
+ "dv",
190
+ "ug"
191
+ ].some((l) => (lng ?? currentLanguage).startsWith(l)) ? "rtl" : "ltr";
192
+ },
193
+ setDefaultNamespace(ns) {
194
+ defaultNS = ns;
195
+ },
196
+ hasLoadedNamespace(ns) {
197
+ try {
198
+ getIntlayer(Array.isArray(ns) ? ns[0] : ns, currentLanguage);
199
+ return true;
200
+ } catch {
201
+ return false;
202
+ }
203
+ },
204
+ async loadNamespaces(_ns) {},
205
+ async loadLanguages(_lngs) {},
206
+ loadResources(_cb) {},
207
+ async reloadResources() {},
208
+ getDataByLanguage(_lng) {},
209
+ getResource(lng, ns, key) {
210
+ try {
211
+ return navigatePath(getIntlayer(ns, lng), key);
212
+ } catch {
213
+ return;
214
+ }
215
+ },
216
+ addResource: () => instance,
217
+ addResources: () => instance,
218
+ addResourceBundle: () => instance,
219
+ hasResourceBundle: () => false,
220
+ getResourceBundle: () => void 0,
221
+ removeResourceBundle: () => instance,
222
+ toJSON() {
223
+ return {
224
+ options: instanceOptions,
225
+ store: {},
226
+ language: currentLanguage,
227
+ languages: config?.locales?.map(String) ?? [currentLanguage],
228
+ resolvedLanguage: currentLanguage
229
+ };
230
+ }
231
+ };
232
+ return instance;
233
+ };
234
+
235
+ //#endregion
236
+ export { createInstance };
237
+ //# sourceMappingURL=createInstance.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createInstance.mjs","names":[],"sources":["../../src/createInstance.ts"],"sourcesContent":["import { internationalization, log } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getIntlayer } from '@intlayer/core/interpreter';\nimport { resolveMessage } from '@intlayer/core/messageFormat';\nimport type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n createInstance as _createInstance,\n i18n as I18nInterface,\n InitOptions,\n TOptions,\n} from 'i18next';\nimport {\n getInterpolationValues,\n resolveTranslation,\n} from './resolveTranslation';\n\ntype EventHandler = (...args: unknown[]) => void;\n\nconst navigatePath = (obj: unknown, path: string): unknown => {\n if (!path) return obj;\n let current: unknown = obj;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\nconst warnIgnoredResources = (location: string) => {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize(location, ANSIColors.CYAN)}: the ${colorize('`resources`', ANSIColors.CYAN)} option is ignored when using ${colorize('@intlayer/i18next', ANSIColors.MAGENTA)} — translations are served from the compiled intlayer dictionaries instead. Remove the resource imports and the ${colorize('`resources`', ANSIColors.CYAN)} option to reduce your bundle size.`\n );\n};\n\nexport const createInstance: typeof _createInstance = (\n instanceOptions: InitOptions = {}\n): I18nInterface => {\n if ((instanceOptions as Record<string, unknown>).resources !== undefined) {\n warnIgnoredResources('createInstance');\n }\n\n const config = internationalization;\n\n let currentLanguage: string =\n (instanceOptions.lng as string) ?? config?.defaultLocale ?? 'en';\n\n let defaultNS: string =\n (instanceOptions.defaultNS as string) ??\n (Array.isArray(instanceOptions.ns)\n ? (instanceOptions.ns[0] as string)\n : (instanceOptions.ns as string)) ??\n 'translation';\n\n const listeners = new Map<string, Set<EventHandler>>();\n let initialized = false;\n\n const emit = (event: string, ...args: unknown[]) => {\n listeners.get(event)?.forEach((h) => {\n h(...args);\n });\n };\n\n const getSeparators = () => ({\n keySeparator:\n (instanceOptions.keySeparator as string | false | undefined) ?? '.',\n nsSeparator:\n (instanceOptions.nsSeparator as string | false | undefined) ?? ':',\n });\n\n /**\n * Resolves a key through the full i18next pipeline (namespace prefix,\n * `ns` option, plural/context suffixes, `$t()` nesting, interpolation).\n * Falls back to the interpolated `defaultValue`, then to the key itself.\n */\n const resolveKey = (\n lang: string,\n ns: string,\n key: string,\n opts?: TOptions | string\n ): string => {\n const options =\n typeof opts === 'string' ? { defaultValue: opts } : (opts as TOptions);\n\n const resolved = resolveTranslation({\n locale: lang as LocalesValues,\n namespace: ns,\n key,\n options,\n ...getSeparators(),\n });\n\n if (resolved !== undefined) return resolved as string;\n\n const defaultValue = (options as Record<string, unknown> | undefined)\n ?.defaultValue;\n if (typeof defaultValue === 'string') {\n return resolveMessage(\n defaultValue,\n getInterpolationValues(options),\n lang as LocalesValues,\n 'i18next'\n );\n }\n\n return key;\n };\n\n const instance = {\n get language() {\n return currentLanguage;\n },\n get languages() {\n return (config?.locales?.map(String) ?? [\n currentLanguage,\n ]) as readonly string[];\n },\n get resolvedLanguage() {\n return currentLanguage;\n },\n get isInitialized() {\n return initialized;\n },\n isInitializing: false,\n initializedStoreOnce: false,\n initializedLanguageOnce: false,\n options: instanceOptions,\n modules: {} as I18nInterface['modules'],\n services: {} as I18nInterface['services'],\n store: {} as I18nInterface['store'],\n format: ((value: unknown) => String(value)) as I18nInterface['format'],\n\n async init(optionsOrCb?: unknown, cb?: unknown) {\n const opts =\n typeof optionsOrCb === 'function'\n ? {}\n : ((optionsOrCb ?? {}) as Record<string, unknown>);\n if (opts.resources !== undefined) {\n warnIgnoredResources('i18next.init');\n }\n if (opts.lng) currentLanguage = opts.lng as string;\n if (opts.defaultNS) defaultNS = opts.defaultNS as string;\n else if (opts.ns)\n defaultNS = Array.isArray(opts.ns)\n ? (opts.ns[0] as string)\n : (opts.ns as string);\n initialized = true;\n emit('initialized', opts);\n const t = instance.t.bind(instance);\n const callback = typeof optionsOrCb === 'function' ? optionsOrCb : cb;\n (callback as ((err: unknown, t: unknown) => void) | undefined)?.(null, t);\n return t as unknown as Promise<I18nInterface['t']>;\n },\n\n t(\n key: unknown,\n optionsOrDefaultValue?: unknown,\n extraOpts?: unknown\n ): unknown {\n const options =\n typeof optionsOrDefaultValue === 'string'\n ? {\n defaultValue: optionsOrDefaultValue,\n ...((extraOpts ?? {}) as Record<string, unknown>),\n }\n : (optionsOrDefaultValue as TOptions | undefined);\n const keys: string[] = Array.isArray(key)\n ? (key as string[])\n : [String(key)];\n for (const candidateKey of keys) {\n const result = resolveTranslation({\n locale: currentLanguage as LocalesValues,\n namespace: defaultNS,\n key: candidateKey,\n options,\n ...getSeparators(),\n });\n if (result !== undefined) return result;\n }\n\n const defaultValue = (options as Record<string, unknown> | undefined)\n ?.defaultValue;\n if (typeof defaultValue === 'string') {\n return resolveMessage(\n defaultValue,\n getInterpolationValues(options),\n currentLanguage as LocalesValues,\n 'i18next'\n );\n }\n\n return defaultValue ?? (Array.isArray(key) ? key[key.length - 1] : key);\n },\n\n async changeLanguage(lng?: string, cb?: unknown) {\n const prev = currentLanguage;\n if (lng) currentLanguage = lng;\n emit('languageChanged', currentLanguage, prev);\n const t = instance.t.bind(instance);\n (cb as ((err: unknown, t: unknown) => void) | undefined)?.(null, t);\n return t as unknown as Promise<I18nInterface['t']>;\n },\n\n exists(key: string, options?: unknown): boolean {\n return (\n resolveTranslation({\n locale: currentLanguage as LocalesValues,\n namespace: defaultNS,\n key,\n options: options as TOptions,\n ...getSeparators(),\n }) !== undefined\n );\n },\n\n /**\n * Returns a `t()` function bound to a fixed locale and namespace.\n * When `ns` matches a registered intlayer dictionary key, the returned\n * function's `key` parameter is typed to only accept valid dot-notation\n * paths for that dictionary.\n *\n * @example\n * ```ts\n * const tAbout = i18n.getFixedT(null, 'about');\n * tAbout('counter.label'); // ✓ typed\n * ```\n */\n getFixedT<N extends DictionaryKeys>(\n lng: string | readonly string[] | null,\n ns?: N | null,\n keyPrefix?: string\n ): <P extends ValidDotPathsFor<N>>(key: P, opts?: TOptions) => string {\n const fixedLng = Array.isArray(lng)\n ? ((lng[0] as string) ?? currentLanguage)\n : ((lng as string) ?? currentLanguage);\n const fixedNS = (ns as string) ?? defaultNS;\n return <P extends ValidDotPathsFor<N>>(\n key: P,\n opts?: TOptions\n ): string => {\n const fullKey = keyPrefix ? `${keyPrefix}.${String(key)}` : String(key);\n return resolveKey(fixedLng, fixedNS, fullKey, opts);\n };\n },\n\n use(module: unknown) {\n (module as { init?: (i18n: I18nInterface) => void })?.init?.(\n instance as unknown as I18nInterface\n );\n return instance as unknown as I18nInterface;\n },\n\n on(event: string, handler: EventHandler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n return instance as unknown as I18nInterface;\n },\n\n once(event: string, handler: EventHandler) {\n const wrapper: EventHandler = (...args) => {\n handler(...args);\n instance.off(event, wrapper);\n };\n instance.on(event, wrapper);\n return instance as unknown as I18nInterface;\n },\n\n off(event: string, handler?: EventHandler) {\n if (!handler) listeners.delete(event);\n else listeners.get(event)?.delete(handler);\n },\n\n emit(eventName: string, ...args: unknown[]) {\n emit(eventName, ...args);\n },\n\n createInstance(opts?: InitOptions, _cb?: unknown) {\n return createInstance({ ...instanceOptions, ...opts });\n },\n\n cloneInstance(opts?: Record<string, unknown>, _cb?: unknown) {\n return createInstance({ ...instanceOptions, ...opts });\n },\n\n dir(lng?: string): 'ltr' | 'rtl' {\n const rtl = ['ar', 'he', 'fa', 'ur', 'ps', 'yi', 'dv', 'ug'];\n return rtl.some((l) => (lng ?? currentLanguage).startsWith(l))\n ? 'rtl'\n : 'ltr';\n },\n\n setDefaultNamespace(ns: string) {\n defaultNS = ns;\n },\n\n hasLoadedNamespace(ns: string | readonly string[]): boolean {\n try {\n getIntlayer(\n (Array.isArray(ns) ? ns[0] : ns) as DictionaryKeys,\n currentLanguage as LocalesValues\n );\n return true;\n } catch {\n return false;\n }\n },\n\n async loadNamespaces(_ns: unknown) {},\n async loadLanguages(_lngs: unknown) {},\n loadResources(_cb?: unknown) {},\n async reloadResources() {},\n\n getDataByLanguage(_lng: string) {\n return undefined;\n },\n\n getResource(lng: string, ns: string, key: string): unknown {\n try {\n return navigatePath(\n getIntlayer(ns as DictionaryKeys, lng as LocalesValues),\n key\n );\n } catch {\n return undefined;\n }\n },\n\n addResource: () => instance as unknown as I18nInterface,\n addResources: () => instance as unknown as I18nInterface,\n addResourceBundle: () => instance as unknown as I18nInterface,\n hasResourceBundle: () => false,\n getResourceBundle: () => undefined,\n removeResourceBundle: () => instance as unknown as I18nInterface,\n\n toJSON() {\n return {\n options: instanceOptions,\n store: {} as I18nInterface['store'],\n language: currentLanguage,\n languages: (config?.locales?.map(String) ?? [\n currentLanguage,\n ]) as readonly string[],\n resolvedLanguage: currentLanguage,\n };\n },\n };\n\n return instance as unknown as I18nInterface;\n};\n\n/** Typed variant of i18next's `getFixedT`, scoped to an intlayer dictionary namespace. */\nexport type TypedGetFixedT = <N extends DictionaryKeys>(\n lng: string | readonly string[] | null,\n ns?: N | null,\n keyPrefix?: string\n) => <P extends ValidDotPathsFor<N>>(key: P, opts?: TOptions) => string;\n"],"mappings":"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"}