@ecopex/ecopex-framework 1.0.12 → 1.0.13
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/package.json +1 -1
- package/routes/auto/handler.js +1 -1
- package/utils/i18n.js +74 -20
- package/utils/middleware.js +4 -6
package/package.json
CHANGED
package/routes/auto/handler.js
CHANGED
|
@@ -542,7 +542,7 @@ const checkUnique = async (value = null, field_name = null, tableName = null) =>
|
|
|
542
542
|
const sqlErrorHandler = (error, request, reply) => {
|
|
543
543
|
return reply.status(500).send({
|
|
544
544
|
status: false,
|
|
545
|
-
message: i18n.t('sql.' + error.code.toLowerCase(),
|
|
545
|
+
message: i18n.t('sql.' + error.code.toLowerCase(), {...request.body, ...request.query, ...request.params})
|
|
546
546
|
});
|
|
547
547
|
}
|
|
548
548
|
|
package/utils/i18n.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const { config } = require('../stores/config');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Internationalization utility for multi-language support
|
|
@@ -7,8 +8,10 @@ const path = require('path');
|
|
|
7
8
|
class I18n {
|
|
8
9
|
constructor() {
|
|
9
10
|
this.locales = {};
|
|
10
|
-
this.defaultLocale = 'en';
|
|
11
|
-
this.supportedLocales = ['en'
|
|
11
|
+
this.defaultLocale = config.default_language || 'en';
|
|
12
|
+
this.supportedLocales = config.supported_languages || ['en'];
|
|
13
|
+
this.localesPath = path.join(__dirname, '../locales');
|
|
14
|
+
this.localesBackend = path.join('./locales');
|
|
12
15
|
this.loadLocales();
|
|
13
16
|
}
|
|
14
17
|
|
|
@@ -16,10 +19,8 @@ class I18n {
|
|
|
16
19
|
* Load all locale files
|
|
17
20
|
*/
|
|
18
21
|
loadLocales() {
|
|
19
|
-
const localesPath = path.join(__dirname, '../locales');
|
|
20
|
-
|
|
21
22
|
for (const locale of this.supportedLocales) {
|
|
22
|
-
const localePath = path.join(localesPath, locale);
|
|
23
|
+
const localePath = path.join(this.localesPath, locale);
|
|
23
24
|
if (fs.existsSync(localePath)) {
|
|
24
25
|
this.locales[locale] = {};
|
|
25
26
|
|
|
@@ -34,7 +35,24 @@ class I18n {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
}
|
|
38
|
+
|
|
39
|
+
const localesBackend = path.join(this.localesBackend, locale);
|
|
40
|
+
if (fs.existsSync(localesBackend)) {
|
|
41
|
+
const files = fs.readdirSync(localesBackend);
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
if (file.endsWith('.json')) {
|
|
44
|
+
const filePath = path.join(localesBackend, file);
|
|
45
|
+
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
46
|
+
const key = file.replace('.json', '');
|
|
47
|
+
if(!this.locales[locale][key]) {
|
|
48
|
+
this.locales[locale][key] = {};
|
|
49
|
+
}
|
|
50
|
+
this.locales[locale][key] = { ...this.locales[locale][key], ...content };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
37
54
|
}
|
|
55
|
+
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
/**
|
|
@@ -47,25 +65,40 @@ class I18n {
|
|
|
47
65
|
t(key, locale = this.defaultLocale, params = {}) {
|
|
48
66
|
const keys = key.split('.');
|
|
49
67
|
let translation = this.locales[locale] || this.locales[this.defaultLocale];
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
const fileName = keys.length > 0 ? keys[0] : 'index';
|
|
69
|
+
|
|
70
|
+
if(!translation[fileName]) {
|
|
71
|
+
translation[fileName] = {};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if(keys.length > 1) {
|
|
75
|
+
for(const k of keys.slice(1)) {
|
|
76
|
+
if(translation[fileName] && translation[fileName][k] !== undefined) {
|
|
77
|
+
translation = translation[fileName][k];
|
|
78
|
+
} else {
|
|
79
|
+
translation = this.locales[this.defaultLocale];
|
|
80
|
+
if(translation[fileName] && translation[fileName][k] !== undefined) {
|
|
81
|
+
translation = translation[fileName][k];
|
|
61
82
|
} else {
|
|
62
|
-
|
|
83
|
+
this.writeFile(key, locale, params);
|
|
84
|
+
return key;
|
|
63
85
|
}
|
|
64
86
|
}
|
|
65
|
-
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
if(translation[fileName] && translation[fileName][keys[0]] !== undefined) {
|
|
90
|
+
translation = translation[fileName][keys[0]];
|
|
91
|
+
} else {
|
|
92
|
+
translation = this.locales[this.defaultLocale];
|
|
93
|
+
if(translation[fileName] && translation[fileName][keys[0]] !== undefined) {
|
|
94
|
+
translation = translation[fileName][keys[0]];
|
|
95
|
+
} else {
|
|
96
|
+
this.writeFile(key, locale, params);
|
|
97
|
+
return key;
|
|
98
|
+
}
|
|
66
99
|
}
|
|
67
100
|
}
|
|
68
|
-
|
|
101
|
+
|
|
69
102
|
// Replace parameters in the translation
|
|
70
103
|
if (typeof translation === 'string') {
|
|
71
104
|
return this.replaceParams(translation, params);
|
|
@@ -74,6 +107,27 @@ class I18n {
|
|
|
74
107
|
return key;
|
|
75
108
|
}
|
|
76
109
|
|
|
110
|
+
writeFile(key, locale, params) {
|
|
111
|
+
const keys = key.split('.');
|
|
112
|
+
const fileName = keys.length > 1 ? keys[0] : 'index'
|
|
113
|
+
|
|
114
|
+
if(!this.locales[locale]) {
|
|
115
|
+
this.locales[locale] = {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let translations = this.locales[locale][fileName] || {};
|
|
119
|
+
|
|
120
|
+
const paramsString = Object.entries(params).map(([key, value]) => `{ ${key} }`).join(', ');
|
|
121
|
+
|
|
122
|
+
if(keys.slice(1).length > 0) {
|
|
123
|
+
translations[keys.slice(1).join('.')] = (paramsString ? paramsString : '');
|
|
124
|
+
} else {
|
|
125
|
+
translations[keys[0]] = (paramsString ? paramsString : '');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fs.writeFileSync(path.join(this.localesBackend, locale, `${fileName}.json`), JSON.stringify(translations, null, 4));
|
|
129
|
+
}
|
|
130
|
+
|
|
77
131
|
/**
|
|
78
132
|
* Replace parameters in translation string
|
|
79
133
|
* @param {string} str - String with parameters
|
|
@@ -160,7 +214,7 @@ class I18n {
|
|
|
160
214
|
enum: params?.allowedValues ? params.allowedValues.join(', ') : ''
|
|
161
215
|
};
|
|
162
216
|
|
|
163
|
-
return this.t(errorKey,
|
|
217
|
+
return this.t(errorKey, errorParams);
|
|
164
218
|
}
|
|
165
219
|
|
|
166
220
|
/**
|
package/utils/middleware.js
CHANGED
|
@@ -15,7 +15,7 @@ class Middleware {
|
|
|
15
15
|
|
|
16
16
|
// Add locale to request object
|
|
17
17
|
request.locale = locale;
|
|
18
|
-
request.t = (key, params = {}) => i18n.t(key,
|
|
18
|
+
request.t = (key, params = {}) => i18n.t(key, params, locale);
|
|
19
19
|
|
|
20
20
|
// Add locale to reply headers
|
|
21
21
|
reply.header('Content-Language', locale);
|
|
@@ -30,8 +30,6 @@ class Middleware {
|
|
|
30
30
|
if(config.development) {
|
|
31
31
|
console.log(error);
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
const locale = request.locale || i18n.detectLanguage(request);
|
|
35
33
|
|
|
36
34
|
if(error.data?.sqlMessage) {
|
|
37
35
|
return sqlErrorHandler(error, request, reply);
|
|
@@ -43,13 +41,13 @@ class Middleware {
|
|
|
43
41
|
const field_name = err.instancePath?.replace('/', '') || err.dataPath?.replace('/', '') || err.params?.missingProperty || 'field'
|
|
44
42
|
return {
|
|
45
43
|
field: field_name,
|
|
46
|
-
message: i18n.t('validation.' + err.keyword,
|
|
44
|
+
message: i18n.t('validation.' + err.keyword, { field: i18n.t('validation.fields.' + field_name) })
|
|
47
45
|
}
|
|
48
46
|
});
|
|
49
47
|
|
|
50
48
|
return reply.status(400).send({
|
|
51
49
|
status: false,
|
|
52
|
-
message: i18n.t('validation.errors.validation'
|
|
50
|
+
message: i18n.t('validation.errors.validation'),
|
|
53
51
|
details: validationErrors,
|
|
54
52
|
code: 400
|
|
55
53
|
});
|
|
@@ -145,7 +143,7 @@ class Middleware {
|
|
|
145
143
|
const sqlErrorHandler = (error, request, reply) => {
|
|
146
144
|
return reply.status(500).send({
|
|
147
145
|
status: false,
|
|
148
|
-
message: i18n.t('sql.' + error.data.code.toLowerCase(),
|
|
146
|
+
message: i18n.t('sql.' + error.data.code.toLowerCase(), {...request.body, ...request.query, ...request.params})
|
|
149
147
|
});
|
|
150
148
|
}
|
|
151
149
|
|