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 +20 -1
- package/cjs/LanguageDetector.js +4 -3
- package/cjs/index.d.ts +179 -0
- package/cjs/index.js +8 -8
- package/cjs/utils.js +0 -1
- package/esm/LanguageDetector.js +4 -2
- package/esm/index.d.ts +179 -0
- package/esm/index.js +8 -7
- package/esm/languageLookups/cookie.js +0 -1
- package/esm/utils.js +0 -1
- package/lib/index.js +13 -2
- package/package.json +23 -15
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>
|
package/cjs/LanguageDetector.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
|
});
|
|
@@ -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
package/esm/LanguageDetector.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 _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('/');
|
package/esm/utils.js
CHANGED
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
25
|
-
"@babel/core": "7.
|
|
26
|
-
"@babel/preset-env": "7.
|
|
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.
|
|
36
|
+
"@types/express-serve-static-core": "^4.17.35",
|
|
29
37
|
"babel-plugin-add-module-exports": "1.0.4",
|
|
30
|
-
"eslint": "8.
|
|
38
|
+
"eslint": "8.41.0",
|
|
31
39
|
"eslint-config-standard": "17.0.0",
|
|
32
|
-
"eslint-plugin-import": "2.
|
|
33
|
-
"eslint-plugin-n": "15.
|
|
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.
|
|
40
|
-
"i18next": "22.0
|
|
41
|
-
"mocha": "10.
|
|
42
|
-
"supertest": "6.3.
|
|
43
|
-
"tsd": "0.
|
|
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",
|