piral-translate 1.4.0-beta.6260 → 1.4.0-beta.6280
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/esm/create.d.ts +2 -2
- package/esm/create.js +7 -11
- package/esm/create.js.map +1 -1
- package/esm/flatten-translations.d.ts +2 -0
- package/esm/flatten-translations.js +23 -0
- package/esm/flatten-translations.js.map +1 -0
- package/esm/localize.d.ts +3 -3
- package/esm/localize.js +2 -1
- package/esm/localize.js.map +1 -1
- package/esm/types.d.ts +15 -2
- package/lib/create.d.ts +2 -2
- package/lib/create.js +7 -11
- package/lib/create.js.map +1 -1
- package/lib/flatten-translations.d.ts +2 -0
- package/lib/flatten-translations.js +27 -0
- package/lib/flatten-translations.js.map +1 -0
- package/lib/localize.d.ts +3 -3
- package/lib/localize.js +2 -1
- package/lib/localize.js.map +1 -1
- package/lib/types.d.ts +15 -2
- package/package.json +3 -3
- package/piral-translate.min.js +1 -1
- package/src/create.test.ts +16 -0
- package/src/create.ts +18 -16
- package/src/flatten-translations.test.ts +56 -0
- package/src/flatten-translations.ts +31 -0
- package/src/localize.test.ts +10 -0
- package/src/localize.ts +8 -3
- package/src/types.ts +18 -2
package/esm/create.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PiralPlugin } from 'piral-core';
|
|
2
|
-
import { PiletLocaleApi,
|
|
2
|
+
import type { PiletLocaleApi, Localizable, AnyLocalizationMessages } from './types';
|
|
3
3
|
export interface TranslationFallback {
|
|
4
4
|
(key: string, language: string): string;
|
|
5
5
|
}
|
|
@@ -14,7 +14,7 @@ export interface LocaleConfig {
|
|
|
14
14
|
* Sets the default (global) localization messages.
|
|
15
15
|
* @default {}
|
|
16
16
|
*/
|
|
17
|
-
messages?:
|
|
17
|
+
messages?: AnyLocalizationMessages;
|
|
18
18
|
/**
|
|
19
19
|
* Sets the default language to use.
|
|
20
20
|
*/
|
package/esm/create.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as deepmerge from 'deepmerge';
|
|
|
2
2
|
import { createActions } from './actions';
|
|
3
3
|
import { Localizer } from './localize';
|
|
4
4
|
import { DefaultPicker } from './default';
|
|
5
|
+
import { flattenTranslations } from './flatten-translations';
|
|
5
6
|
/**
|
|
6
7
|
* Sets up a new localizer by using the given config.
|
|
7
8
|
* @param config The configuration for the new localizer.
|
|
@@ -36,16 +37,13 @@ export function createLocaleApi(localizer = setupLocalizer()) {
|
|
|
36
37
|
}));
|
|
37
38
|
return (api) => {
|
|
38
39
|
let localTranslations = {};
|
|
40
|
+
const setTranslations = (messages) => {
|
|
41
|
+
localTranslations = flattenTranslations(messages);
|
|
42
|
+
};
|
|
39
43
|
return {
|
|
40
44
|
addTranslations(messages, isOverriding = true) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
messagesToMerge.unshift(localizer.messages);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
messagesToMerge.push(localizer.messages);
|
|
47
|
-
}
|
|
48
|
-
this.setTranslations(deepmerge.all(messagesToMerge));
|
|
45
|
+
const current = localizer.messages;
|
|
46
|
+
setTranslations(deepmerge.all(isOverriding ? [current, ...messages] : [...messages, current]));
|
|
49
47
|
},
|
|
50
48
|
getCurrentLanguage(cb) {
|
|
51
49
|
const selected = context.readState((s) => s.language.selected);
|
|
@@ -59,9 +57,7 @@ export function createLocaleApi(localizer = setupLocalizer()) {
|
|
|
59
57
|
}
|
|
60
58
|
return selected;
|
|
61
59
|
},
|
|
62
|
-
setTranslations
|
|
63
|
-
localTranslations = messages;
|
|
64
|
-
},
|
|
60
|
+
setTranslations,
|
|
65
61
|
getTranslations() {
|
|
66
62
|
return localTranslations;
|
|
67
63
|
},
|
package/esm/create.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function flat(source) {
|
|
2
|
+
const target = {};
|
|
3
|
+
flatten(source, target);
|
|
4
|
+
return target;
|
|
5
|
+
}
|
|
6
|
+
function flatten(source, target, prop = '') {
|
|
7
|
+
if (typeof source === 'string') {
|
|
8
|
+
target[prop] = source;
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (typeof source === 'object' && source !== null) {
|
|
12
|
+
Object.keys(source).forEach((key) => {
|
|
13
|
+
flatten(source[key], target, prop ? `${prop}.${key}` : key);
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function flattenTranslations(messages) {
|
|
19
|
+
return Object.fromEntries(Object.entries(messages).map(([language, translations]) => {
|
|
20
|
+
return [language, flat(translations)];
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=flatten-translations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-translations.js","sourceRoot":"","sources":["../src/flatten-translations.ts"],"names":[],"mappings":"AAEA,SAAS,IAAI,CAAC,MAA+B;IAC3C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CAAC,MAAW,EAAE,MAA8B,EAAE,IAAI,GAAG,EAAE;IACrE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QAEtB,OAAO;KACR;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;QACjD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YAClC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,OAAO;KACR;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAA2D;IAC7F,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE;QACxD,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/esm/localize.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { LocalizationMessages, Localizable } from './types';
|
|
1
|
+
import { LocalizationMessages, Localizable, NestedLocalizationMessages } from './types';
|
|
2
2
|
declare function defaultFallback(key: string, language: string): string;
|
|
3
3
|
export declare class Localizer implements Localizable {
|
|
4
|
-
messages: LocalizationMessages;
|
|
5
4
|
language: string;
|
|
6
5
|
languages: Array<string>;
|
|
7
6
|
private fallback;
|
|
7
|
+
messages: LocalizationMessages;
|
|
8
8
|
/**
|
|
9
9
|
* Creates a new instance of a localizer.
|
|
10
10
|
*/
|
|
11
|
-
constructor(messages: LocalizationMessages, language: string, languages: Array<string>, fallback?: typeof defaultFallback);
|
|
11
|
+
constructor(messages: LocalizationMessages | NestedLocalizationMessages, language: string, languages: Array<string>, fallback?: typeof defaultFallback);
|
|
12
12
|
/**
|
|
13
13
|
* Localizes the given key via the global translations.
|
|
14
14
|
* @param key The key of the translation snippet.
|
package/esm/localize.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flattenTranslations } from './flatten-translations';
|
|
1
2
|
function defaultFallback(key, language) {
|
|
2
3
|
if (process.env.NODE_ENV === 'production') {
|
|
3
4
|
return language ? '...' : '';
|
|
@@ -22,10 +23,10 @@ export class Localizer {
|
|
|
22
23
|
* Creates a new instance of a localizer.
|
|
23
24
|
*/
|
|
24
25
|
constructor(messages, language, languages, fallback = defaultFallback) {
|
|
25
|
-
this.messages = messages;
|
|
26
26
|
this.language = language;
|
|
27
27
|
this.languages = languages;
|
|
28
28
|
this.fallback = fallback;
|
|
29
|
+
this.messages = flattenTranslations(messages);
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Localizes the given key via the global translations.
|
package/esm/localize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,SAAS,eAAe,CAAC,GAAW,EAAE,QAAgB;IACpD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;QACzC,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B;SAAM;QACL,IAAI,QAAQ,EAAE;YACZ,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,kBAAkB,QAAQ,IAAI,CAAC,CAAC;YAC3E,OAAO,KAAK,QAAQ,IAAI,GAAG,IAAI,CAAC;SACjC;aAAM;YACL,OAAO,EAAE,CAAC;SACX;KACF;AACH,CAAC;AAED,SAAS,aAAa,CAAmB,OAAe,EAAE,SAAY;IACpE,OAAO,OAAO,CAAC,OAAO,CAAC,6BAA6B,EAAE,CAAC,MAAc,EAAE,EAAU,EAAE,EAAE;QACnF,OAAO,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,SAAS;IAGpB;;OAEG;IACH,YACE,QAA2D,EACpD,QAAgB,EAChB,SAAwB,EACvB,WAAW,eAAe;QAF3B,aAAQ,GAAR,QAAQ,CAAQ;QAChB,cAAS,GAAT,SAAS,CAAe;QACvB,aAAQ,GAAR,QAAQ,CAAkB;QAElC,IAAI,CAAC,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACI,cAAc,CAAmB,GAAW,EAAE,SAAa;QAChE,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACI,aAAa,CAAmB,aAAmC,EAAE,GAAW,EAAE,SAAa;QACpG,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAErE,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAC1C;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,YAAY,CAAmB,GAAW,EAAE,SAAa;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAErE,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;SAC1C;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,gBAAgB,CAAmB,QAA8B,EAAE,GAAW,EAAE,SAAa;QACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,YAAY,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,YAAY,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC1F,CAAC;CACF"}
|
package/esm/types.d.ts
CHANGED
|
@@ -91,6 +91,12 @@ export interface Translations {
|
|
|
91
91
|
*/
|
|
92
92
|
[tag: string]: string;
|
|
93
93
|
}
|
|
94
|
+
export interface NestedTranslations {
|
|
95
|
+
/**
|
|
96
|
+
* The available wordings (tag to translation or nested translations).
|
|
97
|
+
*/
|
|
98
|
+
[tag: string]: string | NestedTranslations;
|
|
99
|
+
}
|
|
94
100
|
export interface LanguageLoader {
|
|
95
101
|
(language: string, current: LanguageData): Promise<LanguageData>;
|
|
96
102
|
}
|
|
@@ -107,6 +113,13 @@ export interface LocalizationMessages {
|
|
|
107
113
|
*/
|
|
108
114
|
[lang: string]: Translations;
|
|
109
115
|
}
|
|
116
|
+
export interface NestedLocalizationMessages {
|
|
117
|
+
/**
|
|
118
|
+
* The available languages (lang to wordings or nested wordings).
|
|
119
|
+
*/
|
|
120
|
+
[lang: string]: NestedTranslations;
|
|
121
|
+
}
|
|
122
|
+
export type AnyLocalizationMessages = LocalizationMessages | NestedLocalizationMessages;
|
|
110
123
|
export interface PiletLocaleApi {
|
|
111
124
|
/**
|
|
112
125
|
* Adds a list of translations to the existing translations.
|
|
@@ -117,7 +130,7 @@ export interface PiletLocaleApi {
|
|
|
117
130
|
* @param messagesList The list of messages that extend the existing translations
|
|
118
131
|
* @param [isOverriding=true] Indicates whether the new translations overwrite the existing translations
|
|
119
132
|
*/
|
|
120
|
-
addTranslations(messagesList:
|
|
133
|
+
addTranslations(messagesList: Array<AnyLocalizationMessages>, isOverriding?: boolean): void;
|
|
121
134
|
/**
|
|
122
135
|
* Gets the currently selected language directly.
|
|
123
136
|
*/
|
|
@@ -139,7 +152,7 @@ export interface PiletLocaleApi {
|
|
|
139
152
|
* The translations will be exclusively used for retrieving translations for the pilet.
|
|
140
153
|
* @param messages The messages to use as translation basis.
|
|
141
154
|
*/
|
|
142
|
-
setTranslations(messages:
|
|
155
|
+
setTranslations(messages: AnyLocalizationMessages): void;
|
|
143
156
|
/**
|
|
144
157
|
* Gets the currently provided translations by the pilet.
|
|
145
158
|
*/
|
package/lib/create.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PiralPlugin } from 'piral-core';
|
|
2
|
-
import { PiletLocaleApi,
|
|
2
|
+
import type { PiletLocaleApi, Localizable, AnyLocalizationMessages } from './types';
|
|
3
3
|
export interface TranslationFallback {
|
|
4
4
|
(key: string, language: string): string;
|
|
5
5
|
}
|
|
@@ -14,7 +14,7 @@ export interface LocaleConfig {
|
|
|
14
14
|
* Sets the default (global) localization messages.
|
|
15
15
|
* @default {}
|
|
16
16
|
*/
|
|
17
|
-
messages?:
|
|
17
|
+
messages?: AnyLocalizationMessages;
|
|
18
18
|
/**
|
|
19
19
|
* Sets the default language to use.
|
|
20
20
|
*/
|
package/lib/create.js
CHANGED
|
@@ -5,6 +5,7 @@ const deepmerge = require("deepmerge");
|
|
|
5
5
|
const actions_1 = require("./actions");
|
|
6
6
|
const localize_1 = require("./localize");
|
|
7
7
|
const default_1 = require("./default");
|
|
8
|
+
const flatten_translations_1 = require("./flatten-translations");
|
|
8
9
|
/**
|
|
9
10
|
* Sets up a new localizer by using the given config.
|
|
10
11
|
* @param config The configuration for the new localizer.
|
|
@@ -40,16 +41,13 @@ function createLocaleApi(localizer = setupLocalizer()) {
|
|
|
40
41
|
}));
|
|
41
42
|
return (api) => {
|
|
42
43
|
let localTranslations = {};
|
|
44
|
+
const setTranslations = (messages) => {
|
|
45
|
+
localTranslations = (0, flatten_translations_1.flattenTranslations)(messages);
|
|
46
|
+
};
|
|
43
47
|
return {
|
|
44
48
|
addTranslations(messages, isOverriding = true) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
messagesToMerge.unshift(localizer.messages);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
messagesToMerge.push(localizer.messages);
|
|
51
|
-
}
|
|
52
|
-
this.setTranslations(deepmerge.all(messagesToMerge));
|
|
49
|
+
const current = localizer.messages;
|
|
50
|
+
setTranslations(deepmerge.all(isOverriding ? [current, ...messages] : [...messages, current]));
|
|
53
51
|
},
|
|
54
52
|
getCurrentLanguage(cb) {
|
|
55
53
|
const selected = context.readState((s) => s.language.selected);
|
|
@@ -63,9 +61,7 @@ function createLocaleApi(localizer = setupLocalizer()) {
|
|
|
63
61
|
}
|
|
64
62
|
return selected;
|
|
65
63
|
},
|
|
66
|
-
setTranslations
|
|
67
|
-
localTranslations = messages;
|
|
68
|
-
},
|
|
64
|
+
setTranslations,
|
|
69
65
|
getTranslations() {
|
|
70
66
|
return localTranslations;
|
|
71
67
|
},
|
package/lib/create.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AAGvC,uCAA0C;AAC1C,yCAAuC;AACvC,uCAA0C;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flattenTranslations = void 0;
|
|
4
|
+
function flat(source) {
|
|
5
|
+
const target = {};
|
|
6
|
+
flatten(source, target);
|
|
7
|
+
return target;
|
|
8
|
+
}
|
|
9
|
+
function flatten(source, target, prop = '') {
|
|
10
|
+
if (typeof source === 'string') {
|
|
11
|
+
target[prop] = source;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (typeof source === 'object' && source !== null) {
|
|
15
|
+
Object.keys(source).forEach((key) => {
|
|
16
|
+
flatten(source[key], target, prop ? `${prop}.${key}` : key);
|
|
17
|
+
});
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function flattenTranslations(messages) {
|
|
22
|
+
return Object.fromEntries(Object.entries(messages).map(([language, translations]) => {
|
|
23
|
+
return [language, flat(translations)];
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
exports.flattenTranslations = flattenTranslations;
|
|
27
|
+
//# sourceMappingURL=flatten-translations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-translations.js","sourceRoot":"","sources":["../src/flatten-translations.ts"],"names":[],"mappings":";;;AAEA,SAAS,IAAI,CAAC,MAA+B;IAC3C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CAAC,MAAW,EAAE,MAA8B,EAAE,IAAI,GAAG,EAAE;IACrE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QAEtB,OAAO;KACR;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;QACjD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YAClC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,OAAO;KACR;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,QAA2D;IAC7F,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE;QACxD,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAND,kDAMC"}
|
package/lib/localize.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { LocalizationMessages, Localizable } from './types';
|
|
1
|
+
import { LocalizationMessages, Localizable, NestedLocalizationMessages } from './types';
|
|
2
2
|
declare function defaultFallback(key: string, language: string): string;
|
|
3
3
|
export declare class Localizer implements Localizable {
|
|
4
|
-
messages: LocalizationMessages;
|
|
5
4
|
language: string;
|
|
6
5
|
languages: Array<string>;
|
|
7
6
|
private fallback;
|
|
7
|
+
messages: LocalizationMessages;
|
|
8
8
|
/**
|
|
9
9
|
* Creates a new instance of a localizer.
|
|
10
10
|
*/
|
|
11
|
-
constructor(messages: LocalizationMessages, language: string, languages: Array<string>, fallback?: typeof defaultFallback);
|
|
11
|
+
constructor(messages: LocalizationMessages | NestedLocalizationMessages, language: string, languages: Array<string>, fallback?: typeof defaultFallback);
|
|
12
12
|
/**
|
|
13
13
|
* Localizes the given key via the global translations.
|
|
14
14
|
* @param key The key of the translation snippet.
|
package/lib/localize.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Localizer = void 0;
|
|
4
|
+
const flatten_translations_1 = require("./flatten-translations");
|
|
4
5
|
function defaultFallback(key, language) {
|
|
5
6
|
if (process.env.NODE_ENV === 'production') {
|
|
6
7
|
return language ? '...' : '';
|
|
@@ -25,10 +26,10 @@ class Localizer {
|
|
|
25
26
|
* Creates a new instance of a localizer.
|
|
26
27
|
*/
|
|
27
28
|
constructor(messages, language, languages, fallback = defaultFallback) {
|
|
28
|
-
this.messages = messages;
|
|
29
29
|
this.language = language;
|
|
30
30
|
this.languages = languages;
|
|
31
31
|
this.fallback = fallback;
|
|
32
|
+
this.messages = (0, flatten_translations_1.flattenTranslations)(messages);
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* Localizes the given key via the global translations.
|
package/lib/localize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":";;;AACA,iEAA6D;AAE7D,SAAS,eAAe,CAAC,GAAW,EAAE,QAAgB;IACpD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;QACzC,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B;SAAM;QACL,IAAI,QAAQ,EAAE;YACZ,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,kBAAkB,QAAQ,IAAI,CAAC,CAAC;YAC3E,OAAO,KAAK,QAAQ,IAAI,GAAG,IAAI,CAAC;SACjC;aAAM;YACL,OAAO,EAAE,CAAC;SACX;KACF;AACH,CAAC;AAED,SAAS,aAAa,CAAmB,OAAe,EAAE,SAAY;IACpE,OAAO,OAAO,CAAC,OAAO,CAAC,6BAA6B,EAAE,CAAC,MAAc,EAAE,EAAU,EAAE,EAAE;QACnF,OAAO,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAa,SAAS;IAGpB;;OAEG;IACH,YACE,QAA2D,EACpD,QAAgB,EAChB,SAAwB,EACvB,WAAW,eAAe;QAF3B,aAAQ,GAAR,QAAQ,CAAQ;QAChB,cAAS,GAAT,SAAS,CAAe;QACvB,aAAQ,GAAR,QAAQ,CAAkB;QAElC,IAAI,CAAC,QAAQ,GAAG,IAAA,0CAAmB,EAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACI,cAAc,CAAmB,GAAW,EAAE,SAAa;QAChE,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACI,aAAa,CAAmB,aAAmC,EAAE,GAAW,EAAE,SAAa;QACpG,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAErE,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAC1C;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,YAAY,CAAmB,GAAW,EAAE,SAAa;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAErE,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;SAC1C;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,gBAAgB,CAAmB,QAA8B,EAAE,GAAW,EAAE,SAAa;QACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,YAAY,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,YAAY,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC1F,CAAC;CACF;AAzDD,8BAyDC"}
|
package/lib/types.d.ts
CHANGED
|
@@ -91,6 +91,12 @@ export interface Translations {
|
|
|
91
91
|
*/
|
|
92
92
|
[tag: string]: string;
|
|
93
93
|
}
|
|
94
|
+
export interface NestedTranslations {
|
|
95
|
+
/**
|
|
96
|
+
* The available wordings (tag to translation or nested translations).
|
|
97
|
+
*/
|
|
98
|
+
[tag: string]: string | NestedTranslations;
|
|
99
|
+
}
|
|
94
100
|
export interface LanguageLoader {
|
|
95
101
|
(language: string, current: LanguageData): Promise<LanguageData>;
|
|
96
102
|
}
|
|
@@ -107,6 +113,13 @@ export interface LocalizationMessages {
|
|
|
107
113
|
*/
|
|
108
114
|
[lang: string]: Translations;
|
|
109
115
|
}
|
|
116
|
+
export interface NestedLocalizationMessages {
|
|
117
|
+
/**
|
|
118
|
+
* The available languages (lang to wordings or nested wordings).
|
|
119
|
+
*/
|
|
120
|
+
[lang: string]: NestedTranslations;
|
|
121
|
+
}
|
|
122
|
+
export type AnyLocalizationMessages = LocalizationMessages | NestedLocalizationMessages;
|
|
110
123
|
export interface PiletLocaleApi {
|
|
111
124
|
/**
|
|
112
125
|
* Adds a list of translations to the existing translations.
|
|
@@ -117,7 +130,7 @@ export interface PiletLocaleApi {
|
|
|
117
130
|
* @param messagesList The list of messages that extend the existing translations
|
|
118
131
|
* @param [isOverriding=true] Indicates whether the new translations overwrite the existing translations
|
|
119
132
|
*/
|
|
120
|
-
addTranslations(messagesList:
|
|
133
|
+
addTranslations(messagesList: Array<AnyLocalizationMessages>, isOverriding?: boolean): void;
|
|
121
134
|
/**
|
|
122
135
|
* Gets the currently selected language directly.
|
|
123
136
|
*/
|
|
@@ -139,7 +152,7 @@ export interface PiletLocaleApi {
|
|
|
139
152
|
* The translations will be exclusively used for retrieving translations for the pilet.
|
|
140
153
|
* @param messages The messages to use as translation basis.
|
|
141
154
|
*/
|
|
142
|
-
setTranslations(messages:
|
|
155
|
+
setTranslations(messages: AnyLocalizationMessages): void;
|
|
143
156
|
/**
|
|
144
157
|
* Gets the currently provided translations by the pilet.
|
|
145
158
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "piral-translate",
|
|
3
|
-
"version": "1.4.0-beta.
|
|
3
|
+
"version": "1.4.0-beta.6280",
|
|
4
4
|
"description": "Plugin for providing translated messages in Piral.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"piral",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@types/deepmerge": "^2.2.0",
|
|
70
70
|
"@types/react": "^18.0.0",
|
|
71
|
-
"piral-core": "1.4.0-beta.
|
|
71
|
+
"piral-core": "1.4.0-beta.6280",
|
|
72
72
|
"react": "^18.0.0"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "8402e4d3d6f5de2e76c48bcc5ce79279a3c957e4"
|
|
75
75
|
}
|
package/piral-translate.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var piralTranslate=(()=>{var
|
|
1
|
+
var piralTranslate=(()=>{var R=Object.create;var p=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var j=e=>p(e,"__esModule",{value:!0});var c=(e=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(e,{get:(t,r)=>(typeof require!="undefined"?require:t)[r]}):e)(function(e){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+e+'" is not supported')});var F=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),U=(e,t)=>{j(e);for(var r in t)p(e,r,{get:t[r],enumerable:!0})},D=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of N(t))!I.call(e,n)&&n!=="default"&&p(e,n,{get:()=>t[n],enumerable:!(r=G(t,n))||r.enumerable});return e},l=e=>D(j(p(e!=null?R($(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var h=F((me,z)=>{"use strict";var B=function(t){return V(t)&&!K(t)};function V(e){return!!e&&typeof e=="object"}function K(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||q(e)}var Y=typeof Symbol=="function"&&Symbol.for,Z=Y?Symbol.for("react.element"):60103;function q(e){return e.$$typeof===Z}function H(e){return Array.isArray(e)?[]:{}}function u(e,t){return t.clone!==!1&&t.isMergeableObject(e)?g(H(e),e,t):e}function J(e,t,r){return e.concat(t).map(function(n){return u(n,r)})}function Q(e,t){if(!t.customMerge)return g;var r=t.customMerge(e);return typeof r=="function"?r:g}function W(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function x(e){return Object.keys(e).concat(W(e))}function A(e,t){try{return t in e}catch{return!1}}function X(e,t){return A(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function ee(e,t,r){var n={};return r.isMergeableObject(e)&&x(e).forEach(function(a){n[a]=u(e[a],r)}),x(t).forEach(function(a){X(e,a)||(A(e,a)&&r.isMergeableObject(t[a])?n[a]=Q(a,r)(e[a],t[a],r):n[a]=u(t[a],r))}),n}function g(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||J,r.isMergeableObject=r.isMergeableObject||B,r.cloneUnlessOtherwiseSpecified=u;var n=Array.isArray(t),a=Array.isArray(e),s=n===a;return s?n?r.arrayMerge(e,t,r):ee(e,t,r):u(t,r)}g.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(n,a){return g(n,a,r)},{})};var te=g;z.exports=te});var ue={};U(ue,{Languages:()=>ge,PiralLanguagesPicker:()=>M,createLocaleApi:()=>se,getUserLocale:()=>ie,setupLocalizer:()=>_,useDynamicLanguage:()=>le,useTranslate:()=>ce});var O=l(c("piral-core")),M=(0,O.getPiralComponent)("LanguagesPicker");var C=l(h());function P(e){return{selectLanguage(t,r){t.dispatch(n=>{e.language=r;let a=n.language.selected,s=r;return setTimeout(()=>{t.emit("select-language",{previousLanguage:a,currentLanguage:s})},0),{...n,language:{...n.language,loading:r===void 0,selected:r}}})},translate(t,r,n){return e&&e.localizeGlobal(r,n)},setTranslations(t,r,n){e.messages[r]=n.global;for(let a of n.locals){let s=t.apis[a.name];if(s){let o=s.getTranslations();o[r]=a.value,s.setTranslations(o)}}},getTranslations(t,r){return{global:e.messages[r],locals:Object.keys(t.apis).map(n=>({name:n,value:t.apis[n].getTranslations()[r]}))}}}}function re(e){let t={};return S(e,t),t}function S(e,t,r=""){if(typeof e=="string"){t[r]=e;return}if(typeof e=="object"&&e!==null){Object.keys(e).forEach(n=>{S(e[n],t,r?`${r}.${n}`:n)});return}}function m(e){return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,re(r)]))}function ne(e,t){return t?"...":""}function ae(e,t){return e.replace(/{{\s*([A-Za-z0-9_.]+)\s*}}/g,(r,n)=>n in t?t[n]||"":`{{${n}}}`)}var T=class{constructor(t,r,n,a=ne){this.language=r;this.languages=n;this.fallback=a;this.messages=m(t)}localizeGlobal(t,r){return this.localizeBase(t,r)}localizeLocal(t,r,n){let a=this.translateMessage(t,r,n);return a===void 0?this.localizeBase(r,n):a}localizeBase(t,r){let n=this.translateMessage(this.messages,t,r);return n===void 0?this.fallback(t,this.language):n}translateMessage(t,r,n){let a=this.language,s=a&&t[a],o=s&&s[r];return o&&(n?ae(o,n):o)}};var v=l(c("piral-core")),E=e=>(0,v.defaultRender)(void 0);function _(e={}){let t=e.messages||{},r=Object.keys(t),n=r[0]||"en",a=e.language,o=(typeof a=="function"?a(r,n,"en"):a)||n;return new T(t,o,r.length?r:[o],e.fallback)}function se(e=_()){return t=>(t.defineActions(P(e)),t.dispatch(r=>({...r,components:{LanguagesPicker:E,...r.components},language:{loading:!1,available:e.languages,selected:e.language}})),r=>{let n={},a=s=>{n=m(s)};return{addTranslations(s,o=!0){let i=e.messages;a(C.all(o?[i,...s]:[...s,i]))},getCurrentLanguage(s){let o=t.readState(i=>i.language.selected);if(s){s(o);let i=L=>{s(L.currentLanguage)};return r.on("select-language",i),()=>r.off("select-language",i)}return o},setTranslations:a,getTranslations(){return n},translate(s,o){return e.localizeLocal(n,s,o)}}})}var b=l(c("piral-core"));function oe(e,t){let r=b.cookie.getItem("_culture")||b.storage.getItem("locale");return r||(t?t.toLowerCase().substring(0,2):navigator.language?navigator.language.substring(0,2):e)}function ie(e,t,r){let n=oe(t,r||"");return e.indexOf(n)!==-1?n:t}var d=l(c("react")),f=l(c("piral-core"));function le(e,t){let[r,n]=(0,d.useState)(e),{selectLanguage:a,setTranslations:s,getTranslations:o}=(0,f.useActions)();return(0,d.useEffect)(()=>{let i=!0,L=o(r);return a(void 0),t(r,L).then(y=>{i&&(s(r,y),a(r))},y=>console.error(y)),()=>{i=!1}},[r]),[r,n]}function ce(){let{translate:e}=(0,f.useActions)();return(0,f.useGlobalState)(t=>t.language.selected),e}var k=l(c("react")),w=l(c("piral-core"));var ge=()=>{let{available:e,selected:t}=(0,w.useGlobalState)(r=>r.language);return k.createElement(M,{selected:t,available:e})};return ue;})();
|
package/src/create.test.ts
CHANGED
|
@@ -73,6 +73,22 @@ describe('Create Localize API', () => {
|
|
|
73
73
|
expect(result).toEqual('bár');
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
it('createApi can translate from local-global translations using the current language and passed nested translations', () => {
|
|
77
|
+
const config = {
|
|
78
|
+
language: 'en'
|
|
79
|
+
};
|
|
80
|
+
const api = (createLocaleApi(setupLocalizer(config))(context) as any)();
|
|
81
|
+
api.setTranslations({
|
|
82
|
+
en: {
|
|
83
|
+
header: {
|
|
84
|
+
title: 'Hello world'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const result = api.translate('header.title');
|
|
89
|
+
expect(result).toBe('Hello world');
|
|
90
|
+
});
|
|
91
|
+
|
|
76
92
|
it('createApi falls back to standard string if language is not found', () => {
|
|
77
93
|
const config = {
|
|
78
94
|
language: 'en',
|
package/src/create.ts
CHANGED
|
@@ -4,7 +4,14 @@ import type { PiralPlugin } from 'piral-core';
|
|
|
4
4
|
import { createActions } from './actions';
|
|
5
5
|
import { Localizer } from './localize';
|
|
6
6
|
import { DefaultPicker } from './default';
|
|
7
|
-
import {
|
|
7
|
+
import { flattenTranslations } from './flatten-translations';
|
|
8
|
+
import type {
|
|
9
|
+
PiletLocaleApi,
|
|
10
|
+
LocalizationMessages,
|
|
11
|
+
Localizable,
|
|
12
|
+
PiralSelectLanguageEvent,
|
|
13
|
+
AnyLocalizationMessages,
|
|
14
|
+
} from './types';
|
|
8
15
|
|
|
9
16
|
export interface TranslationFallback {
|
|
10
17
|
(key: string, language: string): string;
|
|
@@ -22,7 +29,7 @@ export interface LocaleConfig {
|
|
|
22
29
|
* Sets the default (global) localization messages.
|
|
23
30
|
* @default {}
|
|
24
31
|
*/
|
|
25
|
-
messages?:
|
|
32
|
+
messages?: AnyLocalizationMessages;
|
|
26
33
|
/**
|
|
27
34
|
* Sets the default language to use.
|
|
28
35
|
*/
|
|
@@ -71,18 +78,15 @@ export function createLocaleApi(localizer: Localizable = setupLocalizer()): Pira
|
|
|
71
78
|
return (api) => {
|
|
72
79
|
let localTranslations: LocalizationMessages = {};
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (isOverriding) {
|
|
79
|
-
messagesToMerge.unshift(localizer.messages);
|
|
80
|
-
} else {
|
|
81
|
-
messagesToMerge.push(localizer.messages);
|
|
82
|
-
}
|
|
81
|
+
const setTranslations = (messages: AnyLocalizationMessages) => {
|
|
82
|
+
localTranslations = flattenTranslations(messages);
|
|
83
|
+
};
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
return {
|
|
86
|
+
addTranslations(messages, isOverriding = true) {
|
|
87
|
+
const current = localizer.messages;
|
|
88
|
+
setTranslations(
|
|
89
|
+
deepmerge.all<AnyLocalizationMessages>(isOverriding ? [current, ...messages] : [...messages, current]),
|
|
86
90
|
);
|
|
87
91
|
},
|
|
88
92
|
getCurrentLanguage(cb?: (l: string) => void): any {
|
|
@@ -99,9 +103,7 @@ export function createLocaleApi(localizer: Localizable = setupLocalizer()): Pira
|
|
|
99
103
|
|
|
100
104
|
return selected;
|
|
101
105
|
},
|
|
102
|
-
setTranslations
|
|
103
|
-
localTranslations = messages;
|
|
104
|
-
},
|
|
106
|
+
setTranslations,
|
|
105
107
|
getTranslations() {
|
|
106
108
|
return localTranslations;
|
|
107
109
|
},
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { flattenTranslations } from './flatten-translations';
|
|
6
|
+
|
|
7
|
+
describe('Flatten translations', () => {
|
|
8
|
+
it('flattenTranslations can handle flat keys', () => {
|
|
9
|
+
const messages = {
|
|
10
|
+
en: {
|
|
11
|
+
key: 'value'
|
|
12
|
+
},
|
|
13
|
+
fr: {
|
|
14
|
+
key: 'value (fr)'
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const flatMessages = flattenTranslations(messages);
|
|
18
|
+
expect(flatMessages.fr.key).toEqual('value (fr)');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('flattenTranslations can handle flat dot keys', () => {
|
|
22
|
+
const messages = {
|
|
23
|
+
en: {
|
|
24
|
+
'header.title': 'Hello world'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const flatMessages = flattenTranslations(messages);
|
|
28
|
+
expect(flatMessages.en['header.title']).toBe('Hello world');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('flattenTranslations can handle nested keys', () => {
|
|
32
|
+
const messages = {
|
|
33
|
+
en: {
|
|
34
|
+
header: {
|
|
35
|
+
title: 'Hello world'
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const flatMessages = flattenTranslations(messages);
|
|
40
|
+
expect(flatMessages.en['header.title']).toBe('Hello world');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('flattenTranslations can handle nested keys with multiple depth levels', () => {
|
|
44
|
+
const messages = {
|
|
45
|
+
en: {
|
|
46
|
+
header: {
|
|
47
|
+
title: {
|
|
48
|
+
subtitle: 'Hello world'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const flatMessages = flattenTranslations(messages);
|
|
54
|
+
expect(flatMessages.en['header.title.subtitle']).toBe('Hello world');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LocalizationMessages, NestedLocalizationMessages } from './types';
|
|
2
|
+
|
|
3
|
+
function flat(source: Record<string, unknown>): Record<string, string> {
|
|
4
|
+
const target: Record<string, string> = {};
|
|
5
|
+
flatten(source, target);
|
|
6
|
+
return target;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function flatten(source: any, target: Record<string, string>, prop = '') {
|
|
10
|
+
if (typeof source === 'string') {
|
|
11
|
+
target[prop] = source;
|
|
12
|
+
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (typeof source === 'object' && source !== null) {
|
|
17
|
+
Object.keys(source).forEach((key) => {
|
|
18
|
+
flatten(source[key], target, prop ? `${prop}.${key}` : key);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function flattenTranslations(messages: LocalizationMessages | NestedLocalizationMessages): LocalizationMessages {
|
|
26
|
+
return Object.fromEntries(
|
|
27
|
+
Object.entries(messages).map(([language, translations]) => {
|
|
28
|
+
return [language, flat(translations)];
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
}
|
package/src/localize.test.ts
CHANGED
|
@@ -8,6 +8,9 @@ const messages = {
|
|
|
8
8
|
en: {
|
|
9
9
|
hi: 'hello',
|
|
10
10
|
greeting: 'Hi {{name}}, welcome back',
|
|
11
|
+
header: {
|
|
12
|
+
title: 'Hello world'
|
|
13
|
+
}
|
|
11
14
|
},
|
|
12
15
|
de: {
|
|
13
16
|
hi: 'hallo',
|
|
@@ -76,4 +79,11 @@ describe('Localize Module', () => {
|
|
|
76
79
|
const result = localizer.localizeGlobal('greeting', { name: undefined });
|
|
77
80
|
expect(result).toBe('Hi , welcome back');
|
|
78
81
|
});
|
|
82
|
+
|
|
83
|
+
it('localizeGlobal translates from global translations using passed nested translations', () => {
|
|
84
|
+
const localizer = new Localizer(messages, 'en');
|
|
85
|
+
const result = localizer.localizeGlobal('header.title');
|
|
86
|
+
|
|
87
|
+
expect(result).toBe('Hello world');
|
|
88
|
+
});
|
|
79
89
|
});
|
package/src/localize.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { LocalizationMessages, Localizable } from './types';
|
|
1
|
+
import { LocalizationMessages, Localizable, NestedLocalizationMessages } from './types';
|
|
2
|
+
import { flattenTranslations } from './flatten-translations';
|
|
2
3
|
|
|
3
4
|
function defaultFallback(key: string, language: string): string {
|
|
4
5
|
if (process.env.NODE_ENV === 'production') {
|
|
@@ -20,15 +21,19 @@ function formatMessage<T extends object>(message: string, variables: T): string
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export class Localizer implements Localizable {
|
|
24
|
+
public messages: LocalizationMessages;
|
|
25
|
+
|
|
23
26
|
/**
|
|
24
27
|
* Creates a new instance of a localizer.
|
|
25
28
|
*/
|
|
26
29
|
constructor(
|
|
27
|
-
|
|
30
|
+
messages: LocalizationMessages | NestedLocalizationMessages,
|
|
28
31
|
public language: string,
|
|
29
32
|
public languages: Array<string>,
|
|
30
33
|
private fallback = defaultFallback,
|
|
31
|
-
) {
|
|
34
|
+
) {
|
|
35
|
+
this.messages = flattenTranslations(messages);
|
|
36
|
+
}
|
|
32
37
|
|
|
33
38
|
/**
|
|
34
39
|
* Localizes the given key via the global translations.
|
package/src/types.ts
CHANGED
|
@@ -100,6 +100,13 @@ export interface Translations {
|
|
|
100
100
|
[tag: string]: string;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
export interface NestedTranslations {
|
|
104
|
+
/**
|
|
105
|
+
* The available wordings (tag to translation or nested translations).
|
|
106
|
+
*/
|
|
107
|
+
[tag: string]: string | NestedTranslations;
|
|
108
|
+
}
|
|
109
|
+
|
|
103
110
|
export interface LanguageLoader {
|
|
104
111
|
(language: string, current: LanguageData): Promise<LanguageData>;
|
|
105
112
|
}
|
|
@@ -119,6 +126,15 @@ export interface LocalizationMessages {
|
|
|
119
126
|
[lang: string]: Translations;
|
|
120
127
|
}
|
|
121
128
|
|
|
129
|
+
export interface NestedLocalizationMessages {
|
|
130
|
+
/**
|
|
131
|
+
* The available languages (lang to wordings or nested wordings).
|
|
132
|
+
*/
|
|
133
|
+
[lang: string]: NestedTranslations;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export type AnyLocalizationMessages = LocalizationMessages | NestedLocalizationMessages;
|
|
137
|
+
|
|
122
138
|
export interface PiletLocaleApi {
|
|
123
139
|
/**
|
|
124
140
|
* Adds a list of translations to the existing translations.
|
|
@@ -129,7 +145,7 @@ export interface PiletLocaleApi {
|
|
|
129
145
|
* @param messagesList The list of messages that extend the existing translations
|
|
130
146
|
* @param [isOverriding=true] Indicates whether the new translations overwrite the existing translations
|
|
131
147
|
*/
|
|
132
|
-
addTranslations(messagesList:
|
|
148
|
+
addTranslations(messagesList: Array<AnyLocalizationMessages>, isOverriding?: boolean): void;
|
|
133
149
|
/**
|
|
134
150
|
* Gets the currently selected language directly.
|
|
135
151
|
*/
|
|
@@ -151,7 +167,7 @@ export interface PiletLocaleApi {
|
|
|
151
167
|
* The translations will be exclusively used for retrieving translations for the pilet.
|
|
152
168
|
* @param messages The messages to use as translation basis.
|
|
153
169
|
*/
|
|
154
|
-
setTranslations(messages:
|
|
170
|
+
setTranslations(messages: AnyLocalizationMessages): void;
|
|
155
171
|
/**
|
|
156
172
|
* Gets the currently provided translations by the pilet.
|
|
157
173
|
*/
|