123456789101112131415161718192021222324252627282930313233343536373839404142 |
- 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');
- // 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
- 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, '..', '..', '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) || ['en-US'];
- 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();
- };
|