@i18n-micro/core 1.1.1 → 1.1.3

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 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 h(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 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 m(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 d=(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};class N{constructor(e={}){this.formatter=new g,this.helper=h(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}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?m(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()),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=d;exports.interpolate=m;exports.isNoPrefixStrategy=T;exports.isPrefixAndDefaultStrategy=x;exports.isPrefixExceptDefaultStrategy=b;exports.isPrefixStrategy=P;exports.useTranslationHelper=h;exports.withPrefixStrategy=v;
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,5 +1,5 @@
1
- import { useTranslationHelper, TranslationStorage } from './translation';
2
- import { FormatService } from './format-service';
3
- import { interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural } from './helpers';
4
1
  import { BaseI18n, BaseI18nOptions } from './base';
2
+ import { FormatService } from './format-service';
3
+ import { defaultPlural, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, withPrefixStrategy } from './helpers';
4
+ import { TranslationStorage, useTranslationHelper } from './translation';
5
5
  export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, };
package/dist/index.mjs CHANGED
@@ -1,3 +1,62 @@
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
+ };
1
60
  function f(s, e) {
2
61
  if (!s || typeof e != "string") return null;
3
62
  if (e in s) {
@@ -13,7 +72,7 @@ function f(s, e) {
13
72
  return null;
14
73
  return n ?? null;
15
74
  }
16
- function h(s) {
75
+ function p(s) {
17
76
  const e = s?.translations ?? /* @__PURE__ */ new Map();
18
77
  return {
19
78
  hasCache(t, n) {
@@ -68,68 +127,9 @@ function h(s) {
68
127
  }
69
128
  };
70
129
  }
71
- class g {
72
- formatNumber(e, t, n) {
73
- return new Intl.NumberFormat(t, n).format(e);
74
- }
75
- formatDate(e, t, n) {
76
- const r = new Date(e);
77
- return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(t, n).format(r);
78
- }
79
- formatRelativeTime(e, t, n) {
80
- const r = new Date(e);
81
- if (Number.isNaN(r.getTime()))
82
- return new Intl.RelativeTimeFormat(t, n).format(0, "second");
83
- const i = Math.floor(((/* @__PURE__ */ new Date()).getTime() - r.getTime()) / 1e3), o = [
84
- { unit: "year", seconds: 31536e3 },
85
- { unit: "month", seconds: 2592e3 },
86
- { unit: "day", seconds: 86400 },
87
- { unit: "hour", seconds: 3600 },
88
- { unit: "minute", seconds: 60 },
89
- { unit: "second", seconds: 1 }
90
- ];
91
- for (const { unit: l, seconds: u } of o) {
92
- const c = Math.floor(i / u);
93
- if (c >= 1)
94
- return new Intl.RelativeTimeFormat(t, n).format(-c, l);
95
- }
96
- return new Intl.RelativeTimeFormat(t, n).format(0, "second");
97
- }
98
- }
99
- const m = /\{(\w+)\}/g;
100
- function d(s, e) {
101
- return e ? s.replace(m, (t, n) => {
102
- const r = e[n];
103
- return r !== void 0 ? String(r) : `{${n}}`;
104
- }) : s;
105
- }
106
- function v(s) {
107
- return s === "prefix" || s === "prefix_and_default";
108
- }
109
- function T(s) {
110
- return s === "no_prefix";
111
- }
112
- function P(s) {
113
- return s === "prefix";
114
- }
115
- function b(s) {
116
- return s === "prefix_except_default";
117
- }
118
- function N(s) {
119
- return s === "prefix_and_default";
120
- }
121
- const p = (s, e, t, n, r) => {
122
- const a = r(s, t);
123
- if (!a)
124
- return null;
125
- const i = a.toString().split("|");
126
- if (i.length === 0) return null;
127
- const o = e < i.length ? i[e] : i[i.length - 1];
128
- return o ? o.trim().replace("{count}", e.toString()) : null;
129
- };
130
130
  class $ {
131
131
  constructor(e = {}) {
132
- this.formatter = new g(), this.helper = h(e.storage), this.formatter = new g(), this.pluralFunc = e.plural || p, 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;
133
133
  }
134
134
  // --- Public methods (implemented in base class) ---
135
135
  /**
@@ -155,7 +155,7 @@ class $ {
155
155
  const l = this.getCustomMissingHandler?.();
156
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;
157
157
  }
158
- return typeof o == "string" && t ? d(o, t) : o;
158
+ return typeof o == "string" && t ? m(o, t) : o;
159
159
  }
160
160
  /**
161
161
  * Get translation as string
@@ -171,13 +171,7 @@ class $ {
171
171
  if (r === void 0)
172
172
  return n ?? e;
173
173
  const i = (l, u, c) => this.t(l, u, c);
174
- return this.pluralFunc(
175
- e,
176
- Number.parseInt(r.toString()),
177
- a,
178
- this.getLocale(),
179
- i
180
- ) ?? n ?? e;
174
+ return this.pluralFunc(e, Number.parseInt(r.toString(), 10), a, this.getLocale(), i) ?? n ?? e;
181
175
  }
182
176
  /**
183
177
  * Format number
@@ -230,12 +224,12 @@ class $ {
230
224
  export {
231
225
  $ as BaseI18n,
232
226
  g as FormatService,
233
- p as defaultPlural,
234
- d as interpolate,
227
+ d as defaultPlural,
228
+ m as interpolate,
235
229
  T as isNoPrefixStrategy,
236
230
  N as isPrefixAndDefaultStrategy,
237
231
  b as isPrefixExceptDefaultStrategy,
238
232
  P as isPrefixStrategy,
239
- h as useTranslationHelper,
233
+ p as useTranslationHelper,
240
234
  v as withPrefixStrategy
241
235
  };
@@ -1,7 +1,7 @@
1
1
  import { Translations } from '@i18n-micro/types';
2
2
  /**
3
- * Bare Metal: Простое хранилище переводов без Ref, useState, devalue.
4
- * Ключ Map: locale (general) или locale:routeName (page-specific).
3
+ * Bare Metal: Simple translation storage without Ref, useState, devalue.
4
+ * Map key: locale (general) or locale:routeName (page-specific).
5
5
  */
6
6
  export interface TranslationStorage {
7
7
  translations: Map<string, Translations>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-micro/core",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
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.3"
26
26
  },
27
27
  "devDependencies": {
28
28
  "vite": "^7.3.1",
package/src/base.ts CHANGED
@@ -1,15 +1,7 @@
1
- import { useTranslationHelper, type TranslationStorage } from './translation'
1
+ import type { CleanTranslation, Getter, MissingHandler, Params, PluralFunc, TranslationKey, Translations } from '@i18n-micro/types'
2
2
  import { FormatService } from './format-service'
3
- import { interpolate, defaultPlural } from './helpers'
4
- import type {
5
- Translations,
6
- Params,
7
- PluralFunc,
8
- Getter,
9
- CleanTranslation,
10
- TranslationKey,
11
- MissingHandler,
12
- } from '@i18n-micro/types'
3
+ import { defaultPlural, interpolate } from './helpers'
4
+ import { type TranslationStorage, useTranslationHelper } from './translation'
13
5
 
14
6
  export interface BaseI18nOptions {
15
7
  storage?: TranslationStorage
@@ -17,7 +9,7 @@ export interface BaseI18nOptions {
17
9
  missingWarn?: boolean
18
10
  missingHandler?: (locale: string, key: string, routeName: string) => void
19
11
  // Optional hooks for Nuxt runtime specific features
20
- getPreviousPageInfo?: () => { locale: string, routeName: string } | null
12
+ getPreviousPageInfo?: () => { locale: string; routeName: string } | null
21
13
  getCustomMissingHandler?: () => MissingHandler | null
22
14
  enablePreviousPageFallback?: boolean
23
15
  }
@@ -36,7 +28,7 @@ export abstract class BaseI18n {
36
28
  public missingWarn: boolean
37
29
  public missingHandler?: (locale: string, key: string, routeName: string) => void
38
30
  // Optional hooks for Nuxt runtime specific features
39
- public getPreviousPageInfo?: () => { locale: string, routeName: string } | null
31
+ public getPreviousPageInfo?: () => { locale: string; routeName: string } | null
40
32
  public getCustomMissingHandler?: () => MissingHandler | null
41
33
  public enablePreviousPageFallback: boolean
42
34
 
@@ -74,12 +66,7 @@ export abstract class BaseI18n {
74
66
  * Get translation for a key
75
67
  * Based on logic from src/runtime/plugins/01.plugin.ts
76
68
  */
77
- public t(
78
- key: TranslationKey,
79
- params?: Params,
80
- defaultValue?: string | null,
81
- routeName?: string,
82
- ): CleanTranslation {
69
+ public t(key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string): CleanTranslation {
83
70
  if (!key) return ''
84
71
 
85
72
  // Use abstract getters to get current state
@@ -118,33 +105,26 @@ export abstract class BaseI18n {
118
105
  const customHandler = this.getCustomMissingHandler?.()
119
106
  if (customHandler) {
120
107
  customHandler(locale, key, route)
121
- }
122
- else if (this.missingHandler) {
108
+ } else if (this.missingHandler) {
123
109
  this.missingHandler(locale, key as string, route)
124
- }
125
- else if (this.missingWarn) {
110
+ } else if (this.missingWarn) {
126
111
  const isDev = process.env.NODE_ENV !== 'production'
127
112
  const isClient = typeof window !== 'undefined'
128
113
  if (isDev && isClient) {
129
114
  console.warn(`Not found '${key}' key in '${locale}' locale messages for route '${route}'.`)
130
115
  }
131
116
  }
132
- value = defaultValue === undefined ? key : (defaultValue || key)
117
+ value = defaultValue === undefined ? key : defaultValue || key
133
118
  }
134
119
 
135
120
  // 5. Interpolate
136
- return typeof value === 'string' && params ? interpolate(value, params) : value as CleanTranslation
121
+ return typeof value === 'string' && params ? interpolate(value, params) : (value as CleanTranslation)
137
122
  }
138
123
 
139
124
  /**
140
125
  * Get translation as string
141
126
  */
142
- public ts(
143
- key: TranslationKey,
144
- params?: Params,
145
- defaultValue?: string,
146
- routeName?: string,
147
- ): string {
127
+ public ts(key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string): string {
148
128
  const value = this.t(key, params, defaultValue, routeName)
149
129
  return value?.toString() ?? defaultValue ?? key
150
130
  }
@@ -164,13 +144,7 @@ export abstract class BaseI18n {
164
144
  return this.t(k, p, dv)
165
145
  }
166
146
 
167
- const result = this.pluralFunc(
168
- key,
169
- Number.parseInt(countValue.toString()),
170
- params,
171
- this.getLocale(),
172
- getter,
173
- )
147
+ const result = this.pluralFunc(key, Number.parseInt(countValue.toString(), 10), params, this.getLocale(), getter)
174
148
 
175
149
  return result ?? defaultValue ?? key
176
150
  }
@@ -224,8 +198,7 @@ export abstract class BaseI18n {
224
198
  public loadTranslationsCore(locale: string, translations: Translations, merge: boolean): void {
225
199
  if (merge) {
226
200
  this.helper.mergeGlobalTranslation(locale, translations, true)
227
- }
228
- else {
201
+ } else {
229
202
  this.helper.setTranslations(locale, translations)
230
203
  }
231
204
  }
@@ -234,16 +207,10 @@ export abstract class BaseI18n {
234
207
  * Core route translation loading logic (without reactivity)
235
208
  * Subclasses can override addRouteTranslations to add reactivity
236
209
  */
237
- public loadRouteTranslationsCore(
238
- locale: string,
239
- routeName: string,
240
- translations: Translations,
241
- merge: boolean,
242
- ): void {
210
+ public loadRouteTranslationsCore(locale: string, routeName: string, translations: Translations, merge: boolean): void {
243
211
  if (merge) {
244
212
  this.helper.mergeTranslation(locale, routeName, translations, true)
245
- }
246
- else {
213
+ } else {
247
214
  this.helper.loadPageTranslations(locale, routeName, translations)
248
215
  }
249
216
  }
@@ -20,7 +20,7 @@ export class FormatService {
20
20
  const now = new Date()
21
21
  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)
22
22
 
23
- const units: { unit: Intl.RelativeTimeFormatUnit, seconds: number }[] = [
23
+ const units: { unit: Intl.RelativeTimeFormatUnit; seconds: number }[] = [
24
24
  { unit: 'year', seconds: 31536000 },
25
25
  { unit: 'month', seconds: 2592000 },
26
26
  { unit: 'day', seconds: 86400 },
package/src/helpers.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Params, Strategies, PluralFunc, Getter, TranslationKey } from '@i18n-micro/types'
1
+ import type { Getter, Params, PluralFunc, Strategies, TranslationKey } from '@i18n-micro/types'
2
2
 
3
3
  const RE_TOKEN = /\{(\w+)\}/g
4
4
 
package/src/index.ts CHANGED
@@ -1,7 +1,15 @@
1
- import { useTranslationHelper, type TranslationStorage } from './translation'
2
- import { FormatService } from './format-service'
3
- import { interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural } from './helpers'
4
1
  import { BaseI18n, type BaseI18nOptions } from './base'
2
+ import { FormatService } from './format-service'
3
+ import {
4
+ defaultPlural,
5
+ interpolate,
6
+ isNoPrefixStrategy,
7
+ isPrefixAndDefaultStrategy,
8
+ isPrefixExceptDefaultStrategy,
9
+ isPrefixStrategy,
10
+ withPrefixStrategy,
11
+ } from './helpers'
12
+ import { type TranslationStorage, useTranslationHelper } from './translation'
5
13
 
6
14
  export {
7
15
  useTranslationHelper,
@@ -1,8 +1,8 @@
1
1
  import type { Translations } from '@i18n-micro/types'
2
2
 
3
3
  /**
4
- * Bare Metal: Простое хранилище переводов без Ref, useState, devalue.
5
- * Ключ Map: locale (general) или locale:routeName (page-specific).
4
+ * Bare Metal: Simple translation storage without Ref, useState, devalue.
5
+ * Map key: locale (general) or locale:routeName (page-specific).
6
6
  */
7
7
  export interface TranslationStorage {
8
8
  translations: Map<string, Translations>
@@ -24,8 +24,7 @@ function findValue<T = unknown>(data: Translations | null | undefined, key: stri
24
24
  for (const part of parts) {
25
25
  if (value && typeof value === 'object' && part in (value as object)) {
26
26
  value = (value as Translations)[part]
27
- }
28
- else {
27
+ } else {
29
28
  return null
30
29
  }
31
30
  }
@@ -82,11 +81,10 @@ export function useTranslationHelper(storage?: TranslationStorage) {
82
81
  loadPageTranslations(locale: string, routeName: string, data: Translations): void {
83
82
  const key = `${locale}:${routeName}`
84
83
  const existing = translations.get(key)
85
- // Perf: при пустом existing — сохраняем ссылку, избегаем O(n) копирования больших объектов
84
+ // Perf: when existing is empty keep reference, avoid O(n) copying of large objects
86
85
  if (!existing || Object.keys(existing).length === 0) {
87
86
  translations.set(key, data)
88
- }
89
- else {
87
+ } else {
90
88
  translations.set(key, { ...existing, ...data })
91
89
  }
92
90
  },
@@ -1,5 +1,5 @@
1
+ import type { PluralFunc, Translations } from '@i18n-micro/types'
1
2
  import { BaseI18n, type BaseI18nOptions } from '../src/base'
2
- import type { Translations, PluralFunc } from '@i18n-micro/types'
3
3
 
4
4
  // Test implementation of BaseI18n
5
5
  class TestI18n extends BaseI18n {
@@ -7,12 +7,7 @@ class TestI18n extends BaseI18n {
7
7
  private _fallbackLocale: string
8
8
  private _route: string
9
9
 
10
- constructor(
11
- locale: string,
12
- fallbackLocale: string,
13
- route: string,
14
- options?: BaseI18nOptions,
15
- ) {
10
+ constructor(locale: string, fallbackLocale: string, route: string, options?: BaseI18nOptions) {
16
11
  super(options)
17
12
  this._locale = locale
18
13
  this._fallbackLocale = fallbackLocale
@@ -375,7 +370,7 @@ describe('BaseI18n', () => {
375
370
 
376
371
  i18n['loadTranslationsCore']('en', translations, false)
377
372
  // Wait for async operation to complete
378
- await new Promise(resolve => setTimeout(resolve, 0))
373
+ await new Promise((resolve) => setTimeout(resolve, 0))
379
374
 
380
375
  expect(i18n.has('greeting')).toBe(true)
381
376
  })
@@ -388,7 +383,7 @@ describe('BaseI18n', () => {
388
383
  await i18n['helper'].loadTranslations('en', initial)
389
384
  i18n['loadTranslationsCore']('en', additional, true)
390
385
  // Wait for async operation to complete
391
- await new Promise(resolve => setTimeout(resolve, 0))
386
+ await new Promise((resolve) => setTimeout(resolve, 0))
392
387
 
393
388
  expect(i18n.has('greeting')).toBe(true)
394
389
  expect(i18n.has('farewell')).toBe(true)
@@ -402,7 +397,7 @@ describe('BaseI18n', () => {
402
397
 
403
398
  i18n['loadRouteTranslationsCore']('en', 'about', translations, false)
404
399
  // Wait for async operation to complete
405
- await new Promise(resolve => setTimeout(resolve, 0))
400
+ await new Promise((resolve) => setTimeout(resolve, 0))
406
401
 
407
402
  expect(i18n.has('title', 'about')).toBe(true)
408
403
  })
@@ -415,7 +410,7 @@ describe('BaseI18n', () => {
415
410
  await i18n['helper'].loadPageTranslations('en', 'about', initial)
416
411
  i18n['loadRouteTranslationsCore']('en', 'about', additional, true)
417
412
  // Wait for async operation to complete
418
- await new Promise(resolve => setTimeout(resolve, 0))
413
+ await new Promise((resolve) => setTimeout(resolve, 0))
419
414
 
420
415
  expect(i18n.has('title', 'about')).toBe(true)
421
416
  expect(i18n.has('description', 'about')).toBe(true)
@@ -1,4 +1,4 @@
1
- import { useTranslationHelper, interpolate } from '../src'
1
+ import { interpolate, useTranslationHelper } from '../src'
2
2
 
3
3
  describe('Translation Helper', () => {
4
4
  const translations = {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  interpolate,
3
- withPrefixStrategy,
4
3
  isNoPrefixStrategy,
5
- isPrefixStrategy,
6
- isPrefixExceptDefaultStrategy,
7
4
  isPrefixAndDefaultStrategy,
5
+ isPrefixExceptDefaultStrategy,
6
+ isPrefixStrategy,
7
+ withPrefixStrategy,
8
8
  } from '../src/helpers'
9
9
 
10
10
  describe('Helpers', () => {
package/vite.config.mts CHANGED
@@ -1,4 +1,3 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
1
  // @ts-nocheck
3
2
  import { resolve } from 'node:path'
4
3
  import { defineConfig } from 'vite'
@@ -10,7 +9,7 @@ export default defineConfig({
10
9
  entry: resolve(__dirname, 'src/index.ts'),
11
10
  name: '@i18n-micro/core',
12
11
  formats: ['cjs', 'es'],
13
- fileName: format => `index.${format === 'cjs' ? 'cjs' : 'mjs'}`,
12
+ fileName: (format) => `index.${format === 'cjs' ? 'cjs' : 'mjs'}`,
14
13
  },
15
14
  rollupOptions: {
16
15
  external: [],
@@ -19,7 +18,5 @@ export default defineConfig({
19
18
  },
20
19
  },
21
20
  },
22
- plugins: [
23
- dts(),
24
- ],
21
+ plugins: [dts()],
25
22
  })