@i18n-micro/core
Advanced tools
| export { defaultPlural, getByPath, hasTranslationValue, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, mergeTranslationChunk, resolveTranslation, translationCacheKey, withPrefixStrategy, type MergeTranslationChunkOptions, } from './helpers'; |
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=/\{(\w+)\}/g,c="index";function d(t,r){return`${t}:${r||c}`}function f(t,r){if(t==null)return null;const n=a(t,r);return n===void 0?null:n}function g(t,r){return f(t,r)!==null}function y(t,r,n){return Object.keys(t).length===0?r:n?.preserveExisting?Object.assign({},r,t):Object.assign({},t,r)}function x(t,r){return!r||t.indexOf("{")===-1?t:t.replace(s,(n,e)=>{const i=r[e];return i!==void 0?String(i):`{${e}}`})}function a(t,r){if(t==null||typeof r!="string"||r.length===0)return;if(Object.prototype.hasOwnProperty.call(t,r))return t[r];if(!r.includes("."))return;const n=r.split(".");let e=t;for(const i of n){if(e==null||typeof e!="object")return;const u=e;if(!Object.prototype.hasOwnProperty.call(u,i))return;e=u[i]}return e}function p(t){return t==="prefix"||t==="prefix_and_default"}function P(t){return t==="no_prefix"}function v(t){return t==="prefix"}function S(t){return t==="prefix_except_default"}function h(t){return t==="prefix_and_default"}const _=(t,r,n,e,i)=>{const u=i(t,n);if(!u)return null;const l=u.toString().split("|");if(l.length===0)return null;const o=r<l.length?l[r]:l[l.length-1];return o?o.trim().replace("{count}",r.toString()):null};exports.defaultPlural=_;exports.getByPath=a;exports.hasTranslationValue=g;exports.interpolate=x;exports.isNoPrefixStrategy=P;exports.isPrefixAndDefaultStrategy=h;exports.isPrefixExceptDefaultStrategy=S;exports.isPrefixStrategy=v;exports.mergeTranslationChunk=y;exports.resolveTranslation=f;exports.translationCacheKey=d;exports.withPrefixStrategy=p; |
| import { Params, PluralFunc, Strategies } from '@i18n-micro/types'; | ||
| export declare function translationCacheKey(locale: string, routeName?: string): string; | ||
| export declare function resolveTranslation(obj: Record<string, unknown> | null | undefined, key: string): unknown | null; | ||
| export declare function hasTranslationValue(obj: Record<string, unknown> | null | undefined, key: string): boolean; | ||
| export interface MergeTranslationChunkOptions { | ||
| /** When true, existing keys win over incoming. Default: incoming wins. */ | ||
| preserveExisting?: boolean; | ||
| } | ||
| export declare function mergeTranslationChunk(existing: Record<string, unknown>, incoming: Record<string, unknown>, options?: MergeTranslationChunkOptions): Record<string, unknown>; | ||
| export declare function interpolate(template: string, params: Params): string; | ||
| export declare function getByPath(obj: Record<string, unknown> | null | undefined, path: string): unknown; | ||
| export declare function withPrefixStrategy(strategy: Strategies): strategy is "prefix" | "prefix_and_default"; | ||
| export declare function isNoPrefixStrategy(strategy: Strategies): strategy is "no_prefix"; | ||
| export declare function isPrefixStrategy(strategy: Strategies): strategy is "prefix"; | ||
| export declare function isPrefixExceptDefaultStrategy(strategy: Strategies): strategy is "prefix_except_default"; | ||
| export declare function isPrefixAndDefaultStrategy(strategy: Strategies): strategy is "prefix_and_default"; | ||
| /** | ||
| * Default pluralization function | ||
| * Splits translation by '|' and selects form based on count | ||
| * @param key - Translation key | ||
| * @param count - Count for pluralization | ||
| * @param params - Parameters for translation | ||
| * @param _locale - Current locale (unused in default implementation) | ||
| * @param getTranslation - Function to get translation value | ||
| * @returns Selected plural form or null if not found | ||
| */ | ||
| export declare const defaultPlural: PluralFunc; |
| const f = /\{(\w+)\}/g, c = "index"; | ||
| function d(r, t) { | ||
| return `${r}:${t || c}`; | ||
| } | ||
| function s(r, t) { | ||
| if (r == null) return null; | ||
| const e = a(r, t); | ||
| return e === void 0 ? null : e; | ||
| } | ||
| function p(r, t) { | ||
| return s(r, t) !== null; | ||
| } | ||
| function g(r, t, e) { | ||
| return Object.keys(r).length === 0 ? t : e?.preserveExisting ? Object.assign({}, t, r) : Object.assign({}, r, t); | ||
| } | ||
| function x(r, t) { | ||
| return !t || r.indexOf("{") === -1 ? r : r.replace(f, (e, n) => { | ||
| const i = t[n]; | ||
| return i !== void 0 ? String(i) : `{${n}}`; | ||
| }); | ||
| } | ||
| function a(r, t) { | ||
| if (r == null || typeof t != "string" || t.length === 0) return; | ||
| if (Object.prototype.hasOwnProperty.call(r, t)) | ||
| return r[t]; | ||
| if (!t.includes(".")) return; | ||
| const e = t.split("."); | ||
| let n = r; | ||
| for (const i of e) { | ||
| if (n == null || typeof n != "object") return; | ||
| const u = n; | ||
| if (!Object.prototype.hasOwnProperty.call(u, i)) return; | ||
| n = u[i]; | ||
| } | ||
| return n; | ||
| } | ||
| function v(r) { | ||
| return r === "prefix" || r === "prefix_and_default"; | ||
| } | ||
| function y(r) { | ||
| return r === "no_prefix"; | ||
| } | ||
| function _(r) { | ||
| return r === "prefix"; | ||
| } | ||
| function O(r) { | ||
| return r === "prefix_except_default"; | ||
| } | ||
| function P(r) { | ||
| return r === "prefix_and_default"; | ||
| } | ||
| const S = (r, t, e, n, i) => { | ||
| const u = i(r, e); | ||
| if (!u) | ||
| return null; | ||
| const l = u.toString().split("|"); | ||
| if (l.length === 0) return null; | ||
| const o = t < l.length ? l[t] : l[l.length - 1]; | ||
| return o ? o.trim().replace("{count}", t.toString()) : null; | ||
| }; | ||
| export { | ||
| S as defaultPlural, | ||
| a as getByPath, | ||
| p as hasTranslationValue, | ||
| x as interpolate, | ||
| y as isNoPrefixStrategy, | ||
| P as isPrefixAndDefaultStrategy, | ||
| O as isPrefixExceptDefaultStrategy, | ||
| _ as isPrefixStrategy, | ||
| g as mergeTranslationChunk, | ||
| s as resolveTranslation, | ||
| d as translationCacheKey, | ||
| v as withPrefixStrategy | ||
| }; |
+30
-5
@@ -38,10 +38,36 @@ import { CleanTranslation, MissingHandler, Params, PluralFunc, TranslationKey, Translations } from '@i18n-micro/types'; | ||
| /** | ||
| * Called before translation lookup — subclasses use for reactivity tracking. | ||
| */ | ||
| protected touch(): void; | ||
| /** | ||
| * Resolve route name from optional route context (string route name or adapter-specific object). | ||
| */ | ||
| protected resolveRouteName(routeContext?: unknown): string; | ||
| /** | ||
| * Lookup translation value. Returns null when missing. | ||
| */ | ||
| protected resolveLookup(key: TranslationKey, routeContext?: unknown): unknown | null; | ||
| /** | ||
| * Check if translation exists in lookup source. | ||
| */ | ||
| protected resolveHas(key: TranslationKey, routeContext?: unknown): boolean; | ||
| /** | ||
| * Context passed to missing-key handlers. | ||
| */ | ||
| protected getMissingContext(routeContext?: unknown): { | ||
| locale: string; | ||
| routeName: string; | ||
| }; | ||
| /** | ||
| * Warn or invoke handler when translation is missing. | ||
| */ | ||
| protected warnMissing(key: TranslationKey, routeContext?: unknown): void; | ||
| /** | ||
| * Get translation for a key | ||
| * Based on logic from src/runtime/plugins/01.plugin.ts | ||
| */ | ||
| t(key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string): CleanTranslation; | ||
| t(key: TranslationKey, params?: Params, defaultValue?: string | null, routeContext?: unknown): CleanTranslation; | ||
| /** | ||
| * Get translation as string | ||
| */ | ||
| ts(key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string): string; | ||
| ts(key: TranslationKey, params?: Params, defaultValue?: string, routeContext?: unknown): string; | ||
| /** | ||
@@ -65,5 +91,4 @@ * Plural translation | ||
| * Check if translation exists | ||
| * Based on logic from src/runtime/plugins/01.plugin.ts | ||
| */ | ||
| has(key: TranslationKey, routeName?: string): boolean; | ||
| has(key: TranslationKey, routeContext?: unknown): boolean; | ||
| /** | ||
@@ -70,0 +95,0 @@ * Clear cache |
| import { Params, PluralFunc, Strategies } from '@i18n-micro/types'; | ||
| export declare function translationCacheKey(locale: string, routeName?: string): string; | ||
| export declare function resolveTranslation(obj: Record<string, unknown> | null | undefined, key: string): unknown | null; | ||
| export declare function hasTranslationValue(obj: Record<string, unknown> | null | undefined, key: string): boolean; | ||
| export interface MergeTranslationChunkOptions { | ||
| /** When true, existing keys win over incoming. Default: incoming wins. */ | ||
| preserveExisting?: boolean; | ||
| } | ||
| export declare function mergeTranslationChunk(existing: Record<string, unknown>, incoming: Record<string, unknown>, options?: MergeTranslationChunkOptions): Record<string, unknown>; | ||
| export declare function interpolate(template: string, params: Params): string; | ||
| export declare function getByPath(obj: Record<string, unknown> | null | undefined, path: string): unknown; | ||
| export declare function withPrefixStrategy(strategy: Strategies): strategy is "prefix" | "prefix_and_default"; | ||
@@ -4,0 +13,0 @@ export declare function isNoPrefixStrategy(strategy: Strategies): strategy is "no_prefix"; |
+1
-1
@@ -1,1 +0,1 @@ | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class f{formatNumber(t,e,n){return new Intl.NumberFormat(e,n).format(t)}formatDate(t,e,n){const r=new Date(t);return Number.isNaN(r.getTime())?"Invalid Date":new Intl.DateTimeFormat(e,n).format(r)}formatRelativeTime(t,e,n){const r=new Date(t);if(Number.isNaN(r.getTime()))return new Intl.RelativeTimeFormat(e,n).format(0,"second");const i=Math.floor((new Date().getTime()-r.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:c}of o){const u=Math.floor(i/c);if(u>=1)return new Intl.RelativeTimeFormat(e,n).format(-u,l)}return new Intl.RelativeTimeFormat(e,n).format(0,"second")}}const p=/\{(\w+)\}/g;function h(s,t){return t?s.replace(p,(e,n)=>{const r=t[n];return r!==void 0?String(r):`{${n}}`}):s}function x(s){return s==="prefix"||s==="prefix_and_default"}function T(s){return s==="no_prefix"}function v(s){return s==="prefix"}function $(s){return s==="prefix_except_default"}function S(s){return s==="prefix_and_default"}const m=(s,t,e,n,r)=>{const a=r(s,e);if(!a)return null;const i=a.toString().split("|");if(i.length===0)return null;const o=t<i.length?i[t]:i[i.length-1];return o?o.trim().replace("{count}",t.toString()):null};function g(s,t){if(!s||typeof t!="string")return null;if(t in s){const r=s[t];return r}const e=t.split(".");let n=s;for(const r of e)if(n&&typeof n=="object"&&r in n)n=n[r];else return null;return n??null}function d(s){const t=s?.translations??new Map;return{hasCache(e,n){const r=n||"index";return t.has(`${e}:${r}`)},getCache(e,n){const r=n||"index";return t.get(`${e}:${r}`)},setCache(e,n,r){},hasTranslation(e,n){for(const[r,a]of t)if(r.startsWith(`${e}:`)&&g(a,n)!==null)return!0;return!1},hasPageTranslation(e,n){const r=n||"index";return t.has(`${e}:${r}`)},getTranslation(e,n,r){const a=n||"index";return g(t.get(`${e}:${a}`),r)},loadTranslations(e,n,r="index"){const i=`${e}:${r||"index"}`,o=t.get(i)??{};t.set(i,{...o,...n})},setTranslations(e,n,r="index"){const a=r||"index";t.set(`${e}:${a}`,n)},loadPageTranslations(e,n,r){const i=`${e}:${n||"index"}`,o=t.get(i);!o||Object.keys(o).length===0?t.set(i,r):t.set(i,{...o,...r})},mergeTranslation(e,n,r,a=!1){const o=`${e}:${n||"index"}`,l=t.get(o)??{};t.set(o,{...l,...r})},clearCache(){t.clear()}}}class w{constructor(t={}){this.formatter=new f,this.helper=d(t.storage),this.formatter=new f,this.pluralFunc=t.plural||m,this.missingWarn=t.missingWarn??!0,this.missingHandler=t.missingHandler,this.getCustomMissingHandler=t.getCustomMissingHandler}t(t,e,n,r){if(!t)return"";const a=this.getLocale(),i=r||this.getRoute();let o=this.helper.getTranslation(a,i,t);if(!o){const l=this.getFallbackLocale();a!==l&&(o=this.helper.getTranslation(l,i,t))}if(!o){const l=this.getCustomMissingHandler?.();l?l(a,t,i):this.missingHandler?this.missingHandler(a,t,i):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${t}' key in '${a}' locale messages for route '${i}'.`),o=n===void 0?t:n||t}return typeof o=="string"&&e?h(o,e):o}ts(t,e,n,r){return this.t(t,e,n,r)?.toString()??n??t}tc(t,e,n){const{count:r,...a}=typeof e=="number"?{count:e}:e;if(r===void 0)return n??t;const i=(l,c,u)=>this.t(l,c,u);return this.pluralFunc(t,Number.parseInt(r.toString(),10),a,this.getLocale(),i)??n??t}tn(t,e){return this.formatter.formatNumber(t,this.getLocale(),e)}td(t,e){return this.formatter.formatDate(t,this.getLocale(),e)}tdr(t,e){return this.formatter.formatRelativeTime(t,this.getLocale(),e)}has(t,e){const n=e||this.getRoute(),r=this.getLocale();return!!this.helper.getTranslation(r,n,t)}clearCache(){this.helper.clearCache()}loadTranslationsCore(t,e,n,r="index"){n?this.helper.mergeTranslation(t,r,e,!0):this.helper.setTranslations(t,e,r)}loadRouteTranslationsCore(t,e,n,r){r?this.helper.mergeTranslation(t,e,n,!0):this.helper.loadPageTranslations(t,e,n)}}exports.BaseI18n=w;exports.FormatService=f;exports.defaultPlural=m;exports.interpolate=h;exports.isNoPrefixStrategy=T;exports.isPrefixAndDefaultStrategy=S;exports.isPrefixExceptDefaultStrategy=$;exports.isPrefixStrategy=v;exports.useTranslationHelper=d;exports.withPrefixStrategy=x; | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./helpers.cjs");class g{formatNumber(t,e,r){return new Intl.NumberFormat(e,r).format(t)}formatDate(t,e,r){const s=new Date(t);return Number.isNaN(s.getTime())?"Invalid Date":new Intl.DateTimeFormat(e,r).format(s)}formatRelativeTime(t,e,r){const s=new Date(t),n=new Intl.RelativeTimeFormat(e,r);if(Number.isNaN(s.getTime()))return n.format(0,"second");const i=Math.floor((Date.now()-s.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:u,seconds:h}of o){const l=Math.floor(i/h);if(l>=1)return n.format(-l,u)}return n.format(0,"second")}}function f(c){const t=c?.translations??new Map;return{hasCache(e,r){return t.has(a.translationCacheKey(e,r))},getCache(e,r){return t.get(a.translationCacheKey(e,r))},setCache(e,r,s){},hasTranslation(e,r){for(const[s,n]of t)if(s.startsWith(`${e}:`)&&a.getByPath(n,r)!==void 0)return!0;return!1},hasPageTranslation(e,r){return t.has(a.translationCacheKey(e,r))},getTranslation(e,r,s){const n=t.get(a.translationCacheKey(e,r));return n?a.resolveTranslation(n,s):null},loadTranslations(e,r,s="index"){const n=a.translationCacheKey(e,s),i=t.get(n);i?Object.assign(i,r):t.set(n,{...r})},setTranslations(e,r,s="index"){t.set(a.translationCacheKey(e,s),r)},loadPageTranslations(e,r,s){const n=a.translationCacheKey(e,r),i=t.get(n);!i||Object.keys(i).length===0?t.set(n,{...s}):Object.assign(i,s)},mergeTranslation(e,r,s,n=!1){const i=a.translationCacheKey(e,r),o=t.get(i);o?Object.assign(o,s):t.set(i,{...s})},clearCache(){t.clear()}}}class m{constructor(t={}){this.formatter=new g,this.helper=f(t.storage),this.formatter=new g,this.pluralFunc=t.plural||a.defaultPlural,this.missingWarn=t.missingWarn??!0,this.missingHandler=t.missingHandler,this.getCustomMissingHandler=t.getCustomMissingHandler}touch(){}resolveRouteName(t){return typeof t=="string"?t:this.getRoute()}resolveLookup(t,e){const r=this.getLocale(),s=this.resolveRouteName(e);let n=this.helper.getTranslation(r,s,String(t));if(n===null){const i=this.getFallbackLocale();r!==i&&(n=this.helper.getTranslation(i,s,String(t)))}return n}resolveHas(t,e){const r=this.getLocale(),s=this.resolveRouteName(e);return this.helper.getTranslation(r,s,String(t))!==null}getMissingContext(t){return{locale:this.getLocale(),routeName:this.resolveRouteName(t)}}warnMissing(t,e){const{locale:r,routeName:s}=this.getMissingContext(e),n=this.getCustomMissingHandler?.();if(n){n(r,String(t),s);return}if(this.missingHandler){this.missingHandler(r,String(t),s);return}this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${t}' key in '${r}' locale messages for route '${s}'.`)}t(t,e,r,s){if(!t)return"";this.touch();const n=this.resolveLookup(t,s);return n==null?(this.warnMissing(t,s),r===void 0?t:r||t):typeof n!="string"||!e?n:a.interpolate(n,e)}ts(t,e,r,s){return this.t(t,e,r,s)?.toString()??r??t}tc(t,e,r){this.touch();const{count:s,...n}=typeof e=="number"?{count:e}:e;if(s===void 0)return r??t;const i=(u,h,l)=>this.t(u,h,l);return this.pluralFunc(t,Number.parseInt(s.toString(),10),n,this.getLocale(),i)??r??t}tn(t,e){return this.touch(),this.formatter.formatNumber(t,this.getLocale(),e)}td(t,e){return this.touch(),this.formatter.formatDate(t,this.getLocale(),e)}tdr(t,e){return this.touch(),this.formatter.formatRelativeTime(t,this.getLocale(),e)}has(t,e){return this.touch(),this.resolveHas(t,e)}clearCache(){this.helper.clearCache()}loadTranslationsCore(t,e,r,s="index"){r?this.helper.mergeTranslation(t,s,e,!0):this.helper.setTranslations(t,e,s)}loadRouteTranslationsCore(t,e,r,s){s?this.helper.mergeTranslation(t,e,r,!0):this.helper.loadPageTranslations(t,e,r)}}exports.defaultPlural=a.defaultPlural;exports.getByPath=a.getByPath;exports.hasTranslationValue=a.hasTranslationValue;exports.interpolate=a.interpolate;exports.isNoPrefixStrategy=a.isNoPrefixStrategy;exports.isPrefixAndDefaultStrategy=a.isPrefixAndDefaultStrategy;exports.isPrefixExceptDefaultStrategy=a.isPrefixExceptDefaultStrategy;exports.isPrefixStrategy=a.isPrefixStrategy;exports.mergeTranslationChunk=a.mergeTranslationChunk;exports.resolveTranslation=a.resolveTranslation;exports.translationCacheKey=a.translationCacheKey;exports.withPrefixStrategy=a.withPrefixStrategy;exports.BaseI18n=m;exports.FormatService=g;exports.useTranslationHelper=f; |
+2
-2
| import { BaseI18n, BaseI18nOptions } from './base'; | ||
| import { FormatService } from './format-service'; | ||
| import { defaultPlural, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, withPrefixStrategy } from './helpers'; | ||
| import { defaultPlural, getByPath, hasTranslationValue, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, mergeTranslationChunk, resolveTranslation, translationCacheKey, withPrefixStrategy, MergeTranslationChunkOptions } from './helpers'; | ||
| import { TranslationStorage, useTranslationHelper } from './translation'; | ||
| export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, }; | ||
| export { useTranslationHelper, interpolate, getByPath, hasTranslationValue, mergeTranslationChunk, resolveTranslation, translationCacheKey, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type MergeTranslationChunkOptions, type TranslationStorage, type BaseI18nOptions, }; |
+2
-2
| import { BaseI18n, BaseI18nOptions } from './base'; | ||
| import { FormatService } from './format-service'; | ||
| import { defaultPlural, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, withPrefixStrategy } from './helpers'; | ||
| import { defaultPlural, getByPath, hasTranslationValue, interpolate, isNoPrefixStrategy, isPrefixAndDefaultStrategy, isPrefixExceptDefaultStrategy, isPrefixStrategy, mergeTranslationChunk, resolveTranslation, translationCacheKey, withPrefixStrategy, MergeTranslationChunkOptions } from './helpers'; | ||
| import { TranslationStorage, useTranslationHelper } from './translation'; | ||
| export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type TranslationStorage, type BaseI18nOptions, }; | ||
| export { useTranslationHelper, interpolate, getByPath, hasTranslationValue, mergeTranslationChunk, resolveTranslation, translationCacheKey, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, FormatService, BaseI18n, type MergeTranslationChunkOptions, type TranslationStorage, type BaseI18nOptions, }; |
+130
-131
@@ -1,14 +0,16 @@ | ||
| class f { | ||
| formatNumber(t, e, n) { | ||
| return new Intl.NumberFormat(e, n).format(t); | ||
| import { translationCacheKey as a, resolveTranslation as f, getByPath as m, defaultPlural as d, interpolate as v } from "./helpers.mjs"; | ||
| import { hasTranslationValue as w, isNoPrefixStrategy as x, isPrefixAndDefaultStrategy as S, isPrefixExceptDefaultStrategy as D, isPrefixStrategy as H, mergeTranslationChunk as L, withPrefixStrategy as M } from "./helpers.mjs"; | ||
| class g { | ||
| formatNumber(t, e, s) { | ||
| return new Intl.NumberFormat(e, s).format(t); | ||
| } | ||
| formatDate(t, e, n) { | ||
| formatDate(t, e, s) { | ||
| const r = new Date(t); | ||
| return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(e, n).format(r); | ||
| return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(e, s).format(r); | ||
| } | ||
| formatRelativeTime(t, e, n) { | ||
| const r = new Date(t); | ||
| formatRelativeTime(t, e, s) { | ||
| const r = new Date(t), n = new Intl.RelativeTimeFormat(e, s); | ||
| if (Number.isNaN(r.getTime())) | ||
| return new Intl.RelativeTimeFormat(e, n).format(0, "second"); | ||
| const i = Math.floor(((/* @__PURE__ */ new Date()).getTime() - r.getTime()) / 1e3), o = [ | ||
| return n.format(0, "second"); | ||
| const i = Math.floor((Date.now() - r.getTime()) / 1e3), o = [ | ||
| { unit: "year", seconds: 31536e3 }, | ||
@@ -21,98 +23,48 @@ { unit: "month", seconds: 2592e3 }, | ||
| ]; | ||
| for (const { unit: l, seconds: u } of o) { | ||
| const c = Math.floor(i / u); | ||
| if (c >= 1) | ||
| return new Intl.RelativeTimeFormat(e, n).format(-c, l); | ||
| for (const { unit: u, seconds: h } of o) { | ||
| const l = Math.floor(i / h); | ||
| if (l >= 1) | ||
| return n.format(-l, u); | ||
| } | ||
| return new Intl.RelativeTimeFormat(e, n).format(0, "second"); | ||
| return n.format(0, "second"); | ||
| } | ||
| } | ||
| const g = /\{(\w+)\}/g; | ||
| function m(s, t) { | ||
| return t ? s.replace(g, (e, n) => { | ||
| const r = t[n]; | ||
| return r !== void 0 ? String(r) : `{${n}}`; | ||
| }) : s; | ||
| } | ||
| function x(s) { | ||
| return s === "prefix" || s === "prefix_and_default"; | ||
| } | ||
| function T(s) { | ||
| return s === "no_prefix"; | ||
| } | ||
| function $(s) { | ||
| return s === "prefix"; | ||
| } | ||
| function v(s) { | ||
| return s === "prefix_except_default"; | ||
| } | ||
| function w(s) { | ||
| return s === "prefix_and_default"; | ||
| } | ||
| const d = (s, t, e, n, r) => { | ||
| const a = r(s, e); | ||
| if (!a) | ||
| return null; | ||
| const i = a.toString().split("|"); | ||
| if (i.length === 0) return null; | ||
| const o = t < i.length ? i[t] : i[i.length - 1]; | ||
| return o ? o.trim().replace("{count}", t.toString()) : null; | ||
| }; | ||
| function h(s, t) { | ||
| if (!s || typeof t != "string") return null; | ||
| if (t in s) { | ||
| const r = s[t]; | ||
| return r; | ||
| } | ||
| const e = t.split("."); | ||
| let n = s; | ||
| for (const r of e) | ||
| if (n && typeof n == "object" && r in n) | ||
| n = n[r]; | ||
| else | ||
| return null; | ||
| return n ?? null; | ||
| } | ||
| function p(s) { | ||
| const t = s?.translations ?? /* @__PURE__ */ new Map(); | ||
| function T(c) { | ||
| const t = c?.translations ?? /* @__PURE__ */ new Map(); | ||
| return { | ||
| hasCache(e, n) { | ||
| const r = n || "index"; | ||
| return t.has(`${e}:${r}`); | ||
| hasCache(e, s) { | ||
| return t.has(a(e, s)); | ||
| }, | ||
| getCache(e, n) { | ||
| const r = n || "index"; | ||
| return t.get(`${e}:${r}`); | ||
| getCache(e, s) { | ||
| return t.get(a(e, s)); | ||
| }, | ||
| setCache(e, n, r) { | ||
| setCache(e, s, r) { | ||
| }, | ||
| hasTranslation(e, n) { | ||
| for (const [r, a] of t) | ||
| if (r.startsWith(`${e}:`) && h(a, n) !== null) | ||
| hasTranslation(e, s) { | ||
| for (const [r, n] of t) | ||
| if (r.startsWith(`${e}:`) && m(n, s) !== void 0) | ||
| return !0; | ||
| return !1; | ||
| }, | ||
| hasPageTranslation(e, n) { | ||
| const r = n || "index"; | ||
| return t.has(`${e}:${r}`); | ||
| hasPageTranslation(e, s) { | ||
| return t.has(a(e, s)); | ||
| }, | ||
| getTranslation(e, n, r) { | ||
| const a = n || "index"; | ||
| return h(t.get(`${e}:${a}`), r); | ||
| getTranslation(e, s, r) { | ||
| const n = t.get(a(e, s)); | ||
| return n ? f(n, r) : null; | ||
| }, | ||
| loadTranslations(e, n, r = "index") { | ||
| const i = `${e}:${r || "index"}`, o = t.get(i) ?? {}; | ||
| t.set(i, { ...o, ...n }); | ||
| loadTranslations(e, s, r = "index") { | ||
| const n = a(e, r), i = t.get(n); | ||
| i ? Object.assign(i, s) : t.set(n, { ...s }); | ||
| }, | ||
| setTranslations(e, n, r = "index") { | ||
| const a = r || "index"; | ||
| t.set(`${e}:${a}`, n); | ||
| setTranslations(e, s, r = "index") { | ||
| t.set(a(e, r), s); | ||
| }, | ||
| loadPageTranslations(e, n, r) { | ||
| const i = `${e}:${n || "index"}`, o = t.get(i); | ||
| !o || Object.keys(o).length === 0 ? t.set(i, r) : t.set(i, { ...o, ...r }); | ||
| loadPageTranslations(e, s, r) { | ||
| const n = a(e, s), i = t.get(n); | ||
| !i || Object.keys(i).length === 0 ? t.set(n, { ...r }) : Object.assign(i, r); | ||
| }, | ||
| mergeTranslation(e, n, r, a = !1) { | ||
| const o = `${e}:${n || "index"}`, l = t.get(o) ?? {}; | ||
| t.set(o, { ...l, ...r }); | ||
| mergeTranslation(e, s, r, n = !1) { | ||
| const i = a(e, s), o = t.get(i); | ||
| o ? Object.assign(o, r) : t.set(i, { ...r }); | ||
| }, | ||
@@ -124,24 +76,67 @@ clearCache() { | ||
| } | ||
| class _ { | ||
| class N { | ||
| constructor(t = {}) { | ||
| this.formatter = new f(), this.helper = p(t.storage), this.formatter = new f(), this.pluralFunc = t.plural || d, this.missingWarn = t.missingWarn ?? !0, this.missingHandler = t.missingHandler, this.getCustomMissingHandler = t.getCustomMissingHandler; | ||
| this.formatter = new g(), this.helper = T(t.storage), this.formatter = new g(), this.pluralFunc = t.plural || d, this.missingWarn = t.missingWarn ?? !0, this.missingHandler = t.missingHandler, this.getCustomMissingHandler = t.getCustomMissingHandler; | ||
| } | ||
| // --- Protected hooks (subclasses may override) --- | ||
| /** | ||
| * Called before translation lookup — subclasses use for reactivity tracking. | ||
| */ | ||
| touch() { | ||
| } | ||
| /** | ||
| * Resolve route name from optional route context (string route name or adapter-specific object). | ||
| */ | ||
| resolveRouteName(t) { | ||
| return typeof t == "string" ? t : this.getRoute(); | ||
| } | ||
| /** | ||
| * Lookup translation value. Returns null when missing. | ||
| */ | ||
| resolveLookup(t, e) { | ||
| const s = this.getLocale(), r = this.resolveRouteName(e); | ||
| let n = this.helper.getTranslation(s, r, String(t)); | ||
| if (n === null) { | ||
| const i = this.getFallbackLocale(); | ||
| s !== i && (n = this.helper.getTranslation(i, r, String(t))); | ||
| } | ||
| return n; | ||
| } | ||
| /** | ||
| * Check if translation exists in lookup source. | ||
| */ | ||
| resolveHas(t, e) { | ||
| const s = this.getLocale(), r = this.resolveRouteName(e); | ||
| return this.helper.getTranslation(s, r, String(t)) !== null; | ||
| } | ||
| /** | ||
| * Context passed to missing-key handlers. | ||
| */ | ||
| getMissingContext(t) { | ||
| return { locale: this.getLocale(), routeName: this.resolveRouteName(t) }; | ||
| } | ||
| /** | ||
| * Warn or invoke handler when translation is missing. | ||
| */ | ||
| warnMissing(t, e) { | ||
| const { locale: s, routeName: r } = this.getMissingContext(e), n = this.getCustomMissingHandler?.(); | ||
| if (n) { | ||
| n(s, String(t), r); | ||
| return; | ||
| } | ||
| if (this.missingHandler) { | ||
| this.missingHandler(s, String(t), r); | ||
| return; | ||
| } | ||
| this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${t}' key in '${s}' locale messages for route '${r}'.`); | ||
| } | ||
| // --- Public methods (implemented in base class) --- | ||
| /** | ||
| * Get translation for a key | ||
| * Based on logic from src/runtime/plugins/01.plugin.ts | ||
| */ | ||
| t(t, e, n, r) { | ||
| t(t, e, s, r) { | ||
| if (!t) return ""; | ||
| const a = this.getLocale(), i = r || this.getRoute(); | ||
| let o = this.helper.getTranslation(a, i, t); | ||
| if (!o) { | ||
| const l = this.getFallbackLocale(); | ||
| a !== l && (o = this.helper.getTranslation(l, i, t)); | ||
| } | ||
| if (!o) { | ||
| const l = this.getCustomMissingHandler?.(); | ||
| l ? l(a, t, i) : this.missingHandler ? this.missingHandler(a, t, i) : this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${t}' key in '${a}' locale messages for route '${i}'.`), o = n === void 0 ? t : n || t; | ||
| } | ||
| return typeof o == "string" && e ? m(o, e) : o; | ||
| this.touch(); | ||
| const n = this.resolveLookup(t, r); | ||
| return n == null ? (this.warnMissing(t, r), s === void 0 ? t : s || t) : typeof n != "string" || !e ? n : v(n, e); | ||
| } | ||
@@ -151,4 +146,4 @@ /** | ||
| */ | ||
| ts(t, e, n, r) { | ||
| return this.t(t, e, n, r)?.toString() ?? n ?? t; | ||
| ts(t, e, s, r) { | ||
| return this.t(t, e, s, r)?.toString() ?? s ?? t; | ||
| } | ||
@@ -158,8 +153,9 @@ /** | ||
| */ | ||
| tc(t, e, n) { | ||
| const { count: r, ...a } = typeof e == "number" ? { count: e } : e; | ||
| tc(t, e, s) { | ||
| this.touch(); | ||
| const { count: r, ...n } = typeof e == "number" ? { count: e } : e; | ||
| if (r === void 0) | ||
| return n ?? t; | ||
| const i = (l, u, c) => this.t(l, u, c); | ||
| return this.pluralFunc(t, Number.parseInt(r.toString(), 10), a, this.getLocale(), i) ?? n ?? t; | ||
| return s ?? t; | ||
| const i = (u, h, l) => this.t(u, h, l); | ||
| return this.pluralFunc(t, Number.parseInt(r.toString(), 10), n, this.getLocale(), i) ?? s ?? t; | ||
| } | ||
@@ -170,3 +166,3 @@ /** | ||
| tn(t, e) { | ||
| return this.formatter.formatNumber(t, this.getLocale(), e); | ||
| return this.touch(), this.formatter.formatNumber(t, this.getLocale(), e); | ||
| } | ||
@@ -177,3 +173,3 @@ /** | ||
| td(t, e) { | ||
| return this.formatter.formatDate(t, this.getLocale(), e); | ||
| return this.touch(), this.formatter.formatDate(t, this.getLocale(), e); | ||
| } | ||
@@ -184,11 +180,9 @@ /** | ||
| tdr(t, e) { | ||
| return this.formatter.formatRelativeTime(t, this.getLocale(), e); | ||
| return this.touch(), this.formatter.formatRelativeTime(t, this.getLocale(), e); | ||
| } | ||
| /** | ||
| * Check if translation exists | ||
| * Based on logic from src/runtime/plugins/01.plugin.ts | ||
| */ | ||
| has(t, e) { | ||
| const n = e || this.getRoute(), r = this.getLocale(); | ||
| return !!this.helper.getTranslation(r, n, t); | ||
| return this.touch(), this.resolveHas(t, e); | ||
| } | ||
@@ -206,4 +200,4 @@ /** | ||
| */ | ||
| loadTranslationsCore(t, e, n, r = "index") { | ||
| n ? this.helper.mergeTranslation(t, r, e, !0) : this.helper.setTranslations(t, e, r); | ||
| loadTranslationsCore(t, e, s, r = "index") { | ||
| s ? this.helper.mergeTranslation(t, r, e, !0) : this.helper.setTranslations(t, e, r); | ||
| } | ||
@@ -214,17 +208,22 @@ /** | ||
| */ | ||
| loadRouteTranslationsCore(t, e, n, r) { | ||
| r ? this.helper.mergeTranslation(t, e, n, !0) : this.helper.loadPageTranslations(t, e, n); | ||
| loadRouteTranslationsCore(t, e, s, r) { | ||
| r ? this.helper.mergeTranslation(t, e, s, !0) : this.helper.loadPageTranslations(t, e, s); | ||
| } | ||
| } | ||
| export { | ||
| _ as BaseI18n, | ||
| f as FormatService, | ||
| N as BaseI18n, | ||
| g as FormatService, | ||
| d as defaultPlural, | ||
| m as interpolate, | ||
| T as isNoPrefixStrategy, | ||
| w as isPrefixAndDefaultStrategy, | ||
| v as isPrefixExceptDefaultStrategy, | ||
| $ as isPrefixStrategy, | ||
| p as useTranslationHelper, | ||
| x as withPrefixStrategy | ||
| m as getByPath, | ||
| w as hasTranslationValue, | ||
| v as interpolate, | ||
| x as isNoPrefixStrategy, | ||
| S as isPrefixAndDefaultStrategy, | ||
| D as isPrefixExceptDefaultStrategy, | ||
| H as isPrefixStrategy, | ||
| L as mergeTranslationChunk, | ||
| f as resolveTranslation, | ||
| a as translationCacheKey, | ||
| T as useTranslationHelper, | ||
| M as withPrefixStrategy | ||
| }; |
+38
-26
| { | ||
| "name": "@i18n-micro/core", | ||
| "version": "1.3.1", | ||
| "version": "1.3.2", | ||
| "description": "Core utilities for translations, formatting, and locale routing in Nuxt I18n Micro.", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/s00d/nuxt-i18n-micro.git", | ||
| "directory": "packages/core" | ||
| "keywords": [ | ||
| "formatting", | ||
| "i18n", | ||
| "locale", | ||
| "nuxt", | ||
| "translations" | ||
| ], | ||
| "homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/core#readme", | ||
| "bugs": { | ||
| "url": "https://github.com/s00d/nuxt-i18n-micro/issues" | ||
| }, | ||
| "license": "MIT", | ||
| "type": "module", | ||
| "sideEffects": false, | ||
| "author": { | ||
@@ -18,9 +22,14 @@ "name": "s00d", | ||
| }, | ||
| "homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/core#readme", | ||
| "bugs": { | ||
| "url": "https://github.com/s00d/nuxt-i18n-micro/issues" | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/s00d/nuxt-i18n-micro.git", | ||
| "directory": "packages/core" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18" | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md", | ||
| "LICENSE" | ||
| ], | ||
| "type": "module", | ||
| "sideEffects": false, | ||
| "main": "dist/index.cjs", | ||
@@ -40,21 +49,20 @@ "types": "dist/index.d.ts", | ||
| }, | ||
| "./helpers": { | ||
| "import": { | ||
| "types": "./dist/helpers.d.ts", | ||
| "default": "./dist/helpers.mjs" | ||
| }, | ||
| "require": { | ||
| "types": "./dist/helpers.d.cts", | ||
| "default": "./dist/helpers.cjs" | ||
| }, | ||
| "default": "./dist/helpers.mjs" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md", | ||
| "LICENSE" | ||
| ], | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "keywords": [ | ||
| "nuxt", | ||
| "i18n", | ||
| "translations", | ||
| "formatting", | ||
| "locale" | ||
| ], | ||
| "dependencies": { | ||
| "@i18n-micro/types": "1.2.2" | ||
| "@i18n-micro/types": "1.2.4" | ||
| }, | ||
@@ -67,2 +75,5 @@ "devDependencies": { | ||
| }, | ||
| "engines": { | ||
| "node": ">=18" | ||
| }, | ||
| "scripts": { | ||
@@ -72,4 +83,5 @@ "build": "vite build", | ||
| "test": "jest", | ||
| "test:perf": "jest --config jest.perf.config.cjs", | ||
| "test:dist": "vitest run --config vitest.dist.config.ts" | ||
| } | ||
| } |
+7
-8
@@ -70,10 +70,3 @@ # @i18n-micro/core | ||
| // Handle locale-specific routing | ||
| const routeService = new RouteService( | ||
| i18nConfig, | ||
| router, | ||
| hashLocaleDefault, | ||
| noPrefixDefault, | ||
| navigateTo, | ||
| setCookie | ||
| ) | ||
| const routeService = new RouteService(i18nConfig, router, hashLocaleDefault, noPrefixDefault, navigateTo, setCookie) | ||
@@ -89,2 +82,3 @@ const localizedRoute = routeService.getLocalizedRoute('/about', currentRoute, 'en') | ||
| #### Methods | ||
| - **`hasCache(locale: string, page: string): boolean`**: | ||
@@ -112,5 +106,7 @@ Checks if translations for a specific route and locale are cached. | ||
| #### Function | ||
| ```typescript | ||
| interpolate(template: string, params: Params): string | ||
| ``` | ||
| - **`template`**: The translation string with placeholders (e.g., `'Hello, {name}!'`). | ||
@@ -120,2 +116,3 @@ - **`params`**: An object containing key-value pairs for interpolation (e.g., `{ name: 'John' }`). | ||
| #### Example | ||
| ```typescript | ||
@@ -129,2 +126,3 @@ const result = interpolate('Hello, {name}!', { name: 'John' }) | ||
| #### Methods | ||
| - **`formatNumber(value: number, locale: string, options?: Intl.NumberFormatOptions): string`**: | ||
@@ -140,2 +138,3 @@ Formats a number according to the specified locale and options. | ||
| #### Methods | ||
| - **`getCurrentLocale(route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric): string`**: | ||
@@ -142,0 +141,0 @@ Returns the current locale based on the route or configuration. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
36363
31.07%15
36.36%487
32.34%2
100%172
-0.58%+ Added
- Removed
Updated