@i18n-micro/core 1.0.27 → 1.0.28

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/base.d.ts ADDED
@@ -0,0 +1,91 @@
1
+ import { useTranslationHelper, TranslationCache } from './translation';
2
+ import { FormatService } from './format-service';
3
+ import { Translations, Params, PluralFunc, CleanTranslation, TranslationKey, MissingHandler } from '@i18n-micro/types';
4
+ export interface BaseI18nOptions {
5
+ cache?: TranslationCache;
6
+ plural?: PluralFunc;
7
+ missingWarn?: boolean;
8
+ missingHandler?: (locale: string, key: string, routeName: string) => void;
9
+ getPreviousPageInfo?: () => {
10
+ locale: string;
11
+ routeName: string;
12
+ } | null;
13
+ getCustomMissingHandler?: () => MissingHandler | null;
14
+ enablePreviousPageFallback?: boolean;
15
+ }
16
+ /**
17
+ * Abstract base class for i18n adapters
18
+ *
19
+ * Contains all common translation logic (t, ts, tc, tn, td, tdr, has).
20
+ * Adapters must implement abstract methods to provide current state (locale, fallbackLocale, route).
21
+ */
22
+ export declare abstract class BaseI18n {
23
+ helper: ReturnType<typeof useTranslationHelper>;
24
+ formatter: FormatService;
25
+ pluralFunc: PluralFunc;
26
+ missingWarn: boolean;
27
+ missingHandler?: (locale: string, key: string, routeName: string) => void;
28
+ getPreviousPageInfo?: () => {
29
+ locale: string;
30
+ routeName: string;
31
+ } | null;
32
+ getCustomMissingHandler?: () => MissingHandler | null;
33
+ enablePreviousPageFallback: boolean;
34
+ constructor(options?: BaseI18nOptions);
35
+ /**
36
+ * Get current locale
37
+ */
38
+ abstract getLocale(): string;
39
+ /**
40
+ * Get fallback locale
41
+ */
42
+ abstract getFallbackLocale(): string;
43
+ /**
44
+ * Get current route name
45
+ */
46
+ abstract getRoute(): string;
47
+ /**
48
+ * Get translation for a key
49
+ * Based on logic from src/runtime/plugins/01.plugin.ts
50
+ */
51
+ t(key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string): CleanTranslation;
52
+ /**
53
+ * Get translation as string
54
+ */
55
+ ts(key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string): string;
56
+ /**
57
+ * Plural translation
58
+ */
59
+ tc(key: TranslationKey, count: number | Params, defaultValue?: string): string;
60
+ /**
61
+ * Format number
62
+ */
63
+ tn(value: number, options?: Intl.NumberFormatOptions): string;
64
+ /**
65
+ * Format date
66
+ */
67
+ td(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string;
68
+ /**
69
+ * Format relative time
70
+ */
71
+ tdr(value: Date | number | string, options?: Intl.RelativeTimeFormatOptions): string;
72
+ /**
73
+ * Check if translation exists
74
+ * Based on logic from src/runtime/plugins/01.plugin.ts
75
+ */
76
+ has(key: TranslationKey, routeName?: string): boolean;
77
+ /**
78
+ * Clear cache
79
+ */
80
+ clearCache(): void;
81
+ /**
82
+ * Core translation loading logic (without reactivity)
83
+ * Subclasses can override addTranslations/addRouteTranslations to add reactivity
84
+ */
85
+ loadTranslationsCore(locale: string, translations: Translations, merge: boolean): void;
86
+ /**
87
+ * Core route translation loading logic (without reactivity)
88
+ * Subclasses can override addRouteTranslations to add reactivity
89
+ */
90
+ loadRouteTranslationsCore(locale: string, routeName: string, translations: Translations, merge: boolean): void;
91
+ }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R={},x={},P=[],w={};function b(a){return Array.isArray(a)||typeof a=="object"&&a!==null?JSON.parse(JSON.stringify(a)):a}function $(a,e){let r=a;if(a===null||typeof e!="string")return null;if(a[e])r=a[e];else{const n=e.toString().split(".");for(const i of n)if(r&&typeof r=="object"&&i in r)r=r[i];else return null}return typeof r=="object"&&r!==null?b(r):r??null}function C(a){return typeof a=="object"&&a!==null&&"value"in a?a.value:a}function m(a,e,r){const n=C(a);n[e]=r}function d(a,e){return C(a)[e]}function N(a){const e=(a==null?void 0:a.generalLocaleCache)??R,r=(a==null?void 0:a.routeLocaleCache)??x,n=(a==null?void 0:a.dynamicTranslationsCaches)??P,i=(a==null?void 0:a.serverTranslationCache)??w;return{hasCache(t,s){const o=`${t}:${s}`;return(d(i,o)??new Map).size>0},getCache(t,s){const o=`${t}:${s}`;return d(i,o)},setCache(t,s,o){const l=`${t}:${s}`;m(i,l,o)},mergeTranslation(t,s,o,l=!1){const u=`${t}:${s}`,c=d(r,u);(c||l)&&m(r,u,{...c??{},...o});const f=process.env.NODE_ENV!=="production";!c&&f&&console.warn(`[i18n] mergeTranslation called for '${u}' which was not pre-loaded. Skipping merge. Use force: true if this is intentional.`)},mergeGlobalTranslation(t,s,o=!1){const l=d(e,t);!o&&!l&&console.error(`marge: route ${t} not loaded`),m(e,t,{...l??{},...s})},hasGeneralTranslation(t){return!!d(e,t)},hasPageTranslation(t,s){const o=`${t}:${s}`;return!!d(r,o)},hasTranslation:(t,s)=>{const o=C(n);for(const u of o)if($(u[t]||null,s)!==null)return!0;const l=d(e,t);return $(l||null,s)!==null},getTranslation:(t,s,o)=>{const l=`${t}:${s}`,u=d(i,l),c=u==null?void 0:u.get(o);if(c)return c;let f=null;const v=C(n);for(const g of v)if(f=$(g[t]||null,o),f!==null)break;if(!f){const g=d(r,l),p=d(e,t);f=$(g||null,o)??$(p||null,o)}if(f){const g=u??new Map;g.set(o,f),m(i,l,g)}return f},async loadPageTranslations(t,s,o){const l=`${t}:${s}`;m(r,l,{...o})},async loadTranslations(t,s){m(e,t,{...s})},clearCache(){const t=C(e);Object.keys(t).forEach(u=>{m(e,u,{})});const s=C(r);Object.keys(s).forEach(u=>{m(r,u,{})});const o=C(n);o.length=0;const l=C(i);Object.keys(l).forEach(u=>{const c=d(i,u);c==null||c.clear()})}}}function T(a,e){let r=a;for(const n in e)r=r.split(`{${n}}`).join(String(e[n]));return r}function y(a){return a==="prefix"||a==="prefix_and_default"}function h(a){return a==="no_prefix"}function D(a){return a==="prefix"}function L(a){return a==="prefix_except_default"}function q(a){return a==="prefix_and_default"}const z=(a,e,r,n,i)=>{const t=i(a,r);if(!t)return null;const s=t.toString().split("|");if(s.length===0)return null;const o=e<s.length?s[e]:s[s.length-1];return o?o.trim().replace("{count}",e.toString()):null};class F{constructor(e,r,n,i,t,s,o=null,l=null){this.i18nConfig=e,this.router=r,this.hashLocaleDefault=n,this.noPrefixDefault=i,this.navigateTo=t,this.setCookie=s,this.cookieLocaleDefault=o,this.cookieLocaleName=l}extractLocaleFromPath(e){var o,l;if(!e)return null;const n=(o=e.split("?")[0])==null?void 0:o.split("#")[0];if(!n||n==="/")return null;const i=n.split("/").filter(Boolean);if(i.length===0)return null;const t=i[0];return t&&(((l=this.i18nConfig.locales)==null?void 0:l.map(u=>u.code))||[]).includes(t)?t:null}getCurrentLocale(e){var i;if(e=e??this.router.currentRoute.value,this.i18nConfig.hashMode&&this.hashLocaleDefault)return this.hashLocaleDefault;if(h(this.i18nConfig.strategy)&&this.noPrefixDefault)return this.noPrefixDefault;if((i=e.params)!=null&&i.locale)return e.params.locale.toString();const r=e.path||e.fullPath||"",n=this.extractLocaleFromPath(r);return n||(this.cookieLocaleDefault?this.cookieLocaleDefault:(this.i18nConfig.defaultLocale||"en").toString())}getCurrentName(e){var i;const r=this.getCurrentLocale(e),n=(i=this.i18nConfig.locales)==null?void 0:i.find(t=>t.code===r);return(n==null?void 0:n.displayName)??null}getRouteName(e,r){return(e.name??"").toString().toString().replace("localized-","").replace(new RegExp(`-${r}$`),"")}getPluginRouteName(e,r){return this.i18nConfig.disablePageLocales?"general":this.getRouteName(e,r)}getFullPathWithBaseUrl(e,r){let i=this.router.resolve(r).fullPath;e!=null&&e.baseDefault&&(i=i.replace(new RegExp(`^/${e.code}`),""));let t=e.baseUrl;return t||(t=""),t!=null&&t.endsWith("/")&&(t=t.slice(0,-1)),t+i}switchLocaleRoute(e,r,n,i){var f,v;const t=(f=this.i18nConfig.locales)==null?void 0:f.find(g=>g.code===r),s=this.getRouteName(n,e);if(this.router.hasRoute(`localized-${s}-${r}`)){const p={...i!=null&&i[r]?{...i[r]}:{...n.params??{}}};delete p.locale,h(this.i18nConfig.strategy)||(p.locale=r);const S={name:`localized-${s}-${r}`,params:p,query:n.query,hash:n.hash};return t!=null&&t.baseUrl?this.getFullPathWithBaseUrl(t,S):S}let o=s;const u={...i!=null&&i[r]?{...i[r]}:{...n.params??{}}};delete u.locale,h(this.i18nConfig.strategy)||(s==="custom-fallback-route"?o=s:o=r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?`localized-${s}`:s,h(this.i18nConfig.strategy)||(r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(u.locale=r));const c={name:o,params:u,query:n.query,hash:n.hash};return h(this.i18nConfig.strategy)&&((v=this.i18nConfig.locales)==null||v.forEach((g,p)=>{c.name.endsWith(`-${g.code}`)&&(c.name=c.name.slice(0,-g.code-1))})),t!=null&&t.baseUrl?this.getFullPathWithBaseUrl(t,c):c}resolveParams(e){const r=typeof e=="object"&&"params"in e&&typeof e.params=="object"?{...e.params}:{};if(typeof e=="string"){const n=this.router.resolve(e);n&&n.params&&Object.assign(r,n.params)}return r}handlePrefixStrategy(e){if(!y(this.i18nConfig.strategy))return e;const r=this.i18nConfig.defaultLocale;let n=e;typeof e=="string"&&(n=this.router.resolve("/"+r+e));const i=this.getRouteName(n,r),t=this.resolveParams(n);return h(this.i18nConfig.strategy)||(t.locale=r),this.router.hasRoute(`localized-${i}`)?this.router.resolve({name:`localized-${i}`,query:n.query,hash:n.hash,params:t}):this.router.hasRoute(`localized-${i}-${r}`)?this.router.resolve({name:`localized-${i}-${r}`,query:n.query,hash:n.hash,params:t}):e}createLocalizedRoute(e,r,n){const i=this.router.resolve(e),t=this.getRouteName(i,n).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`),"");if(!h(this.i18nConfig.strategy)&&(!t||t==="")){let u=this.router.resolve(e).path.replace(new RegExp(`^/${n}/`),"/");return(n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(u="/"+n+u),this.router.resolve({path:u,query:i.query,hash:i.hash})}if(this.router.hasRoute(`localized-${t}-${n}`)){const l=this.resolveParams(i);return h(this.i18nConfig.strategy)||(l.locale=n),this.router.resolve({name:`localized-${t}-${n}`,params:l,query:i.query,hash:i.hash})}const s=n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?`localized-${t}`:t;if(!this.router.hasRoute(s)){const l=this.resolveParams(e);return delete l.locale,this.router.hasRoute(t)?this.router.resolve({name:t,params:l,query:i.query,hash:i.hash}):this.router.resolve("/")}const o=this.resolveParams(e);return delete o.locale,h(this.i18nConfig.strategy)||(n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(o.locale=n),this.router.resolve({name:s,params:o,query:i.query,hash:i.hash})}getLocalizedRoute(e,r,n){const i=n||this.getCurrentLocale(r),t=this.handlePrefixStrategy(e);return this.createLocalizedRoute(t,r,i)}updateCookies(e){this.i18nConfig.hashMode&&(this.setCookie("hash-locale",e),this.hashLocaleDefault=e),h(this.i18nConfig.strategy)&&(this.setCookie("no-prefix-locale",e),this.noPrefixDefault=e),!this.i18nConfig.hashMode&&!h(this.i18nConfig.strategy)&&this.cookieLocaleName&&(this.setCookie(this.cookieLocaleName,e),this.cookieLocaleDefault=e)}getCurrentRoute(){return this.router.currentRoute.value}resolveRouteWithStrategy(e,r,n){return h(this.i18nConfig.strategy)?this.router.resolve(e):r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?this.router.resolve(`/${n}${e}`):this.router.resolve(e)}switchLocaleLogic(e,r,n){const i=this.getCurrentLocale();let t;typeof n=="string"?t=this.resolveRouteWithStrategy(n,e,i):t=n??this.getCurrentRoute(),this.updateCookies(e);const s=this.switchLocaleRoute(i,e,t,r);return typeof s=="string"&&s.startsWith("http")?this.navigateTo(s,{redirectCode:200,external:!0}):(h(this.i18nConfig.strategy)&&(s.force=!0),this.router.push(s))}resolveLocalizedRoute(e,r){const n=this.getCurrentRoute(),i=this.getCurrentLocale(),t=r??i;let s;if(typeof e=="string")if(e.startsWith("/"))s=this.resolveRouteWithStrategy(e,t,i);else{const o=e;this.router.hasRoute(o)?s=this.router.resolve({name:o}):(e=`/${e}`,s=this.resolveRouteWithStrategy(e,t,i))}else s=e;return this.getLocalizedRoute(s,n,t)}}class j{formatNumber(e,r,n){return new Intl.NumberFormat(r,n).format(e)}formatDate(e,r,n){const i=new Date(e);return Number.isNaN(i.getTime())?"Invalid Date":new Intl.DateTimeFormat(r,n).format(i)}formatRelativeTime(e,r,n){const i=new Date(e);if(Number.isNaN(i.getTime()))return new Intl.RelativeTimeFormat(r,n).format(0,"second");const s=Math.floor((new Date().getTime()-i.getTime())/1e3),o=[{unit:"year",seconds:31536e3},{unit:"month",seconds:2592e3},{unit:"day",seconds:86400},{unit:"hour",seconds:3600},{unit:"minute",seconds:60},{unit:"second",seconds:1}];for(const{unit:l,seconds:u}of o){const c=Math.floor(s/u);if(c>=1)return new Intl.RelativeTimeFormat(r,n).format(-c,l)}return new Intl.RelativeTimeFormat(r,n).format(0,"second")}}exports.FormatService=j;exports.RouteService=F;exports.defaultPlural=z;exports.interpolate=T;exports.isNoPrefixStrategy=h;exports.isPrefixAndDefaultStrategy=q;exports.isPrefixExceptDefaultStrategy=L;exports.isPrefixStrategy=D;exports.useTranslationHelper=N;exports.withPrefixStrategy=y;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const L={},T={},N=[],w={};function x(o){return Array.isArray(o)||typeof o=="object"&&o!==null?JSON.parse(JSON.stringify(o)):o}function v(o,e){let t=o;if(o===null||typeof e!="string")return null;if(o[e])t=o[e];else{const r=e.toString().split(".");for(const n of r)if(t&&typeof t=="object"&&n in t)t=t[n];else return null}return typeof t=="object"&&t!==null?x(t):t??null}function C(o){return typeof o=="object"&&o!==null&&"value"in o?o.value:o}function d(o,e,t){const r=C(o);r[e]=t}function g(o,e){return C(o)[e]}function R(o){const e=o?.generalLocaleCache??L,t=o?.routeLocaleCache??T,r=o?.dynamicTranslationsCaches??N,n=o?.serverTranslationCache??w;return{hasCache(s,i){const a=`${s}:${i}`;return(g(n,a)??new Map).size>0},getCache(s,i){const a=`${s}:${i}`;return g(n,a)},setCache(s,i,a){const l=`${s}:${i}`;d(n,l,a)},mergeTranslation(s,i,a,l=!1){const c=`${s}:${i}`,u=g(t,c);(u||l)&&d(t,c,{...u??{},...a});const h=process.env.NODE_ENV!=="production";!u&&h&&console.warn(`[i18n] mergeTranslation called for '${c}' which was not pre-loaded. Skipping merge. Use force: true if this is intentional.`)},mergeGlobalTranslation(s,i,a=!1){const l=g(e,s);!a&&!l&&console.error(`marge: route ${s} not loaded`),d(e,s,{...l??{},...i})},hasGeneralTranslation(s){return!!g(e,s)},hasPageTranslation(s,i){const a=`${s}:${i}`;return!!g(t,a)},hasTranslation:(s,i)=>{const a=C(r);for(const c of a)if(v(c[s]||null,i)!==null)return!0;const l=g(e,s);return v(l||null,i)!==null},getTranslation:(s,i,a)=>{const l=`${s}:${i}`,c=g(n,l),u=c?.get(a);if(u)return u;let h=null;const y=C(r);for(const m of y)if(h=v(m[s]||null,a),h!==null)break;if(!h){const m=g(t,l),S=g(e,s);h=v(m||null,a)??v(S||null,a)}if(h){const m=c??new Map;m.set(a,h),d(n,l,m)}return h},async loadPageTranslations(s,i,a){const l=`${s}:${i}`;d(t,l,{...a})},async loadTranslations(s,i){d(e,s,{...i})},clearCache(){const s=C(e);Object.keys(s).forEach(c=>{d(e,c,{})});const i=C(t);Object.keys(i).forEach(c=>{d(t,c,{})});const a=C(r);a.length=0;const l=C(n);Object.keys(l).forEach(c=>{g(n,c)?.clear()})}}}function b(o,e){let t=o;for(const r in e)t=t.split(`{${r}}`).join(String(e[r]));return t}function p(o){return o==="prefix"||o==="prefix_and_default"}function f(o){return o==="no_prefix"}function D(o){return o==="prefix"}function F(o){return o==="prefix_except_default"}function q(o){return o==="prefix_and_default"}const $=(o,e,t,r,n)=>{const s=n(o,t);if(!s)return null;const i=s.toString().split("|");if(i.length===0)return null;const a=e<i.length?i[e]:i[i.length-1];return a?a.trim().replace("{count}",e.toString()):null};class z{constructor(e,t,r,n,s,i,a=null,l=null){this.i18nConfig=e,this.router=t,this.hashLocaleDefault=r,this.noPrefixDefault=n,this.navigateTo=s,this.setCookie=i,this.cookieLocaleDefault=a,this.cookieLocaleName=l}extractLocaleFromPath(e){if(!e)return null;const r=e.split("?")[0]?.split("#")[0];if(!r||r==="/")return null;const n=r.split("/").filter(Boolean);if(n.length===0)return null;const s=n[0];return s&&(this.i18nConfig.locales?.map(a=>a.code)||[]).includes(s)?s:null}getCurrentLocale(e){if(e=e??this.router.currentRoute.value,this.i18nConfig.hashMode&&this.hashLocaleDefault)return this.hashLocaleDefault;if(f(this.i18nConfig.strategy)&&this.noPrefixDefault)return this.noPrefixDefault;if(e.params?.locale)return e.params.locale.toString();const t=e.path||e.fullPath||"",r=this.extractLocaleFromPath(t);return r||(this.cookieLocaleDefault?this.cookieLocaleDefault:(this.i18nConfig.defaultLocale||"en").toString())}getCurrentName(e){const t=this.getCurrentLocale(e);return this.i18nConfig.locales?.find(n=>n.code===t)?.displayName??null}getRouteName(e,t){return(e.name??"").toString().toString().replace("localized-","").replace(new RegExp(`-${t}$`),"")}getPluginRouteName(e,t){return this.i18nConfig.disablePageLocales?"general":this.getRouteName(e,t)}getFullPathWithBaseUrl(e,t){let n=this.router.resolve(t).fullPath;e?.baseDefault&&(n=n.replace(new RegExp(`^/${e.code}`),""));let s=e.baseUrl;return s||(s=""),s?.endsWith("/")&&(s=s.slice(0,-1)),s+n}switchLocaleRoute(e,t,r,n){const s=this.i18nConfig.locales?.find(h=>h.code===t),i=this.getRouteName(r,e);if(this.router.hasRoute(`localized-${i}-${t}`)){const y={...n?.[t]?{...n[t]}:{...r.params??{}}};delete y.locale,f(this.i18nConfig.strategy)||(y.locale=t);const m={name:`localized-${i}-${t}`,params:y,query:r.query,hash:r.hash};return s?.baseUrl?this.getFullPathWithBaseUrl(s,m):m}let a=i;const c={...n?.[t]?{...n[t]}:{...r.params??{}}};delete c.locale,f(this.i18nConfig.strategy)||(i==="custom-fallback-route"?a=i:a=t!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy)?`localized-${i}`:i,f(this.i18nConfig.strategy)||(t!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy))&&(c.locale=t));const u={name:a,params:c,query:r.query,hash:r.hash};return f(this.i18nConfig.strategy)&&this.i18nConfig.locales?.forEach((h,y)=>{u.name.endsWith(`-${h.code}`)&&(u.name=u.name.slice(0,-h.code-1))}),s?.baseUrl?this.getFullPathWithBaseUrl(s,u):u}resolveParams(e){const t=typeof e=="object"&&"params"in e&&typeof e.params=="object"?{...e.params}:{};if(typeof e=="string"){const r=this.router.resolve(e);r&&r.params&&Object.assign(t,r.params)}return t}handlePrefixStrategy(e){if(!p(this.i18nConfig.strategy))return e;const t=this.i18nConfig.defaultLocale;let r=e;typeof e=="string"&&(r=this.router.resolve("/"+t+e));const n=this.getRouteName(r,t),s=this.resolveParams(r);return f(this.i18nConfig.strategy)||(s.locale=t),this.router.hasRoute(`localized-${n}`)?this.router.resolve({name:`localized-${n}`,query:r.query,hash:r.hash,params:s}):this.router.hasRoute(`localized-${n}-${t}`)?this.router.resolve({name:`localized-${n}-${t}`,query:r.query,hash:r.hash,params:s}):e}createLocalizedRoute(e,t,r){const n=this.router.resolve(e),s=this.getRouteName(n,r).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`),"");if(!f(this.i18nConfig.strategy)&&(!s||s==="")){let c=this.router.resolve(e).path.replace(new RegExp(`^/${r}/`),"/");return(r!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy))&&(c="/"+r+c),this.router.resolve({path:c,query:n.query,hash:n.hash})}if(this.router.hasRoute(`localized-${s}-${r}`)){const l=this.resolveParams(n);return f(this.i18nConfig.strategy)||(l.locale=r),this.router.resolve({name:`localized-${s}-${r}`,params:l,query:n.query,hash:n.hash})}const i=r!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy)?`localized-${s}`:s;if(!this.router.hasRoute(i)){const l=this.resolveParams(e);return delete l.locale,this.router.hasRoute(s)?this.router.resolve({name:s,params:l,query:n.query,hash:n.hash}):this.router.resolve("/")}const a=this.resolveParams(e);return delete a.locale,f(this.i18nConfig.strategy)||(r!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy))&&(a.locale=r),this.router.resolve({name:i,params:a,query:n.query,hash:n.hash})}getLocalizedRoute(e,t,r){const n=r||this.getCurrentLocale(t),s=this.handlePrefixStrategy(e);return this.createLocalizedRoute(s,t,n)}updateCookies(e){const t=this.cookieLocaleName||this.i18nConfig.localeCookie||"user-locale";this.i18nConfig.hashMode&&(this.setCookie("hash-locale",e),this.hashLocaleDefault=e),f(this.i18nConfig.strategy)&&(this.setCookie(t,e),this.noPrefixDefault=e),!this.i18nConfig.hashMode&&!f(this.i18nConfig.strategy)&&t&&(this.setCookie(t,e),this.cookieLocaleDefault=e)}getCurrentRoute(){return this.router.currentRoute.value}resolveRouteWithStrategy(e,t,r){return f(this.i18nConfig.strategy)?this.router.resolve(e):t!==this.i18nConfig.defaultLocale||p(this.i18nConfig.strategy)?this.router.resolve(`/${r}${e}`):this.router.resolve(e)}switchLocaleLogic(e,t,r){const n=this.getCurrentLocale();let s;typeof r=="string"?s=this.resolveRouteWithStrategy(r,e,n):s=r??this.getCurrentRoute(),this.updateCookies(e);const i=this.switchLocaleRoute(n,e,s,t);return typeof i=="string"&&i.startsWith("http")?this.navigateTo(i,{redirectCode:200,external:!0}):(f(this.i18nConfig.strategy)&&(i.force=!0),this.router.push(i))}resolveLocalizedRoute(e,t){const r=this.getCurrentRoute(),n=this.getCurrentLocale(),s=t??n;let i;if(typeof e=="string")if(e.startsWith("/"))i=this.resolveRouteWithStrategy(e,s,n);else{const a=e;this.router.hasRoute(a)?i=this.router.resolve({name:a}):(e=`/${e}`,i=this.resolveRouteWithStrategy(e,s,n))}else i=e;return this.getLocalizedRoute(i,r,s)}}class P{formatNumber(e,t,r){return new Intl.NumberFormat(t,r).format(e)}formatDate(e,t,r){const n=new Date(e);return Number.isNaN(n.getTime())?"Invalid Date":new Intl.DateTimeFormat(t,r).format(n)}formatRelativeTime(e,t,r){const n=new Date(e);if(Number.isNaN(n.getTime()))return new Intl.RelativeTimeFormat(t,r).format(0,"second");const i=Math.floor((new Date().getTime()-n.getTime())/1e3),a=[{unit:"year",seconds:31536e3},{unit:"month",seconds:2592e3},{unit:"day",seconds:86400},{unit:"hour",seconds:3600},{unit:"minute",seconds:60},{unit:"second",seconds:1}];for(const{unit:l,seconds:c}of a){const u=Math.floor(i/c);if(u>=1)return new Intl.RelativeTimeFormat(t,r).format(-u,l)}return new Intl.RelativeTimeFormat(t,r).format(0,"second")}}class E{constructor(e={}){this.formatter=new P,this.helper=R(e.cache),this.formatter=new P,this.pluralFunc=e.plural||$,this.missingWarn=e.missingWarn??!0,this.missingHandler=e.missingHandler,this.getPreviousPageInfo=e.getPreviousPageInfo,this.getCustomMissingHandler=e.getCustomMissingHandler,this.enablePreviousPageFallback=e.enablePreviousPageFallback??!1}t(e,t,r,n){if(!e)return"";const s=this.getLocale(),i=n||this.getRoute();let a=this.helper.getTranslation(s,i,e);if(!a&&this.enablePreviousPageFallback&&this.getPreviousPageInfo){const l=this.getPreviousPageInfo();if(l){const c=this.helper.getTranslation(l.locale,l.routeName,e);c&&(a=c,process.env.NODE_ENV!=="production"&&console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`))}}if(!a){const l=this.getFallbackLocale();s!==l&&(a=this.helper.getTranslation(l,i,e))}if(!a){const l=this.getCustomMissingHandler?.();l?l(s,e,i):this.missingHandler?this.missingHandler(s,e,i):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${e}' key in '${s}' locale messages for route '${i}'.`),a=r===void 0?e:r||e}return typeof a=="string"&&t?b(a,t):a}ts(e,t,r,n){return this.t(e,t,r,n)?.toString()??r??e}tc(e,t,r){const{count:n,...s}=typeof t=="number"?{count:t}:t;if(n===void 0)return r??e;const i=(l,c,u)=>this.t(l,c,u);return this.pluralFunc(e,Number.parseInt(n.toString()),s,this.getLocale(),i)??r??e}tn(e,t){return this.formatter.formatNumber(e,this.getLocale(),t)}td(e,t){return this.formatter.formatDate(e,this.getLocale(),t)}tdr(e,t){return this.formatter.formatRelativeTime(e,this.getLocale(),t)}has(e,t){const r=t||this.getRoute(),n=this.getLocale();return!!this.helper.getTranslation(n,r,e)}clearCache(){this.helper.clearCache()}loadTranslationsCore(e,t,r){r?this.helper.mergeGlobalTranslation(e,t,!0):this.helper.loadTranslations(e,t)}loadRouteTranslationsCore(e,t,r,n){n?this.helper.mergeTranslation(e,t,r,!0):this.helper.loadPageTranslations(e,t,r)}}exports.BaseI18n=E;exports.FormatService=P;exports.RouteService=z;exports.defaultPlural=$;exports.interpolate=b;exports.isNoPrefixStrategy=f;exports.isPrefixAndDefaultStrategy=q;exports.isPrefixExceptDefaultStrategy=F;exports.isPrefixStrategy=D;exports.useTranslationHelper=R;exports.withPrefixStrategy=p;
package/dist/index.d.ts CHANGED
@@ -2,4 +2,5 @@ import { useTranslationHelper, TranslationCache } from './translation';
2
2
  import { RouteService } from './route-service';
3
3
  import { FormatService } from './format-service';
4
4
  import { interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural } from './helpers';
5
- export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, RouteService, FormatService, type TranslationCache, };
5
+ import { BaseI18n, BaseI18nOptions } from './base';
6
+ export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, RouteService, FormatService, BaseI18n, type TranslationCache, type BaseI18nOptions, };