i18next-http-middleware 3.1.3 → 3.2.0

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 CHANGED
@@ -5,11 +5,14 @@
5
5
  [![Travis](https://img.shields.io/travis/i18next/i18next-http-middleware/master.svg?style=flat-square)](https://travis-ci.org/i18next/i18next-http-middleware)
6
6
  [![npm version](https://img.shields.io/npm/v/i18next-http-middleware.svg?style=flat-square)](https://www.npmjs.com/package/i18next-http-middleware)
7
7
 
8
-
9
8
  This is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.
10
9
 
11
10
  It's based on the deprecated [i18next-express-middleware](https://github.com/i18next/i18next-express-middleware) and can be used as a drop-in replacement.
12
- *It's not bound to a specific http framework anymore.*
11
+ _It's not bound to a specific http framework anymore._
12
+
13
+ ## Advice:
14
+
15
+ To get started with server side internationalization, you may also have a look at [this blog post](https://dev.to/adrai/how-does-server-side-internationalization-i18n-look-like-5f4c) also using [using i18next-http-middleware](https://dev.to/adrai/how-does-server-side-internationalization-i18n-look-like-5f4c#ssr).
13
16
 
14
17
  # Getting started
15
18
 
@@ -52,6 +55,7 @@ div = t('myKey')
52
55
  ```
53
56
 
54
57
  ### Fastify usage
58
+
55
59
  ```js
56
60
  var i18next = require('i18next')
57
61
  var middleware = require('i18next-http-middleware')
@@ -83,6 +87,46 @@ app.get('myRoute', (request, reply) => {
83
87
  })
84
88
  ```
85
89
 
90
+ ### Hapi usage
91
+
92
+ ```js
93
+ const i18next = require('i18next')
94
+ const middleware = require('i18next-http-middleware')
95
+ const Hapi = require('@hapi/hapi')
96
+
97
+ i18next.use(middleware.LanguageDetector).init({
98
+ preload: ['en', 'de', 'it'],
99
+ ...otherOptions
100
+ })
101
+
102
+ const server = Hapi.server({
103
+ port: port,
104
+ host: '0.0.0.0',
105
+
106
+ await server.register({
107
+ plugin: i18nextMiddleware.hapiPlugin,
108
+ options: {
109
+ i18next,
110
+ ignoreRoutes: ['/foo'] // or function(req, res, options, i18next) { /* return true to ignore
111
+ }
112
+ })
113
+
114
+ // in your request handler
115
+ server.route({
116
+ method: 'GET',
117
+ path: '/myRoute',
118
+ handler: (request, h) => {
119
+ var lng = request.language // 'de-CH'
120
+ var lngs = v.languages // ['de-CH', 'de', 'en']
121
+ request.i18n.changeLanguage('en') // will not load that!!! assert it was preloaded
122
+
123
+ var exists = request.i18n.exists('myKey')
124
+ var translation = request.t('myKey')
125
+ }
126
+ })
127
+
128
+ ```
129
+
86
130
  ### Deno usage
87
131
 
88
132
  #### abc
@@ -92,7 +136,7 @@ import i18next from 'https://deno.land/x/i18next/index.js'
92
136
  import Backend from 'https://cdn.jsdelivr.net/gh/i18next/i18next-fs-backend/index.js'
93
137
  import i18nextMiddleware from 'https://deno.land/x/i18next_http_middleware/index.js'
94
138
  import { Application } from 'https://deno.land/x/abc/mod.ts'
95
- import { config } from "https://deno.land/x/dotenv/dotenv.ts";
139
+ import { config } from 'https://deno.land/x/dotenv/dotenv.ts'
96
140
 
97
141
  i18next
98
142
  .use(Backend)
@@ -112,12 +156,10 @@ i18next
112
156
  const port = config.PORT || 8080
113
157
  const app = new Application()
114
158
  const handle = i18nextMiddleware.handle(i18next)
115
- app.use((next) =>
116
- (c) => {
117
- handle(c.request, c.response, () => {})
118
- return next(c)
119
- }
120
- )
159
+ app.use((next) => (c) => {
160
+ handle(c.request, c.response, () => {})
161
+ return next(c)
162
+ })
121
163
  app.get('/', (c) => c.request.t('home.title'))
122
164
  await app.start({ port })
123
165
  ```
@@ -129,7 +171,7 @@ import i18next from 'https://deno.land/x/i18next/index.js'
129
171
  import Backend from 'https://cdn.jsdelivr.net/gh/i18next/i18next-fs-backend/index.js'
130
172
  import i18nextMiddleware from 'https://deno.land/x/i18next_http_middleware/index.js'
131
173
  import { createApp } from 'https://servestjs.org/@v1.0.0-rc2/mod.ts'
132
- import { config } from "https://deno.land/x/dotenv/dotenv.ts";
174
+ import { config } from 'https://deno.land/x/dotenv/dotenv.ts'
133
175
 
134
176
  i18next
135
177
  .use(Backend)
@@ -153,7 +195,7 @@ app.get('/', async (req) => {
153
195
  await req.respond({
154
196
  status: 200,
155
197
  headers: new Headers({
156
- 'content-type': 'text/plain',
198
+ 'content-type': 'text/plain'
157
199
  }),
158
200
  body: req.t('home.title')
159
201
  })
@@ -169,6 +211,10 @@ app.post('/locales/add/:lng/:ns', middleware.missingKeyHandler(i18next))
169
211
 
170
212
  // multiload backend route
171
213
  app.get('/locales/resources.json', middleware.getResourcesHandler(i18next))
214
+ // can be used like:
215
+ // GET /locales/resources.json
216
+ // GET /locales/resources.json?lng=en
217
+ // GET /locales/resources.json?lng=en&ns=translation
172
218
  ```
173
219
 
174
220
  ## add localized routes
@@ -245,7 +291,7 @@ Define your own functions to handle your custom request or response
245
291
  middleware.handle(i18next, {
246
292
  getPath: (req) => req.path,
247
293
  getUrl: (req) => req.url,
248
- setUrl: (req, url) => req.url = url,
294
+ setUrl: (req, url) => (req.url = url),
249
295
  getQuery: (req) => req.query,
250
296
  getParams: (req) => req.params,
251
297
  getBody: (req) => req.body,
@@ -266,6 +312,8 @@ Detects user language from current request. Comes with support for:
266
312
  - querystring
267
313
  - session
268
314
 
315
+ Based on the i18next language detection handling: https://www.i18next.com/misc/creating-own-plugins#languagedetector
316
+
269
317
  Wiring up:
270
318
 
271
319
  ```js
@@ -293,7 +341,7 @@ As with all modules you can either pass the constructor function (class) to the
293
341
  lookupPath: 'lng',
294
342
  lookupFromPathIndex: 0,
295
343
 
296
- // cache user language
344
+ // cache user language, you can define if an how the detected language should be "saved" => 'cookie' and/or 'session'
297
345
  caches: false, // ['cookie']
298
346
 
299
347
  ignoreCase: true, // ignore case of detected language
@@ -344,15 +392,14 @@ lngDetector.init(options)
344
392
  module.exports = {
345
393
  name: 'myDetectorsName',
346
394
 
347
- lookup: function(req, res, options) {
395
+ lookup: function (req, res, options) {
348
396
  // options -> are passed in options
349
397
  return 'en'
350
398
  },
351
399
 
352
- cacheUserLanguage: function(req, res, lng, options) {
400
+ cacheUserLanguage: function (req, res, lng, options) {
353
401
  // options -> are passed in options
354
402
  // lng -> current language, will be called after init and on changeLanguage
355
-
356
403
  // store it
357
404
  }
358
405
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
@@ -23,15 +23,15 @@ var _httpFunctions = require("./httpFunctions.js");
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
 
26
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
26
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
27
 
28
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
28
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
29
 
30
30
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
31
31
 
32
32
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
33
33
 
34
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
34
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
35
35
 
36
36
  function getDefaults() {
37
37
  return (0, _httpFunctions.extendOptionsWithDefaults)({
@@ -117,6 +117,7 @@ var LanguageDetector = function () {
117
117
 
118
118
  if (!found) {
119
119
  var fallbacks = this.allOptions.fallbackLng;
120
+ if (typeof fallbacks === 'function') fallbacks = fallbacks();
120
121
  if (typeof fallbacks === 'string') fallbacks = [fallbacks];
121
122
  if (!fallbacks) fallbacks = [];
122
123
 
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.extendOptionsWithDefaults = exports.getSession = exports.send = exports.setStatus = exports.setContentType = exports.setHeader = exports.getHeader = exports.getBody = exports.getCookies = exports.getHeaders = exports.getParams = exports.getQuery = exports.getOriginalUrl = exports.setUrl = exports.getUrl = exports.getPath = void 0;
6
+ exports.setUrl = exports.setStatus = exports.setHeader = exports.setContentType = exports.send = exports.getUrl = exports.getSession = exports.getQuery = exports.getPath = exports.getParams = exports.getOriginalUrl = exports.getHeaders = exports.getHeader = exports.getCookies = exports.getBody = exports.extendOptionsWithDefaults = void 0;
7
7
 
8
8
  var getPath = function getPath(req) {
9
9
  if (req.path) return req.path;
@@ -15,6 +15,7 @@ var getPath = function getPath(req) {
15
15
  exports.getPath = getPath;
16
16
 
17
17
  var getUrl = function getUrl(req) {
18
+ if (req.url && req.url.href) return req.url.href;
18
19
  if (req.url) return req.url;
19
20
  if (req.raw && req.raw.url) return req.raw.url;
20
21
  console.log('no possibility found to get url');
@@ -42,8 +43,12 @@ var getOriginalUrl = function getOriginalUrl(req) {
42
43
  exports.getOriginalUrl = getOriginalUrl;
43
44
 
44
45
  var getQuery = function getQuery(req) {
45
- if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function' && typeof req.query[Symbol.iterator] === 'function') return Object.fromEntries(req.query);
46
+ if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function' && typeof req.query[Symbol.iterator] === 'function') {
47
+ return Object.fromEntries(req.query);
48
+ }
49
+
46
50
  if (req.query) return req.query;
51
+ if (req.searchParams) return req.searchParams;
47
52
  if (req.raw && req.raw.query) return req.raw.query;
48
53
  if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams;
49
54
  var url = req.url || req.raw && req.raw.url;
@@ -90,10 +95,14 @@ var getCookies = function getCookies(req) {
90
95
  exports.getCookies = getCookies;
91
96
 
92
97
  var getBody = function getBody(req) {
93
- if (req.ctx && typeof req.ctx.body === 'function') return req.ctx.body.bind(req.ctx);
98
+ if (req.ctx && typeof req.ctx.body === 'function') {
99
+ return req.ctx.body.bind(req.ctx);
100
+ }
101
+
94
102
  if (req.ctx && req.ctx.body) return req.ctx.body;
95
103
  if (req.json) return req.json;
96
104
  if (req.body) return req.body;
105
+ if (req.payload) return req.payload;
97
106
  console.log('no possibility found to get body');
98
107
  return {};
99
108
  };
@@ -114,8 +123,15 @@ var setHeader = function setHeader(res, name, value) {
114
123
  if (res._headerSent || res.headersSent) return;
115
124
  if (typeof res.setHeader === 'function') return res.setHeader(name, value);
116
125
  if (typeof res.header === 'function') return res.header(name, value);
117
- if (res.responseHeaders && typeof res.responseHeaders.set === 'function') return res.responseHeaders.set(name, value);
118
- if (res.headers && typeof res.headers.set === 'function') return res.headers.set(name, value);
126
+
127
+ if (res.responseHeaders && typeof res.responseHeaders.set === 'function') {
128
+ return res.responseHeaders.set(name, value);
129
+ }
130
+
131
+ if (res.headers && typeof res.headers.set === 'function') {
132
+ return res.headers.set(name, value);
133
+ }
134
+
119
135
  console.log('no possibility found to set header');
120
136
  };
121
137
 
package/cjs/index.js CHANGED
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.handle = handle;
9
- exports.plugin = plugin;
8
+ exports.LanguageDetector = void 0;
9
+ exports.addRoute = addRoute;
10
+ exports.default = void 0;
10
11
  exports.getResourcesHandler = getResourcesHandler;
12
+ exports.handle = handle;
13
+ exports.hapiPlugin = void 0;
11
14
  exports.missingKeyHandler = missingKeyHandler;
12
- exports.addRoute = addRoute;
13
- exports.default = exports.LanguageDetector = void 0;
15
+ exports.plugin = plugin;
14
16
 
15
17
  var utils = _interopRequireWildcard(require("./utils.js"));
16
18
 
@@ -20,9 +22,15 @@ var _httpFunctions = require("./httpFunctions.js");
20
22
 
21
23
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
24
 
23
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
25
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
26
+
27
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
28
+
29
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
24
30
 
25
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
31
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
32
+
33
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
26
34
 
27
35
  var LanguageDetector = _LanguageDetector.default;
28
36
  exports.LanguageDetector = LanguageDetector;
@@ -73,6 +81,7 @@ function handle(i18next) {
73
81
  });
74
82
  i18n.on('languageChanged', function (lng) {
75
83
  req.language = req.locale = req.lng = lng;
84
+ if (options.attachLocals) res.locals = res.locals || {};
76
85
 
77
86
  if (res.locals) {
78
87
  res.locals.language = lng;
@@ -90,7 +99,11 @@ function handle(i18next) {
90
99
  }
91
100
  });
92
101
  var lng = req.lng;
93
- if (!lng && i18next.services.languageDetector) lng = i18next.services.languageDetector.detect(req, res);
102
+
103
+ if (!lng && i18next.services.languageDetector) {
104
+ lng = i18next.services.languageDetector.detect(req, res);
105
+ }
106
+
94
107
  req.language = req.locale = req.lng = lng;
95
108
 
96
109
  if (lng && options.getHeader(res, 'Content-Language') !== lng) {
@@ -108,6 +121,7 @@ function handle(i18next) {
108
121
  var exists = i18n.exists.bind(i18n);
109
122
  req.i18n = i18n;
110
123
  req.t = t;
124
+ if (options.attachLocals) res.locals = res.locals || {};
111
125
 
112
126
  if (res.locals) {
113
127
  res.locals.t = t;
@@ -117,7 +131,10 @@ function handle(i18next) {
117
131
  res.locals.languageDir = i18next.dir(lng);
118
132
  }
119
133
 
120
- if (i18next.services.languageDetector) i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
134
+ if (i18next.services.languageDetector) {
135
+ i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
136
+ }
137
+
121
138
  if (!req.lng) return next();
122
139
  i18next.loadLanguages(req.lng, function () {
123
140
  return next();
@@ -126,6 +143,7 @@ function handle(i18next) {
126
143
  }
127
144
 
128
145
  function plugin(instance, options, next) {
146
+ options.attachLocals = true;
129
147
  var middleware = handle(options.i18next, options);
130
148
  instance.addHook('preHandler', function (request, reply, next) {
131
149
  return middleware(request, reply, next);
@@ -133,6 +151,21 @@ function plugin(instance, options, next) {
133
151
  return next();
134
152
  }
135
153
 
154
+ var hapiPlugin = {
155
+ name: 'i18next-http-middleware',
156
+ version: '1',
157
+ register: function register(server, options) {
158
+ options.attachLocals = true;
159
+ var middleware = handle(options.i18next, _objectSpread({}, options));
160
+ server.ext('onPreHandler', function (request, h) {
161
+ middleware(request, request.raw.res || h.response() || request.Response, function () {
162
+ return h.continue;
163
+ });
164
+ return h.continue;
165
+ });
166
+ }
167
+ };
168
+ exports.hapiPlugin = hapiPlugin;
136
169
  plugin[Symbol.for('skip-override')] = true;
137
170
 
138
171
  function getResourcesHandler(i18next) {
@@ -163,7 +196,9 @@ function getResourcesHandler(i18next) {
163
196
  var languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : [];
164
197
  var namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : [];
165
198
  namespaces.forEach(function (ns) {
166
- if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) i18next.options.ns.push(ns);
199
+ if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
200
+ i18next.options.ns.push(ns);
201
+ }
167
202
  });
168
203
  i18next.services.backendConnector.load(languages, namespaces, function () {
169
204
  languages.forEach(function (lng) {
@@ -251,6 +286,7 @@ function addRoute(i18next, route, lngs, app, verb, fc) {
251
286
 
252
287
  var _default = {
253
288
  plugin: plugin,
289
+ hapiPlugin: hapiPlugin,
254
290
  handle: handle,
255
291
  getResourcesHandler: getResourcesHandler,
256
292
  missingKeyHandler: missingKeyHandler,
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
8
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
9
9
 
10
10
  var _default = {
11
11
  name: 'session',
package/cjs/utils.js CHANGED
@@ -3,10 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setPath = setPath;
7
6
  exports.defaults = defaults;
8
7
  exports.extend = extend;
9
8
  exports.removeLngFromUrl = removeLngFromUrl;
9
+ exports.setPath = setPath;
10
10
 
11
11
  function setPath(object, path, newValue) {
12
12
  var stack;
@@ -2,7 +2,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
2
2
 
3
3
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4
4
 
5
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
5
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
6
6
 
7
7
  import * as utils from './utils.js';
8
8
  import cookieLookup from './languageLookups/cookie.js';
@@ -96,6 +96,7 @@ var LanguageDetector = function () {
96
96
 
97
97
  if (!found) {
98
98
  var fallbacks = this.allOptions.fallbackLng;
99
+ if (typeof fallbacks === 'function') fallbacks = fallbacks();
99
100
  if (typeof fallbacks === 'string') fallbacks = [fallbacks];
100
101
  if (!fallbacks) fallbacks = [];
101
102
 
@@ -5,6 +5,7 @@ export var getPath = function getPath(req) {
5
5
  console.log('no possibility found to get path');
6
6
  };
7
7
  export var getUrl = function getUrl(req) {
8
+ if (req.url && req.url.href) return req.url.href;
8
9
  if (req.url) return req.url;
9
10
  if (req.raw && req.raw.url) return req.raw.url;
10
11
  console.log('no possibility found to get url');
@@ -23,8 +24,12 @@ export var getOriginalUrl = function getOriginalUrl(req) {
23
24
  return getUrl(req);
24
25
  };
25
26
  export var getQuery = function getQuery(req) {
26
- if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function' && typeof req.query[Symbol.iterator] === 'function') return Object.fromEntries(req.query);
27
+ if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function' && typeof req.query[Symbol.iterator] === 'function') {
28
+ return Object.fromEntries(req.query);
29
+ }
30
+
27
31
  if (req.query) return req.query;
32
+ if (req.searchParams) return req.searchParams;
28
33
  if (req.raw && req.raw.query) return req.raw.query;
29
34
  if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams;
30
35
  var url = req.url || req.raw && req.raw.url;
@@ -59,10 +64,14 @@ export var getCookies = function getCookies(req) {
59
64
  console.log('no possibility found to get cookies');
60
65
  };
61
66
  export var getBody = function getBody(req) {
62
- if (req.ctx && typeof req.ctx.body === 'function') return req.ctx.body.bind(req.ctx);
67
+ if (req.ctx && typeof req.ctx.body === 'function') {
68
+ return req.ctx.body.bind(req.ctx);
69
+ }
70
+
63
71
  if (req.ctx && req.ctx.body) return req.ctx.body;
64
72
  if (req.json) return req.json;
65
73
  if (req.body) return req.body;
74
+ if (req.payload) return req.payload;
66
75
  console.log('no possibility found to get body');
67
76
  return {};
68
77
  };
@@ -77,8 +86,15 @@ export var setHeader = function setHeader(res, name, value) {
77
86
  if (res._headerSent || res.headersSent) return;
78
87
  if (typeof res.setHeader === 'function') return res.setHeader(name, value);
79
88
  if (typeof res.header === 'function') return res.header(name, value);
80
- if (res.responseHeaders && typeof res.responseHeaders.set === 'function') return res.responseHeaders.set(name, value);
81
- if (res.headers && typeof res.headers.set === 'function') return res.headers.set(name, value);
89
+
90
+ if (res.responseHeaders && typeof res.responseHeaders.set === 'function') {
91
+ return res.responseHeaders.set(name, value);
92
+ }
93
+
94
+ if (res.headers && typeof res.headers.set === 'function') {
95
+ return res.headers.set(name, value);
96
+ }
97
+
82
98
  console.log('no possibility found to set header');
83
99
  };
84
100
  export var setContentType = function setContentType(res, type) {
package/esm/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
1
7
  import * as utils from './utils.js';
2
8
  import LD from './LanguageDetector.js';
3
9
  import { extendOptionsWithDefaults } from './httpFunctions.js';
@@ -49,6 +55,7 @@ export function handle(i18next) {
49
55
  });
50
56
  i18n.on('languageChanged', function (lng) {
51
57
  req.language = req.locale = req.lng = lng;
58
+ if (options.attachLocals) res.locals = res.locals || {};
52
59
 
53
60
  if (res.locals) {
54
61
  res.locals.language = lng;
@@ -66,7 +73,11 @@ export function handle(i18next) {
66
73
  }
67
74
  });
68
75
  var lng = req.lng;
69
- if (!lng && i18next.services.languageDetector) lng = i18next.services.languageDetector.detect(req, res);
76
+
77
+ if (!lng && i18next.services.languageDetector) {
78
+ lng = i18next.services.languageDetector.detect(req, res);
79
+ }
80
+
70
81
  req.language = req.locale = req.lng = lng;
71
82
 
72
83
  if (lng && options.getHeader(res, 'Content-Language') !== lng) {
@@ -84,6 +95,7 @@ export function handle(i18next) {
84
95
  var exists = i18n.exists.bind(i18n);
85
96
  req.i18n = i18n;
86
97
  req.t = t;
98
+ if (options.attachLocals) res.locals = res.locals || {};
87
99
 
88
100
  if (res.locals) {
89
101
  res.locals.t = t;
@@ -93,7 +105,10 @@ export function handle(i18next) {
93
105
  res.locals.languageDir = i18next.dir(lng);
94
106
  }
95
107
 
96
- if (i18next.services.languageDetector) i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
108
+ if (i18next.services.languageDetector) {
109
+ i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
110
+ }
111
+
97
112
  if (!req.lng) return next();
98
113
  i18next.loadLanguages(req.lng, function () {
99
114
  return next();
@@ -101,12 +116,27 @@ export function handle(i18next) {
101
116
  };
102
117
  }
103
118
  export function plugin(instance, options, next) {
119
+ options.attachLocals = true;
104
120
  var middleware = handle(options.i18next, options);
105
121
  instance.addHook('preHandler', function (request, reply, next) {
106
122
  return middleware(request, reply, next);
107
123
  });
108
124
  return next();
109
125
  }
126
+ export var hapiPlugin = {
127
+ name: 'i18next-http-middleware',
128
+ version: '1',
129
+ register: function register(server, options) {
130
+ options.attachLocals = true;
131
+ var middleware = handle(options.i18next, _objectSpread({}, options));
132
+ server.ext('onPreHandler', function (request, h) {
133
+ middleware(request, request.raw.res || h.response() || request.Response, function () {
134
+ return h.continue;
135
+ });
136
+ return h.continue;
137
+ });
138
+ }
139
+ };
110
140
  plugin[Symbol.for('skip-override')] = true;
111
141
  export function getResourcesHandler(i18next) {
112
142
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -136,7 +166,9 @@ export function getResourcesHandler(i18next) {
136
166
  var languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : [];
137
167
  var namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : [];
138
168
  namespaces.forEach(function (ns) {
139
- if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) i18next.options.ns.push(ns);
169
+ if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
170
+ i18next.options.ns.push(ns);
171
+ }
140
172
  });
141
173
  i18next.services.backendConnector.load(languages, namespaces, function () {
142
174
  languages.forEach(function (lng) {
@@ -221,6 +253,7 @@ export function addRoute(i18next, route, lngs, app, verb, fc) {
221
253
  }
222
254
  export default {
223
255
  plugin: plugin,
256
+ hapiPlugin: hapiPlugin,
224
257
  handle: handle,
225
258
  getResourcesHandler: getResourcesHandler,
226
259
  missingKeyHandler: missingKeyHandler,
@@ -1,4 +1,4 @@
1
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
2
 
3
3
  export default {
4
4
  name: 'session',
package/index.d.ts CHANGED
@@ -27,6 +27,10 @@ declare global {
27
27
  }
28
28
  }
29
29
 
30
+ declare module 'fastify' {
31
+ interface FastifyRequest extends I18NextRequest {}
32
+ }
33
+
30
34
  interface ExtendedOptions extends Object {
31
35
  getPath?: (req: Request) => string;
32
36
  getOriginalUrl?: (req: Request) => string;
@@ -79,9 +79,9 @@ class LanguageDetector {
79
79
 
80
80
  if (!found) {
81
81
  let fallbacks = this.allOptions.fallbackLng
82
+ if (typeof fallbacks === 'function') fallbacks = fallbacks()
82
83
  if (typeof fallbacks === 'string') fallbacks = [fallbacks]
83
84
  if (!fallbacks) fallbacks = []
84
-
85
85
  if (Object.prototype.toString.apply(fallbacks) === '[object Array]') {
86
86
  found = fallbacks[0]
87
87
  } else {
@@ -5,6 +5,7 @@ export const getPath = (req) => {
5
5
  console.log('no possibility found to get path')
6
6
  }
7
7
  export const getUrl = (req) => {
8
+ if (req.url && req.url.href) return req.url.href
8
9
  if (req.url) return req.url
9
10
  if (req.raw && req.raw.url) return req.raw.url
10
11
  console.log('no possibility found to get url')
@@ -22,8 +23,16 @@ export const getOriginalUrl = (req) => {
22
23
  return getUrl(req)
23
24
  }
24
25
  export const getQuery = (req) => {
25
- if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function' && typeof req.query[Symbol.iterator] === 'function') return Object.fromEntries(req.query)
26
+ if (
27
+ req.query &&
28
+ typeof req.query.entries === 'function' &&
29
+ typeof Object.fromEntries === 'function' &&
30
+ typeof req.query[Symbol.iterator] === 'function'
31
+ ) {
32
+ return Object.fromEntries(req.query)
33
+ }
26
34
  if (req.query) return req.query
35
+ if (req.searchParams) return req.searchParams
27
36
  if (req.raw && req.raw.query) return req.raw.query
28
37
  if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams
29
38
  const url = req.url || (req.raw && req.raw.url)
@@ -47,19 +56,23 @@ export const getCookies = (req) => {
47
56
  if (getHeaders(req)) {
48
57
  const list = {}
49
58
  const rc = getHeaders(req).cookie
50
- rc && rc.split(';').forEach((cookie) => {
51
- const parts = cookie.split('=')
52
- list[parts.shift().trim()] = decodeURI(encodeURI(parts.join('=')))
53
- })
59
+ rc &&
60
+ rc.split(';').forEach((cookie) => {
61
+ const parts = cookie.split('=')
62
+ list[parts.shift().trim()] = decodeURI(encodeURI(parts.join('=')))
63
+ })
54
64
  return list
55
65
  }
56
66
  console.log('no possibility found to get cookies')
57
67
  }
58
68
  export const getBody = (req) => {
59
- if (req.ctx && typeof req.ctx.body === 'function') return req.ctx.body.bind(req.ctx)
69
+ if (req.ctx && typeof req.ctx.body === 'function') {
70
+ return req.ctx.body.bind(req.ctx)
71
+ }
60
72
  if (req.ctx && req.ctx.body) return req.ctx.body
61
73
  if (req.json) return req.json
62
74
  if (req.body) return req.body
75
+ if (req.payload) return req.payload
63
76
  console.log('no possibility found to get body')
64
77
  return {}
65
78
  }
@@ -74,8 +87,12 @@ export const setHeader = (res, name, value) => {
74
87
  if (res._headerSent || res.headersSent) return
75
88
  if (typeof res.setHeader === 'function') return res.setHeader(name, value)
76
89
  if (typeof res.header === 'function') return res.header(name, value)
77
- if (res.responseHeaders && typeof res.responseHeaders.set === 'function') return res.responseHeaders.set(name, value)
78
- if (res.headers && typeof res.headers.set === 'function') return res.headers.set(name, value)
90
+ if (res.responseHeaders && typeof res.responseHeaders.set === 'function') {
91
+ return res.responseHeaders.set(name, value)
92
+ }
93
+ if (res.headers && typeof res.headers.set === 'function') {
94
+ return res.headers.set(name, value)
95
+ }
79
96
  console.log('no possibility found to set header')
80
97
  }
81
98
  export const setContentType = (res, type) => {
@@ -86,7 +103,7 @@ export const setContentType = (res, type) => {
86
103
  export const setStatus = (res, code) => {
87
104
  if (typeof res.status === 'function') return res.status(code)
88
105
  // eslint-disable-next-line no-return-assign
89
- if (res.status) return res.status = code
106
+ if (res.status) return (res.status = code)
90
107
  console.log('no possibility found to set status')
91
108
  }
92
109
  export const send = (res, body) => {
package/lib/index.js CHANGED
@@ -30,16 +30,19 @@ export function handle (i18next, options = {}) {
30
30
  return next()
31
31
  }
32
32
  } else {
33
- const ignores = (options.ignoreRoutes instanceof Array && options.ignoreRoutes) || []
33
+ const ignores =
34
+ (options.ignoreRoutes instanceof Array && options.ignoreRoutes) || []
34
35
  for (let i = 0; i < ignores.length; i++) {
35
36
  if (options.getPath(req).indexOf(ignores[i]) > -1) return next()
36
37
  }
37
38
  }
38
39
 
39
40
  const i18n = i18next.cloneInstance({ initImmediate: false })
40
- i18n.on('languageChanged', (lng) => { // Keep language in sync
41
+ i18n.on('languageChanged', lng => {
42
+ // Keep language in sync
41
43
  req.language = req.locale = req.lng = lng
42
44
 
45
+ if (options.attachLocals) res.locals = res.locals || {}
43
46
  if (res.locals) {
44
47
  res.locals.language = lng
45
48
  res.locals.languageDir = i18next.dir(lng)
@@ -57,7 +60,9 @@ export function handle (i18next, options = {}) {
57
60
  })
58
61
 
59
62
  let lng = req.lng
60
- if (!lng && i18next.services.languageDetector) lng = i18next.services.languageDetector.detect(req, res)
63
+ if (!lng && i18next.services.languageDetector) {
64
+ lng = i18next.services.languageDetector.detect(req, res)
65
+ }
61
66
 
62
67
  // set locale
63
68
  req.language = req.locale = req.lng = lng
@@ -70,7 +75,13 @@ export function handle (i18next, options = {}) {
70
75
  i18n.changeLanguage(lng || i18next.options.fallbackLng[0])
71
76
 
72
77
  if (req.i18nextLookupName === 'path' && options.removeLngFromUrl) {
73
- options.setUrl(req, utils.removeLngFromUrl(options.getUrl(req), i18next.services.languageDetector.options.lookupFromPathIndex))
78
+ options.setUrl(
79
+ req,
80
+ utils.removeLngFromUrl(
81
+ options.getUrl(req),
82
+ i18next.services.languageDetector.options.lookupFromPathIndex
83
+ )
84
+ )
74
85
  }
75
86
 
76
87
  const t = i18n.t.bind(i18n)
@@ -81,6 +92,7 @@ export function handle (i18next, options = {}) {
81
92
  req.t = t
82
93
 
83
94
  // assert for res -> template
95
+ if (options.attachLocals) res.locals = res.locals || {}
84
96
  if (res.locals) {
85
97
  res.locals.t = t
86
98
  res.locals.exists = exists
@@ -89,7 +101,9 @@ export function handle (i18next, options = {}) {
89
101
  res.locals.languageDir = i18next.dir(lng)
90
102
  }
91
103
 
92
- if (i18next.services.languageDetector) i18next.services.languageDetector.cacheUserLanguage(req, res, lng)
104
+ if (i18next.services.languageDetector) {
105
+ i18next.services.languageDetector.cacheUserLanguage(req, res, lng)
106
+ }
93
107
  // load resources
94
108
  if (!req.lng) return next()
95
109
  i18next.loadLanguages(req.lng, () => next())
@@ -97,10 +111,33 @@ export function handle (i18next, options = {}) {
97
111
  }
98
112
 
99
113
  export function plugin (instance, options, next) {
114
+ options.attachLocals = true
100
115
  const middleware = handle(options.i18next, options)
101
- instance.addHook('preHandler', (request, reply, next) => middleware(request, reply, next))
116
+ instance.addHook('preHandler', (request, reply, next) =>
117
+ middleware(request, reply, next)
118
+ )
102
119
  return next()
103
120
  }
121
+
122
+ export const hapiPlugin = {
123
+ name: 'i18next-http-middleware',
124
+ version: '1',
125
+ register: (server, options) => {
126
+ options.attachLocals = true
127
+ const middleware = handle(options.i18next, {
128
+ ...options
129
+ })
130
+ server.ext('onPreHandler', (request, h) => {
131
+ middleware(
132
+ request,
133
+ request.raw.res || h.response() || request.Response,
134
+ () => h.continue
135
+ )
136
+ return h.continue
137
+ })
138
+ }
139
+ }
140
+
104
141
  plugin[Symbol.for('skip-override')] = true
105
142
 
106
143
  export function getResourcesHandler (i18next, options = {}) {
@@ -112,32 +149,55 @@ export function getResourcesHandler (i18next, options = {}) {
112
149
 
113
150
  if (!i18next.services.backendConnector) {
114
151
  options.setStatus(res, 404)
115
- return options.send(res, 'i18next-express-middleware:: no backend configured')
152
+ return options.send(
153
+ res,
154
+ 'i18next-express-middleware:: no backend configured'
155
+ )
116
156
  }
117
157
 
118
158
  const resources = {}
119
159
 
120
160
  options.setContentType(res, 'application/json')
121
- if (options.cache !== undefined ? options.cache : typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production') {
161
+ if (
162
+ options.cache !== undefined
163
+ ? options.cache
164
+ : typeof process !== 'undefined' &&
165
+ process.env &&
166
+ process.env.NODE_ENV === 'production'
167
+ ) {
122
168
  options.setHeader(res, 'Cache-Control', 'public, max-age=' + maxAge)
123
- options.setHeader(res, 'Expires', (new Date(new Date().getTime() + maxAge * 1000)).toUTCString())
169
+ options.setHeader(
170
+ res,
171
+ 'Expires',
172
+ new Date(new Date().getTime() + maxAge * 1000).toUTCString()
173
+ )
124
174
  } else {
125
175
  options.setHeader(res, 'Pragma', 'no-cache')
126
176
  options.setHeader(res, 'Cache-Control', 'no-cache')
127
177
  }
128
178
 
129
- const languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : []
130
- const namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : []
179
+ const languages = options.getQuery(req)[options.lngParam || 'lng']
180
+ ? options.getQuery(req)[options.lngParam || 'lng'].split(' ')
181
+ : []
182
+ const namespaces = options.getQuery(req)[options.nsParam || 'ns']
183
+ ? options.getQuery(req)[options.nsParam || 'ns'].split(' ')
184
+ : []
131
185
 
132
186
  // extend ns
133
187
  namespaces.forEach(ns => {
134
- if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) i18next.options.ns.push(ns)
188
+ if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
189
+ i18next.options.ns.push(ns)
190
+ }
135
191
  })
136
192
 
137
193
  i18next.services.backendConnector.load(languages, namespaces, function () {
138
194
  languages.forEach(lng => {
139
195
  namespaces.forEach(ns => {
140
- utils.setPath(resources, [lng, ns], i18next.getResourceBundle(lng, ns))
196
+ utils.setPath(
197
+ resources,
198
+ [lng, ns],
199
+ i18next.getResourceBundle(lng, ns)
200
+ )
141
201
  })
142
202
  })
143
203
  })
@@ -157,7 +217,10 @@ export function missingKeyHandler (i18next, options = {}) {
157
217
 
158
218
  if (!i18next.services.backendConnector) {
159
219
  options.setStatus(res, 404)
160
- return options.send(res, 'i18next-express-middleware:: no backend configured')
220
+ return options.send(
221
+ res,
222
+ 'i18next-express-middleware:: no backend configured'
223
+ )
161
224
  }
162
225
 
163
226
  const body = options.getBody(req)
@@ -165,8 +228,8 @@ export function missingKeyHandler (i18next, options = {}) {
165
228
  if (typeof body === 'function') {
166
229
  const promise = body()
167
230
  if (promise && typeof promise.then === 'function') {
168
- return new Promise((resolve) => {
169
- promise.then((b) => {
231
+ return new Promise(resolve => {
232
+ promise.then(b => {
170
233
  for (const m in b) {
171
234
  i18next.services.backendConnector.saveMissing([lng], ns, m, b[m])
172
235
  }
@@ -216,6 +279,7 @@ export function addRoute (i18next, route, lngs, app, verb, fc) {
216
279
 
217
280
  export default {
218
281
  plugin,
282
+ hapiPlugin,
219
283
  handle,
220
284
  getResourcesHandler,
221
285
  missingKeyHandler,
package/licence CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 i18next
1
+ Copyright (c) 2022 i18next
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-http-middleware",
3
- "version": "3.1.3",
3
+ "version": "3.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./cjs/index.js",
@@ -21,26 +21,27 @@
21
21
  "module": "./esm/index.js",
22
22
  "dependencies": {},
23
23
  "devDependencies": {
24
- "@babel/cli": "7.12.10",
25
- "@babel/core": "7.12.10",
26
- "@babel/preset-env": "7.12.11",
27
- "@types/express-serve-static-core": "^4.17.18",
24
+ "@babel/cli": "7.16.0",
25
+ "@babel/core": "7.16.5",
26
+ "@babel/preset-env": "7.16.5",
27
+ "@hapi/hapi": "^20.2.1",
28
+ "@types/express-serve-static-core": "^4.17.27",
28
29
  "babel-plugin-add-module-exports": "1.0.4",
29
- "eslint": "7.17.0",
30
- "eslint-config-standard": "16.0.2",
31
- "eslint-plugin-import": "2.22.1",
30
+ "eslint": "7.29.0",
31
+ "eslint-config-standard": "16.0.3",
32
+ "eslint-plugin-import": "2.25.3",
32
33
  "eslint-plugin-node": "11.1.0",
33
- "eslint-plugin-promise": "4.2.1",
34
+ "eslint-plugin-promise": "5.1.0",
34
35
  "eslint-plugin-require-path-exists": "1.1.9",
35
36
  "eslint-plugin-standard": "5.0.0",
36
37
  "expect.js": "0.3.1",
37
- "express": "4.17.1",
38
- "fastify": "3.9.2",
39
- "i18next": "19.8.4",
40
- "mocha": "8.2.1",
41
- "supertest": "6.0.1",
42
- "tsd": "0.14.0",
43
- "uglify-js": "3.12.4"
38
+ "express": "4.17.2",
39
+ "fastify": "3.25.2",
40
+ "i18next": "21.6.3",
41
+ "mocha": "9.1.3",
42
+ "supertest": "6.1.6",
43
+ "tsd": "0.19.0",
44
+ "uglify-js": "3.14.5"
44
45
  },
45
46
  "description": "i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.",
46
47
  "keywords": [
@@ -57,12 +58,7 @@
57
58
  "bugs": {
58
59
  "url": "https://github.com/i18next/i18next-http-middleware/issues"
59
60
  },
60
- "licenses": [
61
- {
62
- "type": "MIT",
63
- "url": "https://raw.github.com/i18next/i18next-http-middleware/master/licence"
64
- }
65
- ],
61
+ "license": "MIT",
66
62
  "scripts": {
67
63
  "lint": "eslint .",
68
64
  "compile:esm": "rm -rf esm && mkdir esm && BABEL_ENV=esm babel lib -d esm",
package/CHANGELOG.md DELETED
@@ -1,45 +0,0 @@
1
- ## [v3.1.3](https://github.com/i18next/i18next-http-middleware/compare/v3.1.2...v3.1.3)
2
- - optimize getQuery() function to check if req.query is iterable
3
-
4
- ## [v3.1.2](https://github.com/i18next/i18next-http-middleware/compare/v3.1.1...v3.1.2)
5
- - fix the type of the lookup method [#37](https://github.com/i18next/i18next-http-middleware/pull/37)
6
-
7
- ## [v3.1.1](https://github.com/i18next/i18next-http-middleware/compare/v3.1.0...v3.1.1)
8
- - make sure no undefined language is detected
9
-
10
- ## [v3.1.0](https://github.com/i18next/i18next-http-middleware/compare/v3.0.6...v3.1.0)
11
- - added types
12
-
13
- ## [v3.0.6](https://github.com/i18next/i18next-http-middleware/compare/v3.0.5...v3.0.6)
14
- - ignoreCase option true by default
15
-
16
- ## [v3.0.5](https://github.com/i18next/i18next-http-middleware/compare/v3.0.4...v3.0.5)
17
- - introduce ignoreCase option
18
-
19
- ## [v3.0.4](https://github.com/i18next/i18next-http-middleware/compare/v3.0.3...v3.0.4)
20
- - fix language detection algorithm to handle fallbackLng correctly
21
-
22
- ## [v3.0.3](https://github.com/i18next/i18next-http-middleware/compare/v3.0.2...v3.0.3)
23
- - prevent URIError with cookie language detector
24
-
25
- ## [v3.0.2](https://github.com/i18next/i18next-http-middleware/compare/v3.0.1...v3.0.2)
26
- - transpile also esm
27
-
28
- ## [v3.0.1](https://github.com/i18next/i18next-http-middleware/compare/v3.0.0...v3.0.1)
29
- - introduce lookupHeaderRegex option
30
-
31
- ## [v3.0.0](https://github.com/i18next/i18next-http-middleware/compare/v2.1.2...v3.0.0)
32
- - **BREAKING** needs i18next >= 19.5.0
33
- - let i18next figure out which detected lng is best match
34
-
35
- ## [v2.1.2](https://github.com/i18next/i18next-http-middleware/compare/v2.1.1...v2.1.2)
36
- - fix: get whitelist from correct property
37
-
38
- ## [v2.1.1](https://github.com/i18next/i18next-http-middleware/compare/v2.1.0...v2.1.1)
39
- - extend httpFunctions getQuery to handle some edge cases
40
-
41
- ## [v2.1.0](https://github.com/i18next/i18next-http-middleware/compare/v2.0.0...v2.1.0)
42
- - LanguageDetector: cookie, new option: cookiePath
43
-
44
- ## [v2.0.0](https://github.com/i18next/i18next-http-middleware/compare/v1.3.1...v2.0.0)
45
- - potentially BREAKING: change cookie defaults: cookieSameSite: 'strict'