@things-factory/i18n-base 4.0.1 → 4.0.7

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.
@@ -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 koaI18next = require('koa-i18next');
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(koaI18next(i18next_1.default, {
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,sDAA6B;AAC7B,iDAAsC;AACtC,4CAAmB;AAEnB,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAEzC,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,UAAU,CAAC,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"}
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.1",
3
+ "version": "4.0.7",
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.1",
28
- "i18next": "^19.8.3",
29
- "i18next-browser-languagedetector": "^6.0.1",
30
- "i18next-http-backend": "^1.0.21",
31
- "koa-i18next": "^1.1.1"
27
+ "@things-factory/shell": "^4.0.7",
28
+ "i18next": "^21.5.4",
29
+ "i18next-browser-languagedetector": "^6.1.2",
30
+ "i18next-http-backend": "^1.3.1"
32
31
  },
33
- "gitHead": "6803d6f150cc64cbb8b12a88d9131bb6fb9ad880"
32
+ "gitHead": "035fa60359aefa9b9111f807fc7e8db6a15a4a6e"
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
- const koaI18next = require('koa-i18next')
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
+ }