@i18n-micro/core 1.0.27 → 1.1.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.
- package/dist/base.d.ts +91 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +329 -268
- package/dist/route-service.d.ts +6 -5
- package/dist/translation.d.ts +16 -17
- package/package.json +4 -4
- package/src/base.ts +250 -0
- package/src/helpers.ts +7 -6
- package/src/index.ts +5 -2
- package/src/route-service.ts +29 -33
- package/src/translation.ts +71 -181
- package/tests/base.test.ts +485 -0
- package/tests/route-service.test.ts +31 -61
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useTranslationHelper, TranslationStorage } 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
|
+
storage?: TranslationStorage;
|
|
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"});function d(o,e){if(!o||typeof e!="string")return null;if(e in o){const s=o[e];return s}const t=e.split(".");let r=o;for(const s of t)if(r&&typeof r=="object"&&s in r)r=r[s];else return null;return r??null}function y(o){const e=o?.translations??new Map;return{hasCache(t,r){const s=`${t}:${r}`;return e.has(s)||e.has(t)},getCache(t,r){const s=`${t}:${r}`;return e.get(s)},setCache(t,r,s){},hasTranslation(t,r){for(const[s,i]of e)if((s===t||s.startsWith(`${t}:`))&&d(i,r)!==null)return!0;return!1},hasGeneralTranslation(t){return e.has(t)},hasPageTranslation(t,r){return e.has(`${t}:${r}`)},getTranslation(t,r,s){const i=`${t}:${r}`,n=e.get(i),a=d(n,s);if(a!==null)return a;const l=e.get(t);return d(l,s)},loadTranslations(t,r){const s=e.get(t)??{};e.set(t,{...s,...r})},setTranslations(t,r){e.set(t,r)},loadPageTranslations(t,r,s){const i=`${t}:${r}`,n=e.get(i);!n||Object.keys(n).length===0?e.set(i,s):e.set(i,{...n,...s})},mergeTranslation(t,r,s,i=!1){const n=`${t}:${r}`,a=e.get(n)??{};e.set(n,{...a,...s})},mergeGlobalTranslation(t,r,s=!1){const i=e.get(t)??{};e.set(t,{...i,...r})},clearCache(){e.clear()}}}const L=/\{(\w+)\}/g;function C(o,e){return e?o.replace(L,(t,r)=>{const s=e[r];return s!==void 0?String(s):`{${r}}`}):o}function f(o){return o==="prefix"||o==="prefix_and_default"}function h(o){return o==="no_prefix"}function b(o){return o==="prefix"}function P(o){return o==="prefix_except_default"}function R(o){return o==="prefix_and_default"}const $=(o,e,t,r,s)=>{const i=s(o,t);if(!i)return null;const n=i.toString().split("|");if(n.length===0)return null;const a=e<n.length?n[e]:n[n.length-1];return a?a.trim().replace("{count}",e.toString()):null};class w{constructor(e,t,r,s,i,n){this.i18nConfig=e,this.router=t,this.hashLocaleDefault=r,this.noPrefixDefault=s,this.navigateTo=i,this.getDefaultLocale=n}extractLocaleFromPath(e){if(!e)return null;const r=e.split("?")[0]?.split("#")[0];if(!r||r==="/")return null;const s=r.split("/").filter(Boolean);if(s.length===0)return null;const i=s[0];return i&&(this.i18nConfig.locales?.map(a=>a.code)||[]).includes(i)?i:null}getCurrentLocale(e){if(e=e??this.router.currentRoute.value,this.i18nConfig.hashMode){const i=this.getDefaultLocale?.();if(i)return i;if(this.hashLocaleDefault)return this.hashLocaleDefault}if(h(this.i18nConfig.strategy)){const i=this.getDefaultLocale?.();if(i)return i;if(this.noPrefixDefault)return this.noPrefixDefault}const t=e.path||e.fullPath||"";if(R(this.i18nConfig.strategy)&&(t==="/"||t==="")){const i=this.getDefaultLocale?.();if(i)return i}if(e.params?.locale)return e.params.locale.toString();const r=this.extractLocaleFromPath(t);if(r)return r;if(P(this.i18nConfig.strategy))return(this.i18nConfig.defaultLocale||"en").toString();const s=this.getDefaultLocale?.();return s||(this.i18nConfig.defaultLocale||"en").toString()}getCurrentName(e){const t=this.getCurrentLocale(e);return this.i18nConfig.locales?.find(s=>s.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 s=this.router.resolve(t).fullPath;e?.baseDefault&&(s=s.replace(new RegExp(`^/${e.code}`),""));let i=e.baseUrl;return i||(i=""),i?.endsWith("/")&&(i=i.slice(0,-1)),i+s}switchLocaleRoute(e,t,r,s){const i=this.i18nConfig.locales?.find(g=>g.code===t),n=this.getRouteName(r,e);if(this.router.hasRoute(`localized-${n}-${t}`)){const m={...s?.[t]?{...s[t]}:{...r.params??{}}};delete m.locale,h(this.i18nConfig.strategy)||(m.locale=t);const v={name:`localized-${n}-${t}`,params:m,query:r.query,hash:r.hash};return i?.baseUrl?this.getFullPathWithBaseUrl(i,v):v}let a=n;const u={...s?.[t]?{...s[t]}:{...r.params??{}}};delete u.locale,h(this.i18nConfig.strategy)||(n==="custom-fallback-route"?a=n:a=t!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy)?`localized-${n}`:n,h(this.i18nConfig.strategy)||(t!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy))&&(u.locale=t));const c={name:a,params:u,query:r.query,hash:r.hash};return h(this.i18nConfig.strategy)&&this.i18nConfig.locales?.forEach((g,m)=>{c.name.endsWith(`-${g.code}`)&&(c.name=c.name.slice(0,-g.code-1))}),i?.baseUrl?this.getFullPathWithBaseUrl(i,c):c}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(!f(this.i18nConfig.strategy))return e;const t=this.i18nConfig.defaultLocale;let r=e;typeof e=="string"&&(r=this.router.resolve("/"+t+e));const s=this.getRouteName(r,t),i=this.resolveParams(r);return h(this.i18nConfig.strategy)||(i.locale=t),this.router.hasRoute(`localized-${s}`)?this.router.resolve({name:`localized-${s}`,query:r.query,hash:r.hash,params:i}):this.router.hasRoute(`localized-${s}-${t}`)?this.router.resolve({name:`localized-${s}-${t}`,query:r.query,hash:r.hash,params:i}):e}createLocalizedRoute(e,t,r){const s=this.router.resolve(e),i=this.getRouteName(s,r).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`),"");if(!h(this.i18nConfig.strategy)&&(!i||i==="")){let u=this.router.resolve(e).path.replace(new RegExp(`^/${r}/`),"/");return(r!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy))&&(u="/"+r+u),this.router.resolve({path:u,query:s.query,hash:s.hash})}if(this.router.hasRoute(`localized-${i}-${r}`)){const l=this.resolveParams(s);return h(this.i18nConfig.strategy)||(l.locale=r),this.router.resolve({name:`localized-${i}-${r}`,params:l,query:s.query,hash:s.hash})}const n=r!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy)?`localized-${i}`:i;if(!this.router.hasRoute(n)){const l=this.resolveParams(e);return delete l.locale,this.router.hasRoute(i)?this.router.resolve({name:i,params:l,query:s.query,hash:s.hash}):this.router.resolve("/")}const a=this.resolveParams(e);return delete a.locale,h(this.i18nConfig.strategy)||(r!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy))&&(a.locale=r),this.router.resolve({name:n,params:a,query:s.query,hash:s.hash})}getLocalizedRoute(e,t,r){const s=r||this.getCurrentLocale(t),i=this.handlePrefixStrategy(e);return this.createLocalizedRoute(i,t,s)}getCurrentRoute(){return this.router.currentRoute.value}resolveRouteWithStrategy(e,t,r){return h(this.i18nConfig.strategy)?this.router.resolve(e):t!==this.i18nConfig.defaultLocale||f(this.i18nConfig.strategy)?this.router.resolve(`/${r}${e}`):this.router.resolve(e)}switchLocaleLogic(e,t,r){const s=this.getCurrentLocale();let i;typeof r=="string"?i=this.resolveRouteWithStrategy(r,e,s):i=r??this.getCurrentRoute();const n=this.switchLocaleRoute(s,e,i,t);return typeof n=="string"&&n.startsWith("http")?this.navigateTo(n,{redirectCode:200,external:!0}):(h(this.i18nConfig.strategy)&&(n.force=!0),this.router.push(n))}resolveLocalizedRoute(e,t){const r=this.getCurrentRoute(),s=this.getCurrentLocale(),i=t??s;let n;if(typeof e=="string")if(e.startsWith("/"))n=this.resolveRouteWithStrategy(e,i,s);else{const a=e;this.router.hasRoute(a)?n=this.router.resolve({name:a}):(e=`/${e}`,n=this.resolveRouteWithStrategy(e,i,s))}else n=e;return this.getLocalizedRoute(n,r,i)}}class p{formatNumber(e,t,r){return new Intl.NumberFormat(t,r).format(e)}formatDate(e,t,r){const s=new Date(e);return Number.isNaN(s.getTime())?"Invalid Date":new Intl.DateTimeFormat(t,r).format(s)}formatRelativeTime(e,t,r){const s=new Date(e);if(Number.isNaN(s.getTime()))return new Intl.RelativeTimeFormat(t,r).format(0,"second");const n=Math.floor((new Date().getTime()-s.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:u}of a){const c=Math.floor(n/u);if(c>=1)return new Intl.RelativeTimeFormat(t,r).format(-c,l)}return new Intl.RelativeTimeFormat(t,r).format(0,"second")}}class S{constructor(e={}){this.formatter=new p,this.helper=y(e.storage),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,s){if(!e)return"";const i=this.getLocale(),n=s||this.getRoute();let a=this.helper.getTranslation(i,n,e);if(!a&&this.enablePreviousPageFallback&&this.getPreviousPageInfo){const l=this.getPreviousPageInfo();if(l){const u=this.helper.getTranslation(l.locale,l.routeName,e);u&&(a=u,process.env.NODE_ENV!=="production"&&console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`))}}if(!a){const l=this.getFallbackLocale();i!==l&&(a=this.helper.getTranslation(l,n,e))}if(!a){const l=this.getCustomMissingHandler?.();l?l(i,e,n):this.missingHandler?this.missingHandler(i,e,n):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${e}' key in '${i}' locale messages for route '${n}'.`),a=r===void 0?e:r||e}return typeof a=="string"&&t?C(a,t):a}ts(e,t,r,s){return this.t(e,t,r,s)?.toString()??r??e}tc(e,t,r){const{count:s,...i}=typeof t=="number"?{count:t}:t;if(s===void 0)return r??e;const n=(l,u,c)=>this.t(l,u,c);return this.pluralFunc(e,Number.parseInt(s.toString()),i,this.getLocale(),n)??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(),s=this.getLocale();return!!this.helper.getTranslation(s,r,e)}clearCache(){this.helper.clearCache()}loadTranslationsCore(e,t,r){r?this.helper.mergeGlobalTranslation(e,t,!0):this.helper.setTranslations(e,t)}loadRouteTranslationsCore(e,t,r,s){s?this.helper.mergeTranslation(e,t,r,!0):this.helper.loadPageTranslations(e,t,r)}}exports.BaseI18n=S;exports.FormatService=p;exports.RouteService=w;exports.defaultPlural=$;exports.interpolate=C;exports.isNoPrefixStrategy=h;exports.isPrefixAndDefaultStrategy=R;exports.isPrefixExceptDefaultStrategy=P;exports.isPrefixStrategy=b;exports.useTranslationHelper=y;exports.withPrefixStrategy=f;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useTranslationHelper,
|
|
1
|
+
import { useTranslationHelper, TranslationStorage } 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
|
-
|
|
5
|
+
import { BaseI18n, BaseI18nOptions } from './base';
|
|
6
|
+
export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, RouteService, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, };
|