@i18n-micro/core 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { useTranslationHelper, TranslationStorage } from './translation';
1
+ import { CleanTranslation, MissingHandler, Params, PluralFunc, TranslationKey, Translations } from '@i18n-micro/types';
2
2
  import { FormatService } from './format-service';
3
- import { Translations, Params, PluralFunc, CleanTranslation, TranslationKey, MissingHandler } from '@i18n-micro/types';
3
+ import { TranslationStorage, useTranslationHelper } from './translation';
4
4
  export interface BaseI18nOptions {
5
5
  storage?: TranslationStorage;
6
6
  plural?: PluralFunc;
package/dist/helpers.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Params, Strategies, PluralFunc } from '@i18n-micro/types';
1
+ import { Params, PluralFunc, Strategies } from '@i18n-micro/types';
2
2
  export declare function interpolate(template: string, params: Params): string;
3
3
  export declare function withPrefixStrategy(strategy: Strategies): strategy is "prefix" | "prefix_and_default";
4
4
  export declare function isNoPrefixStrategy(strategy: Strategies): strategy is "no_prefix";
package/dist/index.cjs CHANGED
@@ -1 +1 @@
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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class g{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),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(i/u);if(c>=1)return new Intl.RelativeTimeFormat(t,r).format(-c,l)}return new Intl.RelativeTimeFormat(t,r).format(0,"second")}}const p=/\{(\w+)\}/g;function h(s,e){return e?s.replace(p,(t,r)=>{const n=e[r];return n!==void 0?String(n):`{${r}}`}):s}function v(s){return s==="prefix"||s==="prefix_and_default"}function T(s){return s==="no_prefix"}function P(s){return s==="prefix"}function b(s){return s==="prefix_except_default"}function x(s){return s==="prefix_and_default"}const m=(s,e,t,r,n)=>{const a=n(s,t);if(!a)return null;const i=a.toString().split("|");if(i.length===0)return null;const o=e<i.length?i[e]:i[i.length-1];return o?o.trim().replace("{count}",e.toString()):null};function f(s,e){if(!s||typeof e!="string")return null;if(e in s){const n=s[e];return n}const t=e.split(".");let r=s;for(const n of t)if(r&&typeof r=="object"&&n in r)r=r[n];else return null;return r??null}function d(s){const e=s?.translations??new Map;return{hasCache(t,r){const n=`${t}:${r}`;return e.has(n)||e.has(t)},getCache(t,r){const n=`${t}:${r}`;return e.get(n)},setCache(t,r,n){},hasTranslation(t,r){for(const[n,a]of e)if((n===t||n.startsWith(`${t}:`))&&f(a,r)!==null)return!0;return!1},hasGeneralTranslation(t){return e.has(t)},hasPageTranslation(t,r){return e.has(`${t}:${r}`)},getTranslation(t,r,n){const a=`${t}:${r}`,i=e.get(a),o=f(i,n);if(o!==null)return o;const l=e.get(t);return f(l,n)},loadTranslations(t,r){const n=e.get(t)??{};e.set(t,{...n,...r})},setTranslations(t,r){e.set(t,r)},loadPageTranslations(t,r,n){const a=`${t}:${r}`,i=e.get(a);!i||Object.keys(i).length===0?e.set(a,n):e.set(a,{...i,...n})},mergeTranslation(t,r,n,a=!1){const i=`${t}:${r}`,o=e.get(i)??{};e.set(i,{...o,...n})},mergeGlobalTranslation(t,r,n=!1){const a=e.get(t)??{};e.set(t,{...a,...r})},clearCache(){e.clear()}}}class N{constructor(e={}){this.formatter=new g,this.helper=d(e.storage),this.formatter=new g,this.pluralFunc=e.plural||m,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 a=this.getLocale(),i=n||this.getRoute();let o=this.helper.getTranslation(a,i,e);if(!o&&this.enablePreviousPageFallback&&this.getPreviousPageInfo){const l=this.getPreviousPageInfo();if(l){const u=this.helper.getTranslation(l.locale,l.routeName,e);u&&(o=u,process.env.NODE_ENV!=="production"&&console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`))}}if(!o){const l=this.getFallbackLocale();a!==l&&(o=this.helper.getTranslation(l,i,e))}if(!o){const l=this.getCustomMissingHandler?.();l?l(a,e,i):this.missingHandler?this.missingHandler(a,e,i):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${e}' key in '${a}' locale messages for route '${i}'.`),o=r===void 0?e:r||e}return typeof o=="string"&&t?h(o,t):o}ts(e,t,r,n){return this.t(e,t,r,n)?.toString()??r??e}tc(e,t,r){const{count:n,...a}=typeof t=="number"?{count:t}:t;if(n===void 0)return r??e;const i=(l,u,c)=>this.t(l,u,c);return this.pluralFunc(e,Number.parseInt(n.toString(),10),a,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.setTranslations(e,t)}loadRouteTranslationsCore(e,t,r,n){n?this.helper.mergeTranslation(e,t,r,!0):this.helper.loadPageTranslations(e,t,r)}}exports.BaseI18n=N;exports.FormatService=g;exports.defaultPlural=m;exports.interpolate=h;exports.isNoPrefixStrategy=T;exports.isPrefixAndDefaultStrategy=x;exports.isPrefixExceptDefaultStrategy=b;exports.isPrefixStrategy=P;exports.useTranslationHelper=d;exports.withPrefixStrategy=v;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { useTranslationHelper, TranslationStorage } from './translation';
2
- import { RouteService } from './route-service';
3
- import { FormatService } from './format-service';
4
- import { interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural } from './helpers';
5
1
  import { BaseI18n, BaseI18nOptions } from './base';
6
- export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, RouteService, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, };
2
+ import { FormatService } from './format-service';
3
+ import { defaultPlural, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, withPrefixStrategy } from './helpers';
4
+ import { TranslationStorage, useTranslationHelper } from './translation';
5
+ export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, };
package/dist/index.mjs CHANGED
@@ -1,368 +1,177 @@
1
- function d(o, e) {
2
- if (!o || typeof e != "string") return null;
3
- if (e in o) {
4
- const s = o[e];
5
- return s;
1
+ class g {
2
+ formatNumber(e, t, n) {
3
+ return new Intl.NumberFormat(t, n).format(e);
4
+ }
5
+ formatDate(e, t, n) {
6
+ const r = new Date(e);
7
+ return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(t, n).format(r);
8
+ }
9
+ formatRelativeTime(e, t, n) {
10
+ const r = new Date(e);
11
+ if (Number.isNaN(r.getTime()))
12
+ return new Intl.RelativeTimeFormat(t, n).format(0, "second");
13
+ const i = Math.floor(((/* @__PURE__ */ new Date()).getTime() - r.getTime()) / 1e3), o = [
14
+ { unit: "year", seconds: 31536e3 },
15
+ { unit: "month", seconds: 2592e3 },
16
+ { unit: "day", seconds: 86400 },
17
+ { unit: "hour", seconds: 3600 },
18
+ { unit: "minute", seconds: 60 },
19
+ { unit: "second", seconds: 1 }
20
+ ];
21
+ for (const { unit: l, seconds: u } of o) {
22
+ const c = Math.floor(i / u);
23
+ if (c >= 1)
24
+ return new Intl.RelativeTimeFormat(t, n).format(-c, l);
25
+ }
26
+ return new Intl.RelativeTimeFormat(t, n).format(0, "second");
27
+ }
28
+ }
29
+ const h = /\{(\w+)\}/g;
30
+ function m(s, e) {
31
+ return e ? s.replace(h, (t, n) => {
32
+ const r = e[n];
33
+ return r !== void 0 ? String(r) : `{${n}}`;
34
+ }) : s;
35
+ }
36
+ function v(s) {
37
+ return s === "prefix" || s === "prefix_and_default";
38
+ }
39
+ function T(s) {
40
+ return s === "no_prefix";
41
+ }
42
+ function P(s) {
43
+ return s === "prefix";
44
+ }
45
+ function b(s) {
46
+ return s === "prefix_except_default";
47
+ }
48
+ function N(s) {
49
+ return s === "prefix_and_default";
50
+ }
51
+ const d = (s, e, t, n, r) => {
52
+ const a = r(s, t);
53
+ if (!a)
54
+ return null;
55
+ const i = a.toString().split("|");
56
+ if (i.length === 0) return null;
57
+ const o = e < i.length ? i[e] : i[i.length - 1];
58
+ return o ? o.trim().replace("{count}", e.toString()) : null;
59
+ };
60
+ function f(s, e) {
61
+ if (!s || typeof e != "string") return null;
62
+ if (e in s) {
63
+ const r = s[e];
64
+ return r;
6
65
  }
7
66
  const t = e.split(".");
8
- let r = o;
9
- for (const s of t)
10
- if (r && typeof r == "object" && s in r)
11
- r = r[s];
67
+ let n = s;
68
+ for (const r of t)
69
+ if (n && typeof n == "object" && r in n)
70
+ n = n[r];
12
71
  else
13
72
  return null;
14
- return r ?? null;
73
+ return n ?? null;
15
74
  }
16
- function C(o) {
17
- const e = o?.translations ?? /* @__PURE__ */ new Map();
75
+ function p(s) {
76
+ const e = s?.translations ?? /* @__PURE__ */ new Map();
18
77
  return {
19
- hasCache(t, r) {
20
- const s = `${t}:${r}`;
21
- return e.has(s) || e.has(t);
78
+ hasCache(t, n) {
79
+ const r = `${t}:${n}`;
80
+ return e.has(r) || e.has(t);
22
81
  },
23
- getCache(t, r) {
24
- const s = `${t}:${r}`;
25
- return e.get(s);
82
+ getCache(t, n) {
83
+ const r = `${t}:${n}`;
84
+ return e.get(r);
26
85
  },
27
- setCache(t, r, s) {
86
+ setCache(t, n, r) {
28
87
  },
29
- hasTranslation(t, r) {
30
- for (const [s, n] of e)
31
- if ((s === t || s.startsWith(`${t}:`)) && d(n, r) !== null)
88
+ hasTranslation(t, n) {
89
+ for (const [r, a] of e)
90
+ if ((r === t || r.startsWith(`${t}:`)) && f(a, n) !== null)
32
91
  return !0;
33
92
  return !1;
34
93
  },
35
94
  hasGeneralTranslation(t) {
36
95
  return e.has(t);
37
96
  },
38
- hasPageTranslation(t, r) {
39
- return e.has(`${t}:${r}`);
97
+ hasPageTranslation(t, n) {
98
+ return e.has(`${t}:${n}`);
40
99
  },
41
- getTranslation(t, r, s) {
42
- const n = `${t}:${r}`, i = e.get(n), a = d(i, s);
43
- if (a !== null) return a;
100
+ getTranslation(t, n, r) {
101
+ const a = `${t}:${n}`, i = e.get(a), o = f(i, r);
102
+ if (o !== null) return o;
44
103
  const l = e.get(t);
45
- return d(l, s);
104
+ return f(l, r);
46
105
  },
47
- loadTranslations(t, r) {
48
- const s = e.get(t) ?? {};
49
- e.set(t, { ...s, ...r });
106
+ loadTranslations(t, n) {
107
+ const r = e.get(t) ?? {};
108
+ e.set(t, { ...r, ...n });
50
109
  },
51
- setTranslations(t, r) {
52
- e.set(t, r);
110
+ setTranslations(t, n) {
111
+ e.set(t, n);
53
112
  },
54
- loadPageTranslations(t, r, s) {
55
- const n = `${t}:${r}`, i = e.get(n);
56
- !i || Object.keys(i).length === 0 ? e.set(n, s) : e.set(n, { ...i, ...s });
113
+ loadPageTranslations(t, n, r) {
114
+ const a = `${t}:${n}`, i = e.get(a);
115
+ !i || Object.keys(i).length === 0 ? e.set(a, r) : e.set(a, { ...i, ...r });
57
116
  },
58
- mergeTranslation(t, r, s, n = !1) {
59
- const i = `${t}:${r}`, a = e.get(i) ?? {};
60
- e.set(i, { ...a, ...s });
117
+ mergeTranslation(t, n, r, a = !1) {
118
+ const i = `${t}:${n}`, o = e.get(i) ?? {};
119
+ e.set(i, { ...o, ...r });
61
120
  },
62
- mergeGlobalTranslation(t, r, s = !1) {
63
- const n = e.get(t) ?? {};
64
- e.set(t, { ...n, ...r });
121
+ mergeGlobalTranslation(t, n, r = !1) {
122
+ const a = e.get(t) ?? {};
123
+ e.set(t, { ...a, ...n });
65
124
  },
66
125
  clearCache() {
67
126
  e.clear();
68
127
  }
69
128
  };
70
129
  }
71
- const y = /\{(\w+)\}/g;
72
- function P(o, e) {
73
- return e ? o.replace(y, (t, r) => {
74
- const s = e[r];
75
- return s !== void 0 ? String(s) : `{${r}}`;
76
- }) : o;
77
- }
78
- function f(o) {
79
- return o === "prefix" || o === "prefix_and_default";
80
- }
81
- function c(o) {
82
- return o === "no_prefix";
83
- }
84
- function b(o) {
85
- return o === "prefix";
86
- }
87
- function R(o) {
88
- return o === "prefix_except_default";
89
- }
90
- function $(o) {
91
- return o === "prefix_and_default";
92
- }
93
- const L = (o, e, t, r, s) => {
94
- const n = s(o, t);
95
- if (!n)
96
- return null;
97
- const i = n.toString().split("|");
98
- if (i.length === 0) return null;
99
- const a = e < i.length ? i[e] : i[i.length - 1];
100
- return a ? a.trim().replace("{count}", e.toString()) : null;
101
- };
102
- class w {
103
- constructor(e, t, r, s, n, i) {
104
- this.i18nConfig = e, this.router = t, this.hashLocaleDefault = r, this.noPrefixDefault = s, this.navigateTo = n, this.getDefaultLocale = i;
105
- }
106
- /**
107
- * Extracts locale from URL path by checking the first path segment
108
- * @param path - URL path (e.g., '/ru/sdfsdf' or '/en/about')
109
- * @returns Locale code or null if not found
110
- */
111
- extractLocaleFromPath(e) {
112
- if (!e)
113
- return null;
114
- const r = e.split("?")[0]?.split("#")[0];
115
- if (!r || r === "/")
116
- return null;
117
- const s = r.split("/").filter(Boolean);
118
- if (s.length === 0)
119
- return null;
120
- const n = s[0];
121
- return n && (this.i18nConfig.locales?.map((a) => a.code) || []).includes(n) ? n : null;
122
- }
123
- getCurrentLocale(e) {
124
- if (e = e ?? this.router.currentRoute.value, this.i18nConfig.hashMode) {
125
- const n = this.getDefaultLocale?.();
126
- if (n) return n;
127
- if (this.hashLocaleDefault) return this.hashLocaleDefault;
128
- }
129
- if (c(this.i18nConfig.strategy)) {
130
- const n = this.getDefaultLocale?.();
131
- if (n) return n;
132
- if (this.noPrefixDefault) return this.noPrefixDefault;
133
- }
134
- const t = e.path || e.fullPath || "";
135
- if ($(this.i18nConfig.strategy) && (t === "/" || t === "")) {
136
- const n = this.getDefaultLocale?.();
137
- if (n) return n;
138
- }
139
- if (e.params?.locale)
140
- return e.params.locale.toString();
141
- const r = this.extractLocaleFromPath(t);
142
- if (r)
143
- return r;
144
- if (R(this.i18nConfig.strategy))
145
- return (this.i18nConfig.defaultLocale || "en").toString();
146
- const s = this.getDefaultLocale?.();
147
- return s || (this.i18nConfig.defaultLocale || "en").toString();
148
- }
149
- getCurrentName(e) {
150
- const t = this.getCurrentLocale(e);
151
- return this.i18nConfig.locales?.find((s) => s.code === t)?.displayName ?? null;
152
- }
153
- getRouteName(e, t) {
154
- return (e.name ?? "").toString().toString().replace("localized-", "").replace(new RegExp(`-${t}$`), "");
155
- }
156
- getPluginRouteName(e, t) {
157
- return this.i18nConfig.disablePageLocales ? "general" : this.getRouteName(e, t);
158
- }
159
- getFullPathWithBaseUrl(e, t) {
160
- let s = this.router.resolve(t).fullPath;
161
- e?.baseDefault && (s = s.replace(new RegExp(`^/${e.code}`), ""));
162
- let n = e.baseUrl;
163
- return n || (n = ""), n?.endsWith("/") && (n = n.slice(0, -1)), n + s;
164
- }
165
- switchLocaleRoute(e, t, r, s) {
166
- const n = this.i18nConfig.locales?.find((g) => g.code === t), i = this.getRouteName(r, e);
167
- if (this.router.hasRoute(`localized-${i}-${t}`)) {
168
- const m = { ...s?.[t] ? { ...s[t] } : { ...r.params ?? {} } };
169
- delete m.locale, c(this.i18nConfig.strategy) || (m.locale = t);
170
- const p = {
171
- name: `localized-${i}-${t}`,
172
- params: m,
173
- query: r.query,
174
- hash: r.hash
175
- };
176
- return n?.baseUrl ? this.getFullPathWithBaseUrl(n, p) : p;
177
- }
178
- let a = i;
179
- const u = { ...s?.[t] ? { ...s[t] } : { ...r.params ?? {} } };
180
- delete u.locale, c(this.i18nConfig.strategy) || (i === "custom-fallback-route" ? a = i : a = t !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy) ? `localized-${i}` : i, c(this.i18nConfig.strategy) || (t !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy)) && (u.locale = t));
181
- const h = {
182
- name: a,
183
- params: u,
184
- query: r.query,
185
- hash: r.hash
186
- };
187
- return c(this.i18nConfig.strategy) && this.i18nConfig.locales?.forEach((g, m) => {
188
- h.name.endsWith(`-${g.code}`) && (h.name = h.name.slice(0, -g.code - 1));
189
- }), n?.baseUrl ? this.getFullPathWithBaseUrl(n, h) : h;
190
- }
191
- resolveParams(e) {
192
- const t = typeof e == "object" && "params" in e && typeof e.params == "object" ? { ...e.params } : {};
193
- if (typeof e == "string") {
194
- const r = this.router.resolve(e);
195
- r && r.params && Object.assign(t, r.params);
196
- }
197
- return t;
198
- }
199
- handlePrefixStrategy(e) {
200
- if (!f(this.i18nConfig.strategy))
201
- return e;
202
- const t = this.i18nConfig.defaultLocale;
203
- let r = e;
204
- typeof e == "string" && (r = this.router.resolve("/" + t + e));
205
- const s = this.getRouteName(r, t), n = this.resolveParams(r);
206
- return c(this.i18nConfig.strategy) || (n.locale = t), this.router.hasRoute(`localized-${s}`) ? this.router.resolve({
207
- name: `localized-${s}`,
208
- query: r.query,
209
- hash: r.hash,
210
- params: n
211
- }) : this.router.hasRoute(`localized-${s}-${t}`) ? this.router.resolve({
212
- name: `localized-${s}-${t}`,
213
- query: r.query,
214
- hash: r.hash,
215
- params: n
216
- }) : e;
217
- }
218
- createLocalizedRoute(e, t, r) {
219
- const s = this.router.resolve(e), n = this.getRouteName(s, r).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`), "");
220
- if (!c(this.i18nConfig.strategy) && (!n || n === "")) {
221
- let u = this.router.resolve(e).path.replace(new RegExp(`^/${r}/`), "/");
222
- return (r !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy)) && (u = "/" + r + u), this.router.resolve({
223
- path: u,
224
- query: s.query,
225
- hash: s.hash
226
- });
227
- }
228
- if (this.router.hasRoute(`localized-${n}-${r}`)) {
229
- const l = this.resolveParams(s);
230
- return c(this.i18nConfig.strategy) || (l.locale = r), this.router.resolve({
231
- name: `localized-${n}-${r}`,
232
- params: l,
233
- query: s.query,
234
- hash: s.hash
235
- });
236
- }
237
- const i = r !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy) ? `localized-${n}` : n;
238
- if (!this.router.hasRoute(i)) {
239
- const l = this.resolveParams(e);
240
- return delete l.locale, this.router.hasRoute(n) ? this.router.resolve({
241
- name: n,
242
- params: l,
243
- query: s.query,
244
- hash: s.hash
245
- }) : this.router.resolve("/");
246
- }
247
- const a = this.resolveParams(e);
248
- return delete a.locale, c(this.i18nConfig.strategy) || (r !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy)) && (a.locale = r), this.router.resolve({
249
- name: i,
250
- params: a,
251
- query: s.query,
252
- hash: s.hash
253
- });
254
- }
255
- getLocalizedRoute(e, t, r) {
256
- const s = r || this.getCurrentLocale(t), n = this.handlePrefixStrategy(e);
257
- return this.createLocalizedRoute(n, t, s);
258
- }
259
- getCurrentRoute() {
260
- return this.router.currentRoute.value;
261
- }
262
- resolveRouteWithStrategy(e, t, r) {
263
- return c(this.i18nConfig.strategy) ? this.router.resolve(e) : t !== this.i18nConfig.defaultLocale || f(this.i18nConfig.strategy) ? this.router.resolve(`/${r}${e}`) : this.router.resolve(e);
264
- }
265
- switchLocaleLogic(e, t, r) {
266
- const s = this.getCurrentLocale();
267
- let n;
268
- typeof r == "string" ? n = this.resolveRouteWithStrategy(r, e, s) : n = r ?? this.getCurrentRoute();
269
- const i = this.switchLocaleRoute(s, e, n, t);
270
- return typeof i == "string" && i.startsWith("http") ? this.navigateTo(i, { redirectCode: 200, external: !0 }) : (c(this.i18nConfig.strategy) && (i.force = !0), this.router.push(i));
271
- }
272
- resolveLocalizedRoute(e, t) {
273
- const r = this.getCurrentRoute(), s = this.getCurrentLocale(), n = t ?? s;
274
- let i;
275
- if (typeof e == "string")
276
- if (e.startsWith("/"))
277
- i = this.resolveRouteWithStrategy(e, n, s);
278
- else {
279
- const a = e;
280
- this.router.hasRoute(a) ? i = this.router.resolve({ name: a }) : (e = `/${e}`, i = this.resolveRouteWithStrategy(e, n, s));
281
- }
282
- else
283
- i = e;
284
- return this.getLocalizedRoute(i, r, n);
285
- }
286
- }
287
- class v {
288
- formatNumber(e, t, r) {
289
- return new Intl.NumberFormat(t, r).format(e);
290
- }
291
- formatDate(e, t, r) {
292
- const s = new Date(e);
293
- return Number.isNaN(s.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(t, r).format(s);
294
- }
295
- formatRelativeTime(e, t, r) {
296
- const s = new Date(e);
297
- if (Number.isNaN(s.getTime()))
298
- return new Intl.RelativeTimeFormat(t, r).format(0, "second");
299
- const i = Math.floor(((/* @__PURE__ */ new Date()).getTime() - s.getTime()) / 1e3), a = [
300
- { unit: "year", seconds: 31536e3 },
301
- { unit: "month", seconds: 2592e3 },
302
- { unit: "day", seconds: 86400 },
303
- { unit: "hour", seconds: 3600 },
304
- { unit: "minute", seconds: 60 },
305
- { unit: "second", seconds: 1 }
306
- ];
307
- for (const { unit: l, seconds: u } of a) {
308
- const h = Math.floor(i / u);
309
- if (h >= 1)
310
- return new Intl.RelativeTimeFormat(t, r).format(-h, l);
311
- }
312
- return new Intl.RelativeTimeFormat(t, r).format(0, "second");
313
- }
314
- }
315
- class T {
130
+ class $ {
316
131
  constructor(e = {}) {
317
- this.formatter = new v(), this.helper = C(e.storage), this.formatter = new v(), this.pluralFunc = e.plural || L, this.missingWarn = e.missingWarn ?? !0, this.missingHandler = e.missingHandler, this.getPreviousPageInfo = e.getPreviousPageInfo, this.getCustomMissingHandler = e.getCustomMissingHandler, this.enablePreviousPageFallback = e.enablePreviousPageFallback ?? !1;
132
+ this.formatter = new g(), this.helper = p(e.storage), this.formatter = new g(), this.pluralFunc = e.plural || d, this.missingWarn = e.missingWarn ?? !0, this.missingHandler = e.missingHandler, this.getPreviousPageInfo = e.getPreviousPageInfo, this.getCustomMissingHandler = e.getCustomMissingHandler, this.enablePreviousPageFallback = e.enablePreviousPageFallback ?? !1;
318
133
  }
319
134
  // --- Public methods (implemented in base class) ---
320
135
  /**
321
136
  * Get translation for a key
322
137
  * Based on logic from src/runtime/plugins/01.plugin.ts
323
138
  */
324
- t(e, t, r, s) {
139
+ t(e, t, n, r) {
325
140
  if (!e) return "";
326
- const n = this.getLocale(), i = s || this.getRoute();
327
- let a = this.helper.getTranslation(n, i, e);
328
- if (!a && this.enablePreviousPageFallback && this.getPreviousPageInfo) {
141
+ const a = this.getLocale(), i = r || this.getRoute();
142
+ let o = this.helper.getTranslation(a, i, e);
143
+ if (!o && this.enablePreviousPageFallback && this.getPreviousPageInfo) {
329
144
  const l = this.getPreviousPageInfo();
330
145
  if (l) {
331
146
  const u = this.helper.getTranslation(l.locale, l.routeName, e);
332
- u && (a = u, process.env.NODE_ENV !== "production" && console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`));
147
+ u && (o = u, process.env.NODE_ENV !== "production" && console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`));
333
148
  }
334
149
  }
335
- if (!a) {
150
+ if (!o) {
336
151
  const l = this.getFallbackLocale();
337
- n !== l && (a = this.helper.getTranslation(l, i, e));
152
+ a !== l && (o = this.helper.getTranslation(l, i, e));
338
153
  }
339
- if (!a) {
154
+ if (!o) {
340
155
  const l = this.getCustomMissingHandler?.();
341
- l ? l(n, e, i) : this.missingHandler ? this.missingHandler(n, e, i) : this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${e}' key in '${n}' locale messages for route '${i}'.`), a = r === void 0 ? e : r || e;
156
+ l ? l(a, e, i) : this.missingHandler ? this.missingHandler(a, e, i) : this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${e}' key in '${a}' locale messages for route '${i}'.`), o = n === void 0 ? e : n || e;
342
157
  }
343
- return typeof a == "string" && t ? P(a, t) : a;
158
+ return typeof o == "string" && t ? m(o, t) : o;
344
159
  }
345
160
  /**
346
161
  * Get translation as string
347
162
  */
348
- ts(e, t, r, s) {
349
- return this.t(e, t, r, s)?.toString() ?? r ?? e;
163
+ ts(e, t, n, r) {
164
+ return this.t(e, t, n, r)?.toString() ?? n ?? e;
350
165
  }
351
166
  /**
352
167
  * Plural translation
353
168
  */
354
- tc(e, t, r) {
355
- const { count: s, ...n } = typeof t == "number" ? { count: t } : t;
356
- if (s === void 0)
357
- return r ?? e;
358
- const i = (l, u, h) => this.t(l, u, h);
359
- return this.pluralFunc(
360
- e,
361
- Number.parseInt(s.toString()),
362
- n,
363
- this.getLocale(),
364
- i
365
- ) ?? r ?? e;
169
+ tc(e, t, n) {
170
+ const { count: r, ...a } = typeof t == "number" ? { count: t } : t;
171
+ if (r === void 0)
172
+ return n ?? e;
173
+ const i = (l, u, c) => this.t(l, u, c);
174
+ return this.pluralFunc(e, Number.parseInt(r.toString(), 10), a, this.getLocale(), i) ?? n ?? e;
366
175
  }
367
176
  /**
368
177
  * Format number
@@ -387,8 +196,8 @@ class T {
387
196
  * Based on logic from src/runtime/plugins/01.plugin.ts
388
197
  */
389
198
  has(e, t) {
390
- const r = t || this.getRoute(), s = this.getLocale();
391
- return !!this.helper.getTranslation(s, r, e);
199
+ const n = t || this.getRoute(), r = this.getLocale();
200
+ return !!this.helper.getTranslation(r, n, e);
392
201
  }
393
202
  /**
394
203
  * Clear cache
@@ -401,27 +210,26 @@ class T {
401
210
  * Core translation loading logic (without reactivity)
402
211
  * Subclasses can override addTranslations/addRouteTranslations to add reactivity
403
212
  */
404
- loadTranslationsCore(e, t, r) {
405
- r ? this.helper.mergeGlobalTranslation(e, t, !0) : this.helper.setTranslations(e, t);
213
+ loadTranslationsCore(e, t, n) {
214
+ n ? this.helper.mergeGlobalTranslation(e, t, !0) : this.helper.setTranslations(e, t);
406
215
  }
407
216
  /**
408
217
  * Core route translation loading logic (without reactivity)
409
218
  * Subclasses can override addRouteTranslations to add reactivity
410
219
  */
411
- loadRouteTranslationsCore(e, t, r, s) {
412
- s ? this.helper.mergeTranslation(e, t, r, !0) : this.helper.loadPageTranslations(e, t, r);
220
+ loadRouteTranslationsCore(e, t, n, r) {
221
+ r ? this.helper.mergeTranslation(e, t, n, !0) : this.helper.loadPageTranslations(e, t, n);
413
222
  }
414
223
  }
415
224
  export {
416
- T as BaseI18n,
417
- v as FormatService,
418
- w as RouteService,
419
- L as defaultPlural,
420
- P as interpolate,
421
- c as isNoPrefixStrategy,
422
- $ as isPrefixAndDefaultStrategy,
423
- R as isPrefixExceptDefaultStrategy,
424
- b as isPrefixStrategy,
425
- C as useTranslationHelper,
426
- f as withPrefixStrategy
225
+ $ as BaseI18n,
226
+ g as FormatService,
227
+ d as defaultPlural,
228
+ m as interpolate,
229
+ T as isNoPrefixStrategy,
230
+ N as isPrefixAndDefaultStrategy,
231
+ b as isPrefixExceptDefaultStrategy,
232
+ P as isPrefixStrategy,
233
+ p as useTranslationHelper,
234
+ v as withPrefixStrategy
427
235
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-micro/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "keywords": [],
24
24
  "dependencies": {
25
- "@i18n-micro/types": "1.1.0"
25
+ "@i18n-micro/types": "1.1.1"
26
26
  },
27
27
  "devDependencies": {
28
28
  "vite": "^7.3.1",