not-locale 0.0.19 → 0.0.20
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 +3 -3
- package/src/common/lib.js +80 -73
- package/src/controllers/common/nsLocale.js +53 -47
- package/src/routes/locale.manifest.js +2 -2
- package/src/routes/locale.ws.js +4 -4
- package/test/index.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "not-locale",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "not-* family module for localization in not- environment",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/interrupter/not-locale#readme",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"not-log": "^0.0.
|
|
27
|
+
"not-log": "^0.0.20",
|
|
28
28
|
"not-path": "^1.0.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"chai": "*",
|
|
32
32
|
"chai-as-promised": "*",
|
|
33
|
-
"eslint": "^8.0
|
|
33
|
+
"eslint": "^8.3.0",
|
|
34
34
|
"ink-docstrap": "^1.3.2",
|
|
35
35
|
"jsdoc": "^3.6.7",
|
|
36
36
|
"mocha": "*",
|
package/src/common/lib.js
CHANGED
|
@@ -15,37 +15,37 @@ var store = {},
|
|
|
15
15
|
getter: null
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
next();
|
|
18
|
+
/**
|
|
19
|
+
* Express middleware, to determine in which locale should we process response
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
function detect(req, res, next) {
|
|
23
|
+
let reqLang;
|
|
24
|
+
if (OPTS.getter) {
|
|
25
|
+
reqLang = OPTS.getter(req);
|
|
26
|
+
} else {
|
|
27
|
+
reqLang = req.get('Accept-Language');
|
|
28
|
+
}
|
|
29
|
+
if (Object.prototype.hasOwnProperty.call(store, reqLang)) {
|
|
30
|
+
res.locals.locale = reqLang;
|
|
31
|
+
} else {
|
|
32
|
+
res.locals.locale = OPTS.default;
|
|
35
33
|
}
|
|
34
|
+
next();
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Express middleware initializer, to determine in which locale should we process response
|
|
39
|
+
* @param {object} options - object with `deafult` {string}, `getter` {function} redefined
|
|
40
|
+
* @return {function} function wich will accept three params (req, res, next) and run as express middleware
|
|
41
|
+
*/
|
|
42
42
|
|
|
43
|
-
exports.getMiddleware = (options)=>{
|
|
44
|
-
if (options){
|
|
45
|
-
if (options.default && options.default.length > 1){
|
|
43
|
+
exports.getMiddleware = (options) => {
|
|
44
|
+
if (options) {
|
|
45
|
+
if (options.default && options.default.length > 1) {
|
|
46
46
|
OPTS.default = options.default;
|
|
47
47
|
}
|
|
48
|
-
if (options.getter && typeof options.getter === 'function'){
|
|
48
|
+
if (options.getter && typeof options.getter === 'function') {
|
|
49
49
|
OPTS.getter = options.getter;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -54,12 +54,12 @@ exports.getMiddleware = (options)=>{
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
exports.fromJSON = (locale, json, prefix = '')=>{
|
|
62
|
-
if(prefix){
|
|
57
|
+
* Add locale by json object
|
|
58
|
+
* @param {string} locale - name of locale
|
|
59
|
+
* @param {json} json - json object
|
|
60
|
+
*/
|
|
61
|
+
exports.fromJSON = (locale, json, prefix = '') => {
|
|
62
|
+
if (prefix) {
|
|
63
63
|
let tmp = {};
|
|
64
64
|
const keys = Object.keys(json);
|
|
65
65
|
keys.forEach((key) => {
|
|
@@ -67,36 +67,36 @@ exports.fromJSON = (locale, json, prefix = '')=>{
|
|
|
67
67
|
});
|
|
68
68
|
json = tmp;
|
|
69
69
|
}
|
|
70
|
-
if (typeof store[locale] !== 'undefined'){
|
|
70
|
+
if (typeof store[locale] !== 'undefined') {
|
|
71
71
|
store[locale] = Object.assign(store[locale], json);
|
|
72
|
-
}else{
|
|
72
|
+
} else {
|
|
73
73
|
store[locale] = Object.assign({}, json);
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
exports.fromDir = (pathToLocales, prefix = '')=>{
|
|
83
|
-
return new Promise((resolve, reject)=>{
|
|
78
|
+
* Load locales from directory, with json files, names as [locale_name].json
|
|
79
|
+
* @param {number} pathToLocales - absolute path to directory
|
|
80
|
+
* @return {Promise}
|
|
81
|
+
*/
|
|
82
|
+
exports.fromDir = (pathToLocales, prefix = '') => {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
84
|
fs.readdir(pathToLocales, (err, items) => {
|
|
85
|
-
if (err){
|
|
85
|
+
if (err) {
|
|
86
86
|
reject(err);
|
|
87
|
-
}else{
|
|
88
|
-
for(let i = 0; i < items.length; i++) {
|
|
87
|
+
} else {
|
|
88
|
+
for (let i = 0; i < items.length; i++) {
|
|
89
89
|
let filename = path.join(pathToLocales, items[i]),
|
|
90
90
|
stats = fs.lstatSync(filename);
|
|
91
|
-
if (stats.isFile()){
|
|
92
|
-
try{
|
|
91
|
+
if (stats.isFile()) {
|
|
92
|
+
try {
|
|
93
93
|
let file = require(filename),
|
|
94
94
|
[localeName] = items[i].split('.');
|
|
95
95
|
exports.fromJSON(localeName, file, prefix);
|
|
96
|
-
}catch(e){
|
|
96
|
+
} catch (e) {
|
|
97
97
|
Log.error(e);
|
|
98
98
|
}
|
|
99
|
-
}else{
|
|
99
|
+
} else {
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -107,56 +107,63 @@ exports.fromDir = (pathToLocales, prefix = '')=>{
|
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
function say(phrase, params = {}, locale = OPTS.default){
|
|
116
|
-
try{
|
|
110
|
+
* Returns localized variant of code phrase
|
|
111
|
+
* @param {string} phrase - code phrase
|
|
112
|
+
* @param {array|object} params - array or hash with params for template parser
|
|
113
|
+
* @return {string} localized variant
|
|
114
|
+
*/
|
|
115
|
+
function say(phrase, params = {}, locale = OPTS.default) {
|
|
116
|
+
try {
|
|
117
117
|
let tmpl = store[locale][phrase],
|
|
118
118
|
result = '';
|
|
119
|
-
if (
|
|
119
|
+
if (typeof tmpl === 'undefined') {
|
|
120
|
+
return phrase;
|
|
121
|
+
}
|
|
122
|
+
if (params) {
|
|
120
123
|
return notPath.parseSubs(tmpl, params, {});
|
|
121
|
-
}else{
|
|
124
|
+
} else {
|
|
122
125
|
result = tmpl;
|
|
123
126
|
}
|
|
124
127
|
return result;
|
|
125
|
-
}catch(e){
|
|
128
|
+
} catch (e) {
|
|
126
129
|
Log.error(e);
|
|
127
130
|
}
|
|
128
|
-
}
|
|
131
|
+
}
|
|
129
132
|
|
|
130
|
-
exports.say = say
|
|
133
|
+
exports.say = say;
|
|
131
134
|
|
|
132
135
|
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
exports.vocabulary = () => {
|
|
136
|
+
* Getter for stores of all locales
|
|
137
|
+
* @return {objects} all locales
|
|
138
|
+
*/
|
|
139
|
+
exports.vocabulary = () => {
|
|
140
|
+
return store;
|
|
141
|
+
};
|
|
137
142
|
|
|
138
143
|
/**
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
exports.OPTS = () => {
|
|
144
|
+
* Getter for OPTS variable
|
|
145
|
+
* @return {object} copy of OPTS object
|
|
146
|
+
*/
|
|
147
|
+
exports.OPTS = () => {
|
|
148
|
+
return Object.assign({}, OPTS);
|
|
149
|
+
};
|
|
143
150
|
|
|
144
151
|
|
|
145
|
-
exports.get = (locale)=>{
|
|
146
|
-
if(Object.prototype.hasOwnProperty.call(store, locale)){
|
|
152
|
+
exports.get = (locale) => {
|
|
153
|
+
if (Object.prototype.hasOwnProperty.call(store, locale)) {
|
|
147
154
|
return store[locale];
|
|
148
|
-
}else{
|
|
155
|
+
} else {
|
|
149
156
|
return {};
|
|
150
157
|
}
|
|
151
158
|
};
|
|
152
159
|
|
|
153
160
|
|
|
154
|
-
exports.available = ()=>{
|
|
161
|
+
exports.available = () => {
|
|
155
162
|
return Object.keys(store);
|
|
156
163
|
};
|
|
157
164
|
|
|
158
165
|
|
|
159
|
-
function modulePhrase(moduleName = ''){
|
|
166
|
+
function modulePhrase(moduleName = '') {
|
|
160
167
|
return (phrase) => [moduleName, phrase].join(':');
|
|
161
168
|
}
|
|
162
169
|
|
|
@@ -169,5 +176,5 @@ exports.sayForModule = (moduleName = '') => {
|
|
|
169
176
|
params,
|
|
170
177
|
locale
|
|
171
178
|
);
|
|
172
|
-
}
|
|
179
|
+
};
|
|
173
180
|
};
|
|
@@ -1,75 +1,81 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* detects current locale, loads dictionary from server
|
|
3
|
-
*
|
|
4
|
-
**/
|
|
2
|
+
* detects current locale, loads dictionary from server
|
|
3
|
+
*
|
|
4
|
+
**/
|
|
5
5
|
|
|
6
6
|
const SECTION_ID = 'locale';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
notCommon,
|
|
10
|
+
notLocale,
|
|
11
|
+
TopMenu
|
|
12
|
+
} from 'not-bulma';
|
|
9
13
|
|
|
10
|
-
class nsLocale{
|
|
11
|
-
constructor(app){
|
|
14
|
+
class nsLocale {
|
|
15
|
+
constructor(app) {
|
|
12
16
|
this.app = app;
|
|
13
17
|
this.locales = [];
|
|
14
18
|
this.failures = 0;
|
|
15
19
|
this.app.on('wsClient:main:connected', this.update.bind(this));
|
|
16
|
-
notLocale.on('change', ()=>{
|
|
20
|
+
notLocale.on('change', () => {
|
|
17
21
|
this.app.emit('locale');
|
|
18
22
|
});
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
interface(data){
|
|
26
|
+
* Creates network interface for this service
|
|
27
|
+
*/
|
|
28
|
+
interface(data) {
|
|
25
29
|
return this.app.getInterface('locale')(data);
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
async update(){
|
|
33
|
-
try{
|
|
33
|
+
* Retrieves dictionary for current locale
|
|
34
|
+
* sets dictionary in notLocale object
|
|
35
|
+
*/
|
|
36
|
+
async update() {
|
|
37
|
+
try {
|
|
34
38
|
await this.updateAvailable();
|
|
35
|
-
let res = await this.interface({
|
|
36
|
-
|
|
39
|
+
let res = await this.interface({
|
|
40
|
+
locale: this.getCurrentLocale()
|
|
41
|
+
}).$get({});
|
|
42
|
+
if (res.status === 'ok' && res.result) {
|
|
37
43
|
notLocale.set(res.result);
|
|
38
|
-
}else{
|
|
44
|
+
} else {
|
|
39
45
|
this.scheduleUpdate();
|
|
40
46
|
}
|
|
41
|
-
}catch(e){
|
|
47
|
+
} catch (e) {
|
|
42
48
|
notCommon.error(e);
|
|
43
49
|
this.scheduleUpdate();
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
scheduleUpdate(){
|
|
53
|
+
scheduleUpdate() {
|
|
48
54
|
this.failures++;
|
|
49
|
-
if(this.failures < 100){
|
|
55
|
+
if (this.failures < 100) {
|
|
50
56
|
setTimeout(this.update.bind(this), 1000 * this.failures);
|
|
51
|
-
}else{
|
|
57
|
+
} else {
|
|
52
58
|
notCommon.error('Too many failures of locale loading');
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
async updateAvailable(){
|
|
57
|
-
try{
|
|
62
|
+
async updateAvailable() {
|
|
63
|
+
try {
|
|
58
64
|
let res = await this.interface({}).$available({});
|
|
59
|
-
if(res.status === 'ok' && res.result){
|
|
65
|
+
if (res.status === 'ok' && res.result) {
|
|
60
66
|
this.setAvailable(res.result);
|
|
61
67
|
}
|
|
62
|
-
}catch(e){
|
|
68
|
+
} catch (e) {
|
|
63
69
|
notCommon.error(e);
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
updateUI(list){
|
|
73
|
+
updateUI(list) {
|
|
68
74
|
let menuItems = this.createMenuItems(list);
|
|
69
75
|
TopMenu.updateSectionItems(SECTION_ID, () => {
|
|
70
76
|
return menuItems;
|
|
71
77
|
});
|
|
72
|
-
setTimeout(()=>{
|
|
78
|
+
setTimeout(() => {
|
|
73
79
|
this.app.emit(`tag-${SECTION_ID}:update`, {
|
|
74
80
|
title: this.getCurrentLocale()
|
|
75
81
|
});
|
|
@@ -91,18 +97,18 @@ class nsLocale{
|
|
|
91
97
|
};
|
|
92
98
|
}
|
|
93
99
|
|
|
94
|
-
changeLocale(locale){
|
|
100
|
+
changeLocale(locale) {
|
|
95
101
|
this.saveLocaleToStore(locale);
|
|
96
102
|
this.update();
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
getCurrentLocale(){
|
|
106
|
+
* @returns {string} code of current locale
|
|
107
|
+
**/
|
|
108
|
+
getCurrentLocale() {
|
|
103
109
|
let stored = this.restoreLocaleFromStore();
|
|
104
|
-
if (stored){
|
|
105
|
-
if(this.locales.includes(stored)){
|
|
110
|
+
if (stored) {
|
|
111
|
+
if (this.locales.includes(stored)) {
|
|
106
112
|
return stored;
|
|
107
113
|
}
|
|
108
114
|
}
|
|
@@ -110,22 +116,22 @@ class nsLocale{
|
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
getAvailable(){
|
|
119
|
+
* @returns {Promise<Array>} of locales objects {code, title}
|
|
120
|
+
**/
|
|
121
|
+
getAvailable() {
|
|
116
122
|
return this.interface().$available({});
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
|
|
120
|
-
setAvailable(list){
|
|
126
|
+
setAvailable(list) {
|
|
121
127
|
this.locales = list;
|
|
122
128
|
this.updateUI(list);
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
restoreLocaleFromStore(){
|
|
131
|
+
restoreLocaleFromStore() {
|
|
126
132
|
if (window.localStorage) {
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
try {
|
|
134
|
+
return window.localStorage.getItem('locale');
|
|
129
135
|
} catch (e) {
|
|
130
136
|
this.app.error(e);
|
|
131
137
|
return false;
|
|
@@ -134,10 +140,10 @@ class nsLocale{
|
|
|
134
140
|
return false;
|
|
135
141
|
}
|
|
136
142
|
|
|
137
|
-
saveLocaleToStore(locale){
|
|
143
|
+
saveLocaleToStore(locale) {
|
|
138
144
|
if (window.localStorage) {
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
try {
|
|
146
|
+
return window.localStorage.setItem('locale', locale);
|
|
141
147
|
} catch (e) {
|
|
142
148
|
this.app.error(e);
|
|
143
149
|
return false;
|
|
@@ -146,12 +152,12 @@ class nsLocale{
|
|
|
146
152
|
return false;
|
|
147
153
|
}
|
|
148
154
|
|
|
149
|
-
selectBest(){
|
|
150
|
-
if(navigator.languages){
|
|
155
|
+
selectBest() {
|
|
156
|
+
if (navigator.languages) {
|
|
151
157
|
let locale = navigator.languages.find((itm) => {
|
|
152
158
|
return this.locales.includes(itm);
|
|
153
159
|
});
|
|
154
|
-
if(locale){
|
|
160
|
+
if (locale) {
|
|
155
161
|
return locale;
|
|
156
162
|
}
|
|
157
163
|
}
|
package/src/routes/locale.ws.js
CHANGED
package/test/index.js
CHANGED