i18next-http-middleware 2.1.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +2 -11
- package/cjs/LanguageDetector.js +19 -61
- package/cjs/httpFunctions.js +1 -2
- package/cjs/index.js +14 -22
- package/cjs/languageLookups/cookie.js +2 -3
- package/cjs/languageLookups/header.js +13 -3
- package/cjs/languageLookups/path.js +2 -3
- package/cjs/languageLookups/querystring.js +2 -2
- package/cjs/languageLookups/session.js +2 -2
- package/cjs/utils.js +1 -2
- package/esm/LanguageDetector.js +119 -0
- package/esm/httpFunctions.js +120 -0
- package/esm/index.js +229 -0
- package/esm/languageLookups/cookie.js +112 -0
- package/esm/languageLookups/header.js +59 -0
- package/esm/languageLookups/path.js +29 -0
- package/esm/languageLookups/querystring.js +35 -0
- package/esm/languageLookups/session.js +21 -0
- package/esm/utils.js +55 -0
- package/lib/LanguageDetector.js +6 -42
- package/lib/languageLookups/header.js +8 -1
- package/package.json +17 -12
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export var getPath = function getPath(req) {
|
|
2
|
+
if (req.path) return req.path;
|
|
3
|
+
if (req.raw && req.raw.path) return req.raw.path;
|
|
4
|
+
if (req.url) return req.url;
|
|
5
|
+
console.log('no possibility found to get path');
|
|
6
|
+
};
|
|
7
|
+
export var getUrl = function getUrl(req) {
|
|
8
|
+
if (req.url) return req.url;
|
|
9
|
+
if (req.raw && req.raw.url) return req.raw.url;
|
|
10
|
+
console.log('no possibility found to get url');
|
|
11
|
+
};
|
|
12
|
+
export var setUrl = function setUrl(req, url) {
|
|
13
|
+
if (req.url) {
|
|
14
|
+
req.url = url;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
console.log('no possibility found to get url');
|
|
19
|
+
};
|
|
20
|
+
export var getOriginalUrl = function getOriginalUrl(req) {
|
|
21
|
+
if (req.originalUrl) return req.originalUrl;
|
|
22
|
+
if (req.raw && req.raw.originalUrl) return req.raw.originalUrl;
|
|
23
|
+
return getUrl(req);
|
|
24
|
+
};
|
|
25
|
+
export var getQuery = function getQuery(req) {
|
|
26
|
+
if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function') return Object.fromEntries(req.query);
|
|
27
|
+
if (req.query) return req.query;
|
|
28
|
+
if (req.raw && req.raw.query) return req.raw.query;
|
|
29
|
+
if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams;
|
|
30
|
+
var url = req.url || req.raw && req.raw.url;
|
|
31
|
+
if (url && url.indexOf('?') < 0) return {};
|
|
32
|
+
console.log('no possibility found to get query');
|
|
33
|
+
return {};
|
|
34
|
+
};
|
|
35
|
+
export var getParams = function getParams(req) {
|
|
36
|
+
if (req.params) return req.params;
|
|
37
|
+
if (req.raw && req.raw.params) return req.raw.params;
|
|
38
|
+
if (req.ctx && req.ctx.params) return req.ctx.params;
|
|
39
|
+
console.log('no possibility found to get params');
|
|
40
|
+
return {};
|
|
41
|
+
};
|
|
42
|
+
export var getHeaders = function getHeaders(req) {
|
|
43
|
+
if (req.headers) return req.headers;
|
|
44
|
+
console.log('no possibility found to get headers');
|
|
45
|
+
};
|
|
46
|
+
export var getCookies = function getCookies(req) {
|
|
47
|
+
if (req.cookies) return req.cookies;
|
|
48
|
+
|
|
49
|
+
if (getHeaders(req)) {
|
|
50
|
+
var list = {};
|
|
51
|
+
var rc = getHeaders(req).cookie;
|
|
52
|
+
rc && rc.split(';').forEach(function (cookie) {
|
|
53
|
+
var parts = cookie.split('=');
|
|
54
|
+
list[parts.shift().trim()] = decodeURI(parts.join('='));
|
|
55
|
+
});
|
|
56
|
+
return list;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log('no possibility found to get cookies');
|
|
60
|
+
};
|
|
61
|
+
export var getBody = function getBody(req) {
|
|
62
|
+
if (req.ctx && req.ctx.body) return req.ctx.body.bind(req.ctx);
|
|
63
|
+
if (req.json) return req.json;
|
|
64
|
+
if (req.body) return req.body;
|
|
65
|
+
console.log('no possibility found to get body');
|
|
66
|
+
return {};
|
|
67
|
+
};
|
|
68
|
+
export var getHeader = function getHeader(res, name) {
|
|
69
|
+
if (res.getHeader) return res.getHeader(name);
|
|
70
|
+
if (res.headers) return res.headers[name];
|
|
71
|
+
if (getHeaders(res) && getHeaders(res)[name]) return getHeaders(res)[name];
|
|
72
|
+
console.log('no possibility found to get header');
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
export var setHeader = function setHeader(res, name, value) {
|
|
76
|
+
if (res._headerSent || res.headersSent) return;
|
|
77
|
+
if (typeof res.setHeader === 'function') return res.setHeader(name, value);
|
|
78
|
+
if (typeof res.header === 'function') return res.header(name, value);
|
|
79
|
+
if (res.responseHeaders && typeof res.responseHeaders.set === 'function') return res.responseHeaders.set(name, value);
|
|
80
|
+
if (res.headers && typeof res.headers.set === 'function') return res.headers.set(name, value);
|
|
81
|
+
console.log('no possibility found to set header');
|
|
82
|
+
};
|
|
83
|
+
export var setContentType = function setContentType(res, type) {
|
|
84
|
+
if (typeof res.contentType === 'function') return res.contentType(type);
|
|
85
|
+
if (typeof res.type === 'function') return res.type(type);
|
|
86
|
+
setHeader(res, 'Content-Type', type);
|
|
87
|
+
};
|
|
88
|
+
export var setStatus = function setStatus(res, code) {
|
|
89
|
+
if (typeof res.status === 'function') return res.status(code);
|
|
90
|
+
if (res.status) return res.status = code;
|
|
91
|
+
console.log('no possibility found to set status');
|
|
92
|
+
};
|
|
93
|
+
export var send = function send(res, body) {
|
|
94
|
+
if (typeof res.send === 'function') return res.send(body);
|
|
95
|
+
return body;
|
|
96
|
+
};
|
|
97
|
+
export var getSession = function getSession(req) {
|
|
98
|
+
if (req.session) return req.session;
|
|
99
|
+
if (req.raw && req.raw.session) return req.raw.session;
|
|
100
|
+
console.log('no possibility found to get session');
|
|
101
|
+
};
|
|
102
|
+
export var extendOptionsWithDefaults = function extendOptionsWithDefaults() {
|
|
103
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
104
|
+
options.getPath = options.getPath || getPath;
|
|
105
|
+
options.getOriginalUrl = options.getOriginalUrl || getOriginalUrl;
|
|
106
|
+
options.getUrl = options.getUrl || getUrl;
|
|
107
|
+
options.setUrl = options.setUrl || setUrl;
|
|
108
|
+
options.getParams = options.getParams || getParams;
|
|
109
|
+
options.getSession = options.getSession || getSession;
|
|
110
|
+
options.getQuery = options.getQuery || getQuery;
|
|
111
|
+
options.getCookies = options.getCookies || getCookies;
|
|
112
|
+
options.getBody = options.getBody || getBody;
|
|
113
|
+
options.getHeaders = options.getHeaders || getHeaders;
|
|
114
|
+
options.getHeader = options.getHeader || getHeader;
|
|
115
|
+
options.setHeader = options.setHeader || setHeader;
|
|
116
|
+
options.setContentType = options.setContentType || setContentType;
|
|
117
|
+
options.setStatus = options.setStatus || setStatus;
|
|
118
|
+
options.send = options.send || send;
|
|
119
|
+
return options;
|
|
120
|
+
};
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import * as utils from './utils.js';
|
|
2
|
+
import LD from './LanguageDetector.js';
|
|
3
|
+
import { extendOptionsWithDefaults } from './httpFunctions.js';
|
|
4
|
+
export var LanguageDetector = LD;
|
|
5
|
+
|
|
6
|
+
var checkForCombinedReqRes = function checkForCombinedReqRes(req, res, next) {
|
|
7
|
+
if (!res) {
|
|
8
|
+
if (req.request && req.response) {
|
|
9
|
+
res = req.response;
|
|
10
|
+
if (!req.request.ctx) req.request.ctx = req;
|
|
11
|
+
req = req.request;
|
|
12
|
+
if (!next) next = function next() {};
|
|
13
|
+
} else if (req.respond) {
|
|
14
|
+
res = req;
|
|
15
|
+
if (!next) next = function next() {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
req: req,
|
|
21
|
+
res: res,
|
|
22
|
+
next: next
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function handle(i18next) {
|
|
27
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
28
|
+
extendOptionsWithDefaults(options);
|
|
29
|
+
return function i18nextMiddleware(rq, rs, n) {
|
|
30
|
+
var _checkForCombinedReqR = checkForCombinedReqRes(rq, rs, n),
|
|
31
|
+
req = _checkForCombinedReqR.req,
|
|
32
|
+
res = _checkForCombinedReqR.res,
|
|
33
|
+
next = _checkForCombinedReqR.next;
|
|
34
|
+
|
|
35
|
+
if (typeof options.ignoreRoutes === 'function') {
|
|
36
|
+
if (options.ignoreRoutes(req, res, options, i18next)) {
|
|
37
|
+
return next();
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
var ignores = options.ignoreRoutes instanceof Array && options.ignoreRoutes || [];
|
|
41
|
+
|
|
42
|
+
for (var i = 0; i < ignores.length; i++) {
|
|
43
|
+
if (options.getPath(req).indexOf(ignores[i]) > -1) return next();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var i18n = i18next.cloneInstance({
|
|
48
|
+
initImmediate: false
|
|
49
|
+
});
|
|
50
|
+
i18n.on('languageChanged', function (lng) {
|
|
51
|
+
req.language = req.locale = req.lng = lng;
|
|
52
|
+
|
|
53
|
+
if (res.locals) {
|
|
54
|
+
res.locals.language = lng;
|
|
55
|
+
res.locals.languageDir = i18next.dir(lng);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (lng && options.getHeader(res, 'Content-Language') !== lng) {
|
|
59
|
+
options.setHeader(res, 'Content-Language', lng);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
req.languages = i18next.services.languageUtils.toResolveHierarchy(lng);
|
|
63
|
+
|
|
64
|
+
if (i18next.services.languageDetector) {
|
|
65
|
+
i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
var lng = req.lng;
|
|
69
|
+
if (!lng && i18next.services.languageDetector) lng = i18next.services.languageDetector.detect(req, res);
|
|
70
|
+
req.language = req.locale = req.lng = lng;
|
|
71
|
+
|
|
72
|
+
if (lng && options.getHeader(res, 'Content-Language') !== lng) {
|
|
73
|
+
options.setHeader(res, 'Content-Language', lng);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
req.languages = i18next.services.languageUtils.toResolveHierarchy(lng);
|
|
77
|
+
i18n.changeLanguage(lng || i18next.options.fallbackLng[0]);
|
|
78
|
+
|
|
79
|
+
if (req.i18nextLookupName === 'path' && options.removeLngFromUrl) {
|
|
80
|
+
options.setUrl(req, utils.removeLngFromUrl(options.getUrl(req), i18next.services.languageDetector.options.lookupFromPathIndex));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
var t = i18n.t.bind(i18n);
|
|
84
|
+
var exists = i18n.exists.bind(i18n);
|
|
85
|
+
req.i18n = i18n;
|
|
86
|
+
req.t = t;
|
|
87
|
+
|
|
88
|
+
if (res.locals) {
|
|
89
|
+
res.locals.t = t;
|
|
90
|
+
res.locals.exists = exists;
|
|
91
|
+
res.locals.i18n = i18n;
|
|
92
|
+
res.locals.language = lng;
|
|
93
|
+
res.locals.languageDir = i18next.dir(lng);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (i18next.services.languageDetector) i18next.services.languageDetector.cacheUserLanguage(req, res, lng);
|
|
97
|
+
if (!req.lng) return next();
|
|
98
|
+
i18next.loadLanguages(req.lng, function () {
|
|
99
|
+
return next();
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export function plugin(instance, options, next) {
|
|
104
|
+
var middleware = handle(options.i18next, options);
|
|
105
|
+
instance.addHook('preHandler', function (request, reply, next) {
|
|
106
|
+
return middleware(request, reply, next);
|
|
107
|
+
});
|
|
108
|
+
return next();
|
|
109
|
+
}
|
|
110
|
+
plugin[Symbol.for('skip-override')] = true;
|
|
111
|
+
export function getResourcesHandler(i18next) {
|
|
112
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
113
|
+
extendOptionsWithDefaults(options);
|
|
114
|
+
var maxAge = options.maxAge || 60 * 60 * 24 * 30;
|
|
115
|
+
return function (rq, rs) {
|
|
116
|
+
var _checkForCombinedReqR2 = checkForCombinedReqRes(rq, rs),
|
|
117
|
+
req = _checkForCombinedReqR2.req,
|
|
118
|
+
res = _checkForCombinedReqR2.res;
|
|
119
|
+
|
|
120
|
+
if (!i18next.services.backendConnector) {
|
|
121
|
+
options.setStatus(res, 404);
|
|
122
|
+
return options.send(res, 'i18next-express-middleware:: no backend configured');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var resources = {};
|
|
126
|
+
options.setContentType(res, 'application/json');
|
|
127
|
+
|
|
128
|
+
if (options.cache !== undefined ? options.cache : typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production') {
|
|
129
|
+
options.setHeader(res, 'Cache-Control', 'public, max-age=' + maxAge);
|
|
130
|
+
options.setHeader(res, 'Expires', new Date(new Date().getTime() + maxAge * 1000).toUTCString());
|
|
131
|
+
} else {
|
|
132
|
+
options.setHeader(res, 'Pragma', 'no-cache');
|
|
133
|
+
options.setHeader(res, 'Cache-Control', 'no-cache');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var languages = options.getQuery(req)[options.lngParam || 'lng'] ? options.getQuery(req)[options.lngParam || 'lng'].split(' ') : [];
|
|
137
|
+
var namespaces = options.getQuery(req)[options.nsParam || 'ns'] ? options.getQuery(req)[options.nsParam || 'ns'].split(' ') : [];
|
|
138
|
+
namespaces.forEach(function (ns) {
|
|
139
|
+
if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) i18next.options.ns.push(ns);
|
|
140
|
+
});
|
|
141
|
+
i18next.services.backendConnector.load(languages, namespaces, function () {
|
|
142
|
+
languages.forEach(function (lng) {
|
|
143
|
+
namespaces.forEach(function (ns) {
|
|
144
|
+
utils.setPath(resources, [lng, ns], i18next.getResourceBundle(lng, ns));
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
return options.send(res, resources);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export function missingKeyHandler(i18next) {
|
|
152
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
153
|
+
extendOptionsWithDefaults(options);
|
|
154
|
+
return function (rq, rs) {
|
|
155
|
+
var _checkForCombinedReqR3 = checkForCombinedReqRes(rq, rs),
|
|
156
|
+
req = _checkForCombinedReqR3.req,
|
|
157
|
+
res = _checkForCombinedReqR3.res;
|
|
158
|
+
|
|
159
|
+
var lng = options.getParams(req)[options.lngParam || 'lng'];
|
|
160
|
+
var ns = options.getParams(req)[options.nsParam || 'ns'];
|
|
161
|
+
|
|
162
|
+
if (!i18next.services.backendConnector) {
|
|
163
|
+
options.setStatus(res, 404);
|
|
164
|
+
return options.send(res, 'i18next-express-middleware:: no backend configured');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var body = options.getBody(req);
|
|
168
|
+
|
|
169
|
+
if (typeof body === 'function') {
|
|
170
|
+
var promise = body();
|
|
171
|
+
|
|
172
|
+
if (promise && typeof promise.then === 'function') {
|
|
173
|
+
return new Promise(function (resolve) {
|
|
174
|
+
promise.then(function (b) {
|
|
175
|
+
for (var m in b) {
|
|
176
|
+
i18next.services.backendConnector.saveMissing([lng], ns, m, b[m]);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
resolve(options.send(res, 'ok'));
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
for (var m in body) {
|
|
186
|
+
i18next.services.backendConnector.saveMissing([lng], ns, m, body[m]);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return options.send(res, 'ok');
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
export function addRoute(i18next, route, lngs, app, verb, fc) {
|
|
193
|
+
if (typeof verb === 'function') {
|
|
194
|
+
fc = verb;
|
|
195
|
+
verb = 'get';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
var callbacks = [fc].concat(Array.prototype.slice.call(arguments, 6));
|
|
199
|
+
|
|
200
|
+
for (var i = 0, li = lngs.length; i < li; i++) {
|
|
201
|
+
var parts = String(route).split('/');
|
|
202
|
+
var locRoute = [];
|
|
203
|
+
|
|
204
|
+
for (var y = 0, ly = parts.length; y < ly; y++) {
|
|
205
|
+
var part = parts[y];
|
|
206
|
+
|
|
207
|
+
if (part === ':lng') {
|
|
208
|
+
locRoute.push(lngs[i]);
|
|
209
|
+
} else if (part.indexOf(':') === 0 || part === '') {
|
|
210
|
+
locRoute.push(part);
|
|
211
|
+
} else {
|
|
212
|
+
locRoute.push(i18next.t(part, {
|
|
213
|
+
lng: lngs[i]
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
var routes = [locRoute.join('/')];
|
|
219
|
+
app[verb || 'get'].apply(app, routes.concat(callbacks));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
export default {
|
|
223
|
+
plugin: plugin,
|
|
224
|
+
handle: handle,
|
|
225
|
+
getResourcesHandler: getResourcesHandler,
|
|
226
|
+
missingKeyHandler: missingKeyHandler,
|
|
227
|
+
addRoute: addRoute,
|
|
228
|
+
LanguageDetector: LanguageDetector
|
|
229
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
|
2
|
+
|
|
3
|
+
var serializeCookie = function serializeCookie(name, val, options) {
|
|
4
|
+
var opt = options || {};
|
|
5
|
+
opt.path = opt.path || '/';
|
|
6
|
+
var value = encodeURIComponent(val);
|
|
7
|
+
var str = name + '=' + value;
|
|
8
|
+
|
|
9
|
+
if (opt.maxAge > 0) {
|
|
10
|
+
var maxAge = opt.maxAge - 0;
|
|
11
|
+
if (isNaN(maxAge)) throw new Error('maxAge should be a Number');
|
|
12
|
+
str += '; Max-Age=' + Math.floor(maxAge);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (opt.domain) {
|
|
16
|
+
if (!fieldContentRegExp.test(opt.domain)) {
|
|
17
|
+
throw new TypeError('option domain is invalid');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
str += '; Domain=' + opt.domain;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (opt.path) {
|
|
24
|
+
if (!fieldContentRegExp.test(opt.path)) {
|
|
25
|
+
throw new TypeError('option path is invalid');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
str += '; Path=' + opt.path;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (opt.expires) {
|
|
32
|
+
if (typeof opt.expires.toUTCString !== 'function') {
|
|
33
|
+
throw new TypeError('option expires is invalid');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
str += '; Expires=' + opt.expires.toUTCString();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (opt.httpOnly) str += '; HttpOnly';
|
|
40
|
+
if (opt.secure) str += '; Secure';
|
|
41
|
+
|
|
42
|
+
if (opt.sameSite) {
|
|
43
|
+
var sameSite = typeof opt.sameSite === 'string' ? opt.sameSite.toLowerCase() : opt.sameSite;
|
|
44
|
+
|
|
45
|
+
switch (sameSite) {
|
|
46
|
+
case true:
|
|
47
|
+
str += '; SameSite=Strict';
|
|
48
|
+
break;
|
|
49
|
+
|
|
50
|
+
case 'lax':
|
|
51
|
+
str += '; SameSite=Lax';
|
|
52
|
+
break;
|
|
53
|
+
|
|
54
|
+
case 'strict':
|
|
55
|
+
str += '; SameSite=Strict';
|
|
56
|
+
break;
|
|
57
|
+
|
|
58
|
+
case 'none':
|
|
59
|
+
str += '; SameSite=None';
|
|
60
|
+
break;
|
|
61
|
+
|
|
62
|
+
default:
|
|
63
|
+
throw new TypeError('option sameSite is invalid');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return str;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default {
|
|
71
|
+
name: 'cookie',
|
|
72
|
+
lookup: function lookup(req, res, options) {
|
|
73
|
+
var found;
|
|
74
|
+
|
|
75
|
+
if (options.lookupCookie && typeof req !== 'undefined') {
|
|
76
|
+
var cookies = options.getCookies(req);
|
|
77
|
+
found = cookies[options.lookupCookie];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return found;
|
|
81
|
+
},
|
|
82
|
+
cacheUserLanguage: function cacheUserLanguage(req, res, lng) {
|
|
83
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
84
|
+
|
|
85
|
+
if (options.lookupCookie && req !== 'undefined') {
|
|
86
|
+
var expirationDate = options.cookieExpirationDate;
|
|
87
|
+
|
|
88
|
+
if (!expirationDate) {
|
|
89
|
+
expirationDate = new Date();
|
|
90
|
+
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var cookieOptions = {
|
|
94
|
+
expires: expirationDate,
|
|
95
|
+
domain: options.cookieDomain,
|
|
96
|
+
path: options.cookiePath,
|
|
97
|
+
httpOnly: false,
|
|
98
|
+
overwrite: true,
|
|
99
|
+
sameSite: options.cookieSameSite
|
|
100
|
+
};
|
|
101
|
+
if (options.cookieSecure) cookieOptions.secure = options.cookieSecure;
|
|
102
|
+
var existingCookie = options.getHeader(res, 'set-cookie') || options.getHeader(res, 'Set-Cookie') || [];
|
|
103
|
+
if (typeof existingCookie === 'string') existingCookie = [existingCookie];
|
|
104
|
+
if (!Array.isArray(existingCookie)) existingCookie = [];
|
|
105
|
+
existingCookie = existingCookie.filter(function (c) {
|
|
106
|
+
return c.indexOf("".concat(options.lookupCookie, "=")) !== 0;
|
|
107
|
+
});
|
|
108
|
+
existingCookie.push(serializeCookie(options.lookupCookie, lng, cookieOptions));
|
|
109
|
+
options.setHeader(res, 'Set-Cookie', existingCookie.length === 1 ? existingCookie[0] : existingCookie);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab'];
|
|
2
|
+
export default {
|
|
3
|
+
name: 'header',
|
|
4
|
+
lookup: function lookup(req, res, options) {
|
|
5
|
+
var found;
|
|
6
|
+
|
|
7
|
+
if (typeof req !== 'undefined') {
|
|
8
|
+
var headers = options.getHeaders(req);
|
|
9
|
+
if (!headers) return found;
|
|
10
|
+
var locales = [];
|
|
11
|
+
var acceptLanguage = options.lookupHeader ? headers[options.lookupHeader] : headers['accept-language'];
|
|
12
|
+
|
|
13
|
+
if (acceptLanguage) {
|
|
14
|
+
var lookupRegex = /(([a-z]{2})-?([A-Z]{2})?)\s*;?\s*(q=([0-9.]+))?/gi;
|
|
15
|
+
|
|
16
|
+
if (acceptLanguage.indexOf('-') > 0) {
|
|
17
|
+
var foundSpecialCase = specialCases.find(function (s) {
|
|
18
|
+
return acceptLanguage.toLowerCase().indexOf("-".concat(s)) > 0;
|
|
19
|
+
});
|
|
20
|
+
if (foundSpecialCase) lookupRegex = /(([a-z]{2})-?([A-Z]{4})?)\s*;?\s*(q=([0-9.]+))?/gi;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var lngs = [];
|
|
24
|
+
var i;
|
|
25
|
+
var m;
|
|
26
|
+
var rgx = options.lookupHeaderRegex || lookupRegex;
|
|
27
|
+
|
|
28
|
+
do {
|
|
29
|
+
m = rgx.exec(acceptLanguage);
|
|
30
|
+
|
|
31
|
+
if (m) {
|
|
32
|
+
var lng = m[1];
|
|
33
|
+
var weight = m[5] || '1';
|
|
34
|
+
var q = Number(weight);
|
|
35
|
+
|
|
36
|
+
if (lng && !isNaN(q)) {
|
|
37
|
+
lngs.push({
|
|
38
|
+
lng: lng,
|
|
39
|
+
q: q
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} while (m);
|
|
44
|
+
|
|
45
|
+
lngs.sort(function (a, b) {
|
|
46
|
+
return b.q - a.q;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
for (i = 0; i < lngs.length; i++) {
|
|
50
|
+
locales.push(lngs[i].lng);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (locales.length) found = locales;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return found;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
name: 'path',
|
|
3
|
+
lookup: function lookup(req, res, options) {
|
|
4
|
+
var found;
|
|
5
|
+
|
|
6
|
+
if (req === undefined) {
|
|
7
|
+
return found;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (options.lookupPath !== undefined && req.params) {
|
|
11
|
+
found = options.getParams(req)[options.lookupPath];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!found && typeof options.lookupFromPathIndex === 'number' && options.getOriginalUrl(req)) {
|
|
15
|
+
var path = options.getOriginalUrl(req).split('?')[0];
|
|
16
|
+
var parts = path.split('/');
|
|
17
|
+
|
|
18
|
+
if (parts[0] === '') {
|
|
19
|
+
parts.shift();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (parts.length > options.lookupFromPathIndex) {
|
|
23
|
+
found = parts[options.lookupFromPathIndex];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return found;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
name: 'querystring',
|
|
3
|
+
lookup: function lookup(req, res, options) {
|
|
4
|
+
var found;
|
|
5
|
+
|
|
6
|
+
if (options.lookupQuerystring !== undefined && typeof req !== 'undefined') {
|
|
7
|
+
if (options.getQuery(req)) {
|
|
8
|
+
found = options.getQuery(req)[options.lookupQuerystring];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!found && options.getUrl(req) && options.getUrl(req).indexOf('?')) {
|
|
12
|
+
var lastPartOfUri = options.getUrl(req).substring(options.getUrl(req).indexOf('?'));
|
|
13
|
+
|
|
14
|
+
if (typeof URLSearchParams !== 'undefined') {
|
|
15
|
+
var urlParams = new URLSearchParams(lastPartOfUri);
|
|
16
|
+
found = urlParams.get(options.lookupQuerystring);
|
|
17
|
+
} else {
|
|
18
|
+
var indexOfQsStart = lastPartOfUri.indexOf("".concat(options.lookupQuerystring, "="));
|
|
19
|
+
|
|
20
|
+
if (indexOfQsStart > -1) {
|
|
21
|
+
var restOfUri = lastPartOfUri.substring(options.lookupQuerystring.length + 2);
|
|
22
|
+
|
|
23
|
+
if (restOfUri.indexOf('&') < 0) {
|
|
24
|
+
found = restOfUri;
|
|
25
|
+
} else {
|
|
26
|
+
found = restOfUri.substring(0, restOfUri.indexOf('&'));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return found;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
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); }
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: 'session',
|
|
5
|
+
lookup: function lookup(req, res, options) {
|
|
6
|
+
var found;
|
|
7
|
+
|
|
8
|
+
if (options.lookupSession !== undefined && _typeof(req) && options.getSession(req)) {
|
|
9
|
+
found = options.getSession(req)[options.lookupSession];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return found;
|
|
13
|
+
},
|
|
14
|
+
cacheUserLanguage: function cacheUserLanguage(req, res, lng) {
|
|
15
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
16
|
+
|
|
17
|
+
if (options.lookupSession && req && options.getSession(req)) {
|
|
18
|
+
options.getSession(req)[options.lookupSession] = lng;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
package/esm/utils.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function setPath(object, path, newValue) {
|
|
2
|
+
var stack;
|
|
3
|
+
if (typeof path !== 'string') stack = [].concat(path);
|
|
4
|
+
if (typeof path === 'string') stack = path.split('.');
|
|
5
|
+
|
|
6
|
+
while (stack.length > 1) {
|
|
7
|
+
var _key = stack.shift();
|
|
8
|
+
|
|
9
|
+
if (_key.indexOf('###') > -1) _key = _key.replace(/###/g, '.');
|
|
10
|
+
if (!object[_key]) object[_key] = {};
|
|
11
|
+
object = object[_key];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var key = stack.shift();
|
|
15
|
+
if (key.indexOf('###') > -1) key = key.replace(/###/g, '.');
|
|
16
|
+
object[key] = newValue;
|
|
17
|
+
}
|
|
18
|
+
var arr = [];
|
|
19
|
+
var each = arr.forEach;
|
|
20
|
+
var slice = arr.slice;
|
|
21
|
+
export function defaults(obj) {
|
|
22
|
+
each.call(slice.call(arguments, 1), function (source) {
|
|
23
|
+
if (source) {
|
|
24
|
+
for (var prop in source) {
|
|
25
|
+
if (obj[prop] === undefined) obj[prop] = source[prop];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
export function extend(obj) {
|
|
32
|
+
each.call(slice.call(arguments, 1), function (source) {
|
|
33
|
+
if (source) {
|
|
34
|
+
for (var prop in source) {
|
|
35
|
+
obj[prop] = source[prop];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return obj;
|
|
40
|
+
}
|
|
41
|
+
export function removeLngFromUrl(url, lookupFromPathIndex) {
|
|
42
|
+
var first = '';
|
|
43
|
+
var pos = lookupFromPathIndex;
|
|
44
|
+
|
|
45
|
+
if (url[0] === '/') {
|
|
46
|
+
pos++;
|
|
47
|
+
first = '/';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var parts = url.split('/');
|
|
51
|
+
parts.splice(pos, 1);
|
|
52
|
+
url = parts.join('/');
|
|
53
|
+
if (url[0] !== '/') url = first + url;
|
|
54
|
+
return url;
|
|
55
|
+
}
|