send/server/middleware/language.js

45 lines
1.4 KiB
JavaScript
Raw Normal View History

2018-02-06 22:31:18 +00:00
const { availableLanguages } = require('../../package.json');
const config = require('../config');
const fs = require('fs');
const path = require('path');
const { negotiateLanguages } = require('fluent-langneg');
const langData = require('cldr-core/supplemental/likelySubtags.json');
2018-03-02 05:36:45 +00:00
// We return early in the middleware if the lang header is long.
// If that ever changes we should re-evaluate this regex.
// eslint-disable-next-line security/detect-unsafe-regex
2018-02-06 22:31:18 +00:00
const acceptLanguages = /(([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?/g;
function allLangs() {
return fs.readdirSync(
path.join(__dirname, '..', '..', 'dist', 'public', 'locales')
);
}
const languages = config.l10n_dev ? allLangs() : availableLanguages;
module.exports = function(req, res, next) {
const header = req.headers['accept-language'] || 'en-US';
if (header.length > 255) {
req.language = 'en-US';
return next();
}
const langs = header.replace(/\s/g, '').match(acceptLanguages);
const preferred = langs
.map(l => {
const parts = l.split(';');
return {
locale: parts[0],
q: parts[1] ? parseFloat(parts[1].split('=')[1]) : 1
};
})
.sort((a, b) => b.q - a.q)
.map(x => x.locale);
req.language = negotiateLanguages(preferred, languages, {
strategy: 'lookup',
likelySubtags: langData.supplemental.likelySubtags,
defaultLocale: 'en-US'
})[0];
next();
};