@tolgee/core 4.9.2 → 4.9.3-rc.04b22e6.0

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.
Files changed (288) hide show
  1. package/dist/tolgee.cjs.js +1277 -7023
  2. package/dist/tolgee.cjs.js.map +1 -1
  3. package/dist/tolgee.cjs.min.js +1 -1
  4. package/dist/tolgee.cjs.min.js.map +1 -1
  5. package/dist/tolgee.esm.js +1407 -0
  6. package/dist/tolgee.esm.js.map +1 -0
  7. package/dist/tolgee.esm.min.mjs +1 -1
  8. package/dist/tolgee.esm.min.mjs.map +1 -1
  9. package/dist/tolgee.umd.js +1277 -7023
  10. package/dist/tolgee.umd.js.map +1 -1
  11. package/dist/tolgee.umd.min.js +1 -1
  12. package/dist/tolgee.umd.min.js.map +1 -1
  13. package/lib/Controller/Cache/Cache.d.ts +22 -0
  14. package/lib/Controller/Cache/helpers.d.ts +4 -0
  15. package/lib/Controller/Controller.d.ts +110 -0
  16. package/lib/Controller/Events/EventEmitter.d.ts +6 -0
  17. package/lib/Controller/Events/EventEmitterSelective.d.ts +7 -0
  18. package/lib/Controller/Events/Events.d.ts +14 -0
  19. package/lib/Controller/Plugins/Plugins.d.ts +36 -0
  20. package/lib/Controller/State/State.d.ts +39 -0
  21. package/lib/Controller/State/helpers.d.ts +6 -0
  22. package/lib/Controller/State/initObserverOptions.d.ts +13 -0
  23. package/lib/Controller/State/initState.d.ts +47 -0
  24. package/lib/Controller/ValueObserver.d.ts +5 -0
  25. package/lib/FormatSimple/FormatError.d.ts +7 -0
  26. package/lib/FormatSimple/FormatSimple.d.ts +3 -0
  27. package/lib/FormatSimple/formatParser.d.ts +1 -0
  28. package/lib/FormatSimple/formatter.d.ts +2 -0
  29. package/lib/Tolgee.d.ts +2 -68
  30. package/lib/TranslateParams.d.ts +2 -0
  31. package/lib/{Constants/Global.d.ts → constants.d.ts} +1 -3
  32. package/lib/helpers.d.ts +3 -0
  33. package/lib/index.d.ts +4 -8
  34. package/lib/types.d.ts +244 -84
  35. package/package.json +21 -29
  36. package/src/Controller/Cache/Cache.ts +296 -0
  37. package/src/Controller/Cache/helpers.ts +37 -0
  38. package/src/Controller/Controller.ts +310 -0
  39. package/src/Controller/Events/EventEmitter.ts +30 -0
  40. package/src/Controller/Events/EventEmitterSelective.test.ts +125 -0
  41. package/src/Controller/Events/EventEmitterSelective.ts +188 -0
  42. package/src/Controller/Events/Events.ts +66 -0
  43. package/src/Controller/Plugins/Plugins.ts +315 -0
  44. package/src/Controller/State/State.ts +175 -0
  45. package/src/Controller/State/helpers.ts +41 -0
  46. package/src/Controller/State/initObserverOptions.ts +38 -0
  47. package/src/Controller/State/initState.ts +81 -0
  48. package/src/Controller/ValueObserver.ts +26 -0
  49. package/src/FormatSimple/FormatError.ts +26 -0
  50. package/src/FormatSimple/FormatSimple.ts +13 -0
  51. package/src/FormatSimple/formatParser.ts +133 -0
  52. package/src/FormatSimple/formatter.test.ts +190 -0
  53. package/src/FormatSimple/formatter.ts +19 -0
  54. package/src/Tolgee.ts +79 -330
  55. package/src/TranslateParams.test.ts +41 -0
  56. package/src/TranslateParams.ts +51 -0
  57. package/src/__test/backend.test.ts +48 -0
  58. package/src/__test/cache.test.ts +148 -0
  59. package/src/__test/client.test.ts +48 -0
  60. package/src/__test/events.test.ts +33 -0
  61. package/src/__test/format.simple.test.ts +26 -0
  62. package/src/__test/initialization.test.ts +85 -0
  63. package/src/__test/jest-setup.ts +2 -0
  64. package/src/__test/languageDetection.test.ts +129 -0
  65. package/src/__test/languageStorage.test.ts +145 -0
  66. package/src/__test/languages.test.ts +112 -0
  67. package/src/__test/loading.test.ts +39 -0
  68. package/src/__test/namespaces.test.ts +99 -0
  69. package/src/__test/namespacesFallback.test.ts +74 -0
  70. package/src/__test/plugins.test.ts +136 -0
  71. package/src/__test/testTools.ts +7 -0
  72. package/src/{Constants/Global.ts → constants.ts} +1 -6
  73. package/src/helpers.ts +17 -0
  74. package/src/index.ts +9 -8
  75. package/src/types.ts +338 -90
  76. package/README.md +0 -45
  77. package/dist/Constants/Global.d.ts +0 -6
  78. package/dist/Constants/ModifierKey.d.ts +0 -6
  79. package/dist/Errors/ApiHttpError.d.ts +0 -5
  80. package/dist/Observer.d.ts +0 -14
  81. package/dist/Observer.test.d.ts +0 -2
  82. package/dist/Properties.d.ts +0 -17
  83. package/dist/Properties.test.d.ts +0 -1
  84. package/dist/Tolgee.d.ts +0 -68
  85. package/dist/Tolgee.test.d.ts +0 -1
  86. package/dist/TolgeeConfig.d.ts +0 -69
  87. package/dist/TolgeeConfig.test.d.ts +0 -1
  88. package/dist/__integration/FormatterIcu.test.d.ts +0 -1
  89. package/dist/__integration/FormatterMissing.d.ts +0 -1
  90. package/dist/__integration/Tolgee.test.d.ts +0 -1
  91. package/dist/__integration/TolgeeInvisible.test.d.ts +0 -1
  92. package/dist/__integration/mockTranslations.d.ts +0 -7
  93. package/dist/__integration/testConfig.d.ts +0 -9
  94. package/dist/__testFixtures/classMock.d.ts +0 -3
  95. package/dist/__testFixtures/createElement.d.ts +0 -2
  96. package/dist/__testFixtures/createTestDom.d.ts +0 -9
  97. package/dist/__testFixtures/mocked.d.ts +0 -20
  98. package/dist/__testFixtures/setupAfterEnv.d.ts +0 -8
  99. package/dist/helpers/NodeHelper.d.ts +0 -14
  100. package/dist/helpers/TextHelper.d.ts +0 -5
  101. package/dist/helpers/TextHelper.test.d.ts +0 -1
  102. package/dist/helpers/commonTypes.d.ts +0 -2
  103. package/dist/helpers/encoderPolyfill.d.ts +0 -8
  104. package/dist/helpers/secret.d.ts +0 -6
  105. package/dist/helpers/secret.test.d.ts +0 -1
  106. package/dist/helpers/sleep.d.ts +0 -1
  107. package/dist/highlighter/HighlightFunctionsInitializer.d.ts +0 -10
  108. package/dist/highlighter/HighlightFunctionsInitializer.test.d.ts +0 -1
  109. package/dist/highlighter/MouseEventHandler.d.ts +0 -29
  110. package/dist/highlighter/MouseEventHandler.test.d.ts +0 -1
  111. package/dist/highlighter/TranslationHighlighter.d.ts +0 -14
  112. package/dist/highlighter/TranslationHighlighter.test.d.ts +0 -1
  113. package/dist/index.d.ts +0 -10
  114. package/dist/internal.d.ts +0 -2
  115. package/dist/modules/IcuFormatter.d.ts +0 -2
  116. package/dist/modules/IcuFormatter.test.d.ts +0 -1
  117. package/dist/modules/index.d.ts +0 -1
  118. package/dist/services/ApiHttpService.d.ts +0 -15
  119. package/dist/services/CoreService.d.ts +0 -18
  120. package/dist/services/CoreService.test.d.ts +0 -1
  121. package/dist/services/DependencyService.d.ts +0 -39
  122. package/dist/services/DependencyService.test.d.ts +0 -1
  123. package/dist/services/ElementRegistrar.d.ts +0 -19
  124. package/dist/services/ElementRegistrar.test.d.ts +0 -1
  125. package/dist/services/EventEmitter.d.ts +0 -13
  126. package/dist/services/EventService.d.ts +0 -9
  127. package/dist/services/ModuleService.d.ts +0 -5
  128. package/dist/services/ScreenshotService.d.ts +0 -15
  129. package/dist/services/Subscription.d.ts +0 -5
  130. package/dist/services/TextService.d.ts +0 -14
  131. package/dist/services/TextService.test.d.ts +0 -1
  132. package/dist/services/TranslationService.d.ts +0 -75
  133. package/dist/services/TranslationService.test.d.ts +0 -1
  134. package/dist/services/__mocks__/CoreService.d.ts +0 -2
  135. package/dist/tolgee.esm.mjs +0 -7150
  136. package/dist/tolgee.esm.mjs.map +0 -1
  137. package/dist/toolsManager/Messages.d.ts +0 -8
  138. package/dist/toolsManager/Messages.test.d.ts +0 -1
  139. package/dist/toolsManager/PluginManager.d.ts +0 -21
  140. package/dist/toolsManager/PluginManager.test.d.ts +0 -1
  141. package/dist/types/DTOs.d.ts +0 -20
  142. package/dist/types/apiSchema.generated.d.ts +0 -6185
  143. package/dist/types.d.ts +0 -123
  144. package/dist/wrappers/AbstractWrapper.d.ts +0 -8
  145. package/dist/wrappers/NodeHandler.d.ts +0 -18
  146. package/dist/wrappers/WrappedHandler.d.ts +0 -8
  147. package/dist/wrappers/invisible/AttributeHandler.d.ts +0 -8
  148. package/dist/wrappers/invisible/Coder.d.ts +0 -7
  149. package/dist/wrappers/invisible/ContentHandler.d.ts +0 -6
  150. package/dist/wrappers/invisible/CoreHandler.d.ts +0 -10
  151. package/dist/wrappers/invisible/InvisibleWrapper.d.ts +0 -18
  152. package/dist/wrappers/invisible/ValueMemory.d.ts +0 -5
  153. package/dist/wrappers/invisible/ValueMemory.test.d.ts +0 -1
  154. package/dist/wrappers/text/AttributeHandler.d.ts +0 -8
  155. package/dist/wrappers/text/AttributeHandler.test.d.ts +0 -1
  156. package/dist/wrappers/text/Coder.d.ts +0 -15
  157. package/dist/wrappers/text/Coder.test.d.ts +0 -1
  158. package/dist/wrappers/text/ContentHandler.d.ts +0 -8
  159. package/dist/wrappers/text/ContentHandler.test.d.ts +0 -1
  160. package/dist/wrappers/text/CoreHandler.d.ts +0 -17
  161. package/dist/wrappers/text/CoreHandler.test.d.ts +0 -1
  162. package/dist/wrappers/text/TextWrapper.d.ts +0 -20
  163. package/index.js +0 -7
  164. package/lib/Constants/ModifierKey.d.ts +0 -6
  165. package/lib/Errors/ApiHttpError.d.ts +0 -5
  166. package/lib/Observer.d.ts +0 -14
  167. package/lib/Properties.d.ts +0 -17
  168. package/lib/TolgeeConfig.d.ts +0 -69
  169. package/lib/helpers/NodeHelper.d.ts +0 -14
  170. package/lib/helpers/TextHelper.d.ts +0 -5
  171. package/lib/helpers/commonTypes.d.ts +0 -2
  172. package/lib/helpers/encoderPolyfill.d.ts +0 -8
  173. package/lib/helpers/secret.d.ts +0 -6
  174. package/lib/helpers/sleep.d.ts +0 -1
  175. package/lib/highlighter/HighlightFunctionsInitializer.d.ts +0 -10
  176. package/lib/highlighter/MouseEventHandler.d.ts +0 -29
  177. package/lib/highlighter/TranslationHighlighter.d.ts +0 -14
  178. package/lib/modules/IcuFormatter.d.ts +0 -2
  179. package/lib/modules/index.d.ts +0 -1
  180. package/lib/services/ApiHttpService.d.ts +0 -15
  181. package/lib/services/CoreService.d.ts +0 -18
  182. package/lib/services/DependencyService.d.ts +0 -39
  183. package/lib/services/ElementRegistrar.d.ts +0 -19
  184. package/lib/services/EventEmitter.d.ts +0 -13
  185. package/lib/services/EventService.d.ts +0 -9
  186. package/lib/services/ModuleService.d.ts +0 -5
  187. package/lib/services/ScreenshotService.d.ts +0 -15
  188. package/lib/services/Subscription.d.ts +0 -5
  189. package/lib/services/TextService.d.ts +0 -14
  190. package/lib/services/TranslationService.d.ts +0 -75
  191. package/lib/toolsManager/Messages.d.ts +0 -8
  192. package/lib/toolsManager/PluginManager.d.ts +0 -21
  193. package/lib/types/DTOs.d.ts +0 -20
  194. package/lib/types/apiSchema.generated.d.ts +0 -6185
  195. package/lib/wrappers/AbstractWrapper.d.ts +0 -8
  196. package/lib/wrappers/NodeHandler.d.ts +0 -18
  197. package/lib/wrappers/WrappedHandler.d.ts +0 -8
  198. package/lib/wrappers/invisible/AttributeHandler.d.ts +0 -8
  199. package/lib/wrappers/invisible/Coder.d.ts +0 -7
  200. package/lib/wrappers/invisible/ContentHandler.d.ts +0 -6
  201. package/lib/wrappers/invisible/CoreHandler.d.ts +0 -10
  202. package/lib/wrappers/invisible/InvisibleWrapper.d.ts +0 -18
  203. package/lib/wrappers/invisible/ValueMemory.d.ts +0 -5
  204. package/lib/wrappers/text/AttributeHandler.d.ts +0 -8
  205. package/lib/wrappers/text/Coder.d.ts +0 -15
  206. package/lib/wrappers/text/ContentHandler.d.ts +0 -8
  207. package/lib/wrappers/text/CoreHandler.d.ts +0 -17
  208. package/lib/wrappers/text/TextWrapper.d.ts +0 -20
  209. package/src/Constants/ModifierKey.ts +0 -6
  210. package/src/Errors/ApiHttpError.ts +0 -8
  211. package/src/Observer.test.ts +0 -119
  212. package/src/Observer.ts +0 -68
  213. package/src/Properties.test.ts +0 -150
  214. package/src/Properties.ts +0 -112
  215. package/src/Tolgee.test.ts +0 -473
  216. package/src/TolgeeConfig.test.ts +0 -21
  217. package/src/TolgeeConfig.ts +0 -134
  218. package/src/__integration/FormatterIcu.test.ts +0 -80
  219. package/src/__integration/FormatterMissing.ts +0 -54
  220. package/src/__integration/Tolgee.test.ts +0 -90
  221. package/src/__integration/TolgeeInvisible.test.ts +0 -145
  222. package/src/__integration/mockTranslations.ts +0 -6
  223. package/src/__integration/testConfig.ts +0 -16
  224. package/src/__testFixtures/classMock.ts +0 -11
  225. package/src/__testFixtures/createElement.ts +0 -43
  226. package/src/__testFixtures/createTestDom.ts +0 -26
  227. package/src/__testFixtures/mocked.ts +0 -25
  228. package/src/__testFixtures/setupAfterEnv.ts +0 -34
  229. package/src/helpers/NodeHelper.ts +0 -90
  230. package/src/helpers/TextHelper.test.ts +0 -62
  231. package/src/helpers/TextHelper.ts +0 -58
  232. package/src/helpers/commonTypes.ts +0 -8
  233. package/src/helpers/encoderPolyfill.ts +0 -96
  234. package/src/helpers/secret.test.ts +0 -61
  235. package/src/helpers/secret.ts +0 -68
  236. package/src/helpers/sleep.ts +0 -2
  237. package/src/highlighter/HighlightFunctionsInitializer.test.ts +0 -40
  238. package/src/highlighter/HighlightFunctionsInitializer.ts +0 -61
  239. package/src/highlighter/MouseEventHandler.test.ts +0 -151
  240. package/src/highlighter/MouseEventHandler.ts +0 -191
  241. package/src/highlighter/TranslationHighlighter.test.ts +0 -177
  242. package/src/highlighter/TranslationHighlighter.ts +0 -113
  243. package/src/internal.ts +0 -2
  244. package/src/modules/IcuFormatter.test.ts +0 -21
  245. package/src/modules/IcuFormatter.ts +0 -39
  246. package/src/modules/index.ts +0 -1
  247. package/src/services/ApiHttpService.ts +0 -85
  248. package/src/services/CoreService.test.ts +0 -141
  249. package/src/services/CoreService.ts +0 -76
  250. package/src/services/DependencyService.test.ts +0 -51
  251. package/src/services/DependencyService.ts +0 -116
  252. package/src/services/ElementRegistrar.test.ts +0 -131
  253. package/src/services/ElementRegistrar.ts +0 -108
  254. package/src/services/EventEmitter.ts +0 -52
  255. package/src/services/EventService.ts +0 -14
  256. package/src/services/ModuleService.ts +0 -14
  257. package/src/services/ScreenshotService.ts +0 -31
  258. package/src/services/Subscription.ts +0 -7
  259. package/src/services/TextService.test.ts +0 -88
  260. package/src/services/TextService.ts +0 -82
  261. package/src/services/TranslationService.test.ts +0 -358
  262. package/src/services/TranslationService.ts +0 -417
  263. package/src/services/__mocks__/CoreService.ts +0 -17
  264. package/src/toolsManager/Messages.test.ts +0 -79
  265. package/src/toolsManager/Messages.ts +0 -60
  266. package/src/toolsManager/PluginManager.test.ts +0 -108
  267. package/src/toolsManager/PluginManager.ts +0 -129
  268. package/src/types/DTOs.ts +0 -25
  269. package/src/types/apiSchema.generated.ts +0 -6208
  270. package/src/wrappers/AbstractWrapper.ts +0 -14
  271. package/src/wrappers/NodeHandler.ts +0 -143
  272. package/src/wrappers/WrappedHandler.ts +0 -28
  273. package/src/wrappers/invisible/AttributeHandler.ts +0 -23
  274. package/src/wrappers/invisible/Coder.ts +0 -65
  275. package/src/wrappers/invisible/ContentHandler.ts +0 -15
  276. package/src/wrappers/invisible/CoreHandler.ts +0 -17
  277. package/src/wrappers/invisible/InvisibleWrapper.ts +0 -59
  278. package/src/wrappers/invisible/ValueMemory.test.ts +0 -25
  279. package/src/wrappers/invisible/ValueMemory.ts +0 -16
  280. package/src/wrappers/text/AttributeHandler.test.ts +0 -118
  281. package/src/wrappers/text/AttributeHandler.ts +0 -25
  282. package/src/wrappers/text/Coder.test.ts +0 -298
  283. package/src/wrappers/text/Coder.ts +0 -202
  284. package/src/wrappers/text/ContentHandler.test.ts +0 -185
  285. package/src/wrappers/text/ContentHandler.ts +0 -21
  286. package/src/wrappers/text/CoreHandler.test.ts +0 -106
  287. package/src/wrappers/text/CoreHandler.ts +0 -45
  288. package/src/wrappers/text/TextWrapper.ts +0 -69
@@ -0,0 +1,190 @@
1
+ import { TranslateParams } from '../types';
2
+ import IntlMessageFormat from 'intl-messageformat';
3
+ import { formatter } from './formatter';
4
+ import {
5
+ ErrorCode,
6
+ ERROR_PARAM_EMPTY,
7
+ ERROR_UNEXPECTED_CHAR,
8
+ ERROR_UNEXPECTED_END,
9
+ FormatError,
10
+ } from './FormatError';
11
+
12
+ function icu(text: string, params?: TranslateParams) {
13
+ return new IntlMessageFormat(text, 'en', undefined, {
14
+ ignoreTag: true,
15
+ }).format(params);
16
+ }
17
+
18
+ function getText() {
19
+ return expect.getState().currentTestName.replace('simple formatter ', '');
20
+ }
21
+
22
+ function matchIcu(params?: TranslateParams) {
23
+ const text = getText();
24
+ expect(formatter(text, params)).toEqual(icu(text, params));
25
+ }
26
+
27
+ function expectToThrow(
28
+ text: string,
29
+ code?: ErrorCode,
30
+ params?: TranslateParams
31
+ ) {
32
+ let error: FormatError | undefined = undefined;
33
+ try {
34
+ formatter(text, params);
35
+ } catch (e) {
36
+ error = e as FormatError;
37
+ }
38
+ expect(error).toBeInstanceOf(FormatError);
39
+ expect(error?.code).toEqual(code);
40
+ }
41
+
42
+ function expectToThrowWithIcu(code?: ErrorCode, params?: TranslateParams) {
43
+ const text = getText();
44
+ expect(() => icu(text, params)).toThrow();
45
+ expectToThrow(text, code, params);
46
+ }
47
+
48
+ function unsupported(code?: ErrorCode, params?: TranslateParams) {
49
+ const text = getText();
50
+ expect(() => icu(text, params)).not.toThrow();
51
+ expectToThrow(text, code, params);
52
+ }
53
+
54
+ function combineChars(chars: string[]) {
55
+ const result: string[] = [];
56
+ chars.forEach((char) => {
57
+ [`start${char}`, `${char}end`, `mid${char}dle`, char].forEach((param) => {
58
+ result.push(param);
59
+ });
60
+ });
61
+ return result;
62
+ }
63
+
64
+ function characterInParamSupported(chars: string[]) {
65
+ combineChars(chars).forEach((param) => {
66
+ const text = `test { ${param} } param`;
67
+ it(`works with: ${text}`, () => {
68
+ const params = { [param]: 'valid' };
69
+ expect(icu(text, params)).toEqual('test valid param');
70
+ expect(formatter(text, params)).toEqual('test valid param');
71
+ });
72
+ });
73
+ }
74
+
75
+ function characterInParamFailWithIcu(chars: string[]) {
76
+ combineChars(chars).forEach((param) => {
77
+ const text = `test { ${param} } param`;
78
+ it(`fails with: ${text}`, () => {
79
+ const params = { [param]: 'test' };
80
+ expect(() => icu(text, params)).toThrow();
81
+ expectToThrow(text, ERROR_UNEXPECTED_CHAR, params);
82
+ });
83
+ });
84
+ }
85
+
86
+ function characterInParamFail(chars: string[]) {
87
+ combineChars(chars).forEach((param) => {
88
+ const text = `test { ${param} } param`;
89
+ it(`works with: ${text}`, () => {
90
+ const params = { [param]: 'valid' };
91
+ expectToThrow(text, ERROR_UNEXPECTED_CHAR, params);
92
+ });
93
+ });
94
+ }
95
+
96
+ describe('simple formatter', () => {
97
+ test('test test', () => {
98
+ expect(getText()).toEqual('test test');
99
+ });
100
+
101
+ test('simple test', () => {
102
+ matchIcu();
103
+ });
104
+
105
+ test('this is {name}', () => {
106
+ matchIcu({ name: 'Bob' });
107
+ });
108
+
109
+ test('this is { name }', () => {
110
+ matchIcu({ name: 'Bob' });
111
+ });
112
+
113
+ test('{ user } has { num } apples.', () => {
114
+ matchIcu({ user: 'John', num: 2 });
115
+ });
116
+
117
+ test('passing params, but no params here', () => {
118
+ matchIcu({ user: 'John', num: 2 });
119
+ });
120
+
121
+ test('{ user } has { user } apples.', () => {
122
+ matchIcu({ user: 'John', num: 2 });
123
+ });
124
+
125
+ test("ICU: '{ parameter '} format", () => {
126
+ matchIcu();
127
+ });
128
+
129
+ test("this '{ escaped }' well", () => {
130
+ matchIcu();
131
+ });
132
+
133
+ test("this is '{ weird } but valid", () => {
134
+ matchIcu();
135
+ });
136
+
137
+ test("edge case '", () => {
138
+ matchIcu();
139
+ });
140
+
141
+ test("What's {subject}?", () => {
142
+ matchIcu({ subject: 'that' });
143
+ });
144
+
145
+ test('this is also } right', () => {
146
+ matchIcu();
147
+ });
148
+
149
+ test('this is just {} wrong', () => {
150
+ expectToThrowWithIcu(ERROR_PARAM_EMPTY);
151
+ });
152
+
153
+ test('this also { } wrong', () => {
154
+ expectToThrowWithIcu(ERROR_PARAM_EMPTY);
155
+ });
156
+
157
+ test('this plain { , } wrong', () => {
158
+ expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR);
159
+ });
160
+
161
+ test('this is { unexpected', () => {
162
+ expectToThrowWithIcu(ERROR_UNEXPECTED_END);
163
+ });
164
+
165
+ test('this is obviously bad { yo yo }', () => {
166
+ expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR);
167
+ });
168
+
169
+ test('this is obviously bad { yo, }', () => {
170
+ expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR);
171
+ });
172
+
173
+ test('good for icu { yo, number } not for me', () => {
174
+ unsupported(ERROR_UNEXPECTED_CHAR, { yo: 6 });
175
+ });
176
+
177
+ describe('supported characters in params', () => {
178
+ characterInParamSupported(Array.from('019_axAX'));
179
+ });
180
+
181
+ describe('invalid characters in params', () => {
182
+ characterInParamFailWithIcu('[+-@#$~^&*{%)(§\'"`!?:.;<>[]\\=|☺'.split(''));
183
+ });
184
+
185
+ describe('unsupported characters which are supported in ICU', () => {
186
+ characterInParamFail(Array.from('šřýíéúůĚŽÝÁÍÉůú¨ˇ'));
187
+ characterInParamFail(['汉字', '字', 'हि', 'हिन्दी']);
188
+ characterInParamFail(['😊']);
189
+ });
190
+ });
@@ -0,0 +1,19 @@
1
+ import { DefaultParamType, TranslateParams } from '../types';
2
+ import { formatParser } from './formatParser';
3
+
4
+ export function formatter(
5
+ translation: string,
6
+ params?: TranslateParams<DefaultParamType>
7
+ ) {
8
+ const [texts, pars] = formatParser(translation);
9
+ const result = [texts[0]];
10
+ for (let i = 1; i < texts.length; i++) {
11
+ const parameter = params?.[pars[i - 1]];
12
+ if (parameter === undefined) {
13
+ throw new Error(`Missing parameter "${pars[i - 1]}" in "${translation}"`);
14
+ }
15
+ result.push(String(parameter));
16
+ result.push(texts[i]);
17
+ }
18
+ return result.join('');
19
+ }
package/src/Tolgee.ts CHANGED
@@ -1,335 +1,84 @@
1
- import { TolgeeConfig } from './TolgeeConfig';
1
+ import { Controller } from './Controller/Controller';
2
2
  import {
3
- InstantProps,
4
- InstantPropsTags,
5
- TolgeeModule,
6
- TranslateProps,
7
- TranslatePropsTags,
8
- TranslationTags,
9
- TranslationParams,
10
- TranslationParamsTags,
3
+ Options,
4
+ TolgeeInstance,
5
+ TolgeePlugin,
6
+ ObserverOptions,
11
7
  } from './types';
12
8
 
13
- import { EventEmitterImpl } from './services/EventEmitter';
14
- import { DependencyService } from './services/DependencyService';
15
-
16
- export class Tolgee {
17
- private dependencyService: DependencyService;
18
-
19
- private constructor() {
20
- this.dependencyService = new DependencyService();
21
- }
22
-
23
- get properties() {
24
- return this.dependencyService.properties;
25
- }
26
-
27
- public get lang() {
28
- return this.properties.currentLanguage;
29
- }
30
-
31
- /**
32
- * This sets a new language.
33
- *
34
- * Using this setter can behave buggy when you change languages
35
- * too fast, since it changes the language property before
36
- * translations are actually loaded.
37
- * @deprecated use asynchronous changeLanguage method.
38
- */
39
- public set lang(newLanguage) {
40
- this.properties.currentLanguage = newLanguage;
41
-
42
- this.dependencyService.translationService
43
- .loadTranslations(newLanguage)
44
- .then(() => {
45
- this.emitLangChangeEvent(newLanguage);
46
- });
47
- }
48
-
49
- public get defaultLanguage() {
50
- return this.properties.config.defaultLanguage;
51
- }
52
-
53
- public get onLangChange() {
54
- return this.dependencyService.eventService.LANGUAGE_CHANGED;
55
- }
56
-
57
- public get onTranslationChange() {
58
- return this.dependencyService.eventService.TRANSLATION_CHANGED;
59
- }
60
-
61
- /**
62
- * Is emitted when language is loaded for the first time
63
- */
64
- public get onLangLoaded() {
65
- return this.dependencyService.eventService.LANGUAGE_LOADED;
66
- }
67
-
68
- /**
69
- * True if loading is needed to wait for Tolgee init.
70
- * When translation data are provided statically (using import
71
- * as staticData config property) then there is no need for translation
72
- * fetching so initial loading is not needed at all.
73
- */
74
- get initialLoading(): boolean {
75
- const currentLang = this.properties.currentLanguage;
76
- const fallbackLang = this.properties.config.fallbackLanguage;
77
- const fallbackPreloading = this.properties.config.preloadFallback;
78
- const isStaticDataProvided = (data?: any) => {
79
- return data !== undefined && typeof data !== 'function';
80
- };
81
-
82
- return (
83
- !isStaticDataProvided(this.properties.config.staticData?.[currentLang]) ||
84
- (!!fallbackPreloading &&
85
- !isStaticDataProvided(
86
- this.properties.config.staticData?.[fallbackLang]
87
- ))
88
- );
89
- }
90
-
91
- private get coreService() {
92
- return this.dependencyService.coreService;
93
- }
94
-
95
- static use(module: TolgeeModule) {
96
- return new Tolgee().use(module);
97
- }
98
-
99
- static init(config: TolgeeConfig) {
100
- return new Tolgee().init(config);
101
- }
102
-
103
- /**
104
- * Sets the new language.
105
- *
106
- * Emits the onLangChange and onLangChangeAndLoad events after
107
- * the translations are loaded.
108
- *
109
- * @return Promise<void> Resolves when translations are loaded
110
- */
111
- public async changeLanguage(newLanguage: string): Promise<void> {
112
- await this.dependencyService.translationService.loadTranslations(
113
- newLanguage
114
- );
115
- this.properties.currentLanguage = newLanguage;
116
- this.emitLangChangeEvent(newLanguage);
117
- }
118
-
119
- use(module: TolgeeModule) {
120
- this.dependencyService.moduleService.addModule(module);
121
- return this;
122
- }
123
-
124
- init(config: TolgeeConfig) {
125
- this.dependencyService.init(config);
126
- const { apiKey, apiUrl } = this.dependencyService.properties.config;
127
- this.dependencyService.properties.mode =
128
- apiKey && apiUrl ? 'development' : 'production';
129
-
130
- return this;
131
- }
132
-
133
- public async run(): Promise<void> {
134
- this.dependencyService.run();
135
- if (this.properties.mode === 'development') {
136
- try {
137
- await this.coreService.loadApiKeyDetails();
138
- } catch (e) {
139
- // eslint-disable-next-line no-console
140
- console.error("Couldn't connect to Tolgee");
141
- // eslint-disable-next-line no-console
142
- console.error(e);
143
- this.properties.mode = 'production';
144
- }
145
- }
146
-
147
- await this.dependencyService.translationService.loadTranslations();
148
- await this.dependencyService.pluginManager.run();
149
-
150
- if (this.properties.config.preloadFallback) {
151
- await this.dependencyService.translationService.loadTranslations(
152
- this.properties.config.fallbackLanguage
153
- );
154
- }
155
-
156
- await this.refresh();
157
-
158
- if (this.properties.config.watch) {
159
- this.dependencyService.observer.observe();
160
- }
161
- }
162
-
163
- public async refresh() {
164
- return this.dependencyService.wrapper.handleSubtree(
165
- this.properties.config.targetElement
166
- );
167
- }
168
-
169
- async translate(props: TranslateProps): Promise<string>;
170
- async translate<T>(props: TranslatePropsTags<T>): Promise<TranslationTags<T>>;
171
-
172
- async translate(
173
- key: string,
174
- params?: TranslationParams,
175
- noWrap?: boolean,
176
- defaultValue?: string
177
- ): Promise<string>;
178
- async translate<T>(
179
- key: string,
180
- params?: TranslationParamsTags<T>,
181
- noWrap?: boolean,
182
- defaultValue?: string
183
- ): Promise<TranslationTags<T>>;
184
-
185
- async translate(
186
- keyOrProps: string | TranslatePropsTags<any>,
187
- params: TranslationParamsTags<any> = {},
188
- noWrap = false,
189
- defaultValue: string | undefined = undefined
190
- ): Promise<TranslationTags<any>> {
191
- const key = typeof keyOrProps === 'string' ? keyOrProps : keyOrProps.key;
192
- let orEmpty = undefined;
193
- if (typeof keyOrProps === 'object') {
194
- const props = keyOrProps as TranslateProps;
195
- // if values are not provided in props object, get them from function
196
- // params defaults
197
- params = props.params !== undefined ? props.params : params;
198
- noWrap = props.noWrap !== undefined ? props.noWrap : noWrap;
199
- defaultValue =
200
- props.defaultValue !== undefined ? props.defaultValue : defaultValue;
201
- orEmpty = props.orEmpty;
202
- }
203
-
204
- const translation = await this.dependencyService.textService.translate(
205
- key,
206
- params,
207
- undefined,
208
- orEmpty,
209
- defaultValue
210
- );
211
-
212
- if (this.properties.mode === 'development' && !noWrap) {
213
- await this.coreService.loadApiKeyDetails();
214
- return this.dependencyService.wrapper.wrap(
215
- key,
216
- params,
217
- defaultValue,
218
- translation
219
- );
220
- }
221
-
222
- return translation;
223
- }
224
-
225
- wrap(
226
- key: string,
227
- params?: TranslationParams,
228
- defaultValue?: string | undefined,
229
- translation?: string
230
- ): string;
231
- wrap<T>(
232
- key: string,
233
- params?: TranslationTags<T>,
234
- defaultValue?: string | undefined,
235
- translation?: TranslationTags<T>
236
- ): TranslationTags<T>;
237
-
238
- wrap(
239
- key: string,
240
- params?: any,
241
- defaultValue?: string | undefined,
242
- translation?: TranslationTags<any>
243
- ): TranslationTags<any> {
244
- if (this.properties.mode === 'development') {
245
- return this.dependencyService.wrapper.wrap(
246
- key,
247
- params,
248
- defaultValue,
249
- translation
250
- );
251
- } else {
252
- return translation || defaultValue;
253
- }
254
- }
255
-
256
- instant(
257
- key: string,
258
- params?: TranslationParams,
259
- noWrap?: boolean,
260
- orEmpty?: boolean,
261
- defaultValue?: string
262
- ): string;
263
- instant<T>(
264
- key: string,
265
- params?: TranslationParamsTags<T>,
266
- noWrap?: boolean,
267
- orEmpty?: boolean,
268
- defaultValue?: string
269
- ): TranslationTags<T>;
270
-
271
- instant(props: InstantProps): string;
272
- instant<T>(props: InstantPropsTags<T>): TranslationTags<T>;
273
-
274
- instant(
275
- keyOrProps: string | InstantPropsTags<any>,
276
- params: TranslationParams = {},
277
- noWrap = false,
278
- orEmpty?: boolean,
279
- defaultValue?: string
280
- ) {
281
- const key = typeof keyOrProps === 'string' ? keyOrProps : keyOrProps.key;
282
- if (typeof keyOrProps === 'object') {
283
- const props = keyOrProps as InstantProps;
284
- // if values are not provided in props object, get them from function
285
- // params defaults
286
- params = props.params !== undefined ? props.params : params;
287
- noWrap = props.noWrap !== undefined ? props.noWrap : noWrap;
288
- defaultValue =
289
- props.defaultValue !== undefined ? props.defaultValue : defaultValue;
290
- orEmpty = props.orEmpty !== undefined ? props.orEmpty : orEmpty;
291
- }
292
-
293
- const translation = this.dependencyService.textService.instant(
294
- key,
295
- params,
296
- undefined,
297
- orEmpty,
298
- defaultValue
299
- );
300
-
301
- if (this.properties.mode === 'development' && !noWrap) {
302
- return this.dependencyService.wrapper.wrap(
303
- key,
304
- params,
305
- defaultValue,
306
- translation
307
- );
308
- }
309
- return translation;
310
- }
311
-
312
- /**
313
- * Get currently cached translations for all languages
314
- */
315
- public getCachedTranslations() {
316
- return this.dependencyService.translationService.getCachedTranslations();
317
- }
318
-
319
- /**
320
- * Loads translations for given language or returns them from cache
321
- * @returns Loaded translations
322
- */
323
- public loadTranslations(lang: string) {
324
- return this.dependencyService.translationService.loadTranslations(lang);
325
- }
326
-
327
- public stop = () => {
328
- this.dependencyService.stop();
9
+ export const Tolgee = (options?: Partial<Options>): TolgeeInstance => {
10
+ const controller = Controller({
11
+ options,
12
+ });
13
+
14
+ const pluginTools = Object.freeze({
15
+ setFinalFormatter: controller.setFinalFormatter,
16
+ addFormatter: controller.addFormatter,
17
+ setObserver: controller.setObserver,
18
+ hasObserver: controller.hasObserver,
19
+ setUi: controller.setUi,
20
+ hasUi: controller.hasUi,
21
+ setDevBackend: controller.setDevBackend,
22
+ addBackend: controller.addBackend,
23
+ setLanguageDetector: controller.setLanguageDetector,
24
+ setLanguageStorage: controller.setLanguageStorage,
25
+ overrideCredentials: controller.overrideCredentials,
26
+ });
27
+
28
+ const withRestart = (callback: () => void) => {
29
+ const wasRunning = controller.isRunning();
30
+ wasRunning && controller.stop();
31
+ callback();
32
+ wasRunning && controller.run();
329
33
  };
330
34
 
331
- private emitLangChangeEvent(value: string) {
332
- const langChangedEmitter = this.onLangChange as EventEmitterImpl<any>;
333
- langChangedEmitter.emit(value);
334
- }
335
- }
35
+ const tolgee: TolgeeInstance = Object.freeze({
36
+ // event listeners
37
+ on: controller.on,
38
+ onKeyUpdate: controller.onKeyUpdate.listenSome,
39
+
40
+ // state
41
+ getLanguage: controller.getLanguage,
42
+ getPendingLanguage: controller.getPendingLanguage,
43
+ changeLanguage: controller.changeLanguage,
44
+ changeTranslation: controller.changeTranslation,
45
+ addActiveNs: controller.addActiveNs,
46
+ removeActiveNs: controller.removeActiveNs,
47
+ loadRecords: controller.loadRecords,
48
+ loadRecord: controller.loadRecord,
49
+ addStaticData: controller.addStaticData,
50
+ getRecord: controller.getRecord,
51
+ getAllRecords: controller.getAllRecords,
52
+ isLoaded: controller.isLoaded,
53
+ isInitialLoading: controller.isInitialLoading,
54
+ isLoading: controller.isLoading,
55
+ isFetching: controller.isFetching,
56
+ isRunning: controller.isRunning,
57
+ run: controller.run,
58
+ stop: controller.stop,
59
+ t: controller.t,
60
+ highlight: controller.highlight,
61
+ getInitialOptions: controller.getInitialOptions,
62
+ isDev: controller.isDev,
63
+ wrap: controller.wrap,
64
+ unwrap: controller.unwrap,
65
+
66
+ // plugins
67
+ setObserverOptions: (options: Partial<ObserverOptions>) => {
68
+ controller.setObserverOptions(options);
69
+ return tolgee;
70
+ },
71
+ use: (plugin: TolgeePlugin | undefined) => {
72
+ if (plugin) {
73
+ withRestart(() => plugin(tolgee, pluginTools));
74
+ }
75
+ return tolgee;
76
+ },
77
+ init: (options: Partial<Options>) => {
78
+ withRestart(() => controller.init(options));
79
+ return tolgee;
80
+ },
81
+ });
82
+
83
+ return tolgee;
84
+ };
@@ -0,0 +1,41 @@
1
+ import { getTranslateParams } from './TranslateParams';
2
+ import { TranslateProps } from './types';
3
+
4
+ const testParams: TranslateProps = {
5
+ key: 'test',
6
+ defaultValue: 'Test',
7
+ noWrap: true,
8
+ ns: [],
9
+ orEmpty: true,
10
+ params: { yo: 'yo', ns: '(this is param not namespace)' },
11
+ };
12
+
13
+ describe('getTranslateParams', () => {
14
+ it('manages regular params', () => {
15
+ const result = getTranslateParams(testParams);
16
+ expect(result).toEqual(testParams);
17
+ });
18
+
19
+ it('manages key with default value', () => {
20
+ const result = getTranslateParams('test', 'Test');
21
+ expect(result).toEqual({ key: 'test', defaultValue: 'Test' });
22
+ });
23
+
24
+ it('manages key with options', () => {
25
+ const result = getTranslateParams('test', { noWrap: true, yo: 'yo' });
26
+ expect(result).toEqual({ key: 'test', noWrap: true, params: { yo: 'yo' } });
27
+ });
28
+
29
+ it('manages key default and options', () => {
30
+ const result = getTranslateParams('test', 'Test', {
31
+ noWrap: true,
32
+ ns: [],
33
+ orEmpty: true,
34
+ yo: 'yo',
35
+ params: {
36
+ ns: '(this is param not namespace)',
37
+ },
38
+ });
39
+ expect(result).toEqual(testParams);
40
+ });
41
+ });