@stacksjs/i18n 0.70.23
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/index.js +2 -0
- package/dist/src/formatter.d.ts +105 -0
- package/dist/src/index.d.ts +83 -0
- package/dist/src/loader.d.ts +49 -0
- package/dist/src/pluralization.d.ts +42 -0
- package/dist/src/translator.d.ts +79 -0
- package/dist/src/types.d.ts +254 -0
- package/package.json +43 -0
- package/src/formatter.ts +399 -0
- package/src/index.ts +87 -0
- package/src/loader.ts +333 -0
- package/src/pluralization.ts +287 -0
- package/src/translator.ts +501 -0
- package/src/types.ts +238 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var i=import.meta.require;function c(q,B){return r(B)(q)}function r(q){let B=q.split("-")[0].toLowerCase(),G=T[B];if(G)return G;return()=>"other"}function C(q,B="|"){let G=q.split(B).map((J)=>J.trim()),K=new Map;if(G.length===1)K.set("other",G[0]);else if(G.length===2)K.set("one",G[0]),K.set("other",G[1]);else if(G.length===3)K.set("zero",G[0]),K.set("one",G[1]),K.set("other",G[2]);else if(G.length>=4){let J=["zero","one","two","few","many","other"];for(let Q=0;Q<G.length&&Q<J.length;Q++)K.set(J[Q],G[Q])}return K}function O(q,B,G){let K=c(B,G);if(q.has(K))return q.get(K);if(q.has("other"))return q.get("other");let J=q.values().next();return J.done?"":J.value}var T={en:(q)=>q===1?"one":"other",de:(q)=>q===1?"one":"other",nl:(q)=>q===1?"one":"other",es:(q)=>q===1?"one":"other",it:(q)=>q===1?"one":"other",pt:(q)=>q===1?"one":"other",sv:(q)=>q===1?"one":"other",da:(q)=>q===1?"one":"other",no:(q)=>q===1?"one":"other",fi:(q)=>q===1?"one":"other",el:(q)=>q===1?"one":"other",he:(q)=>q===1?"one":"other",hu:(q)=>q===1?"one":"other",tr:(q)=>q===1?"one":"other",zh:()=>"other",ja:()=>"other",ko:()=>"other",vi:()=>"other",th:()=>"other",id:()=>"other",ms:()=>"other",fr:(q)=>q===0||q===1?"one":"other",ru:(q)=>{let B=q%10,G=q%100;if(B===1&&G!==11)return"one";if(B>=2&&B<=4&&(G<12||G>14))return"few";if(B===0||B>=5&&B<=9||G>=11&&G<=14)return"many";return"other"},uk:(q)=>{let B=q%10,G=q%100;if(B===1&&G!==11)return"one";if(B>=2&&B<=4&&(G<12||G>14))return"few";if(B===0||B>=5&&B<=9||G>=11&&G<=14)return"many";return"other"},pl:(q)=>{let B=q%10,G=q%100;if(q===1)return"one";if(B>=2&&B<=4&&(G<12||G>14))return"few";if(B===0||B===1||B>=5&&B<=9||G>=12&&G<=14)return"many";return"other"},cs:(q)=>{if(q===1)return"one";if(q>=2&&q<=4)return"few";return"other"},sk:(q)=>{if(q===1)return"one";if(q>=2&&q<=4)return"few";return"other"},ar:(q)=>{if(q===0)return"zero";if(q===1)return"one";if(q===2)return"two";let B=q%100;if(B>=3&&B<=10)return"few";if(B>=11&&B<=99)return"many";return"other"},cy:(q)=>{if(q===0)return"zero";if(q===1)return"one";if(q===2)return"two";if(q===3)return"few";if(q===6)return"many";return"other"},sl:(q)=>{let B=q%100;if(B===1)return"one";if(B===2)return"two";if(B===3||B===4)return"few";return"other"},ga:(q)=>{if(q===1)return"one";if(q===2)return"two";if(q>=3&&q<=6)return"few";if(q>=7&&q<=10)return"many";return"other"},lt:(q)=>{let B=q%10,G=q%100;if(B===1&&(G<11||G>19))return"one";if(B>=2&&B<=9&&(G<11||G>19))return"few";return"other"},lv:(q)=>{let B=q%10,G=q%100;if(q===0)return"zero";if(B===1&&G!==11)return"one";return"other"},ro:(q)=>{if(q===1)return"one";let B=q%100;if(q===0||B>=1&&B<=19)return"few";return"other"},hi:(q)=>q===0||q===1?"one":"other"};function Rq(){return Object.keys(T)}function Tq(q){return q.split("-")[0].toLowerCase()in T}function Fq(q,B){let G=q.split("-")[0].toLowerCase();T[G]=B}var v={locale:"en",fallbackLocale:"en",availableLocales:["en"],messages:{},warnMissing:!0,escapeValues:!1,keySeparator:".",pluralSeparator:"|"},Y="en",z="en",w={},H={...v};class j{_locale;_fallbackLocale;_messages;_config;constructor(q={}){this._config={...v,...q},this._locale=this._config.locale,this._fallbackLocale=this._config.fallbackLocale,this._messages=this._config.messages||{}}get locale(){return this._locale}set locale(q){this._locale=q}get fallbackLocale(){return this._fallbackLocale}get availableLocales(){return Object.keys(this._messages)}t=(q,B,G)=>{return this.translate(q,B,G)};tc=(q,B,G,K)=>{return this.translatePlural(q,B,G,K)};te=(q,B)=>{return this.hasTranslation(q,B)};tm=(q,B)=>{return this.getMessage(q,B)};setLocale=(q)=>{this._locale=q};addTranslations=(q,B)=>{if(!this._messages[q])this._messages[q]={};this._messages[q]=V(this._messages[q],B)};d=(q,B)=>{let G=typeof q==="number"?new Date(q):q,K=this._config.dateTimeFormats?.[this._locale]?.[B||"short"]||{};return new Intl.DateTimeFormat(this._locale,K).format(G)};n=(q,B)=>{let G=this._config.numberFormats?.[this._locale]?.[B||"decimal"]||{};return new Intl.NumberFormat(this._locale,G).format(q)};translate(q,B,G){let K=G||this._locale,J=this.getMessage(q,K);if(J===void 0){let Q=K.indexOf("-");if(Q>0){let X=K.slice(0,Q);if(X!==this._fallbackLocale)J=this.getMessage(q,X)}}if(J===void 0&&K!==this._fallbackLocale)J=this.getMessage(q,this._fallbackLocale);if(J===void 0){if(this._config.warnMissing)console.warn(`[i18n] Missing translation: "${q}" for locale "${K}"`);if(this._config.missingHandler){let Q=this._config.missingHandler(K,q);if(Q!==void 0)return Q}return q}if(typeof J!=="string")return q;return this.interpolate(J,B)}translatePlural(q,B,G,K){let J=K||this._locale,Q=this.getMessage(q,J);if(Q===void 0&&J!==this._fallbackLocale)Q=this.getMessage(q,this._fallbackLocale);if(Q===void 0||typeof Q!=="string"){if(this._config.warnMissing)console.warn(`[i18n] Missing plural translation: "${q}" for locale "${J}"`);return q}let X=C(Q,this._config.pluralSeparator),U=O(X,B,J),Z={count:B,n:B,...G};return this.interpolate(U,Z)}hasTranslation(q,B){let G=B||this._locale;return this.getMessage(q,G)!==void 0}getMessage(q,B){let G=this._messages[B];if(!G)return;let K=q.split(this._config.keySeparator||"."),J=G;for(let Q of K){if(J===void 0||typeof J==="string")return;J=J[Q]}return J}interpolate(q,B){if(!B)return q;return q.replace(/\{(\w+)\}/g,(G,K)=>{let J=B[K];if(J===void 0||J===null)return G;let Q=String(J);return this._config.escapeValues?qq(Q):Q})}}function n(q){Y=q}function _(){return Y}function Vq(q){z=q}function s(){return Object.keys(w)}function F(q,B){if(!w[q])w[q]={};w[q]=V(w[q],B)}function N(q){for(let[B,G]of Object.entries(q))F(B,G)}function L(q,B){return I(q,B||Y)!==void 0}function I(q,B){let G=w[B];if(!G)return;let K=q.split(H.keySeparator||"."),J=G;for(let Q of K){if(J===void 0||typeof J==="string")return;J=J[Q]}return J}function k(q,B){if(!B)return q;return q.replace(/\{(\w+)\}/g,(G,K)=>{let J=B[K];if(J===void 0||J===null)return G;return String(J)})}function f(q,B,G){let K=G||Y,J=I(q,K);if(J===void 0&&K!==z)J=I(q,z);if(J===void 0){if(H.warnMissing)console.warn(`[i18n] Missing translation: "${q}" for locale "${K}"`);return q}if(typeof J!=="string")return q;return k(J,B)}var t=f;function o(q,B,G,K){let J=K||Y,Q=I(q,J);if(Q===void 0&&J!==z)Q=I(q,z);if(Q===void 0||typeof Q!=="string")return q;let X=C(Q,H.pluralSeparator),U=O(X,B,J),Z={count:B,n:B,...G};return k(U,Z)}function l(q,B){return L(q,B)}function a(q,B){return I(q,B||Y)}function y(q={}){return new j(q)}function e(q={}){return y(q)}function Sq(q){if(H={...H,...q},q.locale)Y=q.locale;if(q.fallbackLocale)z=q.fallbackLocale;if(q.messages)N(q.messages)}function V(q,B){let G={...q};for(let K of Object.keys(B)){let J=B[K],Q=G[K];if(typeof J==="object"&&J!==null&&typeof Q==="object"&&Q!==null)G[K]=V(Q,J);else G[K]=J}return G}function qq(q){let B={"&":"&","<":"<",">":">",'"':""","'":"'"};return q.replace(/[&<>"']/g,(G)=>B[G]||G)}function Bq(q,B="medium",G){let K=G||_(),J=R(q),Q=typeof B==="string"?{dateStyle:B}:B;return new Intl.DateTimeFormat(K,Q).format(J)}function Gq(q,B="short",G){let K=G||_(),J=R(q),Q=typeof B==="string"?{timeStyle:B}:B;return new Intl.DateTimeFormat(K,Q).format(J)}function Jq(q,B="medium",G="short",K){let J=K||_(),Q=R(q);return new Intl.DateTimeFormat(J,{dateStyle:B,timeStyle:G}).format(Q)}function Kq(q,B=new Date,G="long",K){let J=K||_(),Q=R(q),X=R(B),U=Q.getTime()-X.getTime(),Z=Math.round(U/1000),$=Math.round(Z/60),A=Math.round($/60),E=Math.round(A/24),b=Math.round(E/7),h=Math.round(E/30),u=Math.round(E/365),W=new Intl.RelativeTimeFormat(J,{style:G});if(Math.abs(Z)<60)return W.format(Z,"second");if(Math.abs($)<60)return W.format($,"minute");if(Math.abs(A)<24)return W.format(A,"hour");if(Math.abs(E)<7)return W.format(E,"day");if(Math.abs(b)<4)return W.format(b,"week");if(Math.abs(h)<12)return W.format(h,"month");return W.format(u,"year")}function Qq(q,B={},G){let K=G||_(),J={...B};if(B.compact)J.notation="compact",J.compactDisplay="short";if(B.precision!==void 0)J.minimumFractionDigits=B.precision,J.maximumFractionDigits=B.precision;return new Intl.NumberFormat(K,J).format(q)}function Uq(q,B="USD",G={},K){let J=K||_();return new Intl.NumberFormat(J,{style:"currency",currency:B,...G}).format(q)}function Xq(q,B={},G){let K=G||_();return new Intl.NumberFormat(K,{style:"percent",...B}).format(q)}function Mq(q,B,G="short",K){let J=K||_();return new Intl.NumberFormat(J,{style:"unit",unit:B,unitDisplay:G}).format(q)}function Dq(q,B=2,G){let K=G||_();if(q===0)return"0 B";let J=1024,Q=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],X=Math.floor(Math.log(q)/Math.log(J)),U=q/Math.pow(J,X);return`${new Intl.NumberFormat(K,{minimumFractionDigits:0,maximumFractionDigits:B}).format(U)} ${Q[X]}`}function Zq(q,B="conjunction",G="long",K){let J=K||_();return new Intl.ListFormat(J,{type:B,style:G}).format(q)}function p(q,B){let G=B||_();return new Intl.PluralRules(G).select(q)}function bq(q,B,G){let K=p(q,G);return B[K]??B.other}function S(q,B="language",G="long",K){let J=K||_();try{return new Intl.DisplayNames(J,{type:B,style:G}).of(q)}catch{return}}function hq(q,B){return S(q,"language","long",B)}function vq(q,B){return S(q,"region","long",B)}function Lq(q,B){return S(q,"currency","long",B)}function kq(q,B,G={},K){let J=K||_();return new Intl.Collator(J,G).compare(q,B)}function fq(q,B={},G){let K=G||_(),J=new Intl.Collator(K,B);return[...q].sort((Q,X)=>J.compare(Q,X))}function R(q){if(q instanceof Date)return q;if(typeof q==="number")return new Date(q);return new Date(q)}function _q(q){let G=(q||_()).split("-")[0].toLowerCase();return["ar","he","fa","ur","yi","ps","sd","ug","ku","ckb"].includes(G)?"rtl":"ltr"}function yq(q){return _q(q)==="rtl"}import{existsSync as $q,readdirSync as g}from"fs";import{readFile as Aq}from"fs/promises";import{basename as d,extname as P,join as x}from"path";import{log as Eq}from"@stacksjs/logging";async function Wq(q){let{directory:B,extensions:G=[".json",".yaml",".yml",".ts",".js"],recursive:K=!1,namespaceSeparator:J="."}=q,Q={};if(!$q(B))return Eq.warn(`[i18n] Translation directory not found: ${B}`),Q;return await m(B,Q,G,K,J,""),N(Q),Q}async function m(q,B,G,K,J,Q){let X=g(q,{withFileTypes:!0});for(let U of X){let Z=x(q,U.name);if(U.isDirectory()){let $=U.name;if(Iq($))await Yq(Z,$,B,G);else if(K){let A=Q?`${Q}${J}${U.name}`:U.name;await m(Z,B,G,K,J,A)}}else if(U.isFile()){let $=P(U.name);if(G.includes($)){let A=d(U.name,$);if(!B[A])B[A]={};let E=await M(Z);if(Q)Hq(B[A],Q,E,J);else B[A]=D(B[A],E)}}}}async function Yq(q,B,G,K){if(!G[B])G[B]={};let J=g(q,{withFileTypes:!0});for(let Q of J){if(!Q.isFile())continue;let X=P(Q.name);if(!K.includes(X))continue;let U=x(q,Q.name),Z=d(Q.name,X),$=await M(U);if(Z===B)G[B]=D(G[B],$);else G[B][Z]=$}}async function M(q){let B=P(q).toLowerCase(),G=await Aq(q,"utf8");switch(B){case".json":try{return JSON.parse(G)}catch{throw Error(`Invalid JSON in translation file: ${q}`)}case".yaml":case".yml":return zq(G);case".ts":case".js":{let K=await import(q);return K.default||K}default:throw Error(`Unsupported file type: ${B}`)}}async function wq(q,B){let G=await M(B);return F(q,G),G}function zq(q){try{let B=Bun.YAML.parse(q);if(!B||typeof B!=="object"||Array.isArray(B))throw Error("YAML content must be an object at the root level");return B}catch(B){let G=B instanceof Error?B.message:"Unknown YAML parse error";throw Error(`Invalid YAML translation file: ${G}`)}}function Iq(q){return/^[a-z]{2}(-[A-Z]{2})?(-[A-Za-z]+)?$/i.test(q)}function Hq(q,B,G,K){let J=B.split(K),Q=q;for(let U=0;U<J.length-1;U++){let Z=J[U];if(!Q[Z]||typeof Q[Z]==="string")Q[Z]={};Q=Q[Z]}let X=J[J.length-1];Q[X]=G}function D(q,B){let G={...q};for(let K of Object.keys(B)){let J=B[K],Q=G[K];if(typeof J==="object"&&J!==null&&typeof Q==="object"&&Q!==null)G[K]=D(Q,J);else G[K]=J}return G}function cq(q,B={}){return{load:()=>Wq({directory:q,...B}),loadLocale:(G,K)=>wq(G,x(q,K))}}async function rq(q){let{loadTranslations:B}=await import("@stacksjs/ts-i18n"),G=await B(q);return N(G),G}var sq={en:{code:"en",name:"English",nativeName:"English",direction:"ltr"},"en-US":{code:"en-US",name:"English (US)",nativeName:"English (US)",direction:"ltr",region:"US"},"en-GB":{code:"en-GB",name:"English (UK)",nativeName:"English (UK)",direction:"ltr",region:"GB"},es:{code:"es",name:"Spanish",nativeName:"Espa\xF1ol",direction:"ltr"},fr:{code:"fr",name:"French",nativeName:"Fran\xE7ais",direction:"ltr"},de:{code:"de",name:"German",nativeName:"Deutsch",direction:"ltr"},it:{code:"it",name:"Italian",nativeName:"Italiano",direction:"ltr"},pt:{code:"pt",name:"Portuguese",nativeName:"Portugu\xEAs",direction:"ltr"},"pt-BR":{code:"pt-BR",name:"Portuguese (Brazil)",nativeName:"Portugu\xEAs (Brasil)",direction:"ltr",region:"BR"},zh:{code:"zh",name:"Chinese",nativeName:"\u4E2D\u6587",direction:"ltr"},"zh-CN":{code:"zh-CN",name:"Chinese (Simplified)",nativeName:"\u7B80\u4F53\u4E2D\u6587",direction:"ltr",region:"CN"},"zh-TW":{code:"zh-TW",name:"Chinese (Traditional)",nativeName:"\u7E41\u9AD4\u4E2D\u6587",direction:"ltr",region:"TW"},ja:{code:"ja",name:"Japanese",nativeName:"\u65E5\u672C\u8A9E",direction:"ltr"},ko:{code:"ko",name:"Korean",nativeName:"\uD55C\uAD6D\uC5B4",direction:"ltr"},ar:{code:"ar",name:"Arabic",nativeName:"\u0627\u0644\u0639\u0631\u0628\u064A\u0629",direction:"rtl"},he:{code:"he",name:"Hebrew",nativeName:"\u05E2\u05D1\u05E8\u05D9\u05EA",direction:"rtl"},ru:{code:"ru",name:"Russian",nativeName:"\u0420\u0443\u0441\u0441\u043A\u0438\u0439",direction:"ltr"},nl:{code:"nl",name:"Dutch",nativeName:"Nederlands",direction:"ltr"},pl:{code:"pl",name:"Polish",nativeName:"Polski",direction:"ltr"},tr:{code:"tr",name:"Turkish",nativeName:"T\xFCrk\xE7e",direction:"ltr"},vi:{code:"vi",name:"Vietnamese",nativeName:"Ti\u1EBFng Vi\u1EC7t",direction:"ltr"},th:{code:"th",name:"Thai",nativeName:"\u0E44\u0E17\u0E22",direction:"ltr"},hi:{code:"hi",name:"Hindi",nativeName:"\u0939\u093F\u0928\u094D\u0926\u0940",direction:"ltr"}};import{loadTranslations as JB,generateTypes as KB,generateTypesFromModule as QB,generateSampleConfig as UB,writeOutputs as XB,createTranslator as ZB}from"@stacksjs/ts-i18n";export{XB as writeI18nOutputs,e as useI18n,t as trans,a as tm,l as te,o as tc,f as t,fq as sortStrings,n as setLocale,Vq as setFallbackLocale,O as selectPluralForm,bq as selectPlural,C as parsePluralForms,JB as loadTranslationsFromDisk,N as loadTranslations,wq as loadLocale,rq as loadFromTsI18n,Wq as loadFromDirectory,M as loadFile,yq as isRTL,L as hasTranslation,Tq as hasPluralRule,_q as getTextDirection,Rq as getSupportedPluralLocales,vq as getRegionName,r as getPluralRule,c as getPluralCategory,_ as getLocale,hq as getLanguageName,S as getDisplayName,Lq as getCurrencyName,s as getAvailableLocales,QB as generateI18nTypesFromModule,KB as generateI18nTypes,UB as generateI18nSampleConfig,Mq as formatUnit,Gq as formatTime,Kq as formatRelativeTime,p as formatPlural,Xq as formatPercent,Qq as formatNumber,Zq as formatList,Jq as formatDateTime,Bq as formatDate,Uq as formatCurrency,Dq as formatBytes,ZB as createSimpleTranslator,cq as createLoader,y as createI18n,Sq as configure,kq as compareStrings,F as addTranslations,Fq as addPluralRule,sq as LOCALE_INFO,j as I18n};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a date
|
|
3
|
+
*/
|
|
4
|
+
export declare function formatDate(date: Date | number | string, style?: DateStyle | DateFormatOptions, locale?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Format a time
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatTime(date: Date | number | string, style?: TimeStyle | DateFormatOptions, locale?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Format a date and time
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatDateTime(date: Date | number | string, dateStyle?: DateStyle, timeStyle?: TimeStyle, locale?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format relative time (e.g., "2 days ago", "in 3 hours")
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatRelativeTime(date: Date | number | string, baseDate?: Date | number | string, style?: 'long' | 'short' | 'narrow', locale?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format a number
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatNumber(value: number, options?: NumberFormatOptions, locale?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Format a currency value
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatCurrency(value: number, currency?: string, options?: Omit<NumberFormatOptions, 'style' | 'currency'>, locale?: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Format a percentage
|
|
27
|
+
*/
|
|
28
|
+
export declare function formatPercent(value: number, options?: Omit<NumberFormatOptions, 'style'>, locale?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format a number with units (e.g., "5 kilograms", "10 miles")
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatUnit(value: number, unit: string, unitDisplay?: 'long' | 'short' | 'narrow', locale?: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Format bytes to human-readable format
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatBytes(bytes: number, decimals?: number, locale?: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Format a list of items
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatList(items: string[], type?: ListType, style?: ListStyle, locale?: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Get the plural category for a number
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatPlural(value: number, locale?: string): Intl.LDMLPluralRule;
|
|
45
|
+
/**
|
|
46
|
+
* Select from plural options based on a number
|
|
47
|
+
*/
|
|
48
|
+
export declare function selectPlural<T>(value: number, options: Partial<Record<Intl.LDMLPluralRule, T>> & { other: T }, locale?: string): T;
|
|
49
|
+
/**
|
|
50
|
+
* Get display name for a code
|
|
51
|
+
*/
|
|
52
|
+
export declare function getDisplayName(code: string, type?: DisplayNameType, style?: 'long' | 'short' | 'narrow', locale?: string): string | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Get language name
|
|
55
|
+
*/
|
|
56
|
+
export declare function getLanguageName(languageCode: string, locale?: string): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Get region/country name
|
|
59
|
+
*/
|
|
60
|
+
export declare function getRegionName(regionCode: string, locale?: string): string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Get currency name
|
|
63
|
+
*/
|
|
64
|
+
export declare function getCurrencyName(currencyCode: string, locale?: string): string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Compare strings in a locale-aware manner
|
|
67
|
+
*/
|
|
68
|
+
export declare function compareStrings(a: string, b: string, options?: Intl.CollatorOptions, locale?: string): number;
|
|
69
|
+
/**
|
|
70
|
+
* Sort an array of strings in locale-aware order
|
|
71
|
+
*/
|
|
72
|
+
export declare function sortStrings(strings: string[], options?: Intl.CollatorOptions, locale?: string): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Get the text direction for a locale
|
|
75
|
+
*/
|
|
76
|
+
export declare function getTextDirection(locale?: string): 'ltr' | 'rtl';
|
|
77
|
+
/**
|
|
78
|
+
* Check if a locale uses RTL text direction
|
|
79
|
+
*/
|
|
80
|
+
export declare function isRTL(locale?: string): boolean;
|
|
81
|
+
export declare interface DateFormatOptions extends Intl.DateTimeFormatOptions {
|
|
82
|
+
dateStyle?: DateStyle
|
|
83
|
+
timeStyle?: TimeStyle
|
|
84
|
+
}
|
|
85
|
+
// =============================================================================
|
|
86
|
+
// Number Formatting
|
|
87
|
+
// =============================================================================
|
|
88
|
+
export declare interface NumberFormatOptions extends Intl.NumberFormatOptions {
|
|
89
|
+
compact?: boolean
|
|
90
|
+
precision?: number
|
|
91
|
+
}
|
|
92
|
+
// =============================================================================
|
|
93
|
+
// Date Formatting
|
|
94
|
+
// =============================================================================
|
|
95
|
+
export type DateStyle = 'full' | 'long' | 'medium' | 'short';
|
|
96
|
+
export type TimeStyle = 'full' | 'long' | 'medium' | 'short';
|
|
97
|
+
// =============================================================================
|
|
98
|
+
// List Formatting
|
|
99
|
+
// =============================================================================
|
|
100
|
+
export type ListType = 'conjunction' | 'disjunction' | 'unit';
|
|
101
|
+
export type ListStyle = 'long' | 'short' | 'narrow';
|
|
102
|
+
// =============================================================================
|
|
103
|
+
// Display Names
|
|
104
|
+
// =============================================================================
|
|
105
|
+
export type DisplayNameType = 'language' | 'region' | 'script' | 'currency' | 'calendar' | 'dateTimeField';
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export type { I18nConfig as TsI18nConfig, TranslationTree, TranslationValue } from '@stacksjs/ts-i18n';
|
|
2
|
+
/**
|
|
3
|
+
* Stacks i18n - Internationalization System
|
|
4
|
+
*
|
|
5
|
+
* A comprehensive internationalization system with support for:
|
|
6
|
+
* - Translation loading from JSON/YAML files
|
|
7
|
+
* - Plural forms
|
|
8
|
+
* - Variable interpolation
|
|
9
|
+
* - Nested translations
|
|
10
|
+
* - Date/time formatting
|
|
11
|
+
* - Number formatting
|
|
12
|
+
* - Currency formatting
|
|
13
|
+
* - Relative time formatting
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { t, setLocale, addTranslations } from '@stacksjs/i18n'
|
|
18
|
+
*
|
|
19
|
+
* // Add translations
|
|
20
|
+
* addTranslations('en', {
|
|
21
|
+
* greeting: 'Hello, {name}!',
|
|
22
|
+
* items: '{count} item | {count} items',
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* // Use translations
|
|
26
|
+
* t('greeting', { name: 'World' }) // "Hello, World!"
|
|
27
|
+
* t('items', { count: 1 }) // "1 item"
|
|
28
|
+
* t('items', { count: 5 }) // "5 items"
|
|
29
|
+
*
|
|
30
|
+
* // Format dates and numbers
|
|
31
|
+
* formatDate(new Date(), 'long') // "January 8, 2026"
|
|
32
|
+
* formatNumber(1234567.89) // "1,234,567.89"
|
|
33
|
+
* formatCurrency(99.99, 'USD') // "$99.99"
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export * from './translator';
|
|
37
|
+
export * from './formatter';
|
|
38
|
+
export * from './pluralization';
|
|
39
|
+
export * from './loader';
|
|
40
|
+
export * from './types';
|
|
41
|
+
// Re-export the file-loading and type-generation surface from
|
|
42
|
+
// `@stacksjs/ts-i18n`. The library handles disk loading (YAML / TS /
|
|
43
|
+
// JSON), namespace resolution, and `.d.ts` codegen for translation
|
|
44
|
+
// keys; the Stacks-side translator/formatter sits on top of that
|
|
45
|
+
// data with locale management, ICU pluralization, and Intl-backed
|
|
46
|
+
// formatters. Importing both names from `@stacksjs/i18n` keeps the
|
|
47
|
+
// app side from caring which symbol comes from which package.
|
|
48
|
+
export {
|
|
49
|
+
loadTranslations as loadTranslationsFromDisk,
|
|
50
|
+
generateTypes as generateI18nTypes,
|
|
51
|
+
generateTypesFromModule as generateI18nTypesFromModule,
|
|
52
|
+
generateSampleConfig as generateI18nSampleConfig,
|
|
53
|
+
writeOutputs as writeI18nOutputs,
|
|
54
|
+
createTranslator as createSimpleTranslator,
|
|
55
|
+
} from '@stacksjs/ts-i18n';
|
|
56
|
+
// Re-export main functions for convenience
|
|
57
|
+
export {
|
|
58
|
+
t,
|
|
59
|
+
trans,
|
|
60
|
+
tc,
|
|
61
|
+
te,
|
|
62
|
+
tm,
|
|
63
|
+
setLocale,
|
|
64
|
+
getLocale,
|
|
65
|
+
addTranslations,
|
|
66
|
+
loadTranslations,
|
|
67
|
+
getAvailableLocales,
|
|
68
|
+
hasTranslation,
|
|
69
|
+
I18n,
|
|
70
|
+
createI18n,
|
|
71
|
+
useI18n,
|
|
72
|
+
} from './translator';
|
|
73
|
+
export {
|
|
74
|
+
formatDate,
|
|
75
|
+
formatTime,
|
|
76
|
+
formatDateTime,
|
|
77
|
+
formatNumber,
|
|
78
|
+
formatCurrency,
|
|
79
|
+
formatPercent,
|
|
80
|
+
formatRelativeTime,
|
|
81
|
+
formatList,
|
|
82
|
+
formatPlural,
|
|
83
|
+
} from './formatter';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { TranslationMessages, Translations } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Load translations from a directory
|
|
4
|
+
*/
|
|
5
|
+
export declare function loadFromDirectory(options: LoaderOptions): Promise<Translations>;
|
|
6
|
+
/**
|
|
7
|
+
* Load a single translation file
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadFile(filePath: string): Promise<TranslationMessages>;
|
|
10
|
+
/**
|
|
11
|
+
* Load a single locale from a file or directory
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadLocale(locale: string, path: string): Promise<TranslationMessages>;
|
|
14
|
+
/**
|
|
15
|
+
* Create a translation loader for a specific directory
|
|
16
|
+
*/
|
|
17
|
+
export declare function createLoader(directory: string, options?: Partial<Omit<LoaderOptions, 'directory'>>): void;
|
|
18
|
+
/**
|
|
19
|
+
* Load translations via `@stacksjs/ts-i18n` and register them with the
|
|
20
|
+
* global translator. This is the recommended path for new projects —
|
|
21
|
+
* it gets you:
|
|
22
|
+
*
|
|
23
|
+
* - Per-locale subdirectory namespacing (en/auth.yaml → en.auth.*)
|
|
24
|
+
* - First-class .ts/.json/.yaml support with consistent error
|
|
25
|
+
* messages
|
|
26
|
+
* - Optional `.d.ts` codegen via `generateI18nTypes()` so message
|
|
27
|
+
* keys autocomplete in `t('…')` calls
|
|
28
|
+
*
|
|
29
|
+
* The legacy `loadFromDirectory()` remains for projects that depend
|
|
30
|
+
* on its specific behavior; new code should prefer this entry.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* await loadFromTsI18n({
|
|
35
|
+
* translationsDir: path.userI18nPath(),
|
|
36
|
+
* defaultLocale: 'en',
|
|
37
|
+
* fallbackLocale: 'en',
|
|
38
|
+
* sources: ['yaml', 'ts', 'json'],
|
|
39
|
+
* optional: true,
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function loadFromTsI18n(config: import('@stacksjs/ts-i18n').I18nConfig): Promise<Translations>;
|
|
44
|
+
export declare interface LoaderOptions {
|
|
45
|
+
directory: string
|
|
46
|
+
extensions?: string[]
|
|
47
|
+
recursive?: boolean
|
|
48
|
+
namespaceSeparator?: string
|
|
49
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the plural category for a number in a given locale
|
|
3
|
+
*/
|
|
4
|
+
export declare function getPluralCategory(n: number, locale: string): PluralCategory;
|
|
5
|
+
/**
|
|
6
|
+
* Get the plural rule function for a locale
|
|
7
|
+
*/
|
|
8
|
+
export declare function getPluralRule(locale: string): PluralRule;
|
|
9
|
+
/**
|
|
10
|
+
* Parse a plural string into its forms
|
|
11
|
+
*
|
|
12
|
+
* Supports formats:
|
|
13
|
+
* - "one | other" (simple)
|
|
14
|
+
* - "zero | one | other" (with zero)
|
|
15
|
+
* - "{0} item | {0} items" (with placeholders)
|
|
16
|
+
* - "no items | one item | {n} items" (with special forms)
|
|
17
|
+
*/
|
|
18
|
+
export declare function parsePluralForms(str: string, separator?: string): Map<PluralCategory, string>;
|
|
19
|
+
/**
|
|
20
|
+
* Select the appropriate plural form for a count
|
|
21
|
+
*/
|
|
22
|
+
export declare function selectPluralForm(forms: Map<PluralCategory, string>, count: number, locale: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get all supported locales for pluralization
|
|
25
|
+
*/
|
|
26
|
+
export declare function getSupportedPluralLocales(): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Check if a locale has custom plural rules
|
|
29
|
+
*/
|
|
30
|
+
export declare function hasPluralRule(locale: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Add a custom plural rule for a locale
|
|
33
|
+
*/
|
|
34
|
+
export declare function addPluralRule(locale: string, rule: PluralRule): void;
|
|
35
|
+
/**
|
|
36
|
+
* Pluralization Rules
|
|
37
|
+
*
|
|
38
|
+
* Implements CLDR plural rules for various languages.
|
|
39
|
+
* @see https://cldr.unicode.org/index/cldr-spec/plural-rules
|
|
40
|
+
*/
|
|
41
|
+
export type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
|
|
42
|
+
export type PluralRule = (_n: number) => PluralCategory;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { I18nConfig, I18nInstance, InterpolationValues, TranslationMessages, Translations } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Set the current locale
|
|
4
|
+
*/
|
|
5
|
+
export declare function setLocale(locale: string): void;
|
|
6
|
+
/**
|
|
7
|
+
* Get the current locale
|
|
8
|
+
*/
|
|
9
|
+
export declare function getLocale(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Set the fallback locale
|
|
12
|
+
*/
|
|
13
|
+
export declare function setFallbackLocale(locale: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Get available locales
|
|
16
|
+
*/
|
|
17
|
+
export declare function getAvailableLocales(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Add translations for a locale
|
|
20
|
+
*/
|
|
21
|
+
export declare function addTranslations(locale: string, messages: TranslationMessages): void;
|
|
22
|
+
/**
|
|
23
|
+
* Load translations (alias for addTranslations for multiple locales)
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadTranslations(messages: Translations): void;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a translation exists
|
|
28
|
+
*/
|
|
29
|
+
export declare function hasTranslation(key: string, locale?: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Translate a key
|
|
32
|
+
*/
|
|
33
|
+
export declare function t(key: string, values?: InterpolationValues, locale?: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Translate with pluralization
|
|
36
|
+
*/
|
|
37
|
+
export declare function tc(key: string, count: number, values?: InterpolationValues, locale?: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Check if translation exists
|
|
40
|
+
*/
|
|
41
|
+
export declare function te(key: string, locale?: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Get translation message object
|
|
44
|
+
*/
|
|
45
|
+
export declare function tm(key: string, locale?: string): TranslationMessages | string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Create a new i18n instance
|
|
48
|
+
*/
|
|
49
|
+
export declare function createI18n(options?: Partial<I18nConfig>): I18n;
|
|
50
|
+
/**
|
|
51
|
+
* Use i18n composable (for Vue-like usage)
|
|
52
|
+
*/
|
|
53
|
+
export declare function useI18n(options?: Partial<I18nConfig>): I18nInstance;
|
|
54
|
+
/**
|
|
55
|
+
* Configure the global i18n instance
|
|
56
|
+
*/
|
|
57
|
+
export declare function configure(options: Partial<I18nConfig>): void;
|
|
58
|
+
/**
|
|
59
|
+
* Alias for t()
|
|
60
|
+
*/
|
|
61
|
+
export declare const trans: unknown;
|
|
62
|
+
/**
|
|
63
|
+
* I18n class for creating isolated instances
|
|
64
|
+
*/
|
|
65
|
+
export declare class I18n implements I18nInstance {
|
|
66
|
+
constructor(options?: Partial<I18nConfig>);
|
|
67
|
+
get locale(): string;
|
|
68
|
+
set locale(value: string);
|
|
69
|
+
get fallbackLocale(): string;
|
|
70
|
+
get availableLocales(): string[];
|
|
71
|
+
t: unknown;
|
|
72
|
+
tc: unknown;
|
|
73
|
+
te: unknown;
|
|
74
|
+
tm: unknown;
|
|
75
|
+
setLocale: unknown;
|
|
76
|
+
addTranslations: unknown;
|
|
77
|
+
d: unknown;
|
|
78
|
+
n: unknown;
|
|
79
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common locales with metadata
|
|
3
|
+
*/
|
|
4
|
+
export declare const LOCALE_INFO: {
|
|
5
|
+
en: {
|
|
6
|
+
code: 'en';
|
|
7
|
+
name: 'English';
|
|
8
|
+
nativeName: 'English';
|
|
9
|
+
direction: 'ltr'
|
|
10
|
+
};
|
|
11
|
+
'en-US': {
|
|
12
|
+
code: 'en-US';
|
|
13
|
+
name: 'English (US)';
|
|
14
|
+
nativeName: 'English (US)';
|
|
15
|
+
direction: 'ltr';
|
|
16
|
+
region: 'US'
|
|
17
|
+
};
|
|
18
|
+
'en-GB': {
|
|
19
|
+
code: 'en-GB';
|
|
20
|
+
name: 'English (UK)';
|
|
21
|
+
nativeName: 'English (UK)';
|
|
22
|
+
direction: 'ltr';
|
|
23
|
+
region: 'GB'
|
|
24
|
+
};
|
|
25
|
+
es: {
|
|
26
|
+
code: 'es';
|
|
27
|
+
name: 'Spanish';
|
|
28
|
+
nativeName: 'Espa\u00f1ol';
|
|
29
|
+
direction: 'ltr'
|
|
30
|
+
};
|
|
31
|
+
fr: {
|
|
32
|
+
code: 'fr';
|
|
33
|
+
name: 'French';
|
|
34
|
+
nativeName: 'Fran\u00e7ais';
|
|
35
|
+
direction: 'ltr'
|
|
36
|
+
};
|
|
37
|
+
de: {
|
|
38
|
+
code: 'de';
|
|
39
|
+
name: 'German';
|
|
40
|
+
nativeName: 'Deutsch';
|
|
41
|
+
direction: 'ltr'
|
|
42
|
+
};
|
|
43
|
+
it: {
|
|
44
|
+
code: 'it';
|
|
45
|
+
name: 'Italian';
|
|
46
|
+
nativeName: 'Italiano';
|
|
47
|
+
direction: 'ltr'
|
|
48
|
+
};
|
|
49
|
+
pt: {
|
|
50
|
+
code: 'pt';
|
|
51
|
+
name: 'Portuguese';
|
|
52
|
+
nativeName: 'Portugu\u00eas';
|
|
53
|
+
direction: 'ltr'
|
|
54
|
+
};
|
|
55
|
+
'pt-BR': {
|
|
56
|
+
code: 'pt-BR';
|
|
57
|
+
name: 'Portuguese (Brazil)';
|
|
58
|
+
nativeName: 'Portugu\u00eas (Brasil)';
|
|
59
|
+
direction: 'ltr';
|
|
60
|
+
region: 'BR'
|
|
61
|
+
};
|
|
62
|
+
zh: {
|
|
63
|
+
code: 'zh';
|
|
64
|
+
name: 'Chinese';
|
|
65
|
+
nativeName: '\u4e2d\u6587';
|
|
66
|
+
direction: 'ltr'
|
|
67
|
+
};
|
|
68
|
+
'zh-CN': {
|
|
69
|
+
code: 'zh-CN';
|
|
70
|
+
name: 'Chinese (Simplified)';
|
|
71
|
+
nativeName: '\u7b80\u4f53\u4e2d\u6587';
|
|
72
|
+
direction: 'ltr';
|
|
73
|
+
region: 'CN'
|
|
74
|
+
};
|
|
75
|
+
'zh-TW': {
|
|
76
|
+
code: 'zh-TW';
|
|
77
|
+
name: 'Chinese (Traditional)';
|
|
78
|
+
nativeName: '\u7e41\u9ad4\u4e2d\u6587';
|
|
79
|
+
direction: 'ltr';
|
|
80
|
+
region: 'TW'
|
|
81
|
+
};
|
|
82
|
+
ja: {
|
|
83
|
+
code: 'ja';
|
|
84
|
+
name: 'Japanese';
|
|
85
|
+
nativeName: '\u65e5\u672c\u8a9e';
|
|
86
|
+
direction: 'ltr'
|
|
87
|
+
};
|
|
88
|
+
ko: {
|
|
89
|
+
code: 'ko';
|
|
90
|
+
name: 'Korean';
|
|
91
|
+
nativeName: '\ud55c\uad6d\uc5b4';
|
|
92
|
+
direction: 'ltr'
|
|
93
|
+
};
|
|
94
|
+
ar: {
|
|
95
|
+
code: 'ar';
|
|
96
|
+
name: 'Arabic';
|
|
97
|
+
nativeName: '\u0627\u0644\u0639\u0631\u0628\u064a\u0629';
|
|
98
|
+
direction: 'rtl'
|
|
99
|
+
};
|
|
100
|
+
he: {
|
|
101
|
+
code: 'he';
|
|
102
|
+
name: 'Hebrew';
|
|
103
|
+
nativeName: '\u05e2\u05d1\u05e8\u05d9\u05ea';
|
|
104
|
+
direction: 'rtl'
|
|
105
|
+
};
|
|
106
|
+
ru: {
|
|
107
|
+
code: 'ru';
|
|
108
|
+
name: 'Russian';
|
|
109
|
+
nativeName: '\u0420\u0443\u0441\u0441\u043a\u0438\u0439';
|
|
110
|
+
direction: 'ltr'
|
|
111
|
+
};
|
|
112
|
+
nl: {
|
|
113
|
+
code: 'nl';
|
|
114
|
+
name: 'Dutch';
|
|
115
|
+
nativeName: 'Nederlands';
|
|
116
|
+
direction: 'ltr'
|
|
117
|
+
};
|
|
118
|
+
pl: {
|
|
119
|
+
code: 'pl';
|
|
120
|
+
name: 'Polish';
|
|
121
|
+
nativeName: 'Polski';
|
|
122
|
+
direction: 'ltr'
|
|
123
|
+
};
|
|
124
|
+
tr: {
|
|
125
|
+
code: 'tr';
|
|
126
|
+
name: 'Turkish';
|
|
127
|
+
nativeName: 'T\u00fcrk\u00e7e';
|
|
128
|
+
direction: 'ltr'
|
|
129
|
+
};
|
|
130
|
+
vi: {
|
|
131
|
+
code: 'vi';
|
|
132
|
+
name: 'Vietnamese';
|
|
133
|
+
nativeName: 'Ti\u1ebfng Vi\u1ec7t';
|
|
134
|
+
direction: 'ltr'
|
|
135
|
+
};
|
|
136
|
+
th: {
|
|
137
|
+
code: 'th';
|
|
138
|
+
name: 'Thai';
|
|
139
|
+
nativeName: '\u0e44\u0e17\u0e22';
|
|
140
|
+
direction: 'ltr'
|
|
141
|
+
};
|
|
142
|
+
hi: {
|
|
143
|
+
code: 'hi';
|
|
144
|
+
name: 'Hindi';
|
|
145
|
+
nativeName: '\u0939\u093f\u0928\u094d\u0926\u0940';
|
|
146
|
+
direction: 'ltr'
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Plural forms for a translation
|
|
151
|
+
*/
|
|
152
|
+
export declare interface PluralForms {
|
|
153
|
+
zero?: string
|
|
154
|
+
one: string
|
|
155
|
+
two?: string
|
|
156
|
+
few?: string
|
|
157
|
+
many?: string
|
|
158
|
+
other: string
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* i18n configuration options
|
|
162
|
+
*/
|
|
163
|
+
export declare interface I18nConfig {
|
|
164
|
+
locale: string
|
|
165
|
+
fallbackLocale: string
|
|
166
|
+
availableLocales?: string[]
|
|
167
|
+
messages?: Translations
|
|
168
|
+
missingHandler?: (locale: string, key: string) => string | undefined
|
|
169
|
+
warnMissing?: boolean
|
|
170
|
+
escapeValues?: boolean
|
|
171
|
+
keySeparator?: string
|
|
172
|
+
pluralSeparator?: string
|
|
173
|
+
dateTimeFormats?: DateTimeFormats
|
|
174
|
+
numberFormats?: NumberFormats
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* i18n instance interface
|
|
178
|
+
*/
|
|
179
|
+
export declare interface I18nInstance {
|
|
180
|
+
locale: string
|
|
181
|
+
fallbackLocale: string
|
|
182
|
+
availableLocales: string[]
|
|
183
|
+
t: TranslateFunction
|
|
184
|
+
tc: TranslatePluralFunction
|
|
185
|
+
te: (key: string, locale?: string) => boolean
|
|
186
|
+
tm: (key: string, locale?: string) => TranslationMessages | string | undefined
|
|
187
|
+
setLocale: (locale: string) => void
|
|
188
|
+
addTranslations: (locale: string, messages: TranslationMessages) => void
|
|
189
|
+
d: (value: Date | number, format?: string) => string
|
|
190
|
+
n: (value: number, format?: string) => string
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Locale metadata
|
|
194
|
+
*/
|
|
195
|
+
export declare interface LocaleInfo {
|
|
196
|
+
code: string
|
|
197
|
+
name: string
|
|
198
|
+
nativeName: string
|
|
199
|
+
direction: 'ltr' | 'rtl'
|
|
200
|
+
region?: string
|
|
201
|
+
script?: string
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* i18n Type Definitions
|
|
205
|
+
*/
|
|
206
|
+
/**
|
|
207
|
+
* Translation messages - can be nested objects or strings
|
|
208
|
+
*/
|
|
209
|
+
export type TranslationMessages = {
|
|
210
|
+
[key: string]: string | TranslationMessages
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* All translations keyed by locale
|
|
214
|
+
*/
|
|
215
|
+
export type Translations = {
|
|
216
|
+
[locale: string]: TranslationMessages
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Interpolation values for translations
|
|
220
|
+
*/
|
|
221
|
+
export type InterpolationValues = Record<string, string | number | boolean | null | undefined>;
|
|
222
|
+
/**
|
|
223
|
+
* Date/time format configurations per locale
|
|
224
|
+
*/
|
|
225
|
+
export type DateTimeFormats = {
|
|
226
|
+
[locale: string]: {
|
|
227
|
+
[formatName: string]: Intl.DateTimeFormatOptions
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Number format configurations per locale
|
|
232
|
+
*/
|
|
233
|
+
export type NumberFormats = {
|
|
234
|
+
[locale: string]: {
|
|
235
|
+
[formatName: string]: Intl.NumberFormatOptions
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Translation function
|
|
240
|
+
*/
|
|
241
|
+
export type TranslateFunction = (
|
|
242
|
+
key: string,
|
|
243
|
+
values?: InterpolationValues,
|
|
244
|
+
locale?: string,
|
|
245
|
+
) => string;
|
|
246
|
+
/**
|
|
247
|
+
* Plural translation function
|
|
248
|
+
*/
|
|
249
|
+
export type TranslatePluralFunction = (
|
|
250
|
+
key: string,
|
|
251
|
+
count: number,
|
|
252
|
+
values?: InterpolationValues,
|
|
253
|
+
locale?: string,
|
|
254
|
+
) => string;
|