-
Notifications
You must be signed in to change notification settings - Fork 0
/
i18n.js
344 lines (251 loc) · 8.13 KB
/
i18n.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
/**
* @license MIT
* cinetech (muvisho)
* Copyright (c) 2023 Abraham Ukachi. The Muvisho Project Contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @project cinetech (muvisho)
* @name I18n (internationalization) - Helper
* @file src/helpers/i18n.php
* @author: Abraham Ukachi <[email protected]>
* @version: 0.0.1
*
* Usage:
* 1+|> // import the I18n class
* -|>
* -|> import I18n from './helpers/i18n';
*
*
*
* 2+|> // create an instance of the I18n class
* -|>
* -|> let i18n = new I18n('fr'); // <- using the french language (i.e. 'fr')
*
*
*
* 3+|> // get the string value of a given key, say 'hello'
* -|>
* -|> let hello = i18n.getString('hello');
* -|> console.log(hello); // <- 'Bonjour'
*
*
*/
"use strict"; // <- use strict mode
// define some constants
const DEFAULT_LANG = 'en';
const LANGS = ['en', 'fr', 'ru', 'es']; // <- currently supported languages
// paths
const ASSETS_PATH = 'root/public/assets/';
const LOCALE_PATH = ASSETS_PATH + 'locale/';
const STRINGS_PATH = LOCALE_PATH + 'strings/';
const NUMBERS_PATH = LOCALE_PATH + 'numbers/';
const ARRAYS_PATH = LOCALE_PATH + 'arrays/';
// TODO: Handle the case where import fails
/*
* Define the Internationalization class as `I18n`
*
* Example usage:
* const i18n = new I18n('fr');
* let str = i18n.getString('hello'); // <- 'Bonjour'
*/
class I18n {
// protected properties
#strings = [];
#numbers = [];
#arrays = [];
// public properties
// private properties
_stringsLoaded = false;
_numbersLoaded = false;
_arraysLoaded = false;
/*
* Constructor of the I18n class
* This method will be called automatically when an instace of the class is created
*
* @param { String } lang - the language to use
*/
constructor(lang = DEFAULT_LANG) {
// initialize the `lang` property
this.lang = lang;
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(`\x1b[30m[__constructor]: I'm in the constructor of the class I18n\x1b[0m`);
// this._loadData(lang);
}
// PUBLIC SETTERS
/**
* Sets the language to use
*
* @param { String } lang - the language to use
*/
set lang(value) {
// check if the language is supported
if (!LANGS.includes(value)) {
throw new Error(`The language ${value} is not supported`);
}
// set the language
this._lang = value;
// load the required / corresponding data (i.e. strings, numbers and arrays)
this._loadData(value);
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(`\x1b[32m[lang]: lang has been set to ${value}\x1b[0m`);
}
// PUBLIC GETTERS
/**
* Returns the language currently used
*
* @returns { String }
*/
get lang() {
return this._lang;
}
// PUBLIC METHODS
/**
* Handler that is called when the data is loaded
*
* @param { Object } data - the data that has been loaded (e.g. { hello: 'Bonjour' })
*/
dataLoaded(data) {}
/**
* Method used to get the string value of the given `key`
*
* @param { String } key - the key of the string to get
* @returns { String } - the string value of the given `key`
*/
getString(key) {
return this.#strings[key];
}
/**
* Method used to get the number value of the given `key`
*
* @param { String } key - the key of the number to get
* @returns { String } - the number value of the given `key`
*/
getNumber(key) {
return this.#numbers[key];
}
/**
* Method used to get the array value of the given `key`
*
* @param { String } key - the key of the array to get
* @returns { String } - the array value of the given `key`
*/
getArray(key) {
return this.#arrays[key];
}
/**
* Returns the list of supported languages
*
* @returns { Array[Object] } - the list of supported languages and their corresponding names
*/
getSupportedLanguages() {
return LANGS.map((lang) => {
return {lang: lang, name: this.getString(lang)}
});
}
// PRIVATE SETTERS
// PRIVATE GETTERS
// PRIVATE METHODS
/**
* Method used to load all the string, number and array data for the given `lang`
*
* @param { String } lang - the language to use
* @private
*/
async _loadData(lang = this.lang) {
// load the strings data
let stringsData = await this._loadStringsData(lang);
// load the numbers data
let numbersData = await this._loadNumbersData(lang);
// load the arrays data
let arraysData = await this._loadArraysData(lang);
// call the `dataLoaded` method
this.dataLoaded({stringsData, numbersData, arraysData});
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(`\x1b[35m[_loadData]: Data has been loaded appName is ${this.getString('appName')}\x1b[0m`);
}
/**
* Method used to load the strings data for the given `lang`
*
* @param { String } lang - the language to use
* @returns { Object } - the strings data
* @private
*/
async _loadStringsData(lang = this.lang) {
// set `_stringsLoaded` to `false`
this._stringsLoaded = false;
// dynamically import the corresponding strings data / JSON file
//let response = await import(STRINGS_PATH + lang + '.json');
let response = await fetch(STRINGS_PATH + lang + '.json');
let stringsData = await response.json();
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(stringsData);
// load the strings data, and update the `#strings` property
this.#strings = stringsData;
// set `_stringsLoaded` to `true`
this._stringsLoaded = true;
// return the `stringsData`
return stringsData;
}
/**
* Method used to load the numbers data for the given `lang`
*
* @param { String } lang - the language to use
* @private
*/
async _loadNumbersData(lang = this.lang) {
// set `_numbersLoaded` to `false`
this._numbersLoaded = false;
// dynamically import the corresponding numbers data / JSON file
let response = await fetch(NUMBERS_PATH + lang + '.json');
let numbersData = await response.json();
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(numbersData);
// load the numbers data, and update the `#numbers` property
this.#numbers = numbersData;
// set `_numbersLoaded` to `true`
this._numbersLoaded = true;
// return the `numbersData`
return numbersData;
}
/**
* Method used to load the arrays data for the given `lang`
*
* @param { String } lang - the language to use
* @private
*/
async _loadArraysData(lang = this.lang) {
// set `_arraysLoaded` to `false`
this._arraysLoaded = false;
// dynamically import the corresponding arrays data / JSON file
let response = await fetch(ARRAYS_PATH + lang + '.json');
let arraysData = await response.json();
// DEBUG [4dbsmaster]: tell me about it ;)
console.log(arraysData);
// load the arrays data, and update the `#arrays` property
this.#arrays = arraysData;
// set `_arraysLoaded` to `true`
this._arraysLoaded = true;
// return the `arraysData`
return arraysData;
}
};
// export the I18n class as default
// so that we can import it in other files
export default I18n;