i18next-http-middleware 3.2.2 → 3.3.1

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
@@ -36,7 +36,8 @@ i18next.use(middleware.LanguageDetector).init({
36
36
  var app = express()
37
37
  app.use(
38
38
  middleware.handle(i18next, {
39
- ignoreRoutes: ['/foo'] // or function(req, res, options, i18next) { /* return true to ignore */ }
39
+ ignoreRoutes: ['/foo'], // or function(req, res, options, i18next) { /* return true to ignore */ }
40
+ removeLngFromUrl: false // removes the language from the url when language detected in path
40
41
  })
41
42
  )
42
43
 
@@ -208,6 +209,7 @@ await app.listen({ port })
208
209
  ```js
209
210
  // missing keys make sure the body is parsed (i.e. with [body-parser](https://github.com/expressjs/body-parser#bodyparserjsonoptions))
210
211
  app.post('/locales/add/:lng/:ns', middleware.missingKeyHandler(i18next))
212
+ // addPath for client: http://localhost:8080/locales/add/{{lng}}/{{ns}}
211
213
 
212
214
  // multiload backend route
213
215
  app.get('/locales/resources.json', middleware.getResourcesHandler(i18next))
@@ -215,6 +217,21 @@ app.get('/locales/resources.json', middleware.getResourcesHandler(i18next))
215
217
  // GET /locales/resources.json
216
218
  // GET /locales/resources.json?lng=en
217
219
  // GET /locales/resources.json?lng=en&ns=translation
220
+
221
+ // serve translations:
222
+ app.use('/locales', express.static('locales'))
223
+ // GET /locales/en/translation.json
224
+ // loadPath for client: http://localhost:8080/locales/{{lng}}/{{ns}}.json
225
+
226
+ // or instead of static
227
+ app.get('/locales/:lng/:ns', middleware.getResourcesHandler(i18next))
228
+ // GET /locales/en/translation
229
+ // loadPath for client: http://localhost:8080/locales/{{lng}}/{{ns}}
230
+
231
+ app.get('/locales/:lng/:ns', middleware.getResourcesHandler(i18next, {
232
+ maxAge: 60 * 60 * 24 * 30, // adds appropriate cache header if cache option is passed or NODE_ENV === 'production', defaults to 30 days
233
+ cache: true // defaults to false
234
+ }))
218
235
  ```
219
236
 
220
237
  ## add localized routes
@@ -419,6 +436,8 @@ i18next.use(lngDetector).init({
419
436
  })
420
437
  ```
421
438
 
439
+ Don't forget: You have to add the name of your detector (`myDetectorsName` in this case) to the `order` array in your `options` object. Without that, your detector won't be used. See the [Detector Options section for more](#detector-options).
440
+
422
441
  ---
423
442
 
424
443
  <h3 align='center'>Gold Sponsors</h3>
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
 
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
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
@@ -15,9 +14,12 @@ var _httpFunctions = require("./httpFunctions.js");
15
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
15
  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); }
17
16
  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; }
17
+ 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); }
18
18
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19
- 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); } }
19
+ 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, _toPropertyKey(descriptor.key), descriptor); } }
20
20
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
21
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
22
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
21
23
  function getDefaults() {
22
24
  return (0, _httpFunctions.extendOptionsWithDefaults)({
23
25
  order: ['querystring', 'cookie', 'header'],
@@ -89,7 +91,6 @@ var LanguageDetector = function () {
89
91
  found = detections.length > 0 ? detections[0] : null;
90
92
  }
91
93
  });
92
-
93
94
  if (!found) {
94
95
  var fallbacks = this.allOptions.fallbackLng;
95
96
  if (typeof fallbacks === 'function') fallbacks = fallbacks();
package/cjs/index.d.ts ADDED
@@ -0,0 +1,179 @@
1
+ import {
2
+ Application,
3
+ Handler,
4
+ NextFunction,
5
+ Request,
6
+ RequestHandler,
7
+ Response,
8
+ Router,
9
+ } from "express-serve-static-core";
10
+ import * as i18next from "i18next";
11
+
12
+ /// <reference types="express-serve-static-core" />
13
+
14
+ type I18next = i18next.i18n;
15
+ type App = Application | Router;
16
+
17
+ type I18NextRequest = {
18
+ language: string;
19
+ languages: string[];
20
+ i18n: i18next.i18n;
21
+ t: i18next.TFunction;
22
+ };
23
+
24
+ declare global {
25
+ namespace Express {
26
+ interface Request extends I18NextRequest {}
27
+ }
28
+ }
29
+
30
+ declare module 'fastify' {
31
+ interface FastifyRequest extends I18NextRequest {}
32
+ }
33
+
34
+ interface ExtendedOptions extends Object {
35
+ getPath?: (req: Request) => string;
36
+ getOriginalUrl?: (req: Request) => string;
37
+ getUrl?: (req: Request) => string;
38
+ setUrl?: (req: Request, url: string) => void;
39
+ getParams?: (req: Request) => Object;
40
+ getSession?: (req: Request) => Object;
41
+ getQuery?: (req: Request) => Object;
42
+ getCookies?: (req: Request) => Object;
43
+ getBody?: (req: Request) => Object;
44
+ getHeaders?: (req: Request) => Object;
45
+ getHeader?: (res: Response, name: string) => Object;
46
+ setHeader?: (res: Response, name: string, value: string) => void;
47
+ setContentType?: (res: Response, type: string) => void;
48
+ setStatus?: (res: Response, code: number) => void;
49
+ send?: (res: Response, body: any) => void;
50
+ }
51
+
52
+ interface HandleOptions extends ExtendedOptions {
53
+ ignoreRoutes?: string[] | IgnoreRoutesFunction;
54
+ removeLngFromUrl?: boolean;
55
+ }
56
+
57
+ interface GetResourcesHandlerOptions extends ExtendedOptions {
58
+ maxAge?: number;
59
+ cache?: boolean;
60
+ lngParam?: string;
61
+ nsParam?: string;
62
+ }
63
+
64
+ interface MissingKeyHandlerOptions extends ExtendedOptions {
65
+ lngParam?: string;
66
+ nsParam?: string;
67
+ }
68
+
69
+ type IgnoreRoutesFunction = (
70
+ req: Request,
71
+ res: Response,
72
+ options: HandleOptions,
73
+ i18next: I18next
74
+ ) => boolean;
75
+
76
+ export function handle(i18next: I18next, options?: HandleOptions): Handler;
77
+
78
+ export function plugin(
79
+ instance: any,
80
+ options: HandleOptions & { i18next?: I18next },
81
+ next: NextFunction
82
+ ): Handler;
83
+
84
+ export function getResourcesHandler(
85
+ i18next: I18next,
86
+ options?: GetResourcesHandlerOptions
87
+ ): Handler;
88
+
89
+ export function missingKeyHandler(
90
+ i18next: I18next,
91
+ options?: MissingKeyHandlerOptions
92
+ ): Handler;
93
+
94
+ export function addRoute(
95
+ i18next: I18next,
96
+ route: string,
97
+ lngs: string[],
98
+ app: App,
99
+ verb: string,
100
+ fc: RequestHandler
101
+ ): void;
102
+
103
+ // LanguageDetector
104
+ type LanguageDetectorServices = any;
105
+ type LanguageDetectorOrder = string[];
106
+ type LanguageDetectorCaches = boolean | string[];
107
+ interface LanguageDetectorOptions {
108
+ order?: LanguageDetectorOrder;
109
+ lookupQuerystring?: string;
110
+ lookupCookie?: string;
111
+ lookupSession?: string;
112
+ lookupFromPathIndex?: number;
113
+ caches?: LanguageDetectorCaches;
114
+ cookieExpirationDate?: Date;
115
+ cookieDomain?: string;
116
+ }
117
+ interface LanguageDetectorAllOptions {
118
+ fallbackLng: boolean | string | string[];
119
+ }
120
+ interface LanguageDetectorInterfaceOptions {
121
+ [name: string]: any;
122
+ }
123
+ interface LanguageDetectorInterface {
124
+ name: string;
125
+
126
+ lookup: (
127
+ req: Request,
128
+ res: Response,
129
+ options?: LanguageDetectorInterfaceOptions
130
+ ) => string | string[] | undefined;
131
+
132
+ cacheUserLanguage?: (
133
+ req: Request,
134
+ res: Response,
135
+ lng: string,
136
+ options?: Object
137
+ ) => void;
138
+ }
139
+
140
+ export class LanguageDetector implements i18next.Module {
141
+ type: "languageDetector";
142
+
143
+ constructor(
144
+ services: LanguageDetectorServices,
145
+ options?: LanguageDetectorOptions,
146
+ allOptions?: LanguageDetectorAllOptions
147
+ );
148
+
149
+ constructor(
150
+ options?: LanguageDetectorOptions,
151
+ allOptions?: LanguageDetectorAllOptions
152
+ );
153
+
154
+ init(
155
+ services: LanguageDetectorServices,
156
+ options?: LanguageDetectorOptions,
157
+ allOptions?: LanguageDetectorAllOptions
158
+ ): void;
159
+
160
+ init(
161
+ options?: LanguageDetectorOptions,
162
+ allOptions?: LanguageDetectorAllOptions
163
+ ): void;
164
+
165
+ addDetector(detector: LanguageDetectorInterface): void;
166
+
167
+ detect(
168
+ req: Request,
169
+ res: Response,
170
+ detectionOrder: LanguageDetectorOrder
171
+ ): void;
172
+
173
+ cacheUserLanguage(
174
+ req: Request,
175
+ res: Response,
176
+ lng: string,
177
+ caches: LanguageDetectorCaches
178
+ ): void;
179
+ }
package/cjs/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
 
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
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
@@ -18,9 +17,12 @@ var _httpFunctions = require("./httpFunctions.js");
18
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
18
  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); }
20
19
  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; }
20
+ 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); }
21
21
  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; }
22
22
  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; }
23
- 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; }
23
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
24
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
25
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
24
26
  var LanguageDetector = _LanguageDetector.default;
25
27
  exports.LanguageDetector = LanguageDetector;
26
28
  var checkForCombinedReqRes = function checkForCombinedReqRes(req, res, next) {
@@ -81,23 +83,19 @@ function handle(i18next) {
81
83
  if (!lng && i18next.services.languageDetector) {
82
84
  lng = i18next.services.languageDetector.detect(req, res);
83
85
  }
84
-
85
86
  req.language = req.locale = req.lng = lng;
86
87
  if (lng && options.getHeader(res, 'Content-Language') !== lng) {
87
88
  options.setHeader(res, 'Content-Language', lng);
88
89
  }
89
90
  req.languages = i18next.services.languageUtils.toResolveHierarchy(lng);
90
-
91
91
  i18n.changeLanguage(lng || i18next.options.fallbackLng[0]);
92
92
  if (req.i18nextLookupName === 'path' && options.removeLngFromUrl) {
93
93
  options.setUrl(req, utils.removeLngFromUrl(options.getUrl(req), i18next.services.languageDetector.options.lookupFromPathIndex));
94
94
  }
95
95
  var t = i18n.t.bind(i18n);
96
96
  var exists = i18n.exists.bind(i18n);
97
-
98
97
  req.i18n = i18n;
99
98
  req.t = t;
100
-
101
99
  if (options.attachLocals) res.locals = res.locals || {};
102
100
  if (res.locals) {
103
101
  res.locals.t = t;
@@ -162,7 +160,10 @@ function getResourcesHandler(i18next) {
162
160
  }
163
161
  var languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : [];
164
162
  var namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : [];
165
-
163
+ if (languages.length === 0 && namespaces.length === 0) {
164
+ languages = options.getParams(req)[options.lngParam || 'lng'] ? options.getParams(req)[options.lngParam || 'lng'].split(' ') : [];
165
+ namespaces = options.getParams(req)[options.nsParam || 'ns'] ? options.getParams(req)[options.nsParam || 'ns'].split(' ') : [];
166
+ }
166
167
  namespaces.forEach(function (ns) {
167
168
  if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
168
169
  i18next.options.ns.push(ns);
@@ -216,7 +217,6 @@ function addRoute(i18next, route, lngs, app, verb, fc) {
216
217
  fc = verb;
217
218
  verb = 'get';
218
219
  }
219
-
220
220
  var callbacks = [fc].concat(Array.prototype.slice.call(arguments, 6));
221
221
  for (var i = 0, li = lngs.length; i < li; i++) {
222
222
  var parts = String(route).split('/');
package/cjs/utils.js CHANGED
@@ -51,7 +51,6 @@ function removeLngFromUrl(url, lookupFromPathIndex) {
51
51
  pos++;
52
52
  first = '/';
53
53
  }
54
-
55
54
  var parts = url.split('/');
56
55
  parts.splice(pos, 1);
57
56
  url = parts.join('/');
@@ -1,6 +1,9 @@
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); }
1
2
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
- 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); } }
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, _toPropertyKey(descriptor.key), descriptor); } }
3
4
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
5
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
6
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
7
  import * as utils from './utils.js';
5
8
  import cookieLookup from './languageLookups/cookie.js';
6
9
  import querystringLookup from './languageLookups/querystring.js';
@@ -79,7 +82,6 @@ var LanguageDetector = function () {
79
82
  found = detections.length > 0 ? detections[0] : null;
80
83
  }
81
84
  });
82
-
83
85
  if (!found) {
84
86
  var fallbacks = this.allOptions.fallbackLng;
85
87
  if (typeof fallbacks === 'function') fallbacks = fallbacks();
package/esm/index.d.ts ADDED
@@ -0,0 +1,179 @@
1
+ import {
2
+ Application,
3
+ Handler,
4
+ NextFunction,
5
+ Request,
6
+ RequestHandler,
7
+ Response,
8
+ Router,
9
+ } from "express-serve-static-core";
10
+ import * as i18next from "i18next";
11
+
12
+ /// <reference types="express-serve-static-core" />
13
+
14
+ type I18next = i18next.i18n;
15
+ type App = Application | Router;
16
+
17
+ type I18NextRequest = {
18
+ language: string;
19
+ languages: string[];
20
+ i18n: i18next.i18n;
21
+ t: i18next.TFunction;
22
+ };
23
+
24
+ declare global {
25
+ namespace Express {
26
+ interface Request extends I18NextRequest {}
27
+ }
28
+ }
29
+
30
+ declare module 'fastify' {
31
+ interface FastifyRequest extends I18NextRequest {}
32
+ }
33
+
34
+ interface ExtendedOptions extends Object {
35
+ getPath?: (req: Request) => string;
36
+ getOriginalUrl?: (req: Request) => string;
37
+ getUrl?: (req: Request) => string;
38
+ setUrl?: (req: Request, url: string) => void;
39
+ getParams?: (req: Request) => Object;
40
+ getSession?: (req: Request) => Object;
41
+ getQuery?: (req: Request) => Object;
42
+ getCookies?: (req: Request) => Object;
43
+ getBody?: (req: Request) => Object;
44
+ getHeaders?: (req: Request) => Object;
45
+ getHeader?: (res: Response, name: string) => Object;
46
+ setHeader?: (res: Response, name: string, value: string) => void;
47
+ setContentType?: (res: Response, type: string) => void;
48
+ setStatus?: (res: Response, code: number) => void;
49
+ send?: (res: Response, body: any) => void;
50
+ }
51
+
52
+ interface HandleOptions extends ExtendedOptions {
53
+ ignoreRoutes?: string[] | IgnoreRoutesFunction;
54
+ removeLngFromUrl?: boolean;
55
+ }
56
+
57
+ interface GetResourcesHandlerOptions extends ExtendedOptions {
58
+ maxAge?: number;
59
+ cache?: boolean;
60
+ lngParam?: string;
61
+ nsParam?: string;
62
+ }
63
+
64
+ interface MissingKeyHandlerOptions extends ExtendedOptions {
65
+ lngParam?: string;
66
+ nsParam?: string;
67
+ }
68
+
69
+ type IgnoreRoutesFunction = (
70
+ req: Request,
71
+ res: Response,
72
+ options: HandleOptions,
73
+ i18next: I18next
74
+ ) => boolean;
75
+
76
+ export function handle(i18next: I18next, options?: HandleOptions): Handler;
77
+
78
+ export function plugin(
79
+ instance: any,
80
+ options: HandleOptions & { i18next?: I18next },
81
+ next: NextFunction
82
+ ): Handler;
83
+
84
+ export function getResourcesHandler(
85
+ i18next: I18next,
86
+ options?: GetResourcesHandlerOptions
87
+ ): Handler;
88
+
89
+ export function missingKeyHandler(
90
+ i18next: I18next,
91
+ options?: MissingKeyHandlerOptions
92
+ ): Handler;
93
+
94
+ export function addRoute(
95
+ i18next: I18next,
96
+ route: string,
97
+ lngs: string[],
98
+ app: App,
99
+ verb: string,
100
+ fc: RequestHandler
101
+ ): void;
102
+
103
+ // LanguageDetector
104
+ type LanguageDetectorServices = any;
105
+ type LanguageDetectorOrder = string[];
106
+ type LanguageDetectorCaches = boolean | string[];
107
+ interface LanguageDetectorOptions {
108
+ order?: LanguageDetectorOrder;
109
+ lookupQuerystring?: string;
110
+ lookupCookie?: string;
111
+ lookupSession?: string;
112
+ lookupFromPathIndex?: number;
113
+ caches?: LanguageDetectorCaches;
114
+ cookieExpirationDate?: Date;
115
+ cookieDomain?: string;
116
+ }
117
+ interface LanguageDetectorAllOptions {
118
+ fallbackLng: boolean | string | string[];
119
+ }
120
+ interface LanguageDetectorInterfaceOptions {
121
+ [name: string]: any;
122
+ }
123
+ interface LanguageDetectorInterface {
124
+ name: string;
125
+
126
+ lookup: (
127
+ req: Request,
128
+ res: Response,
129
+ options?: LanguageDetectorInterfaceOptions
130
+ ) => string | string[] | undefined;
131
+
132
+ cacheUserLanguage?: (
133
+ req: Request,
134
+ res: Response,
135
+ lng: string,
136
+ options?: Object
137
+ ) => void;
138
+ }
139
+
140
+ export class LanguageDetector implements i18next.Module {
141
+ type: "languageDetector";
142
+
143
+ constructor(
144
+ services: LanguageDetectorServices,
145
+ options?: LanguageDetectorOptions,
146
+ allOptions?: LanguageDetectorAllOptions
147
+ );
148
+
149
+ constructor(
150
+ options?: LanguageDetectorOptions,
151
+ allOptions?: LanguageDetectorAllOptions
152
+ );
153
+
154
+ init(
155
+ services: LanguageDetectorServices,
156
+ options?: LanguageDetectorOptions,
157
+ allOptions?: LanguageDetectorAllOptions
158
+ ): void;
159
+
160
+ init(
161
+ options?: LanguageDetectorOptions,
162
+ allOptions?: LanguageDetectorAllOptions
163
+ ): void;
164
+
165
+ addDetector(detector: LanguageDetectorInterface): void;
166
+
167
+ detect(
168
+ req: Request,
169
+ res: Response,
170
+ detectionOrder: LanguageDetectorOrder
171
+ ): void;
172
+
173
+ cacheUserLanguage(
174
+ req: Request,
175
+ res: Response,
176
+ lng: string,
177
+ caches: LanguageDetectorCaches
178
+ ): void;
179
+ }
package/esm/index.js CHANGED
@@ -1,6 +1,9 @@
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); }
1
2
  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; }
3
- 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; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
6
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
7
  import * as utils from './utils.js';
5
8
  import LD from './LanguageDetector.js';
6
9
  import { extendOptionsWithDefaults } from './httpFunctions.js';
@@ -63,23 +66,19 @@ export function handle(i18next) {
63
66
  if (!lng && i18next.services.languageDetector) {
64
67
  lng = i18next.services.languageDetector.detect(req, res);
65
68
  }
66
-
67
69
  req.language = req.locale = req.lng = lng;
68
70
  if (lng && options.getHeader(res, 'Content-Language') !== lng) {
69
71
  options.setHeader(res, 'Content-Language', lng);
70
72
  }
71
73
  req.languages = i18next.services.languageUtils.toResolveHierarchy(lng);
72
-
73
74
  i18n.changeLanguage(lng || i18next.options.fallbackLng[0]);
74
75
  if (req.i18nextLookupName === 'path' && options.removeLngFromUrl) {
75
76
  options.setUrl(req, utils.removeLngFromUrl(options.getUrl(req), i18next.services.languageDetector.options.lookupFromPathIndex));
76
77
  }
77
78
  var t = i18n.t.bind(i18n);
78
79
  var exists = i18n.exists.bind(i18n);
79
-
80
80
  req.i18n = i18n;
81
81
  req.t = t;
82
-
83
82
  if (options.attachLocals) res.locals = res.locals || {};
84
83
  if (res.locals) {
85
84
  res.locals.t = t;
@@ -143,7 +142,10 @@ export function getResourcesHandler(i18next) {
143
142
  }
144
143
  var languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : [];
145
144
  var namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : [];
146
-
145
+ if (languages.length === 0 && namespaces.length === 0) {
146
+ languages = options.getParams(req)[options.lngParam || 'lng'] ? options.getParams(req)[options.lngParam || 'lng'].split(' ') : [];
147
+ namespaces = options.getParams(req)[options.nsParam || 'ns'] ? options.getParams(req)[options.nsParam || 'ns'].split(' ') : [];
148
+ }
147
149
  namespaces.forEach(function (ns) {
148
150
  if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
149
151
  i18next.options.ns.push(ns);
@@ -197,7 +199,6 @@ export function addRoute(i18next, route, lngs, app, verb, fc) {
197
199
  fc = verb;
198
200
  verb = 'get';
199
201
  }
200
-
201
202
  var callbacks = [fc].concat(Array.prototype.slice.call(arguments, 6));
202
203
  for (var i = 0, li = lngs.length; i < li; i++) {
203
204
  var parts = String(route).split('/');
@@ -1,4 +1,3 @@
1
-
2
1
  var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
3
2
  var serializeCookie = function serializeCookie(name, val, options) {
4
3
  var opt = options || {};
package/esm/utils.js CHANGED
@@ -42,7 +42,6 @@ export function removeLngFromUrl(url, lookupFromPathIndex) {
42
42
  pos++;
43
43
  first = '/';
44
44
  }
45
-
46
45
  var parts = url.split('/');
47
46
  parts.splice(pos, 1);
48
47
  url = parts.join('/');
package/lib/index.js CHANGED
@@ -176,13 +176,24 @@ export function getResourcesHandler (i18next, options = {}) {
176
176
  options.setHeader(res, 'Cache-Control', 'no-cache')
177
177
  }
178
178
 
179
- const languages = options.getQuery(req)[options.lngParam || 'lng']
179
+ // first check query
180
+ let languages = options.getQuery(req)[options.lngParam || 'lng']
180
181
  ? options.getQuery(req)[options.lngParam || 'lng'].split(' ')
181
182
  : []
182
- const namespaces = options.getQuery(req)[options.nsParam || 'ns']
183
+ let namespaces = options.getQuery(req)[options.nsParam || 'ns']
183
184
  ? options.getQuery(req)[options.nsParam || 'ns'].split(' ')
184
185
  : []
185
186
 
187
+ // then check route params
188
+ if (languages.length === 0 && namespaces.length === 0) {
189
+ languages = options.getParams(req)[options.lngParam || 'lng']
190
+ ? options.getParams(req)[options.lngParam || 'lng'].split(' ')
191
+ : []
192
+ namespaces = options.getParams(req)[options.nsParam || 'ns']
193
+ ? options.getParams(req)[options.nsParam || 'ns'].split(' ')
194
+ : []
195
+ }
196
+
186
197
  // extend ns
187
198
  namespaces.forEach(ns => {
188
199
  if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-http-middleware",
3
- "version": "3.2.2",
3
+ "version": "3.3.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./cjs/index.js",
@@ -8,39 +8,47 @@
8
8
  "exports": {
9
9
  "./package.json": "./package.json",
10
10
  ".": {
11
+ "types": {
12
+ "require": "./cjs/index.d.ts",
13
+ "import": "./esm/index.d.ts"
14
+ },
15
+ "module": "./esm/index.js",
16
+ "import": "./esm/index.js",
11
17
  "require": "./cjs/index.js",
12
18
  "default": "./esm/index.js"
13
19
  },
14
20
  "./cjs": {
21
+ "types": "./cjs/index.d.ts",
15
22
  "default": "./cjs/index.js"
16
23
  },
17
24
  "./esm": {
25
+ "types": "./esm/index.d.ts",
18
26
  "default": "./esm/index.js"
19
27
  }
20
28
  },
21
29
  "module": "./esm/index.js",
22
30
  "dependencies": {},
23
31
  "devDependencies": {
24
- "@babel/cli": "7.19.3",
25
- "@babel/core": "7.19.6",
26
- "@babel/preset-env": "7.19.4",
32
+ "@babel/cli": "7.21.5",
33
+ "@babel/core": "7.21.8",
34
+ "@babel/preset-env": "7.21.5",
27
35
  "@hapi/hapi": "^20.2.2",
28
- "@types/express-serve-static-core": "^4.17.31",
36
+ "@types/express-serve-static-core": "^4.17.35",
29
37
  "babel-plugin-add-module-exports": "1.0.4",
30
- "eslint": "8.26.0",
38
+ "eslint": "8.41.0",
31
39
  "eslint-config-standard": "17.0.0",
32
- "eslint-plugin-import": "2.26.0",
33
- "eslint-plugin-n": "15.3.0",
40
+ "eslint-plugin-import": "2.27.5",
41
+ "eslint-plugin-n": "15.7.0",
34
42
  "eslint-plugin-promise": "6.1.1",
35
43
  "eslint-plugin-require-path-exists": "1.1.9",
36
44
  "eslint-plugin-standard": "5.0.0",
37
45
  "expect.js": "0.3.1",
38
46
  "express": "4.18.2",
39
- "fastify": "4.9.2",
40
- "i18next": "22.0.2",
41
- "mocha": "10.1.0",
42
- "supertest": "6.3.1",
43
- "tsd": "0.24.1",
47
+ "fastify": "4.17.0",
48
+ "i18next": "22.5.0",
49
+ "mocha": "10.2.0",
50
+ "supertest": "6.3.3",
51
+ "tsd": "0.28.1",
44
52
  "uglify-js": "3.17.4"
45
53
  },
46
54
  "description": "i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.",
@@ -61,8 +69,8 @@
61
69
  "license": "MIT",
62
70
  "scripts": {
63
71
  "lint": "eslint .",
64
- "compile:esm": "rm -rf esm && mkdir esm && BABEL_ENV=esm babel lib -d esm",
65
- "compile:cjs": "rm -rf cjs && mkdir cjs && BABEL_ENV=cjs babel lib -d cjs && echo '{\"type\":\"commonjs\"}' > cjs/package.json",
72
+ "compile:esm": "rm -rf esm && mkdir esm && BABEL_ENV=esm babel lib -d esm && cp index.d.ts esm/index.d.ts",
73
+ "compile:cjs": "rm -rf cjs && mkdir cjs && BABEL_ENV=cjs babel lib -d cjs && cp index.d.ts cjs/index.d.ts && echo '{\"type\":\"commonjs\"}' > cjs/package.json",
66
74
  "compile": "npm run compile:esm && npm run compile:cjs",
67
75
  "build": "npm run compile",
68
76
  "test": "npm run lint && npm run build && mocha test -R spec --exit --experimental-modules && npm run test:types",