@tramvai/module-i18n 6.79.10
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/README.md +3 -0
- package/lib/browser.d.ts +10 -0
- package/lib/browser.js +28 -0
- package/lib/server.d.ts +10 -0
- package/lib/server.es.js +28 -0
- package/lib/server.js +41 -0
- package/lib/shared/config.browser.js +10 -0
- package/lib/shared/config.d.ts +3 -0
- package/lib/shared/config.es.js +10 -0
- package/lib/shared/config.js +14 -0
- package/lib/shared/constants.browser.js +9 -0
- package/lib/shared/constants.d.ts +8 -0
- package/lib/shared/constants.es.js +9 -0
- package/lib/shared/constants.js +13 -0
- package/lib/shared/hooks.browser.js +13 -0
- package/lib/shared/hooks.d.ts +3 -0
- package/lib/shared/hooks.es.js +13 -0
- package/lib/shared/hooks.js +17 -0
- package/lib/shared/providers.browser.js +335 -0
- package/lib/shared/providers.d.ts +328 -0
- package/lib/shared/providers.es.js +335 -0
- package/lib/shared/providers.js +339 -0
- package/lib/shared/service.browser.js +164 -0
- package/lib/shared/service.d.ts +32 -0
- package/lib/shared/service.es.js +164 -0
- package/lib/shared/service.js +168 -0
- package/lib/shared/store.browser.js +20 -0
- package/lib/shared/store.d.ts +22 -0
- package/lib/shared/store.es.js +20 -0
- package/lib/shared/store.js +26 -0
- package/lib/tokens.browser.js +9 -0
- package/lib/tokens.d.ts +24 -0
- package/lib/tokens.es.js +9 -0
- package/lib/tokens.js +17 -0
- package/lib/types.d.ts +72 -0
- package/package.json +39 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
export declare const sharedProviders: (import("@tinkoff/dippy/lib/Provider").ValueProvider<any> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<unknown, any> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithoutDeps<any> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<unknown, any> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithoutDeps<any> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
2
|
+
config: import("../types").I18nConfiguration & {
|
|
3
|
+
__type?: "base token" | undefined;
|
|
4
|
+
};
|
|
5
|
+
}, (() => Promise<string[]>) & {
|
|
6
|
+
__type?: "base token" | undefined;
|
|
7
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
8
|
+
config: import("../types").I18nConfiguration & {
|
|
9
|
+
__type?: "base token" | undefined;
|
|
10
|
+
};
|
|
11
|
+
}, (() => Promise<string[]>) & {
|
|
12
|
+
__type?: "base token" | undefined;
|
|
13
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
14
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
15
|
+
__type?: "base token" | undefined;
|
|
16
|
+
};
|
|
17
|
+
config: import("../types").I18nConfiguration & {
|
|
18
|
+
__type?: "base token" | undefined;
|
|
19
|
+
};
|
|
20
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
21
|
+
__type?: "base token" | undefined;
|
|
22
|
+
};
|
|
23
|
+
router: import("@tinkoff/router").AbstractRouter & {
|
|
24
|
+
__type?: "base token" | undefined;
|
|
25
|
+
};
|
|
26
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
27
|
+
__type?: "base token" | undefined;
|
|
28
|
+
};
|
|
29
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
30
|
+
[key: string]: any;
|
|
31
|
+
name: string;
|
|
32
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
33
|
+
__type?: "base token" | undefined;
|
|
34
|
+
};
|
|
35
|
+
}, import("../types").I18nService & {
|
|
36
|
+
__type?: "base token" | undefined;
|
|
37
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
38
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
39
|
+
__type?: "base token" | undefined;
|
|
40
|
+
};
|
|
41
|
+
config: import("../types").I18nConfiguration & {
|
|
42
|
+
__type?: "base token" | undefined;
|
|
43
|
+
};
|
|
44
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
45
|
+
__type?: "base token" | undefined;
|
|
46
|
+
};
|
|
47
|
+
router: import("@tinkoff/router").AbstractRouter & {
|
|
48
|
+
__type?: "base token" | undefined;
|
|
49
|
+
};
|
|
50
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
51
|
+
__type?: "base token" | undefined;
|
|
52
|
+
};
|
|
53
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
54
|
+
[key: string]: any;
|
|
55
|
+
name: string;
|
|
56
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
57
|
+
__type?: "base token" | undefined;
|
|
58
|
+
};
|
|
59
|
+
}, import("../types").I18nService & {
|
|
60
|
+
__type?: "base token" | undefined;
|
|
61
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
62
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
63
|
+
__type?: "base token" | undefined;
|
|
64
|
+
};
|
|
65
|
+
config: import("../types").I18nConfiguration & {
|
|
66
|
+
__type?: "base token" | undefined;
|
|
67
|
+
};
|
|
68
|
+
}, {
|
|
69
|
+
name: string;
|
|
70
|
+
priority: number;
|
|
71
|
+
resolve: () => Promise<string | undefined>;
|
|
72
|
+
} & {
|
|
73
|
+
__type?: "multi token" | undefined;
|
|
74
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
75
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
76
|
+
__type?: "base token" | undefined;
|
|
77
|
+
};
|
|
78
|
+
config: import("../types").I18nConfiguration & {
|
|
79
|
+
__type?: "base token" | undefined;
|
|
80
|
+
};
|
|
81
|
+
}, {
|
|
82
|
+
name: string;
|
|
83
|
+
priority: number;
|
|
84
|
+
resolve: () => Promise<string | undefined>;
|
|
85
|
+
} & {
|
|
86
|
+
__type?: "multi token" | undefined;
|
|
87
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
88
|
+
i18n: import("../types").I18nService & {
|
|
89
|
+
__type?: "base token" | undefined;
|
|
90
|
+
};
|
|
91
|
+
userLanguage: string[] & {
|
|
92
|
+
__type?: "base token" | undefined;
|
|
93
|
+
};
|
|
94
|
+
}, {
|
|
95
|
+
name: string;
|
|
96
|
+
priority: number;
|
|
97
|
+
resolve: () => Promise<string | undefined>;
|
|
98
|
+
} & {
|
|
99
|
+
__type?: "multi token" | undefined;
|
|
100
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
101
|
+
i18n: import("../types").I18nService & {
|
|
102
|
+
__type?: "base token" | undefined;
|
|
103
|
+
};
|
|
104
|
+
userLanguage: string[] & {
|
|
105
|
+
__type?: "base token" | undefined;
|
|
106
|
+
};
|
|
107
|
+
}, {
|
|
108
|
+
name: string;
|
|
109
|
+
priority: number;
|
|
110
|
+
resolve: () => Promise<string | undefined>;
|
|
111
|
+
} & {
|
|
112
|
+
__type?: "multi token" | undefined;
|
|
113
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
114
|
+
router: import("@tinkoff/router").AbstractRouter & {
|
|
115
|
+
__type?: "base token" | undefined;
|
|
116
|
+
};
|
|
117
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
118
|
+
__type?: "base token" | undefined;
|
|
119
|
+
};
|
|
120
|
+
i18n: import("../types").I18nService & {
|
|
121
|
+
__type?: "base token" | undefined;
|
|
122
|
+
};
|
|
123
|
+
}, {
|
|
124
|
+
name: string;
|
|
125
|
+
priority: number;
|
|
126
|
+
resolve: () => Promise<string | undefined>;
|
|
127
|
+
} & {
|
|
128
|
+
__type?: "multi token" | undefined;
|
|
129
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
130
|
+
router: import("@tinkoff/router").AbstractRouter & {
|
|
131
|
+
__type?: "base token" | undefined;
|
|
132
|
+
};
|
|
133
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
134
|
+
__type?: "base token" | undefined;
|
|
135
|
+
};
|
|
136
|
+
i18n: import("../types").I18nService & {
|
|
137
|
+
__type?: "base token" | undefined;
|
|
138
|
+
};
|
|
139
|
+
}, {
|
|
140
|
+
name: string;
|
|
141
|
+
priority: number;
|
|
142
|
+
resolve: () => Promise<string | undefined>;
|
|
143
|
+
} & {
|
|
144
|
+
__type?: "multi token" | undefined;
|
|
145
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
146
|
+
config: import("../types").I18nConfiguration & {
|
|
147
|
+
__type?: "base token" | undefined;
|
|
148
|
+
};
|
|
149
|
+
}, {
|
|
150
|
+
name: string;
|
|
151
|
+
priority: number;
|
|
152
|
+
resolve: () => Promise<string | undefined>;
|
|
153
|
+
} & {
|
|
154
|
+
__type?: "multi token" | undefined;
|
|
155
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
156
|
+
config: import("../types").I18nConfiguration & {
|
|
157
|
+
__type?: "base token" | undefined;
|
|
158
|
+
};
|
|
159
|
+
}, {
|
|
160
|
+
name: string;
|
|
161
|
+
priority: number;
|
|
162
|
+
resolve: () => Promise<string | undefined>;
|
|
163
|
+
} & {
|
|
164
|
+
__type?: "multi token" | undefined;
|
|
165
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
166
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
167
|
+
__type?: "base token" | undefined;
|
|
168
|
+
};
|
|
169
|
+
envManager: import("@tramvai/tokens-common").EnvironmentManager & {
|
|
170
|
+
__type?: "base token" | undefined;
|
|
171
|
+
};
|
|
172
|
+
resolveSources: {
|
|
173
|
+
name: string;
|
|
174
|
+
priority: number;
|
|
175
|
+
resolve: () => Promise<string | undefined>;
|
|
176
|
+
} & {
|
|
177
|
+
__type?: "multi token" | undefined;
|
|
178
|
+
};
|
|
179
|
+
}, (() => Promise<{
|
|
180
|
+
language: string;
|
|
181
|
+
source: string;
|
|
182
|
+
}>) & {
|
|
183
|
+
__type?: "base token" | undefined;
|
|
184
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
185
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
186
|
+
__type?: "base token" | undefined;
|
|
187
|
+
};
|
|
188
|
+
envManager: import("@tramvai/tokens-common").EnvironmentManager & {
|
|
189
|
+
__type?: "base token" | undefined;
|
|
190
|
+
};
|
|
191
|
+
resolveSources: {
|
|
192
|
+
name: string;
|
|
193
|
+
priority: number;
|
|
194
|
+
resolve: () => Promise<string | undefined>;
|
|
195
|
+
} & {
|
|
196
|
+
__type?: "multi token" | undefined;
|
|
197
|
+
};
|
|
198
|
+
}, (() => Promise<{
|
|
199
|
+
language: string;
|
|
200
|
+
source: string;
|
|
201
|
+
}>) & {
|
|
202
|
+
__type?: "base token" | undefined;
|
|
203
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
204
|
+
di: import("@tinkoff/dippy").Container & {
|
|
205
|
+
__type?: "base token" | undefined;
|
|
206
|
+
};
|
|
207
|
+
config: import("../types").I18nConfiguration & {
|
|
208
|
+
__type?: "base token" | undefined;
|
|
209
|
+
};
|
|
210
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
211
|
+
[key: string]: any;
|
|
212
|
+
name: string;
|
|
213
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
214
|
+
__type?: "base token" | undefined;
|
|
215
|
+
};
|
|
216
|
+
}, import("@tramvai/core").Command & {
|
|
217
|
+
__type?: "multi token" | undefined;
|
|
218
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
219
|
+
di: import("@tinkoff/dippy").Container & {
|
|
220
|
+
__type?: "base token" | undefined;
|
|
221
|
+
};
|
|
222
|
+
config: import("../types").I18nConfiguration & {
|
|
223
|
+
__type?: "base token" | undefined;
|
|
224
|
+
};
|
|
225
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
226
|
+
[key: string]: any;
|
|
227
|
+
name: string;
|
|
228
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
229
|
+
__type?: "base token" | undefined;
|
|
230
|
+
};
|
|
231
|
+
}, import("@tramvai/core").Command & {
|
|
232
|
+
__type?: "multi token" | undefined;
|
|
233
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
234
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
235
|
+
[key: string]: any;
|
|
236
|
+
name: string;
|
|
237
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
238
|
+
__type?: "base token" | undefined;
|
|
239
|
+
};
|
|
240
|
+
i18n: import("../types").I18nService & {
|
|
241
|
+
__type?: "base token" | undefined;
|
|
242
|
+
};
|
|
243
|
+
config: import("../types").I18nConfiguration & {
|
|
244
|
+
__type?: "base token" | undefined;
|
|
245
|
+
};
|
|
246
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
247
|
+
__type?: "base token" | undefined;
|
|
248
|
+
};
|
|
249
|
+
}, import("@tinkoff/router").NavigationGuard & {
|
|
250
|
+
__type?: "multi token" | undefined;
|
|
251
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
252
|
+
logger: import("@tramvai/tokens-common").Logger & ((configOrName: string | {
|
|
253
|
+
[key: string]: any;
|
|
254
|
+
name: string;
|
|
255
|
+
}) => import("@tramvai/tokens-common").Logger) & {
|
|
256
|
+
__type?: "base token" | undefined;
|
|
257
|
+
};
|
|
258
|
+
i18n: import("../types").I18nService & {
|
|
259
|
+
__type?: "base token" | undefined;
|
|
260
|
+
};
|
|
261
|
+
config: import("../types").I18nConfiguration & {
|
|
262
|
+
__type?: "base token" | undefined;
|
|
263
|
+
};
|
|
264
|
+
cookieManager: import("@tramvai/tokens-cookie").CookieManager & {
|
|
265
|
+
__type?: "base token" | undefined;
|
|
266
|
+
};
|
|
267
|
+
}, import("@tinkoff/router").NavigationGuard & {
|
|
268
|
+
__type?: "multi token" | undefined;
|
|
269
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
270
|
+
config: import("../types").I18nConfiguration & {
|
|
271
|
+
__type?: "base token" | undefined;
|
|
272
|
+
};
|
|
273
|
+
di: import("@tinkoff/dippy").Container & {
|
|
274
|
+
__type?: "base token" | undefined;
|
|
275
|
+
};
|
|
276
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
277
|
+
__type?: "base token" | undefined;
|
|
278
|
+
};
|
|
279
|
+
}, import("@tinkoff/router").RouterPlugin & {
|
|
280
|
+
__type?: "multi token" | undefined;
|
|
281
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
282
|
+
config: import("../types").I18nConfiguration & {
|
|
283
|
+
__type?: "base token" | undefined;
|
|
284
|
+
};
|
|
285
|
+
di: import("@tinkoff/dippy").Container & {
|
|
286
|
+
__type?: "base token" | undefined;
|
|
287
|
+
};
|
|
288
|
+
store: import("@tramvai/tokens-common").Store<Record<string, any>> & {
|
|
289
|
+
__type?: "base token" | undefined;
|
|
290
|
+
};
|
|
291
|
+
}, import("@tinkoff/router").RouterPlugin & {
|
|
292
|
+
__type?: "multi token" | undefined;
|
|
293
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
294
|
+
i18n: import("../types").I18nService & {
|
|
295
|
+
__type?: "base token" | undefined;
|
|
296
|
+
};
|
|
297
|
+
}, import("@tramvai/tokens-render").HtmlAttrs & {
|
|
298
|
+
__type?: "multi token" | undefined;
|
|
299
|
+
}> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
300
|
+
i18n: import("../types").I18nService & {
|
|
301
|
+
__type?: "base token" | undefined;
|
|
302
|
+
};
|
|
303
|
+
}, import("@tramvai/tokens-render").HtmlAttrs & {
|
|
304
|
+
__type?: "multi token" | undefined;
|
|
305
|
+
}> | import("@tinkoff/dippy/lib/Provider").ClassProviderWithDeps<{
|
|
306
|
+
i18n: import("../types").I18nService & {
|
|
307
|
+
__type?: "base token" | undefined;
|
|
308
|
+
};
|
|
309
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
310
|
+
__type?: "base token" | undefined;
|
|
311
|
+
};
|
|
312
|
+
}, (import("@tramvai/tokens-render").PageResource & {
|
|
313
|
+
__type?: "multi token" | undefined;
|
|
314
|
+
}) | (import("@tramvai/tokens-render").PageResource[] & {
|
|
315
|
+
__type?: "multi token" | undefined;
|
|
316
|
+
})> | import("@tinkoff/dippy/lib/Provider").FactoryProviderWithDeps<{
|
|
317
|
+
i18n: import("../types").I18nService & {
|
|
318
|
+
__type?: "base token" | undefined;
|
|
319
|
+
};
|
|
320
|
+
requestManager: import("@tramvai/tokens-common").RequestManager & {
|
|
321
|
+
__type?: "base token" | undefined;
|
|
322
|
+
};
|
|
323
|
+
}, (import("@tramvai/tokens-render").PageResource & {
|
|
324
|
+
__type?: "multi token" | undefined;
|
|
325
|
+
}) | (import("@tramvai/tokens-render").PageResource[] & {
|
|
326
|
+
__type?: "multi token" | undefined;
|
|
327
|
+
})>)[];
|
|
328
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { provide, commandLineListTokens, DI_TOKEN } from '@tramvai/core';
|
|
2
|
+
import { COMBINE_REDUCERS, STORE_TOKEN, REQUEST_MANAGER_TOKEN, LOGGER_TOKEN, ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
|
|
3
|
+
import { COOKIE_MANAGER_TOKEN } from '@tramvai/tokens-cookie';
|
|
4
|
+
import { ROUTER_TOKEN, ROUTER_GUARD_TOKEN, ROUTER_PLUGIN } from '@tramvai/tokens-router';
|
|
5
|
+
import { USER_LANGUAGE_TOKEN } from '@tramvai/module-client-hints';
|
|
6
|
+
import { HTML_ATTRS, RENDER_SLOTS, ResourceType, ResourceSlot } from '@tramvai/tokens-render';
|
|
7
|
+
import { I18N_CONFIGURATION_TOKEN, I18N_RESOLVE_AVAILABLE_LANGUAGES_TOKEN, I18N_TOKEN, I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN, I18N_RESOLVE_LANGUAGE_TOKEN } from '../tokens.es.js';
|
|
8
|
+
import { I18nStore, setAvailableLanguages, setLanguage } from './store.es.js';
|
|
9
|
+
import { I18nServiceImpl } from './service.es.js';
|
|
10
|
+
import { defaultConfiguration } from './config.es.js';
|
|
11
|
+
import { LanguageSourcePriority } from './constants.es.js';
|
|
12
|
+
|
|
13
|
+
const sharedProviders = [
|
|
14
|
+
provide({
|
|
15
|
+
provide: I18N_CONFIGURATION_TOKEN,
|
|
16
|
+
useValue: defaultConfiguration,
|
|
17
|
+
}),
|
|
18
|
+
provide({
|
|
19
|
+
provide: COMBINE_REDUCERS,
|
|
20
|
+
useValue: [I18nStore],
|
|
21
|
+
}),
|
|
22
|
+
provide({
|
|
23
|
+
provide: I18N_RESOLVE_AVAILABLE_LANGUAGES_TOKEN,
|
|
24
|
+
useFactory: ({ config }) => {
|
|
25
|
+
// TODO: sync with state from server if SSR?
|
|
26
|
+
return async () => config.availableLanguages ?? [config.defaultLanguage];
|
|
27
|
+
},
|
|
28
|
+
deps: {
|
|
29
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
30
|
+
},
|
|
31
|
+
}),
|
|
32
|
+
provide({
|
|
33
|
+
provide: I18N_TOKEN,
|
|
34
|
+
useClass: I18nServiceImpl,
|
|
35
|
+
deps: {
|
|
36
|
+
store: STORE_TOKEN,
|
|
37
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
38
|
+
cookieManager: COOKIE_MANAGER_TOKEN,
|
|
39
|
+
router: ROUTER_TOKEN,
|
|
40
|
+
requestManager: REQUEST_MANAGER_TOKEN,
|
|
41
|
+
logger: LOGGER_TOKEN,
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
// Language from cookie has higher priority
|
|
45
|
+
provide({
|
|
46
|
+
provide: I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN,
|
|
47
|
+
useFactory: ({ cookieManager, config }) => {
|
|
48
|
+
return {
|
|
49
|
+
name: 'cookie',
|
|
50
|
+
priority: LanguageSourcePriority.Cookie,
|
|
51
|
+
resolve: async () => {
|
|
52
|
+
const valueFromCookie = cookieManager.get(config.cookieName);
|
|
53
|
+
if (typeof valueFromCookie === 'string') {
|
|
54
|
+
return valueFromCookie;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
deps: {
|
|
60
|
+
cookieManager: COOKIE_MANAGER_TOKEN,
|
|
61
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
// Then, check user preferences (Accept-Language or navigator.languages)
|
|
65
|
+
provide({
|
|
66
|
+
provide: I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN,
|
|
67
|
+
useFactory: ({ i18n, userLanguage }) => {
|
|
68
|
+
return {
|
|
69
|
+
name: 'accept-language',
|
|
70
|
+
priority: LanguageSourcePriority.AcceptLanguage,
|
|
71
|
+
resolve: async () => {
|
|
72
|
+
const availableLanguages = i18n.getAvailableLanguages();
|
|
73
|
+
for (let i = 0; i < userLanguage.length; i++) {
|
|
74
|
+
const lang = userLanguage[i];
|
|
75
|
+
// Try exact match first, because userLanguage already sorted by priority
|
|
76
|
+
if (availableLanguages.includes(lang)) {
|
|
77
|
+
return lang;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
deps: {
|
|
84
|
+
i18n: I18N_TOKEN,
|
|
85
|
+
userLanguage: USER_LANGUAGE_TOKEN,
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
// Then, check language from URL (if prefix strategy is used, defined under the hood)
|
|
89
|
+
provide({
|
|
90
|
+
provide: I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN,
|
|
91
|
+
useFactory: ({ router, requestManager, i18n }) => {
|
|
92
|
+
return {
|
|
93
|
+
name: 'url',
|
|
94
|
+
priority: LanguageSourcePriority.Url,
|
|
95
|
+
resolve: async () => {
|
|
96
|
+
const currentUrl = router.getCurrentUrl() ?? requestManager.getParsedUrl();
|
|
97
|
+
const valueFromUrl = i18n.getLanguageFromUrl(currentUrl);
|
|
98
|
+
const availableLanguages = i18n.getAvailableLanguages();
|
|
99
|
+
if (typeof valueFromUrl === 'string' && availableLanguages.includes(valueFromUrl)) {
|
|
100
|
+
return valueFromUrl;
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
deps: {
|
|
106
|
+
router: ROUTER_TOKEN,
|
|
107
|
+
requestManager: REQUEST_MANAGER_TOKEN,
|
|
108
|
+
i18n: I18N_TOKEN,
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
// As a last resort, return default language
|
|
112
|
+
provide({
|
|
113
|
+
provide: I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN,
|
|
114
|
+
useFactory: ({ config }) => {
|
|
115
|
+
return {
|
|
116
|
+
name: 'default',
|
|
117
|
+
priority: LanguageSourcePriority.Default,
|
|
118
|
+
resolve: async () => {
|
|
119
|
+
return config.defaultLanguage;
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
deps: {
|
|
124
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
127
|
+
provide({
|
|
128
|
+
provide: I18N_RESOLVE_LANGUAGE_TOKEN,
|
|
129
|
+
useFactory: ({ store, envManager, resolveSources }) => {
|
|
130
|
+
return async () => {
|
|
131
|
+
// At client-side, for SSR mode, we can resolve language from server state
|
|
132
|
+
if (typeof window !== 'undefined' &&
|
|
133
|
+
envManager.get('TRAMVAI_FORCE_CLIENT_SIDE_RENDERING') !== 'true') {
|
|
134
|
+
const { language, source } = store.getState(I18nStore);
|
|
135
|
+
return { language, source };
|
|
136
|
+
}
|
|
137
|
+
const sources = [...resolveSources].sort(({ priority: a }, { priority: b }) => b - a);
|
|
138
|
+
for (const source of sources) {
|
|
139
|
+
const language = await source.resolve();
|
|
140
|
+
if (typeof language === 'string') {
|
|
141
|
+
return {
|
|
142
|
+
language: language,
|
|
143
|
+
source: source.name,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Impossible case, because we always have default source
|
|
148
|
+
throw Error('No language could be resolved from any sources');
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
deps: {
|
|
152
|
+
store: STORE_TOKEN,
|
|
153
|
+
envManager: ENV_MANAGER_TOKEN,
|
|
154
|
+
resolveSources: I18N_RESOLVE_LANGUAGE_SOURCE_TOKEN,
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
provide({
|
|
158
|
+
provide: commandLineListTokens.init,
|
|
159
|
+
useFactory: ({ di, config, logger }) => {
|
|
160
|
+
const log = logger('i18n');
|
|
161
|
+
return function registerI18nResolveLanguagesCommands() {
|
|
162
|
+
di.register({
|
|
163
|
+
provide: config.resolveLanguagesCommandLineStage
|
|
164
|
+
? commandLineListTokens[config.resolveLanguagesCommandLineStage]
|
|
165
|
+
: commandLineListTokens.customerStart,
|
|
166
|
+
useFactory: ({ store, resolveAvailableLanguages, resolveLanguage, cookieManager, router, requestManager, i18n, }) => {
|
|
167
|
+
return async function resolveLanguagesFn() {
|
|
168
|
+
// Resolve available languages first, so we can use them to validate current language
|
|
169
|
+
const availableLanguages = await resolveAvailableLanguages();
|
|
170
|
+
log.info(`Resolved available languages: ${availableLanguages}`);
|
|
171
|
+
store.dispatch(setAvailableLanguages(availableLanguages));
|
|
172
|
+
const language = await resolveLanguage();
|
|
173
|
+
log.info(`Resolved language: "${language.language}" from "${language.source}" source`);
|
|
174
|
+
store.dispatch(setLanguage(language));
|
|
175
|
+
if (!cookieManager.get(config.cookieName)) {
|
|
176
|
+
log.info(`${config.cookieName} cookie is not found, save resolved "${language.language}" language to cookie`);
|
|
177
|
+
cookieManager.set({
|
|
178
|
+
name: config.cookieName,
|
|
179
|
+
value: language.language,
|
|
180
|
+
// TODO valid params!
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
const currentUrl = router.getCurrentUrl() ?? requestManager.getParsedUrl();
|
|
184
|
+
const languageFromUrl = i18n.getLanguageFromUrl(currentUrl);
|
|
185
|
+
if (typeof languageFromUrl === 'string' && languageFromUrl !== language.language) {
|
|
186
|
+
log.info(`Language "${languageFromUrl}" from current url "${currentUrl}" is not matched to resolved language "${language.language}"`);
|
|
187
|
+
if (config.enableAutoRedirect) {
|
|
188
|
+
log.info(`Sync resolved language with url because 'config.enableAutoRedirect' is enabled`);
|
|
189
|
+
await i18n.switchLanguage(language.language);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
deps: {
|
|
195
|
+
store: STORE_TOKEN,
|
|
196
|
+
resolveAvailableLanguages: I18N_RESOLVE_AVAILABLE_LANGUAGES_TOKEN,
|
|
197
|
+
resolveLanguage: I18N_RESOLVE_LANGUAGE_TOKEN,
|
|
198
|
+
cookieManager: COOKIE_MANAGER_TOKEN,
|
|
199
|
+
i18n: I18N_TOKEN,
|
|
200
|
+
router: ROUTER_TOKEN,
|
|
201
|
+
requestManager: REQUEST_MANAGER_TOKEN,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
deps: {
|
|
207
|
+
di: DI_TOKEN,
|
|
208
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
209
|
+
logger: LOGGER_TOKEN,
|
|
210
|
+
},
|
|
211
|
+
}),
|
|
212
|
+
// Router guard to sync language prefix in URL with current language
|
|
213
|
+
provide({
|
|
214
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
215
|
+
useFactory: ({ logger, i18n, config, cookieManager }) => {
|
|
216
|
+
const log = logger('i18n');
|
|
217
|
+
return async ({ url, to }) => {
|
|
218
|
+
if (typeof window !== 'undefined' && url && to) {
|
|
219
|
+
// i18n store will be updated after navigation, so we need to use cookie to get current language
|
|
220
|
+
const language = cookieManager.get(config.cookieName);
|
|
221
|
+
const languageFromUrl = i18n.getLanguageFromUrl(url.href);
|
|
222
|
+
if (typeof languageFromUrl === 'string' && languageFromUrl !== language) {
|
|
223
|
+
log.info(`Language "${languageFromUrl}" from target url "${url.pathname}" is not matched to current language "${language}"`);
|
|
224
|
+
if (config.enableAutoRedirect) {
|
|
225
|
+
log.info(`Force navigate to url with correct language prefix because 'config.enableAutoRedirect' is enabled`);
|
|
226
|
+
const hasLanguagePrefix = typeof languageFromUrl === 'string';
|
|
227
|
+
const targetUrl = hasLanguagePrefix
|
|
228
|
+
? i18n.addLanguageToUrl(i18n.removeLanguageFromUrl(url), language)
|
|
229
|
+
: i18n.addLanguageToUrl(url, language);
|
|
230
|
+
return `${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
},
|
|
236
|
+
deps: {
|
|
237
|
+
logger: LOGGER_TOKEN,
|
|
238
|
+
i18n: I18N_TOKEN,
|
|
239
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
240
|
+
cookieManager: COOKIE_MANAGER_TOKEN,
|
|
241
|
+
},
|
|
242
|
+
}),
|
|
243
|
+
provide({
|
|
244
|
+
provide: ROUTER_PLUGIN,
|
|
245
|
+
useFactory: ({ config, di, store }) => {
|
|
246
|
+
return {
|
|
247
|
+
apply(router) {
|
|
248
|
+
if (config.updateStrategy === 'update') {
|
|
249
|
+
router.syncHooks.get('change').tap('i18n', (_, { navigation }) => {
|
|
250
|
+
// Resolve from DI to avoid circular dependency
|
|
251
|
+
const i18n = di.get(I18N_TOKEN);
|
|
252
|
+
if (navigation.to?.params?.__lang) {
|
|
253
|
+
const currentLang = i18n.getLanguage();
|
|
254
|
+
const nextLang = navigation.to.params.__lang;
|
|
255
|
+
if (currentLang !== nextLang) {
|
|
256
|
+
store.dispatch(setLanguage({
|
|
257
|
+
language: navigation.to.params.__lang,
|
|
258
|
+
source: 'user-interaction',
|
|
259
|
+
}));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
router.internalHooks['router:resolve-route'].wrap((_, args, next) => {
|
|
265
|
+
// Resolve from DI to avoid circular dependency
|
|
266
|
+
const i18n = di.get(I18N_TOKEN);
|
|
267
|
+
const [navigation, options] = args;
|
|
268
|
+
if (navigation.url) {
|
|
269
|
+
const languageFromUrl = i18n.getLanguageFromUrl(navigation.url);
|
|
270
|
+
const hasLanguagePrefix = typeof languageFromUrl === 'string';
|
|
271
|
+
if (hasLanguagePrefix) {
|
|
272
|
+
// If language is in URL, we need to remove it to resolve the same route for all languages
|
|
273
|
+
const urlWithoutPrefix = i18n.removeLanguageFromUrl(navigation.url);
|
|
274
|
+
const route = next([{ ...navigation, url: urlWithoutPrefix }, options]);
|
|
275
|
+
if (route) {
|
|
276
|
+
// If route is resolved, we need to save actual url and information about language for logs and debugging
|
|
277
|
+
route.actualPath = navigation.url.pathname;
|
|
278
|
+
route.params.__lang = languageFromUrl;
|
|
279
|
+
}
|
|
280
|
+
return route;
|
|
281
|
+
}
|
|
282
|
+
if (config.routingStrategy === 'prefix') {
|
|
283
|
+
// If routing strategy is prefix, we need to send 404 for all urls without language prefix
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return next(args);
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
deps: {
|
|
293
|
+
config: I18N_CONFIGURATION_TOKEN,
|
|
294
|
+
di: DI_TOKEN,
|
|
295
|
+
store: STORE_TOKEN,
|
|
296
|
+
},
|
|
297
|
+
}),
|
|
298
|
+
provide({
|
|
299
|
+
provide: HTML_ATTRS,
|
|
300
|
+
useFactory: ({ i18n }) => {
|
|
301
|
+
return {
|
|
302
|
+
target: 'html',
|
|
303
|
+
attrs: {
|
|
304
|
+
lang: i18n.getLanguage(),
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
deps: {
|
|
309
|
+
i18n: I18N_TOKEN,
|
|
310
|
+
},
|
|
311
|
+
}),
|
|
312
|
+
provide({
|
|
313
|
+
provide: RENDER_SLOTS,
|
|
314
|
+
multi: true,
|
|
315
|
+
useFactory: ({ i18n, requestManager }) => {
|
|
316
|
+
const parsedUrl = requestManager.getParsedUrl();
|
|
317
|
+
const url = `${parsedUrl.origin}${parsedUrl.pathname}`;
|
|
318
|
+
// TODO: dynamic list of available languages for specific route to generate alternate links
|
|
319
|
+
// TODO: `x-default` link?
|
|
320
|
+
return [
|
|
321
|
+
{
|
|
322
|
+
type: ResourceType.asIs,
|
|
323
|
+
slot: ResourceSlot.HEAD_META,
|
|
324
|
+
payload: `<link rel="alternate" hreflang="${i18n.getLanguage()}" href="${url}" />`,
|
|
325
|
+
},
|
|
326
|
+
];
|
|
327
|
+
},
|
|
328
|
+
deps: {
|
|
329
|
+
i18n: I18N_TOKEN,
|
|
330
|
+
requestManager: REQUEST_MANAGER_TOKEN,
|
|
331
|
+
},
|
|
332
|
+
}),
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
export { sharedProviders };
|