@i18n-micro/core 1.0.27
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/LICENSE +21 -0
- package/README.md +176 -0
- package/dist/format-service.d.ts +5 -0
- package/dist/helpers.d.ts +18 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +366 -0
- package/dist/route-service.d.ts +40 -0
- package/dist/translation.d.ts +24 -0
- package/fix.ts +1 -0
- package/jest.config.cjs +7 -0
- package/package.json +35 -0
- package/src/format-service.ts +41 -0
- package/src/helpers.ts +53 -0
- package/src/index.ts +18 -0
- package/src/route-service.ts +473 -0
- package/src/translation.ts +216 -0
- package/tests/core.test.ts +81 -0
- package/tests/format-service.test.ts +101 -0
- package/tests/helpers.test.ts +103 -0
- package/tests/route-service.test.ts +377 -0
- package/tsconfig.json +24 -0
- package/vite.config.mts +25 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @i18n-micro/core
|
|
2
|
+
|
|
3
|
+
`@i18n-micro/core` is the core module for handling translations, routing, and formatting in a Nuxt.js application. It provides utilities for managing translations, interpolating placeholders, formatting numbers, dates, and relative times, and handling locale-specific routing. This module is designed to work seamlessly with `nuxt-i18n-micro` and its associated utilities.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
You can install `@i18n-micro/core` using npm or yarn:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @i18n-micro/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
or
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @i18n-micro/core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
This package provides several utilities for managing translations, formatting, and routing:
|
|
22
|
+
|
|
23
|
+
1. **`useTranslationHelper`**: A helper for managing translations, including loading, caching, and retrieving translations.
|
|
24
|
+
2. **`interpolate`**: A utility for interpolating placeholders in translation strings with dynamic values.
|
|
25
|
+
3. **`FormatService`**: A service for formatting numbers, dates, and relative times.
|
|
26
|
+
4. **`RouteService`**: A service for handling locale-specific routing and route localization.
|
|
27
|
+
|
|
28
|
+
### Example
|
|
29
|
+
|
|
30
|
+
Here’s an example of how you might use these utilities in your Nuxt.js project:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { useTranslationHelper, interpolate, FormatService, RouteService } from '@i18n-micro/core'
|
|
34
|
+
|
|
35
|
+
// Initialize the translation helper
|
|
36
|
+
const translationHelper = useTranslationHelper()
|
|
37
|
+
|
|
38
|
+
// Load translations for a specific locale
|
|
39
|
+
translationHelper.loadTranslations('en', {
|
|
40
|
+
greeting: 'Hello, {name}!',
|
|
41
|
+
nested: {
|
|
42
|
+
message: 'This is a nested message.',
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Load page-specific translations for a specific locale
|
|
47
|
+
translationHelper.loadPageTranslations('en', 'home', {
|
|
48
|
+
welcome: 'Welcome to the home page!',
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Retrieve a translation for a specific locale
|
|
52
|
+
const greeting = translationHelper.getTranslation<string>('en', 'index', 'greeting')
|
|
53
|
+
console.log(greeting) // 'Hello, {name}!'
|
|
54
|
+
|
|
55
|
+
// Interpolate placeholders
|
|
56
|
+
const interpolatedGreeting = interpolate(greeting!, { name: 'John' })
|
|
57
|
+
console.log(interpolatedGreeting) // 'Hello, John!'
|
|
58
|
+
|
|
59
|
+
// Format numbers, dates, and relative times
|
|
60
|
+
const formatService = new FormatService()
|
|
61
|
+
const formattedNumber = formatService.formatNumber(123456.789, 'en-US')
|
|
62
|
+
const formattedDate = formatService.formatDate(new Date(), 'en-US')
|
|
63
|
+
const formattedRelativeTime = formatService.formatRelativeTime(new Date(), 'en-US')
|
|
64
|
+
|
|
65
|
+
console.log(formattedNumber) // '123,456.789'
|
|
66
|
+
console.log(formattedDate) // '10/5/2023'
|
|
67
|
+
console.log(formattedRelativeTime) // 'just now'
|
|
68
|
+
|
|
69
|
+
// Handle locale-specific routing
|
|
70
|
+
const routeService = new RouteService(
|
|
71
|
+
i18nConfig,
|
|
72
|
+
router,
|
|
73
|
+
hashLocaleDefault,
|
|
74
|
+
noPrefixDefault,
|
|
75
|
+
navigateTo,
|
|
76
|
+
setCookie
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const localizedRoute = routeService.getLocalizedRoute('/about', currentRoute, 'en')
|
|
80
|
+
console.log(localizedRoute) // Localized route object
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
### `useTranslationHelper`
|
|
86
|
+
|
|
87
|
+
#### Methods
|
|
88
|
+
- **`hasCache(locale: string, page: string): boolean`**:
|
|
89
|
+
Checks if translations for a specific route and locale are cached.
|
|
90
|
+
- **`getCache(locale: string, routeName: string): Map<string, Translations | unknown> | undefined`**:
|
|
91
|
+
Retrieves the cache for a specific route and locale.
|
|
92
|
+
- **`setCache(locale: string, routeName: string, cache: Map<string, Translations | unknown>): void`**:
|
|
93
|
+
Sets the cache for a specific route and locale.
|
|
94
|
+
- **`mergeTranslation(locale: string, routeName: string, newTranslations: Translations, force = false): void`**:
|
|
95
|
+
Merges new translations into the cache for a specific route and locale.
|
|
96
|
+
- **`mergeGlobalTranslation(locale: string, newTranslations: Translations, force = false): void`**:
|
|
97
|
+
Merges new translations into the global cache for a specific locale.
|
|
98
|
+
- **`hasGeneralTranslation(locale: string): boolean`**:
|
|
99
|
+
Checks if global translations are loaded for the specified locale.
|
|
100
|
+
- **`hasPageTranslation(locale: string, routeName: string): boolean`**:
|
|
101
|
+
Checks if translations for a specific route and locale are loaded.
|
|
102
|
+
- **`hasTranslation(locale: string, key: string): boolean`**:
|
|
103
|
+
Checks if a translation exists for the given key and locale.
|
|
104
|
+
- **`getTranslation<T = unknown>(locale: string, routeName: string, key: string): T | null`**:
|
|
105
|
+
Retrieves a translation for the given key, route, and locale.
|
|
106
|
+
- **`loadPageTranslations(locale: string, routeName: string, translations: Translations): Promise<void>`**:
|
|
107
|
+
Loads translations for a specific route and locale.
|
|
108
|
+
- **`loadTranslations(locale: string, translations: Translations): Promise<void>`**:
|
|
109
|
+
Loads global translations for the specified locale.
|
|
110
|
+
|
|
111
|
+
### `interpolate`
|
|
112
|
+
|
|
113
|
+
#### Function
|
|
114
|
+
```typescript
|
|
115
|
+
interpolate(template: string, params: Params): string
|
|
116
|
+
```
|
|
117
|
+
- **`template`**: The translation string with placeholders (e.g., `'Hello, {name}!'`).
|
|
118
|
+
- **`params`**: An object containing key-value pairs for interpolation (e.g., `{ name: 'John' }`).
|
|
119
|
+
|
|
120
|
+
#### Example
|
|
121
|
+
```typescript
|
|
122
|
+
const result = interpolate('Hello, {name}!', { name: 'John' })
|
|
123
|
+
console.log(result) // 'Hello, John!'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `FormatService`
|
|
127
|
+
|
|
128
|
+
#### Methods
|
|
129
|
+
- **`formatNumber(value: number, locale: string, options?: Intl.NumberFormatOptions): string`**:
|
|
130
|
+
Formats a number according to the specified locale and options.
|
|
131
|
+
- **`formatDate(value: Date | number | string, locale: string, options?: Intl.DateTimeFormatOptions): string`**:
|
|
132
|
+
Formats a date according to the specified locale and options.
|
|
133
|
+
- **`formatRelativeTime(value: Date | number | string, locale: string, options?: Intl.RelativeTimeFormatOptions): string`**:
|
|
134
|
+
Formats a relative time (e.g., "2 hours ago") according to the specified locale and options.
|
|
135
|
+
|
|
136
|
+
### `RouteService`
|
|
137
|
+
|
|
138
|
+
#### Methods
|
|
139
|
+
- **`getCurrentLocale(route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric): string`**:
|
|
140
|
+
Returns the current locale based on the route or configuration.
|
|
141
|
+
- **`getCurrentName(route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric): string | null`**:
|
|
142
|
+
Returns the display name of the current locale.
|
|
143
|
+
- **`getRouteName(route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, locale: string): string`**:
|
|
144
|
+
Returns the route name without the locale suffix.
|
|
145
|
+
- **`getFullPathWithBaseUrl(currentLocale: Locale, route: RouteLocationRaw): string`**:
|
|
146
|
+
Returns the full path with the base URL for the specified locale.
|
|
147
|
+
- **`switchLocaleRoute(fromLocale: string, toLocale: string, route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, i18nRouteParams: I18nRouteParams): RouteLocationRaw`**:
|
|
148
|
+
Switches the locale for the specified route.
|
|
149
|
+
- **`getLocalizedRoute(to: RouteLocationAsString | RouteLocationAsRelative | RouteLocationAsPath, route: RouteLocationNormalizedLoaded, locale?: string): RouteLocationResolved`**:
|
|
150
|
+
Returns a localized route for the specified locale.
|
|
151
|
+
- **`updateCookies(toLocale: string): void`**:
|
|
152
|
+
Updates cookies with the new locale.
|
|
153
|
+
- **`getCurrentRoute(): RouteLocationNormalizedLoaded`**:
|
|
154
|
+
Returns the current route.
|
|
155
|
+
- **`switchLocaleLogic(toLocale: string, i18nRouteParams: I18nRouteParams, route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric | string)`**:
|
|
156
|
+
Handles the logic for switching locales and navigating to the new route.
|
|
157
|
+
- **`resolveLocalizedRoute(to: RouteLocationAsString | RouteLocationAsRelative | RouteLocationAsPath | string, locale?: string): RouteLocationResolved`**:
|
|
158
|
+
Resolves a localized route for the specified locale.
|
|
159
|
+
|
|
160
|
+
## Contributing
|
|
161
|
+
|
|
162
|
+
If you find any issues or have suggestions for improvements, feel free to open an issue or submit a pull request on the [GitHub repository](https://github.com/s00d/nuxt-i18n-micro).
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
This project is licensed under the MIT License. See the [LICENSE](https://github.com/s00d/nuxt-i18n-micro/blob/main/LICENSE) file for more details.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
For more information, visit the [GitHub repository](https://github.com/s00d/nuxt-i18n-micro).
|
|
171
|
+
|
|
172
|
+
## Author
|
|
173
|
+
|
|
174
|
+
- **Name**: s00d
|
|
175
|
+
- **Email**: Virus191288@gmail.com
|
|
176
|
+
- **Website**: [https://s00d.github.io/](https://s00d.github.io/)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare class FormatService {
|
|
2
|
+
formatNumber(value: number, locale: string, options?: Intl.NumberFormatOptions): string;
|
|
3
|
+
formatDate(value: Date | number | string, locale: string, options?: Intl.DateTimeFormatOptions): string;
|
|
4
|
+
formatRelativeTime(value: Date | number | string, locale: string, options?: Intl.RelativeTimeFormatOptions): string;
|
|
5
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Params, Strategies, PluralFunc } from '@i18n-micro/types';
|
|
2
|
+
export declare function interpolate(template: string, params: Params): string;
|
|
3
|
+
export declare function withPrefixStrategy(strategy: Strategies): strategy is "prefix" | "prefix_and_default";
|
|
4
|
+
export declare function isNoPrefixStrategy(strategy: Strategies): strategy is "no_prefix";
|
|
5
|
+
export declare function isPrefixStrategy(strategy: Strategies): strategy is "prefix";
|
|
6
|
+
export declare function isPrefixExceptDefaultStrategy(strategy: Strategies): strategy is "prefix_except_default";
|
|
7
|
+
export declare function isPrefixAndDefaultStrategy(strategy: Strategies): strategy is "prefix_and_default";
|
|
8
|
+
/**
|
|
9
|
+
* Default pluralization function
|
|
10
|
+
* Splits translation by '|' and selects form based on count
|
|
11
|
+
* @param key - Translation key
|
|
12
|
+
* @param count - Count for pluralization
|
|
13
|
+
* @param params - Parameters for translation
|
|
14
|
+
* @param _locale - Current locale (unused in default implementation)
|
|
15
|
+
* @param getTranslation - Function to get translation value
|
|
16
|
+
* @returns Selected plural form or null if not found
|
|
17
|
+
*/
|
|
18
|
+
export declare const defaultPlural: PluralFunc;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R={},x={},P=[],w={};function b(a){return Array.isArray(a)||typeof a=="object"&&a!==null?JSON.parse(JSON.stringify(a)):a}function $(a,e){let r=a;if(a===null||typeof e!="string")return null;if(a[e])r=a[e];else{const n=e.toString().split(".");for(const i of n)if(r&&typeof r=="object"&&i in r)r=r[i];else return null}return typeof r=="object"&&r!==null?b(r):r??null}function C(a){return typeof a=="object"&&a!==null&&"value"in a?a.value:a}function m(a,e,r){const n=C(a);n[e]=r}function d(a,e){return C(a)[e]}function N(a){const e=(a==null?void 0:a.generalLocaleCache)??R,r=(a==null?void 0:a.routeLocaleCache)??x,n=(a==null?void 0:a.dynamicTranslationsCaches)??P,i=(a==null?void 0:a.serverTranslationCache)??w;return{hasCache(t,s){const o=`${t}:${s}`;return(d(i,o)??new Map).size>0},getCache(t,s){const o=`${t}:${s}`;return d(i,o)},setCache(t,s,o){const l=`${t}:${s}`;m(i,l,o)},mergeTranslation(t,s,o,l=!1){const u=`${t}:${s}`,c=d(r,u);(c||l)&&m(r,u,{...c??{},...o});const f=process.env.NODE_ENV!=="production";!c&&f&&console.warn(`[i18n] mergeTranslation called for '${u}' which was not pre-loaded. Skipping merge. Use force: true if this is intentional.`)},mergeGlobalTranslation(t,s,o=!1){const l=d(e,t);!o&&!l&&console.error(`marge: route ${t} not loaded`),m(e,t,{...l??{},...s})},hasGeneralTranslation(t){return!!d(e,t)},hasPageTranslation(t,s){const o=`${t}:${s}`;return!!d(r,o)},hasTranslation:(t,s)=>{const o=C(n);for(const u of o)if($(u[t]||null,s)!==null)return!0;const l=d(e,t);return $(l||null,s)!==null},getTranslation:(t,s,o)=>{const l=`${t}:${s}`,u=d(i,l),c=u==null?void 0:u.get(o);if(c)return c;let f=null;const v=C(n);for(const g of v)if(f=$(g[t]||null,o),f!==null)break;if(!f){const g=d(r,l),p=d(e,t);f=$(g||null,o)??$(p||null,o)}if(f){const g=u??new Map;g.set(o,f),m(i,l,g)}return f},async loadPageTranslations(t,s,o){const l=`${t}:${s}`;m(r,l,{...o})},async loadTranslations(t,s){m(e,t,{...s})},clearCache(){const t=C(e);Object.keys(t).forEach(u=>{m(e,u,{})});const s=C(r);Object.keys(s).forEach(u=>{m(r,u,{})});const o=C(n);o.length=0;const l=C(i);Object.keys(l).forEach(u=>{const c=d(i,u);c==null||c.clear()})}}}function T(a,e){let r=a;for(const n in e)r=r.split(`{${n}}`).join(String(e[n]));return r}function y(a){return a==="prefix"||a==="prefix_and_default"}function h(a){return a==="no_prefix"}function D(a){return a==="prefix"}function L(a){return a==="prefix_except_default"}function q(a){return a==="prefix_and_default"}const z=(a,e,r,n,i)=>{const t=i(a,r);if(!t)return null;const s=t.toString().split("|");if(s.length===0)return null;const o=e<s.length?s[e]:s[s.length-1];return o?o.trim().replace("{count}",e.toString()):null};class F{constructor(e,r,n,i,t,s,o=null,l=null){this.i18nConfig=e,this.router=r,this.hashLocaleDefault=n,this.noPrefixDefault=i,this.navigateTo=t,this.setCookie=s,this.cookieLocaleDefault=o,this.cookieLocaleName=l}extractLocaleFromPath(e){var o,l;if(!e)return null;const n=(o=e.split("?")[0])==null?void 0:o.split("#")[0];if(!n||n==="/")return null;const i=n.split("/").filter(Boolean);if(i.length===0)return null;const t=i[0];return t&&(((l=this.i18nConfig.locales)==null?void 0:l.map(u=>u.code))||[]).includes(t)?t:null}getCurrentLocale(e){var i;if(e=e??this.router.currentRoute.value,this.i18nConfig.hashMode&&this.hashLocaleDefault)return this.hashLocaleDefault;if(h(this.i18nConfig.strategy)&&this.noPrefixDefault)return this.noPrefixDefault;if((i=e.params)!=null&&i.locale)return e.params.locale.toString();const r=e.path||e.fullPath||"",n=this.extractLocaleFromPath(r);return n||(this.cookieLocaleDefault?this.cookieLocaleDefault:(this.i18nConfig.defaultLocale||"en").toString())}getCurrentName(e){var i;const r=this.getCurrentLocale(e),n=(i=this.i18nConfig.locales)==null?void 0:i.find(t=>t.code===r);return(n==null?void 0:n.displayName)??null}getRouteName(e,r){return(e.name??"").toString().toString().replace("localized-","").replace(new RegExp(`-${r}$`),"")}getPluginRouteName(e,r){return this.i18nConfig.disablePageLocales?"general":this.getRouteName(e,r)}getFullPathWithBaseUrl(e,r){let i=this.router.resolve(r).fullPath;e!=null&&e.baseDefault&&(i=i.replace(new RegExp(`^/${e.code}`),""));let t=e.baseUrl;return t||(t=""),t!=null&&t.endsWith("/")&&(t=t.slice(0,-1)),t+i}switchLocaleRoute(e,r,n,i){var f,v;const t=(f=this.i18nConfig.locales)==null?void 0:f.find(g=>g.code===r),s=this.getRouteName(n,e);if(this.router.hasRoute(`localized-${s}-${r}`)){const p={...i!=null&&i[r]?{...i[r]}:{...n.params??{}}};delete p.locale,h(this.i18nConfig.strategy)||(p.locale=r);const S={name:`localized-${s}-${r}`,params:p,query:n.query,hash:n.hash};return t!=null&&t.baseUrl?this.getFullPathWithBaseUrl(t,S):S}let o=s;const u={...i!=null&&i[r]?{...i[r]}:{...n.params??{}}};delete u.locale,h(this.i18nConfig.strategy)||(s==="custom-fallback-route"?o=s:o=r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?`localized-${s}`:s,h(this.i18nConfig.strategy)||(r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(u.locale=r));const c={name:o,params:u,query:n.query,hash:n.hash};return h(this.i18nConfig.strategy)&&((v=this.i18nConfig.locales)==null||v.forEach((g,p)=>{c.name.endsWith(`-${g.code}`)&&(c.name=c.name.slice(0,-g.code-1))})),t!=null&&t.baseUrl?this.getFullPathWithBaseUrl(t,c):c}resolveParams(e){const r=typeof e=="object"&&"params"in e&&typeof e.params=="object"?{...e.params}:{};if(typeof e=="string"){const n=this.router.resolve(e);n&&n.params&&Object.assign(r,n.params)}return r}handlePrefixStrategy(e){if(!y(this.i18nConfig.strategy))return e;const r=this.i18nConfig.defaultLocale;let n=e;typeof e=="string"&&(n=this.router.resolve("/"+r+e));const i=this.getRouteName(n,r),t=this.resolveParams(n);return h(this.i18nConfig.strategy)||(t.locale=r),this.router.hasRoute(`localized-${i}`)?this.router.resolve({name:`localized-${i}`,query:n.query,hash:n.hash,params:t}):this.router.hasRoute(`localized-${i}-${r}`)?this.router.resolve({name:`localized-${i}-${r}`,query:n.query,hash:n.hash,params:t}):e}createLocalizedRoute(e,r,n){const i=this.router.resolve(e),t=this.getRouteName(i,n).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`),"");if(!h(this.i18nConfig.strategy)&&(!t||t==="")){let u=this.router.resolve(e).path.replace(new RegExp(`^/${n}/`),"/");return(n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(u="/"+n+u),this.router.resolve({path:u,query:i.query,hash:i.hash})}if(this.router.hasRoute(`localized-${t}-${n}`)){const l=this.resolveParams(i);return h(this.i18nConfig.strategy)||(l.locale=n),this.router.resolve({name:`localized-${t}-${n}`,params:l,query:i.query,hash:i.hash})}const s=n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?`localized-${t}`:t;if(!this.router.hasRoute(s)){const l=this.resolveParams(e);return delete l.locale,this.router.hasRoute(t)?this.router.resolve({name:t,params:l,query:i.query,hash:i.hash}):this.router.resolve("/")}const o=this.resolveParams(e);return delete o.locale,h(this.i18nConfig.strategy)||(n!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy))&&(o.locale=n),this.router.resolve({name:s,params:o,query:i.query,hash:i.hash})}getLocalizedRoute(e,r,n){const i=n||this.getCurrentLocale(r),t=this.handlePrefixStrategy(e);return this.createLocalizedRoute(t,r,i)}updateCookies(e){this.i18nConfig.hashMode&&(this.setCookie("hash-locale",e),this.hashLocaleDefault=e),h(this.i18nConfig.strategy)&&(this.setCookie("no-prefix-locale",e),this.noPrefixDefault=e),!this.i18nConfig.hashMode&&!h(this.i18nConfig.strategy)&&this.cookieLocaleName&&(this.setCookie(this.cookieLocaleName,e),this.cookieLocaleDefault=e)}getCurrentRoute(){return this.router.currentRoute.value}resolveRouteWithStrategy(e,r,n){return h(this.i18nConfig.strategy)?this.router.resolve(e):r!==this.i18nConfig.defaultLocale||y(this.i18nConfig.strategy)?this.router.resolve(`/${n}${e}`):this.router.resolve(e)}switchLocaleLogic(e,r,n){const i=this.getCurrentLocale();let t;typeof n=="string"?t=this.resolveRouteWithStrategy(n,e,i):t=n??this.getCurrentRoute(),this.updateCookies(e);const s=this.switchLocaleRoute(i,e,t,r);return typeof s=="string"&&s.startsWith("http")?this.navigateTo(s,{redirectCode:200,external:!0}):(h(this.i18nConfig.strategy)&&(s.force=!0),this.router.push(s))}resolveLocalizedRoute(e,r){const n=this.getCurrentRoute(),i=this.getCurrentLocale(),t=r??i;let s;if(typeof e=="string")if(e.startsWith("/"))s=this.resolveRouteWithStrategy(e,t,i);else{const o=e;this.router.hasRoute(o)?s=this.router.resolve({name:o}):(e=`/${e}`,s=this.resolveRouteWithStrategy(e,t,i))}else s=e;return this.getLocalizedRoute(s,n,t)}}class j{formatNumber(e,r,n){return new Intl.NumberFormat(r,n).format(e)}formatDate(e,r,n){const i=new Date(e);return Number.isNaN(i.getTime())?"Invalid Date":new Intl.DateTimeFormat(r,n).format(i)}formatRelativeTime(e,r,n){const i=new Date(e);if(Number.isNaN(i.getTime()))return new Intl.RelativeTimeFormat(r,n).format(0,"second");const s=Math.floor((new Date().getTime()-i.getTime())/1e3),o=[{unit:"year",seconds:31536e3},{unit:"month",seconds:2592e3},{unit:"day",seconds:86400},{unit:"hour",seconds:3600},{unit:"minute",seconds:60},{unit:"second",seconds:1}];for(const{unit:l,seconds:u}of o){const c=Math.floor(s/u);if(c>=1)return new Intl.RelativeTimeFormat(r,n).format(-c,l)}return new Intl.RelativeTimeFormat(r,n).format(0,"second")}}exports.FormatService=j;exports.RouteService=F;exports.defaultPlural=z;exports.interpolate=T;exports.isNoPrefixStrategy=h;exports.isPrefixAndDefaultStrategy=q;exports.isPrefixExceptDefaultStrategy=L;exports.isPrefixStrategy=D;exports.useTranslationHelper=N;exports.withPrefixStrategy=y;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useTranslationHelper, TranslationCache } from './translation';
|
|
2
|
+
import { RouteService } from './route-service';
|
|
3
|
+
import { FormatService } from './format-service';
|
|
4
|
+
import { interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural } from './helpers';
|
|
5
|
+
export { useTranslationHelper, interpolate, withPrefixStrategy, isNoPrefixStrategy, isPrefixStrategy, isPrefixExceptDefaultStrategy, isPrefixAndDefaultStrategy, defaultPlural, RouteService, FormatService, type TranslationCache, };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
const w = {}, x = {}, S = [], N = {};
|
|
2
|
+
function b(a) {
|
|
3
|
+
return Array.isArray(a) || typeof a == "object" && a !== null ? JSON.parse(JSON.stringify(a)) : a;
|
|
4
|
+
}
|
|
5
|
+
function $(a, e) {
|
|
6
|
+
let r = a;
|
|
7
|
+
if (a === null || typeof e != "string")
|
|
8
|
+
return null;
|
|
9
|
+
if (a[e])
|
|
10
|
+
r = a[e];
|
|
11
|
+
else {
|
|
12
|
+
const n = e.toString().split(".");
|
|
13
|
+
for (const i of n)
|
|
14
|
+
if (r && typeof r == "object" && i in r)
|
|
15
|
+
r = r[i];
|
|
16
|
+
else
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return typeof r == "object" && r !== null ? b(r) : r ?? null;
|
|
20
|
+
}
|
|
21
|
+
function C(a) {
|
|
22
|
+
return typeof a == "object" && a !== null && "value" in a ? a.value : a;
|
|
23
|
+
}
|
|
24
|
+
function m(a, e, r) {
|
|
25
|
+
const n = C(a);
|
|
26
|
+
n[e] = r;
|
|
27
|
+
}
|
|
28
|
+
function d(a, e) {
|
|
29
|
+
return C(a)[e];
|
|
30
|
+
}
|
|
31
|
+
function P(a) {
|
|
32
|
+
const e = (a == null ? void 0 : a.generalLocaleCache) ?? w, r = (a == null ? void 0 : a.routeLocaleCache) ?? x, n = (a == null ? void 0 : a.dynamicTranslationsCaches) ?? S, i = (a == null ? void 0 : a.serverTranslationCache) ?? N;
|
|
33
|
+
return {
|
|
34
|
+
hasCache(t, s) {
|
|
35
|
+
const o = `${t}:${s}`;
|
|
36
|
+
return (d(i, o) ?? /* @__PURE__ */ new Map()).size > 0;
|
|
37
|
+
},
|
|
38
|
+
getCache(t, s) {
|
|
39
|
+
const o = `${t}:${s}`;
|
|
40
|
+
return d(i, o);
|
|
41
|
+
},
|
|
42
|
+
setCache(t, s, o) {
|
|
43
|
+
const l = `${t}:${s}`;
|
|
44
|
+
m(i, l, o);
|
|
45
|
+
},
|
|
46
|
+
mergeTranslation(t, s, o, l = !1) {
|
|
47
|
+
const u = `${t}:${s}`, c = d(r, u);
|
|
48
|
+
(c || l) && m(r, u, {
|
|
49
|
+
...c ?? {},
|
|
50
|
+
...o
|
|
51
|
+
});
|
|
52
|
+
const f = process.env.NODE_ENV !== "production";
|
|
53
|
+
!c && f && console.warn(`[i18n] mergeTranslation called for '${u}' which was not pre-loaded. Skipping merge. Use force: true if this is intentional.`);
|
|
54
|
+
},
|
|
55
|
+
mergeGlobalTranslation(t, s, o = !1) {
|
|
56
|
+
const l = d(e, t);
|
|
57
|
+
!o && !l && console.error(`marge: route ${t} not loaded`), m(e, t, {
|
|
58
|
+
...l ?? {},
|
|
59
|
+
...s
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
hasGeneralTranslation(t) {
|
|
63
|
+
return !!d(e, t);
|
|
64
|
+
},
|
|
65
|
+
hasPageTranslation(t, s) {
|
|
66
|
+
const o = `${t}:${s}`;
|
|
67
|
+
return !!d(r, o);
|
|
68
|
+
},
|
|
69
|
+
hasTranslation: (t, s) => {
|
|
70
|
+
const o = C(n);
|
|
71
|
+
for (const u of o)
|
|
72
|
+
if ($(u[t] || null, s) !== null)
|
|
73
|
+
return !0;
|
|
74
|
+
const l = d(e, t);
|
|
75
|
+
return $(l || null, s) !== null;
|
|
76
|
+
},
|
|
77
|
+
getTranslation: (t, s, o) => {
|
|
78
|
+
const l = `${t}:${s}`, u = d(i, l), c = u == null ? void 0 : u.get(o);
|
|
79
|
+
if (c)
|
|
80
|
+
return c;
|
|
81
|
+
let f = null;
|
|
82
|
+
const v = C(n);
|
|
83
|
+
for (const g of v)
|
|
84
|
+
if (f = $(g[t] || null, o), f !== null) break;
|
|
85
|
+
if (!f) {
|
|
86
|
+
const g = d(r, l), p = d(e, t);
|
|
87
|
+
f = $(g || null, o) ?? $(p || null, o);
|
|
88
|
+
}
|
|
89
|
+
if (f) {
|
|
90
|
+
const g = u ?? /* @__PURE__ */ new Map();
|
|
91
|
+
g.set(o, f), m(i, l, g);
|
|
92
|
+
}
|
|
93
|
+
return f;
|
|
94
|
+
},
|
|
95
|
+
async loadPageTranslations(t, s, o) {
|
|
96
|
+
const l = `${t}:${s}`;
|
|
97
|
+
m(r, l, { ...o });
|
|
98
|
+
},
|
|
99
|
+
async loadTranslations(t, s) {
|
|
100
|
+
m(e, t, { ...s });
|
|
101
|
+
},
|
|
102
|
+
clearCache() {
|
|
103
|
+
const t = C(e);
|
|
104
|
+
Object.keys(t).forEach((u) => {
|
|
105
|
+
m(e, u, {});
|
|
106
|
+
});
|
|
107
|
+
const s = C(r);
|
|
108
|
+
Object.keys(s).forEach((u) => {
|
|
109
|
+
m(r, u, {});
|
|
110
|
+
});
|
|
111
|
+
const o = C(n);
|
|
112
|
+
o.length = 0;
|
|
113
|
+
const l = C(i);
|
|
114
|
+
Object.keys(l).forEach((u) => {
|
|
115
|
+
const c = d(i, u);
|
|
116
|
+
c == null || c.clear();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function T(a, e) {
|
|
122
|
+
let r = a;
|
|
123
|
+
for (const n in e)
|
|
124
|
+
r = r.split(`{${n}}`).join(String(e[n]));
|
|
125
|
+
return r;
|
|
126
|
+
}
|
|
127
|
+
function y(a) {
|
|
128
|
+
return a === "prefix" || a === "prefix_and_default";
|
|
129
|
+
}
|
|
130
|
+
function h(a) {
|
|
131
|
+
return a === "no_prefix";
|
|
132
|
+
}
|
|
133
|
+
function D(a) {
|
|
134
|
+
return a === "prefix";
|
|
135
|
+
}
|
|
136
|
+
function L(a) {
|
|
137
|
+
return a === "prefix_except_default";
|
|
138
|
+
}
|
|
139
|
+
function q(a) {
|
|
140
|
+
return a === "prefix_and_default";
|
|
141
|
+
}
|
|
142
|
+
const z = (a, e, r, n, i) => {
|
|
143
|
+
const t = i(a, r);
|
|
144
|
+
if (!t)
|
|
145
|
+
return null;
|
|
146
|
+
const s = t.toString().split("|");
|
|
147
|
+
if (s.length === 0) return null;
|
|
148
|
+
const o = e < s.length ? s[e] : s[s.length - 1];
|
|
149
|
+
return o ? o.trim().replace("{count}", e.toString()) : null;
|
|
150
|
+
};
|
|
151
|
+
class F {
|
|
152
|
+
constructor(e, r, n, i, t, s, o = null, l = null) {
|
|
153
|
+
this.i18nConfig = e, this.router = r, this.hashLocaleDefault = n, this.noPrefixDefault = i, this.navigateTo = t, this.setCookie = s, this.cookieLocaleDefault = o, this.cookieLocaleName = l;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Extracts locale from URL path by checking the first path segment
|
|
157
|
+
* @param path - URL path (e.g., '/ru/sdfsdf' or '/en/about')
|
|
158
|
+
* @returns Locale code or null if not found
|
|
159
|
+
*/
|
|
160
|
+
extractLocaleFromPath(e) {
|
|
161
|
+
var o, l;
|
|
162
|
+
if (!e)
|
|
163
|
+
return null;
|
|
164
|
+
const n = (o = e.split("?")[0]) == null ? void 0 : o.split("#")[0];
|
|
165
|
+
if (!n || n === "/")
|
|
166
|
+
return null;
|
|
167
|
+
const i = n.split("/").filter(Boolean);
|
|
168
|
+
if (i.length === 0)
|
|
169
|
+
return null;
|
|
170
|
+
const t = i[0];
|
|
171
|
+
return t && (((l = this.i18nConfig.locales) == null ? void 0 : l.map((u) => u.code)) || []).includes(t) ? t : null;
|
|
172
|
+
}
|
|
173
|
+
getCurrentLocale(e) {
|
|
174
|
+
var i;
|
|
175
|
+
if (e = e ?? this.router.currentRoute.value, this.i18nConfig.hashMode && this.hashLocaleDefault)
|
|
176
|
+
return this.hashLocaleDefault;
|
|
177
|
+
if (h(this.i18nConfig.strategy) && this.noPrefixDefault)
|
|
178
|
+
return this.noPrefixDefault;
|
|
179
|
+
if ((i = e.params) != null && i.locale)
|
|
180
|
+
return e.params.locale.toString();
|
|
181
|
+
const r = e.path || e.fullPath || "", n = this.extractLocaleFromPath(r);
|
|
182
|
+
return n || (this.cookieLocaleDefault ? this.cookieLocaleDefault : (this.i18nConfig.defaultLocale || "en").toString());
|
|
183
|
+
}
|
|
184
|
+
getCurrentName(e) {
|
|
185
|
+
var i;
|
|
186
|
+
const r = this.getCurrentLocale(e), n = (i = this.i18nConfig.locales) == null ? void 0 : i.find((t) => t.code === r);
|
|
187
|
+
return (n == null ? void 0 : n.displayName) ?? null;
|
|
188
|
+
}
|
|
189
|
+
getRouteName(e, r) {
|
|
190
|
+
return (e.name ?? "").toString().toString().replace("localized-", "").replace(new RegExp(`-${r}$`), "");
|
|
191
|
+
}
|
|
192
|
+
getPluginRouteName(e, r) {
|
|
193
|
+
return this.i18nConfig.disablePageLocales ? "general" : this.getRouteName(e, r);
|
|
194
|
+
}
|
|
195
|
+
getFullPathWithBaseUrl(e, r) {
|
|
196
|
+
let i = this.router.resolve(r).fullPath;
|
|
197
|
+
e != null && e.baseDefault && (i = i.replace(new RegExp(`^/${e.code}`), ""));
|
|
198
|
+
let t = e.baseUrl;
|
|
199
|
+
return t || (t = ""), t != null && t.endsWith("/") && (t = t.slice(0, -1)), t + i;
|
|
200
|
+
}
|
|
201
|
+
switchLocaleRoute(e, r, n, i) {
|
|
202
|
+
var f, v;
|
|
203
|
+
const t = (f = this.i18nConfig.locales) == null ? void 0 : f.find((g) => g.code === r), s = this.getRouteName(n, e);
|
|
204
|
+
if (this.router.hasRoute(`localized-${s}-${r}`)) {
|
|
205
|
+
const p = { ...i != null && i[r] ? { ...i[r] } : { ...n.params ?? {} } };
|
|
206
|
+
delete p.locale, h(this.i18nConfig.strategy) || (p.locale = r);
|
|
207
|
+
const R = {
|
|
208
|
+
name: `localized-${s}-${r}`,
|
|
209
|
+
params: p,
|
|
210
|
+
query: n.query,
|
|
211
|
+
hash: n.hash
|
|
212
|
+
};
|
|
213
|
+
return t != null && t.baseUrl ? this.getFullPathWithBaseUrl(t, R) : R;
|
|
214
|
+
}
|
|
215
|
+
let o = s;
|
|
216
|
+
const u = { ...i != null && i[r] ? { ...i[r] } : { ...n.params ?? {} } };
|
|
217
|
+
delete u.locale, h(this.i18nConfig.strategy) || (s === "custom-fallback-route" ? o = s : o = r !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy) ? `localized-${s}` : s, h(this.i18nConfig.strategy) || (r !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy)) && (u.locale = r));
|
|
218
|
+
const c = {
|
|
219
|
+
name: o,
|
|
220
|
+
params: u,
|
|
221
|
+
query: n.query,
|
|
222
|
+
hash: n.hash
|
|
223
|
+
};
|
|
224
|
+
return h(this.i18nConfig.strategy) && ((v = this.i18nConfig.locales) == null || v.forEach((g, p) => {
|
|
225
|
+
c.name.endsWith(`-${g.code}`) && (c.name = c.name.slice(0, -g.code - 1));
|
|
226
|
+
})), t != null && t.baseUrl ? this.getFullPathWithBaseUrl(t, c) : c;
|
|
227
|
+
}
|
|
228
|
+
resolveParams(e) {
|
|
229
|
+
const r = typeof e == "object" && "params" in e && typeof e.params == "object" ? { ...e.params } : {};
|
|
230
|
+
if (typeof e == "string") {
|
|
231
|
+
const n = this.router.resolve(e);
|
|
232
|
+
n && n.params && Object.assign(r, n.params);
|
|
233
|
+
}
|
|
234
|
+
return r;
|
|
235
|
+
}
|
|
236
|
+
handlePrefixStrategy(e) {
|
|
237
|
+
if (!y(this.i18nConfig.strategy))
|
|
238
|
+
return e;
|
|
239
|
+
const r = this.i18nConfig.defaultLocale;
|
|
240
|
+
let n = e;
|
|
241
|
+
typeof e == "string" && (n = this.router.resolve("/" + r + e));
|
|
242
|
+
const i = this.getRouteName(n, r), t = this.resolveParams(n);
|
|
243
|
+
return h(this.i18nConfig.strategy) || (t.locale = r), this.router.hasRoute(`localized-${i}`) ? this.router.resolve({
|
|
244
|
+
name: `localized-${i}`,
|
|
245
|
+
query: n.query,
|
|
246
|
+
hash: n.hash,
|
|
247
|
+
params: t
|
|
248
|
+
}) : this.router.hasRoute(`localized-${i}-${r}`) ? this.router.resolve({
|
|
249
|
+
name: `localized-${i}-${r}`,
|
|
250
|
+
query: n.query,
|
|
251
|
+
hash: n.hash,
|
|
252
|
+
params: t
|
|
253
|
+
}) : e;
|
|
254
|
+
}
|
|
255
|
+
createLocalizedRoute(e, r, n) {
|
|
256
|
+
const i = this.router.resolve(e), t = this.getRouteName(i, n).replace(new RegExp(`-${this.i18nConfig.defaultLocale}$`), "");
|
|
257
|
+
if (!h(this.i18nConfig.strategy) && (!t || t === "")) {
|
|
258
|
+
let u = this.router.resolve(e).path.replace(new RegExp(`^/${n}/`), "/");
|
|
259
|
+
return (n !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy)) && (u = "/" + n + u), this.router.resolve({
|
|
260
|
+
path: u,
|
|
261
|
+
query: i.query,
|
|
262
|
+
hash: i.hash
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (this.router.hasRoute(`localized-${t}-${n}`)) {
|
|
266
|
+
const l = this.resolveParams(i);
|
|
267
|
+
return h(this.i18nConfig.strategy) || (l.locale = n), this.router.resolve({
|
|
268
|
+
name: `localized-${t}-${n}`,
|
|
269
|
+
params: l,
|
|
270
|
+
query: i.query,
|
|
271
|
+
hash: i.hash
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
const s = n !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy) ? `localized-${t}` : t;
|
|
275
|
+
if (!this.router.hasRoute(s)) {
|
|
276
|
+
const l = this.resolveParams(e);
|
|
277
|
+
return delete l.locale, this.router.hasRoute(t) ? this.router.resolve({
|
|
278
|
+
name: t,
|
|
279
|
+
params: l,
|
|
280
|
+
query: i.query,
|
|
281
|
+
hash: i.hash
|
|
282
|
+
}) : this.router.resolve("/");
|
|
283
|
+
}
|
|
284
|
+
const o = this.resolveParams(e);
|
|
285
|
+
return delete o.locale, h(this.i18nConfig.strategy) || (n !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy)) && (o.locale = n), this.router.resolve({
|
|
286
|
+
name: s,
|
|
287
|
+
params: o,
|
|
288
|
+
query: i.query,
|
|
289
|
+
hash: i.hash
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
getLocalizedRoute(e, r, n) {
|
|
293
|
+
const i = n || this.getCurrentLocale(r), t = this.handlePrefixStrategy(e);
|
|
294
|
+
return this.createLocalizedRoute(t, r, i);
|
|
295
|
+
}
|
|
296
|
+
updateCookies(e) {
|
|
297
|
+
this.i18nConfig.hashMode && (this.setCookie("hash-locale", e), this.hashLocaleDefault = e), h(this.i18nConfig.strategy) && (this.setCookie("no-prefix-locale", e), this.noPrefixDefault = e), !this.i18nConfig.hashMode && !h(this.i18nConfig.strategy) && this.cookieLocaleName && (this.setCookie(this.cookieLocaleName, e), this.cookieLocaleDefault = e);
|
|
298
|
+
}
|
|
299
|
+
getCurrentRoute() {
|
|
300
|
+
return this.router.currentRoute.value;
|
|
301
|
+
}
|
|
302
|
+
resolveRouteWithStrategy(e, r, n) {
|
|
303
|
+
return h(this.i18nConfig.strategy) ? this.router.resolve(e) : r !== this.i18nConfig.defaultLocale || y(this.i18nConfig.strategy) ? this.router.resolve(`/${n}${e}`) : this.router.resolve(e);
|
|
304
|
+
}
|
|
305
|
+
switchLocaleLogic(e, r, n) {
|
|
306
|
+
const i = this.getCurrentLocale();
|
|
307
|
+
let t;
|
|
308
|
+
typeof n == "string" ? t = this.resolveRouteWithStrategy(n, e, i) : t = n ?? this.getCurrentRoute(), this.updateCookies(e);
|
|
309
|
+
const s = this.switchLocaleRoute(i, e, t, r);
|
|
310
|
+
return typeof s == "string" && s.startsWith("http") ? this.navigateTo(s, { redirectCode: 200, external: !0 }) : (h(this.i18nConfig.strategy) && (s.force = !0), this.router.push(s));
|
|
311
|
+
}
|
|
312
|
+
resolveLocalizedRoute(e, r) {
|
|
313
|
+
const n = this.getCurrentRoute(), i = this.getCurrentLocale(), t = r ?? i;
|
|
314
|
+
let s;
|
|
315
|
+
if (typeof e == "string")
|
|
316
|
+
if (e.startsWith("/"))
|
|
317
|
+
s = this.resolveRouteWithStrategy(e, t, i);
|
|
318
|
+
else {
|
|
319
|
+
const o = e;
|
|
320
|
+
this.router.hasRoute(o) ? s = this.router.resolve({ name: o }) : (e = `/${e}`, s = this.resolveRouteWithStrategy(e, t, i));
|
|
321
|
+
}
|
|
322
|
+
else
|
|
323
|
+
s = e;
|
|
324
|
+
return this.getLocalizedRoute(s, n, t);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
class j {
|
|
328
|
+
formatNumber(e, r, n) {
|
|
329
|
+
return new Intl.NumberFormat(r, n).format(e);
|
|
330
|
+
}
|
|
331
|
+
formatDate(e, r, n) {
|
|
332
|
+
const i = new Date(e);
|
|
333
|
+
return Number.isNaN(i.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(r, n).format(i);
|
|
334
|
+
}
|
|
335
|
+
formatRelativeTime(e, r, n) {
|
|
336
|
+
const i = new Date(e);
|
|
337
|
+
if (Number.isNaN(i.getTime()))
|
|
338
|
+
return new Intl.RelativeTimeFormat(r, n).format(0, "second");
|
|
339
|
+
const s = Math.floor(((/* @__PURE__ */ new Date()).getTime() - i.getTime()) / 1e3), o = [
|
|
340
|
+
{ unit: "year", seconds: 31536e3 },
|
|
341
|
+
{ unit: "month", seconds: 2592e3 },
|
|
342
|
+
{ unit: "day", seconds: 86400 },
|
|
343
|
+
{ unit: "hour", seconds: 3600 },
|
|
344
|
+
{ unit: "minute", seconds: 60 },
|
|
345
|
+
{ unit: "second", seconds: 1 }
|
|
346
|
+
];
|
|
347
|
+
for (const { unit: l, seconds: u } of o) {
|
|
348
|
+
const c = Math.floor(s / u);
|
|
349
|
+
if (c >= 1)
|
|
350
|
+
return new Intl.RelativeTimeFormat(r, n).format(-c, l);
|
|
351
|
+
}
|
|
352
|
+
return new Intl.RelativeTimeFormat(r, n).format(0, "second");
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
export {
|
|
356
|
+
j as FormatService,
|
|
357
|
+
F as RouteService,
|
|
358
|
+
z as defaultPlural,
|
|
359
|
+
T as interpolate,
|
|
360
|
+
h as isNoPrefixStrategy,
|
|
361
|
+
q as isPrefixAndDefaultStrategy,
|
|
362
|
+
L as isPrefixExceptDefaultStrategy,
|
|
363
|
+
D as isPrefixStrategy,
|
|
364
|
+
P as useTranslationHelper,
|
|
365
|
+
y as withPrefixStrategy
|
|
366
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { NavigationFailure, RouteLocationAsPathGeneric, RouteLocationNamedRaw, RouteLocationNormalizedLoaded, RouteLocationRaw, RouteLocationResolved, RouteLocationResolvedGeneric, Router } from 'vue-router';
|
|
2
|
+
import { I18nRouteParams, Locale, ModuleOptionsExtend } from '@i18n-micro/types';
|
|
3
|
+
interface NavigateToInterface {
|
|
4
|
+
replace?: boolean;
|
|
5
|
+
redirectCode?: number;
|
|
6
|
+
external?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class RouteService {
|
|
9
|
+
private i18nConfig;
|
|
10
|
+
private router;
|
|
11
|
+
private hashLocaleDefault;
|
|
12
|
+
private noPrefixDefault;
|
|
13
|
+
private navigateTo;
|
|
14
|
+
private setCookie;
|
|
15
|
+
private cookieLocaleDefault;
|
|
16
|
+
private cookieLocaleName;
|
|
17
|
+
constructor(i18nConfig: ModuleOptionsExtend, router: Router, hashLocaleDefault: string | null | undefined, noPrefixDefault: string | null | undefined, navigateTo: (to: RouteLocationRaw | undefined | null, options?: NavigateToInterface) => Promise<void | NavigationFailure | false> | false | void | RouteLocationRaw, setCookie: (name: string, value: string) => void, cookieLocaleDefault?: string | null | undefined, cookieLocaleName?: string | null | undefined);
|
|
18
|
+
/**
|
|
19
|
+
* Extracts locale from URL path by checking the first path segment
|
|
20
|
+
* @param path - URL path (e.g., '/ru/sdfsdf' or '/en/about')
|
|
21
|
+
* @returns Locale code or null if not found
|
|
22
|
+
*/
|
|
23
|
+
private extractLocaleFromPath;
|
|
24
|
+
getCurrentLocale(route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric): string;
|
|
25
|
+
getCurrentName(route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric): string | null;
|
|
26
|
+
getRouteName(route: RouteLocationResolvedGeneric | RouteLocationNamedRaw, locale: string): string;
|
|
27
|
+
getPluginRouteName(route: RouteLocationResolvedGeneric | RouteLocationNamedRaw, locale: string): string;
|
|
28
|
+
getFullPathWithBaseUrl(currentLocale: Locale, route: RouteLocationRaw): string;
|
|
29
|
+
switchLocaleRoute(fromLocale: string, toLocale: string, route: RouteLocationResolvedGeneric | RouteLocationNamedRaw, i18nRouteParams: I18nRouteParams): RouteLocationRaw;
|
|
30
|
+
private resolveParams;
|
|
31
|
+
private handlePrefixStrategy;
|
|
32
|
+
private createLocalizedRoute;
|
|
33
|
+
getLocalizedRoute(to: RouteLocationResolvedGeneric | RouteLocationAsPathGeneric | RouteLocationNamedRaw | string, route: RouteLocationNormalizedLoaded, locale?: string): RouteLocationResolved;
|
|
34
|
+
updateCookies(toLocale: string): void;
|
|
35
|
+
getCurrentRoute(): RouteLocationNormalizedLoaded;
|
|
36
|
+
private resolveRouteWithStrategy;
|
|
37
|
+
switchLocaleLogic(toLocale: string, i18nRouteParams: I18nRouteParams, to?: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string): string | false | void | import('vue-router').RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric | Promise<false | void | NavigationFailure>;
|
|
38
|
+
resolveLocalizedRoute(to: RouteLocationNamedRaw | RouteLocationAsPathGeneric | string, locale?: string): RouteLocationResolved;
|
|
39
|
+
}
|
|
40
|
+
export {};
|