@things-factory/i18n-base 4.0.4 → 4.0.9
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/dist-server/middlewares/index.js +3 -3
- package/dist-server/middlewares/index.js.map +1 -1
- package/dist-server/middlewares/koa-i18next/detect.js +100 -0
- package/dist-server/middlewares/koa-i18next/detect.js.map +1 -0
- package/dist-server/middlewares/koa-i18next/index.js +131 -0
- package/dist-server/middlewares/koa-i18next/index.js.map +1 -0
- package/package.json +6 -7
- package/server/middlewares/index.ts +2 -3
- package/server/middlewares/koa-i18next/detect.ts +110 -0
- package/server/middlewares/koa-i18next/index.ts +139 -0
|
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.initMiddlewares = void 0;
|
|
7
|
-
const i18next_1 = __importDefault(require("i18next"));
|
|
8
7
|
const translations_1 = require("./translations");
|
|
9
8
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const
|
|
9
|
+
const i18next_1 = __importDefault(require("i18next"));
|
|
10
|
+
const koa_i18next_1 = __importDefault(require("./koa-i18next"));
|
|
11
11
|
const debug = require('debug')('things-factory:i18n-base:middlewares');
|
|
12
12
|
i18next_1.default.init({
|
|
13
13
|
debug: false,
|
|
@@ -29,7 +29,7 @@ process.on('client-rebuilt', (app, fs) => {
|
|
|
29
29
|
(0, translations_1.build)(fs);
|
|
30
30
|
});
|
|
31
31
|
function initMiddlewares(app) {
|
|
32
|
-
app.use(
|
|
32
|
+
app.use((0, koa_i18next_1.default)(i18next_1.default, {
|
|
33
33
|
lookupCookie: 'i18next',
|
|
34
34
|
order: ['cookie', 'header'],
|
|
35
35
|
next: true // if koa is version 2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/middlewares/index.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/middlewares/index.ts"],"names":[],"mappings":";;;;;;AAAA,iDAAsC;AACtC,4CAAmB;AACnB,sDAA6B;AAC7B,gEAAsC;AAEtC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,sCAAsC,CAAC,CAAA;AAEtE,iBAAO,CAAC,IAAI,CAAC;IACX,KAAK,EAAE,KAAK;IACZ,EAAE,EAAE,CAAC,cAAc,CAAC;IACpB,SAAS,EAAE,cAAc;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACjC,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE;QACb,MAAM,EAAE,GAAG;QACX,MAAM,EAAE,GAAG;KACZ;IACD,IAAI,EAAE,cAAc;IACpB,YAAY,EAAE,KAAK;CACpB,CAAC,CAAA;AAEF,IAAA,oBAAK,EAAC,YAAE,CAAC,CAAA;AAET,OAAO,CAAC,EAAE,CAAC,gBAAuB,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;IAC9C,qEAAqE;IACrE,KAAK,CAAC,gBAAgB,EAAE,qBAAqB,CAAC,CAAA;IAC9C,IAAA,oBAAK,EAAC,EAAE,CAAC,CAAA;AACX,CAAC,CAAC,CAAA;AAEF,SAAgB,eAAe,CAAC,GAAQ;IACtC,GAAG,CAAC,GAAG,CACL,IAAA,qBAAU,EAAC,iBAAO,EAAE;QAClB,YAAY,EAAE,SAAS;QACvB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,sBAAsB;KAClC,CAAC,CACH,CAAA;AACH,CAAC;AARD,0CAQC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const debug = require('debug')('things-factory:i18n-base:middlewares:koa:i18next');
|
|
4
|
+
const DEFAULT_ORDER = ['querystring', 'cookie', 'header'];
|
|
5
|
+
const detectors = {
|
|
6
|
+
cookie: function (context, options) {
|
|
7
|
+
let cookie = options.lookupCookie || 'i18next';
|
|
8
|
+
return context.cookies.get(cookie);
|
|
9
|
+
},
|
|
10
|
+
// fork from i18next-express-middleware
|
|
11
|
+
header: function (context) {
|
|
12
|
+
let acceptLanguage = context.get('accept-language');
|
|
13
|
+
let found;
|
|
14
|
+
let locales = [];
|
|
15
|
+
if (acceptLanguage) {
|
|
16
|
+
let lngs = [];
|
|
17
|
+
// associate language tags by their 'q' value (between 1 and 0)
|
|
18
|
+
acceptLanguage.split(',').forEach(function (l) {
|
|
19
|
+
let parts = l.split(';'); // 'en-GB;q=0.8' -> ['en-GB', 'q=0.8']
|
|
20
|
+
// get the language tag qvalue: 'q=0.8' -> 0.8
|
|
21
|
+
let qvalue = 1; // default qvalue
|
|
22
|
+
for (let i = 0; i < parts.length; i++) {
|
|
23
|
+
let part = parts[i].split('=');
|
|
24
|
+
if (part[0] === 'q' && !isNaN(part[1])) {
|
|
25
|
+
qvalue = Number(part[1]);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// add the tag and primary subtag to the qvalue associations
|
|
30
|
+
lngs.push({
|
|
31
|
+
lng: parts[0],
|
|
32
|
+
q: qvalue
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
lngs.sort(function (a, b) {
|
|
36
|
+
return b.q - a.q;
|
|
37
|
+
});
|
|
38
|
+
for (let i = 0; i < lngs.length; i++) {
|
|
39
|
+
locales.push(lngs[i].lng);
|
|
40
|
+
}
|
|
41
|
+
if (locales.length)
|
|
42
|
+
found = locales;
|
|
43
|
+
}
|
|
44
|
+
return found;
|
|
45
|
+
},
|
|
46
|
+
path: function (context, options) {
|
|
47
|
+
let found;
|
|
48
|
+
if (options.lookupPath !== undefined && context.params) {
|
|
49
|
+
found = context.params[options.lookupPath];
|
|
50
|
+
}
|
|
51
|
+
if (!found && options.lookupFromPathIndex !== undefined) {
|
|
52
|
+
let parts = context.path.split('/');
|
|
53
|
+
if (parts[0] === '') {
|
|
54
|
+
// Handle paths that start with a slash, i.e., '/foo' -> ['', 'foo']
|
|
55
|
+
parts.shift();
|
|
56
|
+
}
|
|
57
|
+
if (parts.length > options.lookupFromPathIndex) {
|
|
58
|
+
found = parts[options.lookupFromPathIndex];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return found;
|
|
62
|
+
},
|
|
63
|
+
querystring: function (context, options) {
|
|
64
|
+
let name = options.lookupQuerystring || 'lng';
|
|
65
|
+
return context.query[name];
|
|
66
|
+
},
|
|
67
|
+
session: function (context, options) {
|
|
68
|
+
let name = options.lookupSession || 'lng';
|
|
69
|
+
return context.session && context.session[name];
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
function default_1(context, options = {}) {
|
|
73
|
+
let { order, fallback } = options;
|
|
74
|
+
order = order && Array.isArray(order) ? order : DEFAULT_ORDER;
|
|
75
|
+
let lngs = [];
|
|
76
|
+
for (let i = 0, len = order.length; i < len; i++) {
|
|
77
|
+
let detector = detectors[order[i]];
|
|
78
|
+
let lng;
|
|
79
|
+
if (detector) {
|
|
80
|
+
lng = detector(context, options);
|
|
81
|
+
}
|
|
82
|
+
if (lng && typeof lng === 'string') {
|
|
83
|
+
lngs.push(lng);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
lngs = lngs.concat(lng);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
let found;
|
|
90
|
+
for (let i = 0, len = lngs.length; i < len; i++) {
|
|
91
|
+
let cleanedLng = context.i18next.services.languageUtils.formatLanguageCode(lngs[i]);
|
|
92
|
+
if (context.i18next.services.languageUtils.isSupportedCode(cleanedLng))
|
|
93
|
+
found = cleanedLng;
|
|
94
|
+
if (found)
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
return found || fallback;
|
|
98
|
+
}
|
|
99
|
+
exports.default = default_1;
|
|
100
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../server/middlewares/koa-i18next/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const detect_1 = __importDefault(require("./detect"));
|
|
7
|
+
const debug = require('debug')('things-factory:i18n-base:middlewares:koa:i18next');
|
|
8
|
+
function koaI18next(i18next, options = {}) {
|
|
9
|
+
return async function i18nextMiddleware(ctx, next) {
|
|
10
|
+
ctx.i18next = i18next;
|
|
11
|
+
let { lookupCookie, lookupSession } = options;
|
|
12
|
+
let lng = (0, detect_1.default)(ctx, options);
|
|
13
|
+
lng && setLanguage(ctx, lng, options);
|
|
14
|
+
debug('language is', lng);
|
|
15
|
+
ctx.t = function (...args) {
|
|
16
|
+
let key;
|
|
17
|
+
let opts;
|
|
18
|
+
// do detect path
|
|
19
|
+
if (!lng && isDetectPath(options.order)) {
|
|
20
|
+
lng = (0, detect_1.default)(ctx, Object.assign(options, { order: ['path'] }));
|
|
21
|
+
lng && setLanguage(ctx, lng, options);
|
|
22
|
+
}
|
|
23
|
+
if (args.length === 1) {
|
|
24
|
+
args.push({});
|
|
25
|
+
}
|
|
26
|
+
for (let i = 0, len = args.length; i < len; i++) {
|
|
27
|
+
let arg = args[i];
|
|
28
|
+
if (typeof arg === 'object' && !Array.isArray(arg)) {
|
|
29
|
+
arg.lng = lng;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return i18next.t.apply(i18next, args);
|
|
33
|
+
};
|
|
34
|
+
await next();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.default = koaI18next;
|
|
38
|
+
function setPath(object, path, newValue) {
|
|
39
|
+
let stack;
|
|
40
|
+
if (typeof path !== 'string')
|
|
41
|
+
stack = [].concat(path);
|
|
42
|
+
if (typeof path === 'string')
|
|
43
|
+
stack = path.split('.');
|
|
44
|
+
while (stack.length > 1) {
|
|
45
|
+
let key = stack.shift();
|
|
46
|
+
if (key.indexOf('###') > -1)
|
|
47
|
+
key = key.replace(/###/g, '.');
|
|
48
|
+
if (!object[key])
|
|
49
|
+
object[key] = {};
|
|
50
|
+
object = object[key];
|
|
51
|
+
}
|
|
52
|
+
let key = stack.shift();
|
|
53
|
+
if (key.indexOf('###') > -1)
|
|
54
|
+
key = key.replace(/###/g, '.');
|
|
55
|
+
object[key] = newValue;
|
|
56
|
+
}
|
|
57
|
+
koaI18next.getResourcesHandler = function (i18next, options) {
|
|
58
|
+
options = options || {};
|
|
59
|
+
let maxAge = options.maxAge || 60 * 60 * 24 * 30;
|
|
60
|
+
const propertyParam = options.propertyParam || 'query';
|
|
61
|
+
return async function (ctx, next) {
|
|
62
|
+
if (options.path && ctx.path !== options.path) {
|
|
63
|
+
return await next();
|
|
64
|
+
}
|
|
65
|
+
if (!i18next.services.backendConnector)
|
|
66
|
+
return ctx.throw(404, 'koa-i18next-middleware:: no backend configured');
|
|
67
|
+
let resources = {};
|
|
68
|
+
ctx.type = 'json';
|
|
69
|
+
if (options.cache !== undefined ? options.cache : process.env.NODE_ENV === 'production') {
|
|
70
|
+
ctx.set('Cache-Control', 'public, max-age=' + maxAge);
|
|
71
|
+
ctx.set('Expires', new Date(new Date().getTime() + maxAge * 1000).toUTCString());
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
ctx.set('Pragma', 'no-cache');
|
|
75
|
+
ctx.set('Cache-Control', 'no-cache');
|
|
76
|
+
}
|
|
77
|
+
let languages = ctx[propertyParam][options.lngParam || 'lng']
|
|
78
|
+
? ctx[propertyParam][options.lngParam || 'lng'].split(' ')
|
|
79
|
+
: [];
|
|
80
|
+
let namespaces = ctx[propertyParam][options.nsParam || 'ns']
|
|
81
|
+
? ctx[propertyParam][options.nsParam || 'ns'].split(' ')
|
|
82
|
+
: [];
|
|
83
|
+
// extend ns
|
|
84
|
+
namespaces.forEach(ns => {
|
|
85
|
+
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0)
|
|
86
|
+
i18next.options.ns.push(ns);
|
|
87
|
+
});
|
|
88
|
+
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
89
|
+
languages.forEach(lng => {
|
|
90
|
+
namespaces.forEach(ns => {
|
|
91
|
+
setPath(resources, [lng, ns], i18next.getResourceBundle(lng, ns));
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
ctx.body = resources;
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
koaI18next.getMissingKeyHandler = function (i18next, options) {
|
|
99
|
+
options = options || {};
|
|
100
|
+
const propertyParam = options.propertyParam || 'query';
|
|
101
|
+
return async function (ctx, next) {
|
|
102
|
+
if (options.path && ctx.path !== options.path) {
|
|
103
|
+
return await next();
|
|
104
|
+
}
|
|
105
|
+
let lng = ctx[propertyParam][options.lngParam || 'lng'];
|
|
106
|
+
let ns = ctx[propertyParam][options.nsParam || 'ns'];
|
|
107
|
+
if (!i18next.services.backendConnector)
|
|
108
|
+
return ctx.throw(404, 'koa-i18next-middleware:: no backend configured');
|
|
109
|
+
for (var m in ctx.request.body) {
|
|
110
|
+
i18next.services.backendConnector.saveMissing([lng], ns, m, ctx.request.body[m]);
|
|
111
|
+
}
|
|
112
|
+
ctx.body = 'ok';
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
function isDetectPath(order = []) {
|
|
116
|
+
return order.indexOf('path') !== -1;
|
|
117
|
+
}
|
|
118
|
+
function setLanguage(context, lng, options = {}) {
|
|
119
|
+
const { lookupCookie, lookupPath, lookupSession } = options;
|
|
120
|
+
context.locals = Object.assign(context.locals || {}, { lng });
|
|
121
|
+
context.state = Object.assign(context.state || {}, { lng });
|
|
122
|
+
context.language = context.lng = lng;
|
|
123
|
+
context.set('content-language', lng);
|
|
124
|
+
if (lookupCookie) {
|
|
125
|
+
context.cookies.set(lookupCookie, lng, { httpOnly: false, signed: false });
|
|
126
|
+
}
|
|
127
|
+
if (lookupSession && context.session) {
|
|
128
|
+
context.session[lookupSession] = lng;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/middlewares/koa-i18next/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/i18n-base",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.9",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -24,11 +24,10 @@
|
|
|
24
24
|
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@things-factory/shell": "^4.0.
|
|
28
|
-
"i18next": "^
|
|
29
|
-
"i18next-browser-languagedetector": "^6.
|
|
30
|
-
"i18next-http-backend": "^1.
|
|
31
|
-
"koa-i18next": "^1.1.1"
|
|
27
|
+
"@things-factory/shell": "^4.0.9",
|
|
28
|
+
"i18next": "^21.5.4",
|
|
29
|
+
"i18next-browser-languagedetector": "^6.1.2",
|
|
30
|
+
"i18next-http-backend": "^1.3.1"
|
|
32
31
|
},
|
|
33
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "81c8ae24487cfe79da62717f12bb6752761911ae"
|
|
34
33
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import i18next from 'i18next'
|
|
2
1
|
import { build } from './translations'
|
|
3
2
|
import fs from 'fs'
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import i18next from 'i18next'
|
|
4
|
+
import koaI18next from './koa-i18next'
|
|
6
5
|
|
|
7
6
|
const debug = require('debug')('things-factory:i18n-base:middlewares')
|
|
8
7
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const debug = require('debug')('things-factory:i18n-base:middlewares:koa:i18next')
|
|
2
|
+
|
|
3
|
+
const DEFAULT_ORDER = ['querystring', 'cookie', 'header']
|
|
4
|
+
|
|
5
|
+
const detectors = {
|
|
6
|
+
cookie: function (context, options) {
|
|
7
|
+
let cookie = options.lookupCookie || 'i18next'
|
|
8
|
+
return context.cookies.get(cookie)
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// fork from i18next-express-middleware
|
|
12
|
+
header: function (context) {
|
|
13
|
+
let acceptLanguage = context.get('accept-language')
|
|
14
|
+
let found
|
|
15
|
+
let locales = []
|
|
16
|
+
if (acceptLanguage) {
|
|
17
|
+
let lngs = []
|
|
18
|
+
|
|
19
|
+
// associate language tags by their 'q' value (between 1 and 0)
|
|
20
|
+
acceptLanguage.split(',').forEach(function (l) {
|
|
21
|
+
let parts = l.split(';') // 'en-GB;q=0.8' -> ['en-GB', 'q=0.8']
|
|
22
|
+
|
|
23
|
+
// get the language tag qvalue: 'q=0.8' -> 0.8
|
|
24
|
+
let qvalue = 1 // default qvalue
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < parts.length; i++) {
|
|
27
|
+
let part = parts[i].split('=')
|
|
28
|
+
if (part[0] === 'q' && !isNaN(part[1])) {
|
|
29
|
+
qvalue = Number(part[1])
|
|
30
|
+
break
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// add the tag and primary subtag to the qvalue associations
|
|
34
|
+
lngs.push({
|
|
35
|
+
lng: parts[0],
|
|
36
|
+
q: qvalue
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
lngs.sort(function (a, b) {
|
|
41
|
+
return b.q - a.q
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < lngs.length; i++) {
|
|
45
|
+
locales.push(lngs[i].lng)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (locales.length) found = locales
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return found
|
|
52
|
+
},
|
|
53
|
+
path: function (context, options) {
|
|
54
|
+
let found
|
|
55
|
+
|
|
56
|
+
if (options.lookupPath !== undefined && context.params) {
|
|
57
|
+
found = context.params[options.lookupPath]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!found && options.lookupFromPathIndex !== undefined) {
|
|
61
|
+
let parts = context.path.split('/')
|
|
62
|
+
if (parts[0] === '') {
|
|
63
|
+
// Handle paths that start with a slash, i.e., '/foo' -> ['', 'foo']
|
|
64
|
+
parts.shift()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (parts.length > options.lookupFromPathIndex) {
|
|
68
|
+
found = parts[options.lookupFromPathIndex]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return found
|
|
72
|
+
},
|
|
73
|
+
querystring: function (context, options) {
|
|
74
|
+
let name = options.lookupQuerystring || 'lng'
|
|
75
|
+
return context.query[name]
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
session: function (context, options) {
|
|
79
|
+
let name = options.lookupSession || 'lng'
|
|
80
|
+
return context.session && context.session[name]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default function (context, options = {}) {
|
|
85
|
+
let { order, fallback } = options as any
|
|
86
|
+
order = order && Array.isArray(order) ? order : DEFAULT_ORDER
|
|
87
|
+
|
|
88
|
+
let lngs = []
|
|
89
|
+
|
|
90
|
+
for (let i = 0, len = order.length; i < len; i++) {
|
|
91
|
+
let detector = detectors[order[i]]
|
|
92
|
+
let lng
|
|
93
|
+
if (detector) {
|
|
94
|
+
lng = detector(context, options)
|
|
95
|
+
}
|
|
96
|
+
if (lng && typeof lng === 'string') {
|
|
97
|
+
lngs.push(lng)
|
|
98
|
+
} else {
|
|
99
|
+
lngs = lngs.concat(lng)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
let found
|
|
103
|
+
for (let i = 0, len = lngs.length; i < len; i++) {
|
|
104
|
+
let cleanedLng = context.i18next.services.languageUtils.formatLanguageCode(lngs[i])
|
|
105
|
+
if (context.i18next.services.languageUtils.isSupportedCode(cleanedLng)) found = cleanedLng
|
|
106
|
+
if (found) break
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return found || fallback
|
|
110
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import detect from './detect'
|
|
2
|
+
|
|
3
|
+
const debug = require('debug')('things-factory:i18n-base:middlewares:koa:i18next')
|
|
4
|
+
|
|
5
|
+
export default function koaI18next(i18next, options = {} as any) {
|
|
6
|
+
return async function i18nextMiddleware(ctx, next) {
|
|
7
|
+
ctx.i18next = i18next
|
|
8
|
+
let { lookupCookie, lookupSession } = options
|
|
9
|
+
|
|
10
|
+
let lng = detect(ctx, options)
|
|
11
|
+
lng && setLanguage(ctx, lng, options)
|
|
12
|
+
|
|
13
|
+
debug('language is', lng)
|
|
14
|
+
|
|
15
|
+
ctx.t = function (...args) {
|
|
16
|
+
let key
|
|
17
|
+
let opts
|
|
18
|
+
// do detect path
|
|
19
|
+
if (!lng && isDetectPath(options.order)) {
|
|
20
|
+
lng = detect(ctx, Object.assign(options, { order: ['path'] }))
|
|
21
|
+
lng && setLanguage(ctx, lng, options)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (args.length === 1) {
|
|
25
|
+
args.push({})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (let i = 0, len = args.length; i < len; i++) {
|
|
29
|
+
let arg = args[i]
|
|
30
|
+
if (typeof arg === 'object' && !Array.isArray(arg)) {
|
|
31
|
+
arg.lng = lng
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return i18next.t.apply(i18next, args)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await next()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function setPath(object, path, newValue) {
|
|
42
|
+
let stack
|
|
43
|
+
if (typeof path !== 'string') stack = [].concat(path)
|
|
44
|
+
if (typeof path === 'string') stack = path.split('.')
|
|
45
|
+
|
|
46
|
+
while (stack.length > 1) {
|
|
47
|
+
let key = stack.shift()
|
|
48
|
+
if (key.indexOf('###') > -1) key = key.replace(/###/g, '.')
|
|
49
|
+
if (!object[key]) object[key] = {}
|
|
50
|
+
object = object[key]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let key = stack.shift()
|
|
54
|
+
if (key.indexOf('###') > -1) key = key.replace(/###/g, '.')
|
|
55
|
+
object[key] = newValue
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
koaI18next.getResourcesHandler = function (i18next, options) {
|
|
59
|
+
options = options || {}
|
|
60
|
+
let maxAge = options.maxAge || 60 * 60 * 24 * 30
|
|
61
|
+
const propertyParam = options.propertyParam || 'query'
|
|
62
|
+
|
|
63
|
+
return async function (ctx, next) {
|
|
64
|
+
if (options.path && ctx.path !== options.path) {
|
|
65
|
+
return await next()
|
|
66
|
+
}
|
|
67
|
+
if (!i18next.services.backendConnector) return ctx.throw(404, 'koa-i18next-middleware:: no backend configured')
|
|
68
|
+
|
|
69
|
+
let resources = {}
|
|
70
|
+
|
|
71
|
+
ctx.type = 'json'
|
|
72
|
+
if (options.cache !== undefined ? options.cache : process.env.NODE_ENV === 'production') {
|
|
73
|
+
ctx.set('Cache-Control', 'public, max-age=' + maxAge)
|
|
74
|
+
ctx.set('Expires', new Date(new Date().getTime() + maxAge * 1000).toUTCString())
|
|
75
|
+
} else {
|
|
76
|
+
ctx.set('Pragma', 'no-cache')
|
|
77
|
+
ctx.set('Cache-Control', 'no-cache')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let languages = ctx[propertyParam][options.lngParam || 'lng']
|
|
81
|
+
? ctx[propertyParam][options.lngParam || 'lng'].split(' ')
|
|
82
|
+
: []
|
|
83
|
+
let namespaces = ctx[propertyParam][options.nsParam || 'ns']
|
|
84
|
+
? ctx[propertyParam][options.nsParam || 'ns'].split(' ')
|
|
85
|
+
: []
|
|
86
|
+
|
|
87
|
+
// extend ns
|
|
88
|
+
namespaces.forEach(ns => {
|
|
89
|
+
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) i18next.options.ns.push(ns)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
93
|
+
languages.forEach(lng => {
|
|
94
|
+
namespaces.forEach(ns => {
|
|
95
|
+
setPath(resources, [lng, ns], i18next.getResourceBundle(lng, ns))
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
ctx.body = resources
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
koaI18next.getMissingKeyHandler = function (i18next, options) {
|
|
104
|
+
options = options || {}
|
|
105
|
+
const propertyParam = options.propertyParam || 'query'
|
|
106
|
+
|
|
107
|
+
return async function (ctx, next) {
|
|
108
|
+
if (options.path && ctx.path !== options.path) {
|
|
109
|
+
return await next()
|
|
110
|
+
}
|
|
111
|
+
let lng = ctx[propertyParam][options.lngParam || 'lng']
|
|
112
|
+
let ns = ctx[propertyParam][options.nsParam || 'ns']
|
|
113
|
+
|
|
114
|
+
if (!i18next.services.backendConnector) return ctx.throw(404, 'koa-i18next-middleware:: no backend configured')
|
|
115
|
+
|
|
116
|
+
for (var m in ctx.request.body) {
|
|
117
|
+
i18next.services.backendConnector.saveMissing([lng], ns, m, ctx.request.body[m])
|
|
118
|
+
}
|
|
119
|
+
ctx.body = 'ok'
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function isDetectPath(order = []) {
|
|
124
|
+
return order.indexOf('path') !== -1
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function setLanguage(context, lng, options = {} as any) {
|
|
128
|
+
const { lookupCookie, lookupPath, lookupSession } = options
|
|
129
|
+
context.locals = Object.assign(context.locals || {}, { lng })
|
|
130
|
+
context.state = Object.assign(context.state || {}, { lng })
|
|
131
|
+
context.language = context.lng = lng
|
|
132
|
+
context.set('content-language', lng)
|
|
133
|
+
if (lookupCookie) {
|
|
134
|
+
context.cookies.set(lookupCookie, lng, { httpOnly: false, signed: false })
|
|
135
|
+
}
|
|
136
|
+
if (lookupSession && context.session) {
|
|
137
|
+
context.session[lookupSession] = lng
|
|
138
|
+
}
|
|
139
|
+
}
|