i18next-http-middleware 3.10.0 → 3.10.2
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/README.md +3 -0
- package/cjs/index.js +9 -7
- package/esm/index.js +9 -7
- package/lib/index.js +18 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -270,6 +270,9 @@ const app = new App()
|
|
|
270
270
|
|
|
271
271
|
```js
|
|
272
272
|
// missing keys make sure the body is parsed (i.e. with [body-parser](https://github.com/expressjs/body-parser#bodyparserjsonoptions))
|
|
273
|
+
// this route takes writes from anyone who can reach it: every key in the body goes to the
|
|
274
|
+
// backend's create (i18next-fs-backend writes it into a file) and stays in the server's memory,
|
|
275
|
+
// so mount it only in development or behind authentication
|
|
273
276
|
app.post('/locales/add/:lng/:ns', middleware.missingKeyHandler(i18next))
|
|
274
277
|
// addPath for client: http://localhost:8080/locales/add/{{lng}}/{{ns}}
|
|
275
278
|
|
package/cjs/index.js
CHANGED
|
@@ -132,7 +132,7 @@ function handle(i18next) {
|
|
|
132
132
|
i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
|
|
133
133
|
}
|
|
134
134
|
if (!req.lng) return next();
|
|
135
|
-
|
|
135
|
+
i18n.loadLanguages(req.lng, function () {
|
|
136
136
|
return next();
|
|
137
137
|
});
|
|
138
138
|
};
|
|
@@ -253,17 +253,16 @@ function getResourcesHandler(i18next) {
|
|
|
253
253
|
}
|
|
254
254
|
languages = languages.filter(utils.isSafeLangIdentifier);
|
|
255
255
|
namespaces = namespaces.filter(utils.isSafeNsIdentifier);
|
|
256
|
-
namespaces.forEach(function (ns) {
|
|
257
|
-
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
258
|
-
i18next.options.ns.push(ns);
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
256
|
var loaded = false;
|
|
262
257
|
var onLoaded;
|
|
263
258
|
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
264
259
|
languages.forEach(function (lng) {
|
|
265
260
|
namespaces.forEach(function (ns) {
|
|
266
|
-
|
|
261
|
+
var bundle = i18next.getResourceBundle(lng, ns);
|
|
262
|
+
if (bundle && i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
263
|
+
i18next.options.ns.push(ns);
|
|
264
|
+
}
|
|
265
|
+
utils.setPath(resources, [lng, ns], bundle);
|
|
267
266
|
});
|
|
268
267
|
});
|
|
269
268
|
loaded = true;
|
|
@@ -302,6 +301,8 @@ function missingKeyHandler(i18next) {
|
|
|
302
301
|
var keySeparator = i18next.options && i18next.options.keySeparator;
|
|
303
302
|
var utilsOfRequest = req.i18n && req.i18n.services && req.i18n.services.utils;
|
|
304
303
|
var hasLoadedNamespace = utilsOfRequest && utilsOfRequest.hasLoadedNamespace;
|
|
304
|
+
var sharedNs = i18next.options && i18next.options.ns;
|
|
305
|
+
var nsWasKnown = !Array.isArray(sharedNs) || sharedNs.indexOf(ns) > -1;
|
|
305
306
|
var saveMissingKeys = function saveMissingKeys(src) {
|
|
306
307
|
if (!src || _typeof(src) !== 'object') return;
|
|
307
308
|
for (var _i = 0, _Object$keys = Object.keys(src); _i < _Object$keys.length; _i++) {
|
|
@@ -309,6 +310,7 @@ function missingKeyHandler(i18next) {
|
|
|
309
310
|
if (utils.hasUnsafeKeySegment(m, keySeparator)) continue;
|
|
310
311
|
i18next.services.backendConnector.saveMissing([lng], ns, m, src[m], undefined, undefined, undefined, hasLoadedNamespace);
|
|
311
312
|
}
|
|
313
|
+
if (!nsWasKnown && sharedNs.indexOf(ns) > -1) sharedNs.splice(sharedNs.indexOf(ns), 1);
|
|
312
314
|
};
|
|
313
315
|
if (typeof body === 'function') {
|
|
314
316
|
var promise = body();
|
package/esm/index.js
CHANGED
|
@@ -115,7 +115,7 @@ export function handle(i18next) {
|
|
|
115
115
|
i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
|
|
116
116
|
}
|
|
117
117
|
if (!req.lng) return next();
|
|
118
|
-
|
|
118
|
+
i18n.loadLanguages(req.lng, function () {
|
|
119
119
|
return next();
|
|
120
120
|
});
|
|
121
121
|
};
|
|
@@ -236,17 +236,16 @@ export function getResourcesHandler(i18next) {
|
|
|
236
236
|
}
|
|
237
237
|
languages = languages.filter(utils.isSafeLangIdentifier);
|
|
238
238
|
namespaces = namespaces.filter(utils.isSafeNsIdentifier);
|
|
239
|
-
namespaces.forEach(function (ns) {
|
|
240
|
-
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
241
|
-
i18next.options.ns.push(ns);
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
239
|
var loaded = false;
|
|
245
240
|
var onLoaded;
|
|
246
241
|
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
247
242
|
languages.forEach(function (lng) {
|
|
248
243
|
namespaces.forEach(function (ns) {
|
|
249
|
-
|
|
244
|
+
var bundle = i18next.getResourceBundle(lng, ns);
|
|
245
|
+
if (bundle && i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
246
|
+
i18next.options.ns.push(ns);
|
|
247
|
+
}
|
|
248
|
+
utils.setPath(resources, [lng, ns], bundle);
|
|
250
249
|
});
|
|
251
250
|
});
|
|
252
251
|
loaded = true;
|
|
@@ -285,6 +284,8 @@ export function missingKeyHandler(i18next) {
|
|
|
285
284
|
var keySeparator = i18next.options && i18next.options.keySeparator;
|
|
286
285
|
var utilsOfRequest = req.i18n && req.i18n.services && req.i18n.services.utils;
|
|
287
286
|
var hasLoadedNamespace = utilsOfRequest && utilsOfRequest.hasLoadedNamespace;
|
|
287
|
+
var sharedNs = i18next.options && i18next.options.ns;
|
|
288
|
+
var nsWasKnown = !Array.isArray(sharedNs) || sharedNs.indexOf(ns) > -1;
|
|
288
289
|
var saveMissingKeys = function saveMissingKeys(src) {
|
|
289
290
|
if (!src || _typeof(src) !== 'object') return;
|
|
290
291
|
for (var _i = 0, _Object$keys = Object.keys(src); _i < _Object$keys.length; _i++) {
|
|
@@ -292,6 +293,7 @@ export function missingKeyHandler(i18next) {
|
|
|
292
293
|
if (utils.hasUnsafeKeySegment(m, keySeparator)) continue;
|
|
293
294
|
i18next.services.backendConnector.saveMissing([lng], ns, m, src[m], undefined, undefined, undefined, hasLoadedNamespace);
|
|
294
295
|
}
|
|
296
|
+
if (!nsWasKnown && sharedNs.indexOf(ns) > -1) sharedNs.splice(sharedNs.indexOf(ns), 1);
|
|
295
297
|
};
|
|
296
298
|
if (typeof body === 'function') {
|
|
297
299
|
var promise = body();
|
package/lib/index.js
CHANGED
|
@@ -127,9 +127,11 @@ export function handle (i18next, options = {}) {
|
|
|
127
127
|
if (i18next.services.languageDetector) {
|
|
128
128
|
i18next.services.languageDetector.cacheUserLanguage(req, res, lng)
|
|
129
129
|
}
|
|
130
|
-
// load resources
|
|
130
|
+
// load resources: through the request's clone, as loadLanguages() adds
|
|
131
|
+
// the language to options.preload, and every request on the shared
|
|
132
|
+
// instance pays for the length of that list until the process restarts
|
|
131
133
|
if (!req.lng) return next()
|
|
132
|
-
|
|
134
|
+
i18n.loadLanguages(req.lng, () => next())
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -265,23 +267,19 @@ export function getResourcesHandler (i18next, options = {}) {
|
|
|
265
267
|
languages = languages.filter(utils.isSafeLangIdentifier)
|
|
266
268
|
namespaces = namespaces.filter(utils.isSafeNsIdentifier)
|
|
267
269
|
|
|
268
|
-
// extend ns
|
|
269
|
-
namespaces.forEach(ns => {
|
|
270
|
-
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
271
|
-
i18next.options.ns.push(ns)
|
|
272
|
-
}
|
|
273
|
-
})
|
|
274
|
-
|
|
275
270
|
let loaded = false
|
|
276
271
|
let onLoaded
|
|
277
272
|
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
278
273
|
languages.forEach(lng => {
|
|
279
274
|
namespaces.forEach(ns => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
)
|
|
275
|
+
const bundle = i18next.getResourceBundle(lng, ns)
|
|
276
|
+
// extend ns only with a namespace the backend has: every request
|
|
277
|
+
// pays for the length of this shared list, and a made-up ns from
|
|
278
|
+
// the request would stay in it until the process restarts
|
|
279
|
+
if (bundle && i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
|
|
280
|
+
i18next.options.ns.push(ns)
|
|
281
|
+
}
|
|
282
|
+
utils.setPath(resources, [lng, ns], bundle)
|
|
285
283
|
})
|
|
286
284
|
})
|
|
287
285
|
loaded = true
|
|
@@ -337,6 +335,11 @@ export function missingKeyHandler (i18next, options = {}) {
|
|
|
337
335
|
const keySeparator = i18next.options && i18next.options.keySeparator
|
|
338
336
|
const utilsOfRequest = req.i18n && req.i18n.services && req.i18n.services.utils
|
|
339
337
|
const hasLoadedNamespace = utilsOfRequest && utilsOfRequest.hasLoadedNamespace
|
|
338
|
+
// saveMissing() writes the key to the store, which also adds its namespace to the
|
|
339
|
+
// shared i18next.options.ns: every request walks that list, so a namespace that
|
|
340
|
+
// came from this request must not stay in it
|
|
341
|
+
const sharedNs = i18next.options && i18next.options.ns
|
|
342
|
+
const nsWasKnown = !Array.isArray(sharedNs) || sharedNs.indexOf(ns) > -1
|
|
340
343
|
|
|
341
344
|
// iterate only over own, non-prototype-polluting keys. The check also
|
|
342
345
|
// rejects dotted variants like `__proto__.polluted` whose segments under
|
|
@@ -349,6 +352,7 @@ export function missingKeyHandler (i18next, options = {}) {
|
|
|
349
352
|
// request) as the 8th argument; without it, it checks the newest clone
|
|
350
353
|
i18next.services.backendConnector.saveMissing([lng], ns, m, src[m], undefined, undefined, undefined, hasLoadedNamespace)
|
|
351
354
|
}
|
|
355
|
+
if (!nsWasKnown && sharedNs.indexOf(ns) > -1) sharedNs.splice(sharedNs.indexOf(ns), 1)
|
|
352
356
|
}
|
|
353
357
|
|
|
354
358
|
if (typeof body === 'function') {
|