resolve-accept-language
Advanced tools
Comparing version 2.1.23 to 2.2.0
@@ -1,34 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var locale_1 = require("./locale"); | ||
var LocaleList = /** @class */ (function () { | ||
/** | ||
* Create a list of locale identifiers. | ||
* | ||
* @param locales - An array of locale identifiers using the BCP 47 `language`-`country` format. | ||
* | ||
* @throws Will throw an error if one of the locale's format is invalid. | ||
*/ | ||
function LocaleList(locales) { | ||
var _this = this; | ||
/** A set of ISO 3166-1 alpha-2 country codes. */ | ||
this.countries = new Set(); | ||
/** A set of ISO 639-1 alpha-2 language codes. */ | ||
this.languages = new Set(); | ||
/** A set of locale identifiers using the BCP 47 `language`-`country` case-normalized format. */ | ||
this.locales = new Set(); | ||
/** A list of locale objects. */ | ||
this.objects = []; | ||
locales.forEach(function (locale) { | ||
var localeObject = new locale_1.default(locale); | ||
if (!_this.locales.has(localeObject.identifier)) { | ||
_this.objects.push(localeObject); | ||
_this.locales.add(localeObject.identifier); | ||
_this.languages.add(localeObject.languageCode); | ||
_this.countries.add(localeObject.countryCode); | ||
} | ||
}); | ||
} | ||
return LocaleList; | ||
}()); | ||
exports.default = LocaleList; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var locale_1=require("./locale"),LocaleList=function(e){var t=this;this.countries=new Set,this.languages=new Set,this.locales=new Set,this.objects=[],e.forEach((function(e){var a=new locale_1.default(e);t.locales.has(a.identifier)||(t.objects.push(a),t.locales.add(a.identifier),t.languages.add(a.languageCode),t.countries.add(a.countryCode))}))};exports.default=LocaleList; |
@@ -1,56 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** Class to manage a locale identifier using the BCP 47 `language`-`country` format. */ | ||
var Locale = /** @class */ (function () { | ||
/** | ||
* Create a new `Locale` object. | ||
* | ||
* @param identifier - A locale identifier using the BCP 47 `language`-`country` format (case insensitive). | ||
* | ||
* @throws An error if the `identifier` format is invalid. | ||
*/ | ||
function Locale(identifier) { | ||
if (!Locale.isLocale(identifier, false)) { | ||
throw new Error("invalid locale identifier '".concat(identifier, "'")); | ||
} | ||
var _a = identifier.split('-'), languageCode = _a[0], countryCode = _a[1]; | ||
this.languageCode = languageCode.toLowerCase(); | ||
this.countryCode = countryCode.toUpperCase(); | ||
this.identifier = "".concat(this.languageCode, "-").concat(this.countryCode); | ||
} | ||
/** | ||
* Is a given string an ISO 3166-1 alpha-2 country code. | ||
* | ||
* @param countryCode - An ISO 3166-1 alpha-2 country code. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isCountryCode = function (countryCode, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[A-Z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(countryCode); | ||
}; | ||
/** | ||
* Is a given string an ISO 639-1 alpha-2 language code. | ||
* | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isLanguageCode = function (languageCode, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[a-z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(languageCode); | ||
}; | ||
/** | ||
* Is a given string a locale identifier following the BCP 47 `language`-`country` format. | ||
* | ||
* @param identifier - A potential locale identify to verify. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isLocale = function (identifier, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[a-z]{2}-[A-Z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(identifier); | ||
}; | ||
return Locale; | ||
}()); | ||
exports.default = Locale; | ||
"use strict";var __read=this&&this.__read||function(e,t){var o="function"==typeof Symbol&&e[Symbol.iterator];if(!o)return e;var r,i,n=o.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=n.next()).done;)a.push(r.value)}catch(e){i={error:e}}finally{try{r&&!r.done&&(o=n.return)&&o.call(n)}finally{if(i)throw i.error}}return a};Object.defineProperty(exports,"__esModule",{value:!0});var Locale=function(){function e(t){if(!e.isLocale(t,!1))throw new Error("invalid locale identifier '".concat(t,"'"));var o=__read(t.split("-"),2),r=o[0],i=o[1];this.languageCode=r.toLowerCase(),this.countryCode=i.toUpperCase(),this.identifier="".concat(this.languageCode,"-").concat(this.countryCode)}return e.isCountryCode=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[A-Z]{2}$/,t?void 0:"i").test(e)},e.isLanguageCode=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[a-z]{2}$/,t?void 0:"i").test(e)},e.isLocale=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[a-z]{2}-[A-Z]{2}$/,t?void 0:"i").test(e)},e}();exports.default=Locale; |
@@ -1,209 +0,1 @@ | ||
"use strict"; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var locale_1 = require("./locale"); | ||
var locale_list_1 = require("./locale-list"); | ||
/** Lookup list used to match the preferred locale based on the value of an `Accept-Language` HTTP header. */ | ||
var LookupList = /** @class */ (function () { | ||
/** | ||
* Create a new `LookupList` object. | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers. The order will be used for matching where the first identifier will be more | ||
* likely to be matched than the last identifier. | ||
*/ | ||
function LookupList(acceptLanguageHeader, locales, defaultLocale) { | ||
var _this = this; | ||
/** | ||
* Data object where the properties are quality (in string format) and their values a set containing locale | ||
* identifiers using the `language`-`country` format and ISO 639-1 alpha-2 language code. | ||
*/ | ||
this.localesAndLanguagesByQuality = {}; | ||
/** | ||
* Data object where the properties are quality (in string format) and their value a set of ISO 639-1 alpha-2 | ||
* language code. | ||
*/ | ||
this.relatedLocaleLanguagesByQuality = {}; | ||
// Put the default locale first so that it will be more likely to be matched. | ||
this.localeList = new locale_list_1.default(__spreadArray([ | ||
defaultLocale | ||
], locales.filter(function (locale) { return locale !== defaultLocale; }), true)); | ||
var directives = acceptLanguageHeader | ||
.split(',') | ||
.map(function (directiveString) { return _this.getDirective(directiveString.trim()); }) | ||
.filter(function (directive) { return directive !== undefined; }); | ||
// Check if 'es-419' exists in the directives | ||
var es419DirectiveIndex = directives.findIndex(function (directive) { return directive.locale === 'es-419'; }); | ||
if (es419DirectiveIndex >= 0) { | ||
// Remove 'es-419' from the directive. | ||
var es419Directive_1 = directives[es419DirectiveIndex]; | ||
directives.splice(es419DirectiveIndex, 1); | ||
// Replace `es-419` by the common Latin American spanish variants supported by browsers. | ||
var latinAmericanLocales = [ | ||
'es-AR', // Spanish Argentina | ||
'es-CL', // Spanish Chile | ||
'es-CO', // Spanish Colombia | ||
'es-CR', // Spanish Costa Rica | ||
'es-HN', // Spanish Honduras | ||
'es-MX', // Spanish Mexico | ||
'es-PE', // Spanish Peru | ||
'es-US', // Spanish United States | ||
'es-UY', // Spanish Uruguay | ||
'es-VE', // Spanish Venezuela | ||
]; | ||
latinAmericanLocales.forEach(function (locale) { | ||
directives.push({ | ||
languageCode: 'es', | ||
locale: locale, | ||
quality: es419Directive_1.quality, | ||
}); | ||
}); | ||
} | ||
for (var _i = 0, directives_1 = directives; _i < directives_1.length; _i++) { | ||
var directive = directives_1[_i]; | ||
var locale = directive.locale, languageCode = directive.languageCode, quality = directive.quality; | ||
// If the language is not supported, skip to the next match. | ||
if (!this.localeList.languages.has(languageCode)) { | ||
continue; | ||
} | ||
// If there is no country code (while the language is supported), add the language preference. | ||
if (!locale) { | ||
this.addLanguage(quality, languageCode); | ||
continue; | ||
} | ||
// If the locale is not supported, but the locale's language is, add to locale language preference. | ||
if (!this.localeList.locales.has(locale) && this.localeList.languages.has(languageCode)) { | ||
this.addRelatedLocaleLanguage(quality, languageCode); | ||
continue; | ||
} | ||
// If the locale is supported, add the locale preference. | ||
this.addLocale(quality, locale); | ||
} | ||
} | ||
/** | ||
* Get the top locale-based match if available. | ||
* | ||
* @returns The top locale-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getLocaleBasedMatch = function () { | ||
var match = this.getMatch(this.localesAndLanguagesByQuality); | ||
return match && locale_1.default.isLocale(match) | ||
? match | ||
: undefined; | ||
}; | ||
/** | ||
* Get the language-based match if available. | ||
* | ||
* @returns The language-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getLanguageBasedMatch = function () { | ||
var match = this.getMatch(this.localesAndLanguagesByQuality); | ||
return match && !locale_1.default.isLocale(match) | ||
? this.localeList.objects.find(function (locale) { return locale.languageCode === match; }) | ||
.identifier | ||
: undefined; | ||
}; | ||
/** | ||
* Get the related-locale-based match if available. | ||
* | ||
* @returns The related-locale-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getRelatedLocaleBasedMatch = function () { | ||
var match = this.getMatch(this.relatedLocaleLanguagesByQuality); | ||
return match | ||
? this.localeList.objects.find(function (locale) { return locale.languageCode === match; }) | ||
.identifier | ||
: undefined; | ||
}; | ||
/** | ||
* Add a language in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a language. | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
*/ | ||
LookupList.prototype.addLanguage = function (quality, languageCode) { | ||
if (!this.localesAndLanguagesByQuality[quality]) { | ||
this.localesAndLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.localesAndLanguagesByQuality[quality].add(languageCode); | ||
}; | ||
/** | ||
* Add a locale in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a locale. | ||
* @param identifier - A locale identifier using the BCP 47 `language`-`country` case-normalized format. | ||
*/ | ||
LookupList.prototype.addLocale = function (quality, identifier) { | ||
if (!this.localesAndLanguagesByQuality[quality]) { | ||
this.localesAndLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.localesAndLanguagesByQuality[quality].add(identifier); | ||
}; | ||
/** | ||
* Add a related locale's language in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a related locale's language. | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
*/ | ||
LookupList.prototype.addRelatedLocaleLanguage = function (quality, languageCode) { | ||
if (!this.relatedLocaleLanguagesByQuality[quality]) { | ||
this.relatedLocaleLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.relatedLocaleLanguagesByQuality[quality].add(languageCode); | ||
}; | ||
/** | ||
* Get a directive object from a directive string. | ||
* | ||
* @param directiveString - The string representing a directive, extracted from the HTTP header. | ||
* | ||
* @returns A `Directive` object or `undefined` if the string's format is invalid. | ||
*/ | ||
LookupList.prototype.getDirective = function (directiveString) { | ||
/** | ||
* The regular expression is excluding certain directives due to the inability to configure those options in modern | ||
* browsers today (also those options seem unpractical): | ||
* | ||
* - The wildcard character "*", as per RFC 2616 (section 14.4), should match any unmatched language tag. | ||
* - Language tags that starts with a wildcard (e.g., "*-CA") should match the first supported locale of a country. | ||
* - A quality value equivalent to "0", as per RFC 2616 (section 3.9), should be considered as "not acceptable". | ||
* - We hardcode the support for the `419` UN M49 code (as country code) representing Latin America to support `es-419`. | ||
*/ | ||
var directiveMatch = directiveString.match(/^((?<matchedLanguageCode>([a-z]{2}))(-(?<matchedCountryCode>[a-z]{2}|419))?)(;q=(?<matchedQuality>(1(\.0{0,3})?)|(0(\.\d{0,3})?)))?$/i); | ||
if (!(directiveMatch === null || directiveMatch === void 0 ? void 0 : directiveMatch.groups)) { | ||
return undefined; // No regular expression match. | ||
} | ||
var _a = directiveMatch.groups, matchedLanguageCode = _a.matchedLanguageCode, matchedCountryCode = _a.matchedCountryCode, matchedQuality = _a.matchedQuality; | ||
var languageCode = matchedLanguageCode.toLowerCase(); | ||
var countryCode = matchedCountryCode ? matchedCountryCode.toUpperCase() : undefined; | ||
// Only `es-419` is supported in browsers - if any other languages are using `419` we filter them out. | ||
if (countryCode === '419' && languageCode !== 'es') { | ||
return undefined; | ||
} | ||
var quality = matchedQuality === undefined ? '1' : Number.parseFloat(matchedQuality).toString(); // Remove trailing zeros. | ||
var locale = countryCode ? "".concat(languageCode, "-").concat(countryCode) : undefined; | ||
return { languageCode: languageCode, locale: locale, quality: quality }; | ||
}; | ||
/** | ||
* Get a match from a data object. | ||
* | ||
* @param dataObject - A data object. | ||
* | ||
* @returns A match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getMatch = function (dataObject) { | ||
var dataObjectEntries = Object.entries(dataObject); | ||
return dataObjectEntries.length === 0 | ||
? undefined | ||
: dataObjectEntries.sort().reverse()[0][1].values().next().value; | ||
}; | ||
return LookupList; | ||
}()); | ||
exports.default = LookupList; | ||
"use strict";var __read=this&&this.__read||function(e,t){var a="function"==typeof Symbol&&e[Symbol.iterator];if(!a)return e;var l,o,r=a.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(l=r.next()).done;)i.push(l.value)}catch(e){o={error:e}}finally{try{l&&!l.done&&(a=r.return)&&a.call(r)}finally{if(o)throw o.error}}return i},__spreadArray=this&&this.__spreadArray||function(e,t,a){if(a||2===arguments.length)for(var l,o=0,r=t.length;o<r;o++)!l&&o in t||(l||(l=Array.prototype.slice.call(t,0,o)),l[o]=t[o]);return e.concat(l||Array.prototype.slice.call(t))},__values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,a=t&&e[t],l=0;if(a)return a.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&l>=e.length&&(e=void 0),{value:e&&e[l++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(exports,"__esModule",{value:!0});var locale_1=require("./locale"),locale_list_1=require("./locale-list"),LookupList=function(){function e(e,t,a){var l,o,r=this;this.localesAndLanguagesByQuality={},this.relatedLocaleLanguagesByQuality={},this.localeList=new locale_list_1.default(__spreadArray([a],__read(t.filter((function(e){return e!==a}))),!1));var i=e.split(",").map((function(e){return r.getDirective(e.trim())})).filter((function(e){return void 0!==e})),n=i.findIndex((function(e){return"es-419"===e.locale}));if(n>=0){var s=i[n];i.splice(n,1);["es-AR","es-CL","es-CO","es-CR","es-HN","es-MX","es-PE","es-US","es-UY","es-VE"].forEach((function(e){i.push({languageCode:"es",locale:e,quality:s.quality})}))}try{for(var u=__values(i),c=u.next();!c.done;c=u.next()){var d=c.value,g=d.locale,y=d.languageCode,h=d.quality;this.localeList.languages.has(y)&&(g?this.localeList.locales.has(g)||!this.localeList.languages.has(y)?this.addLocale(h,g):this.addRelatedLocaleLanguage(h,y):this.addLanguage(h,y))}}catch(e){l={error:e}}finally{try{c&&!c.done&&(o=u.return)&&o.call(u)}finally{if(l)throw l.error}}}return e.prototype.getLocaleBasedMatch=function(){var e=this.getMatch(this.localesAndLanguagesByQuality);return e&&locale_1.default.isLocale(e)?e:void 0},e.prototype.getLanguageBasedMatch=function(){var e=this.getMatch(this.localesAndLanguagesByQuality);return e&&!locale_1.default.isLocale(e)?this.localeList.objects.find((function(t){return t.languageCode===e})).identifier:void 0},e.prototype.getRelatedLocaleBasedMatch=function(){var e=this.getMatch(this.relatedLocaleLanguagesByQuality);return e?this.localeList.objects.find((function(t){return t.languageCode===e})).identifier:void 0},e.prototype.addLanguage=function(e,t){this.localesAndLanguagesByQuality[e]||(this.localesAndLanguagesByQuality[e]=new Set),this.localesAndLanguagesByQuality[e].add(t)},e.prototype.addLocale=function(e,t){this.localesAndLanguagesByQuality[e]||(this.localesAndLanguagesByQuality[e]=new Set),this.localesAndLanguagesByQuality[e].add(t)},e.prototype.addRelatedLocaleLanguage=function(e,t){this.relatedLocaleLanguagesByQuality[e]||(this.relatedLocaleLanguagesByQuality[e]=new Set),this.relatedLocaleLanguagesByQuality[e].add(t)},e.prototype.getDirective=function(e){var t=e.match(/^((?<matchedLanguageCode>([a-z]{2}))(-(?<matchedCountryCode>[a-z]{2}|419))?)(;q=(?<matchedQuality>(1(\.0{0,3})?)|(0(\.\d{0,3})?)))?$/i);if(null==t?void 0:t.groups){var a=t.groups,l=a.matchedLanguageCode,o=a.matchedCountryCode,r=a.matchedQuality,i=l.toLowerCase(),n=o?o.toUpperCase():void 0;if("419"!==n||"es"===i){var s=void 0===r?"1":Number.parseFloat(r).toString();return{languageCode:i,locale:n?"".concat(i,"-").concat(n):void 0,quality:s}}}},e.prototype.getMatch=function(e){var t=Object.entries(e);return 0===t.length?void 0:t.sort().reverse()[0][1].values().next().value},e}();exports.default=LookupList; |
@@ -1,106 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResolveAcceptLanguage = exports.MATCH_TYPES = void 0; | ||
var locale_1 = require("./locale"); | ||
var lookup_list_1 = require("./lookup-list"); | ||
/** Match type enumeration. */ | ||
exports.MATCH_TYPES = { | ||
localeBased: 'localeBased', | ||
languageBased: 'languageBased', | ||
relatedLocaleBased: 'relatedLocaleBased', | ||
defaultLocale: 'defaultLocale', | ||
}; | ||
/** Resolve the preferred locale from an HTTP `Accept-Language` header. */ | ||
var ResolveAcceptLanguage = /** @class */ (function () { | ||
/** | ||
* Create a new `ResolveAcceptLanguage` object. | ||
* | ||
* All locale identifiers provided as parameters must following the BCP 47 `language`-`country` (case insensitive). | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers. The order will be used for matching where the first identifier will be more | ||
* likely to be matched than the last identifier. | ||
*/ | ||
function ResolveAcceptLanguage(acceptLanguageHeader, locales, defaultLocale) { | ||
// Check if the locales are valid. | ||
locales.forEach(function (locale) { | ||
if (!locale_1.default.isLocale(locale, false)) { | ||
throw new Error("invalid locale identifier '".concat(locale, "'")); | ||
} | ||
}); | ||
// Check if the default locale is valid. | ||
if (!locale_1.default.isLocale(defaultLocale, false)) { | ||
throw new Error("invalid default locale identifier '".concat(defaultLocale, "'")); | ||
} | ||
// Check if the default locale is included in the locales. | ||
if (!locales.some(function (locale) { return locale.toLowerCase() === defaultLocale.toLowerCase(); })) { | ||
throw new Error('the default locale must be included in the locales'); | ||
} | ||
this.defaultLocale = new locale_1.default(defaultLocale).identifier; | ||
var lookupList = new lookup_list_1.default(acceptLanguageHeader, locales, defaultLocale); | ||
// Check if the match if locale based. | ||
this.localeBasedMatch = lookupList.getLocaleBasedMatch(); | ||
if (this.localeBasedMatch) { | ||
return; | ||
} | ||
// Check if the match is language based. | ||
this.languageBasedMatch = lookupList.getLanguageBasedMatch(); | ||
if (this.languageBasedMatch) { | ||
return; | ||
} | ||
// Check if the match is related-locale based. | ||
this.relatedLocaleBasedMatch = lookupList.getRelatedLocaleBasedMatch(); | ||
if (this.relatedLocaleBasedMatch) { | ||
return; | ||
} | ||
} | ||
/** | ||
* Get the type of match. | ||
* | ||
* @returns The type of match. | ||
*/ | ||
ResolveAcceptLanguage.prototype.getMatchType = function () { | ||
return this.localeBasedMatch | ||
? exports.MATCH_TYPES.localeBased | ||
: this.languageBasedMatch | ||
? exports.MATCH_TYPES.languageBased | ||
: this.relatedLocaleBasedMatch | ||
? exports.MATCH_TYPES.relatedLocaleBased | ||
: exports.MATCH_TYPES.defaultLocale; | ||
}; | ||
/** | ||
* Get the matching locale. | ||
* | ||
* @returns The matching locale. | ||
*/ | ||
ResolveAcceptLanguage.prototype.getMatch = function () { | ||
var _a, _b, _c; | ||
return ((_c = (_b = (_a = this.localeBasedMatch) !== null && _a !== void 0 ? _a : this.languageBasedMatch) !== null && _b !== void 0 ? _b : this.relatedLocaleBasedMatch) !== null && _c !== void 0 ? _c : this.defaultLocale); | ||
}; | ||
return ResolveAcceptLanguage; | ||
}()); | ||
exports.ResolveAcceptLanguage = ResolveAcceptLanguage; | ||
/** | ||
* Resolve the preferred locale from an HTTP `Accept-Language` header. | ||
* | ||
* All locale identifiers provided as parameters must following the BCP 47 `language`-`country` (case insensitive). | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers that must include the default locale. The order will be used for matching where | ||
* the first identifier will be more likely to be matched than the last identifier. | ||
* @param defaultLocale - The default locale identifier when no match is found. | ||
* | ||
* @returns The locale identifier which was the best match, in case-normalized format. | ||
* | ||
* @example | ||
* // returns 'fr-CA' | ||
* resolveAcceptLanguage( | ||
* 'fr-CA;q=0.01,en-CA;q=0.1,en-US;q=0.001', | ||
* ['en-US', 'fr-CA'], | ||
* 'en-US' | ||
* ) | ||
*/ | ||
var resolveAcceptLanguage = function (acceptLanguageHeader, locales, defaultLocale) { | ||
return new ResolveAcceptLanguage(acceptLanguageHeader, locales, defaultLocale).getMatch(); | ||
}; | ||
exports.default = resolveAcceptLanguage; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResolveAcceptLanguage=exports.MATCH_TYPES=void 0;var locale_1=require("./locale"),lookup_list_1=require("./lookup-list");exports.MATCH_TYPES={localeBased:"localeBased",languageBased:"languageBased",relatedLocaleBased:"relatedLocaleBased",defaultLocale:"defaultLocale"};var ResolveAcceptLanguage=function(){function e(e,a,t){if(a.forEach((function(e){if(!locale_1.default.isLocale(e,!1))throw new Error("invalid locale identifier '".concat(e,"'"))})),!locale_1.default.isLocale(t,!1))throw new Error("invalid default locale identifier '".concat(t,"'"));if(!a.some((function(e){return e.toLowerCase()===t.toLowerCase()})))throw new Error("the default locale must be included in the locales");this.defaultLocale=new locale_1.default(t).identifier;var l=new lookup_list_1.default(e,a,t);this.localeBasedMatch=l.getLocaleBasedMatch(),this.localeBasedMatch||(this.languageBasedMatch=l.getLanguageBasedMatch(),this.languageBasedMatch||(this.relatedLocaleBasedMatch=l.getRelatedLocaleBasedMatch(),this.relatedLocaleBasedMatch))}return e.prototype.getMatchType=function(){return this.localeBasedMatch?exports.MATCH_TYPES.localeBased:this.languageBasedMatch?exports.MATCH_TYPES.languageBased:this.relatedLocaleBasedMatch?exports.MATCH_TYPES.relatedLocaleBased:exports.MATCH_TYPES.defaultLocale},e.prototype.getMatch=function(){var e,a,t;return null!==(t=null!==(a=null!==(e=this.localeBasedMatch)&&void 0!==e?e:this.languageBasedMatch)&&void 0!==a?a:this.relatedLocaleBasedMatch)&&void 0!==t?t:this.defaultLocale},e}();exports.ResolveAcceptLanguage=ResolveAcceptLanguage;var resolveAcceptLanguage=function(e,a,t){return new ResolveAcceptLanguage(e,a,t).getMatch()};exports.default=resolveAcceptLanguage; |
@@ -1,2 +0,2 @@ | ||
import Locale from './locale'; | ||
import Locale from './locale.js'; | ||
export default class LocaleList<TLocales extends readonly string[]> { | ||
@@ -3,0 +3,0 @@ /** A set of ISO 3166-1 alpha-2 country codes. */ |
@@ -1,32 +0,1 @@ | ||
import Locale from './locale'; | ||
var LocaleList = /** @class */ (function () { | ||
/** | ||
* Create a list of locale identifiers. | ||
* | ||
* @param locales - An array of locale identifiers using the BCP 47 `language`-`country` format. | ||
* | ||
* @throws Will throw an error if one of the locale's format is invalid. | ||
*/ | ||
function LocaleList(locales) { | ||
var _this = this; | ||
/** A set of ISO 3166-1 alpha-2 country codes. */ | ||
this.countries = new Set(); | ||
/** A set of ISO 639-1 alpha-2 language codes. */ | ||
this.languages = new Set(); | ||
/** A set of locale identifiers using the BCP 47 `language`-`country` case-normalized format. */ | ||
this.locales = new Set(); | ||
/** A list of locale objects. */ | ||
this.objects = []; | ||
locales.forEach(function (locale) { | ||
var localeObject = new Locale(locale); | ||
if (!_this.locales.has(localeObject.identifier)) { | ||
_this.objects.push(localeObject); | ||
_this.locales.add(localeObject.identifier); | ||
_this.languages.add(localeObject.languageCode); | ||
_this.countries.add(localeObject.countryCode); | ||
} | ||
}); | ||
} | ||
return LocaleList; | ||
}()); | ||
export default LocaleList; | ||
import Locale from"./locale.js";var LocaleList=function(e){var a=this;this.countries=new Set,this.languages=new Set,this.locales=new Set,this.objects=[],e.forEach((function(e){var t=new Locale(e);a.locales.has(t.identifier)||(a.objects.push(t),a.locales.add(t.identifier),a.languages.add(t.languageCode),a.countries.add(t.countryCode))}))};export default LocaleList; |
@@ -1,2 +0,2 @@ | ||
import { NormalizeLocale } from './resolve-accept-language'; | ||
import { NormalizeLocale } from './resolve-accept-language.js'; | ||
/** Class to manage a locale identifier using the BCP 47 `language`-`country` format. */ | ||
@@ -3,0 +3,0 @@ export default class Locale<TLocale extends string = string> { |
@@ -1,54 +0,1 @@ | ||
/** Class to manage a locale identifier using the BCP 47 `language`-`country` format. */ | ||
var Locale = /** @class */ (function () { | ||
/** | ||
* Create a new `Locale` object. | ||
* | ||
* @param identifier - A locale identifier using the BCP 47 `language`-`country` format (case insensitive). | ||
* | ||
* @throws An error if the `identifier` format is invalid. | ||
*/ | ||
function Locale(identifier) { | ||
if (!Locale.isLocale(identifier, false)) { | ||
throw new Error("invalid locale identifier '".concat(identifier, "'")); | ||
} | ||
var _a = identifier.split('-'), languageCode = _a[0], countryCode = _a[1]; | ||
this.languageCode = languageCode.toLowerCase(); | ||
this.countryCode = countryCode.toUpperCase(); | ||
this.identifier = "".concat(this.languageCode, "-").concat(this.countryCode); | ||
} | ||
/** | ||
* Is a given string an ISO 3166-1 alpha-2 country code. | ||
* | ||
* @param countryCode - An ISO 3166-1 alpha-2 country code. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isCountryCode = function (countryCode, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[A-Z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(countryCode); | ||
}; | ||
/** | ||
* Is a given string an ISO 639-1 alpha-2 language code. | ||
* | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isLanguageCode = function (languageCode, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[a-z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(languageCode); | ||
}; | ||
/** | ||
* Is a given string a locale identifier following the BCP 47 `language`-`country` format. | ||
* | ||
* @param identifier - A potential locale identify to verify. | ||
* @param caseNormalized - Should we verify if the identifier is using the case-normalized format? | ||
*/ | ||
Locale.isLocale = function (identifier, caseNormalized) { | ||
if (caseNormalized === void 0) { caseNormalized = true; } | ||
var regExp = new RegExp(/^[a-z]{2}-[A-Z]{2}$/, caseNormalized ? undefined : 'i'); | ||
return regExp.test(identifier); | ||
}; | ||
return Locale; | ||
}()); | ||
export default Locale; | ||
var __read=this&&this.__read||function(e,t){var o="function"==typeof Symbol&&e[Symbol.iterator];if(!o)return e;var r,i,n=o.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=n.next()).done;)a.push(r.value)}catch(e){i={error:e}}finally{try{r&&!r.done&&(o=n.return)&&o.call(n)}finally{if(i)throw i.error}}return a},Locale=function(){function e(t){if(!e.isLocale(t,!1))throw new Error("invalid locale identifier '".concat(t,"'"));var o=__read(t.split("-"),2),r=o[0],i=o[1];this.languageCode=r.toLowerCase(),this.countryCode=i.toUpperCase(),this.identifier="".concat(this.languageCode,"-").concat(this.countryCode)}return e.isCountryCode=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[A-Z]{2}$/,t?void 0:"i").test(e)},e.isLanguageCode=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[a-z]{2}$/,t?void 0:"i").test(e)},e.isLocale=function(e,t){return void 0===t&&(t=!0),new RegExp(/^[a-z]{2}-[A-Z]{2}$/,t?void 0:"i").test(e)},e}();export default Locale; |
@@ -1,2 +0,2 @@ | ||
import { NormalizeLocale } from './resolve-accept-language'; | ||
import { NormalizeLocale } from './resolve-accept-language.js'; | ||
/** Lookup list used to match the preferred locale based on the value of an `Accept-Language` HTTP header. */ | ||
@@ -3,0 +3,0 @@ export default class LookupList<TLocales extends readonly string[]> { |
@@ -1,207 +0,1 @@ | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
import Locale from './locale'; | ||
import LocaleList from './locale-list'; | ||
/** Lookup list used to match the preferred locale based on the value of an `Accept-Language` HTTP header. */ | ||
var LookupList = /** @class */ (function () { | ||
/** | ||
* Create a new `LookupList` object. | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers. The order will be used for matching where the first identifier will be more | ||
* likely to be matched than the last identifier. | ||
*/ | ||
function LookupList(acceptLanguageHeader, locales, defaultLocale) { | ||
var _this = this; | ||
/** | ||
* Data object where the properties are quality (in string format) and their values a set containing locale | ||
* identifiers using the `language`-`country` format and ISO 639-1 alpha-2 language code. | ||
*/ | ||
this.localesAndLanguagesByQuality = {}; | ||
/** | ||
* Data object where the properties are quality (in string format) and their value a set of ISO 639-1 alpha-2 | ||
* language code. | ||
*/ | ||
this.relatedLocaleLanguagesByQuality = {}; | ||
// Put the default locale first so that it will be more likely to be matched. | ||
this.localeList = new LocaleList(__spreadArray([ | ||
defaultLocale | ||
], locales.filter(function (locale) { return locale !== defaultLocale; }), true)); | ||
var directives = acceptLanguageHeader | ||
.split(',') | ||
.map(function (directiveString) { return _this.getDirective(directiveString.trim()); }) | ||
.filter(function (directive) { return directive !== undefined; }); | ||
// Check if 'es-419' exists in the directives | ||
var es419DirectiveIndex = directives.findIndex(function (directive) { return directive.locale === 'es-419'; }); | ||
if (es419DirectiveIndex >= 0) { | ||
// Remove 'es-419' from the directive. | ||
var es419Directive_1 = directives[es419DirectiveIndex]; | ||
directives.splice(es419DirectiveIndex, 1); | ||
// Replace `es-419` by the common Latin American spanish variants supported by browsers. | ||
var latinAmericanLocales = [ | ||
'es-AR', // Spanish Argentina | ||
'es-CL', // Spanish Chile | ||
'es-CO', // Spanish Colombia | ||
'es-CR', // Spanish Costa Rica | ||
'es-HN', // Spanish Honduras | ||
'es-MX', // Spanish Mexico | ||
'es-PE', // Spanish Peru | ||
'es-US', // Spanish United States | ||
'es-UY', // Spanish Uruguay | ||
'es-VE', // Spanish Venezuela | ||
]; | ||
latinAmericanLocales.forEach(function (locale) { | ||
directives.push({ | ||
languageCode: 'es', | ||
locale: locale, | ||
quality: es419Directive_1.quality, | ||
}); | ||
}); | ||
} | ||
for (var _i = 0, directives_1 = directives; _i < directives_1.length; _i++) { | ||
var directive = directives_1[_i]; | ||
var locale = directive.locale, languageCode = directive.languageCode, quality = directive.quality; | ||
// If the language is not supported, skip to the next match. | ||
if (!this.localeList.languages.has(languageCode)) { | ||
continue; | ||
} | ||
// If there is no country code (while the language is supported), add the language preference. | ||
if (!locale) { | ||
this.addLanguage(quality, languageCode); | ||
continue; | ||
} | ||
// If the locale is not supported, but the locale's language is, add to locale language preference. | ||
if (!this.localeList.locales.has(locale) && this.localeList.languages.has(languageCode)) { | ||
this.addRelatedLocaleLanguage(quality, languageCode); | ||
continue; | ||
} | ||
// If the locale is supported, add the locale preference. | ||
this.addLocale(quality, locale); | ||
} | ||
} | ||
/** | ||
* Get the top locale-based match if available. | ||
* | ||
* @returns The top locale-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getLocaleBasedMatch = function () { | ||
var match = this.getMatch(this.localesAndLanguagesByQuality); | ||
return match && Locale.isLocale(match) | ||
? match | ||
: undefined; | ||
}; | ||
/** | ||
* Get the language-based match if available. | ||
* | ||
* @returns The language-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getLanguageBasedMatch = function () { | ||
var match = this.getMatch(this.localesAndLanguagesByQuality); | ||
return match && !Locale.isLocale(match) | ||
? this.localeList.objects.find(function (locale) { return locale.languageCode === match; }) | ||
.identifier | ||
: undefined; | ||
}; | ||
/** | ||
* Get the related-locale-based match if available. | ||
* | ||
* @returns The related-locale-based match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getRelatedLocaleBasedMatch = function () { | ||
var match = this.getMatch(this.relatedLocaleLanguagesByQuality); | ||
return match | ||
? this.localeList.objects.find(function (locale) { return locale.languageCode === match; }) | ||
.identifier | ||
: undefined; | ||
}; | ||
/** | ||
* Add a language in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a language. | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
*/ | ||
LookupList.prototype.addLanguage = function (quality, languageCode) { | ||
if (!this.localesAndLanguagesByQuality[quality]) { | ||
this.localesAndLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.localesAndLanguagesByQuality[quality].add(languageCode); | ||
}; | ||
/** | ||
* Add a locale in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a locale. | ||
* @param identifier - A locale identifier using the BCP 47 `language`-`country` case-normalized format. | ||
*/ | ||
LookupList.prototype.addLocale = function (quality, identifier) { | ||
if (!this.localesAndLanguagesByQuality[quality]) { | ||
this.localesAndLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.localesAndLanguagesByQuality[quality].add(identifier); | ||
}; | ||
/** | ||
* Add a related locale's language in the data object matching its quality. | ||
* | ||
* @param quality - The HTTP header's quality factor associated with a related locale's language. | ||
* @param languageCode - An ISO 639-1 alpha-2 language code. | ||
*/ | ||
LookupList.prototype.addRelatedLocaleLanguage = function (quality, languageCode) { | ||
if (!this.relatedLocaleLanguagesByQuality[quality]) { | ||
this.relatedLocaleLanguagesByQuality[quality] = new Set(); | ||
} | ||
this.relatedLocaleLanguagesByQuality[quality].add(languageCode); | ||
}; | ||
/** | ||
* Get a directive object from a directive string. | ||
* | ||
* @param directiveString - The string representing a directive, extracted from the HTTP header. | ||
* | ||
* @returns A `Directive` object or `undefined` if the string's format is invalid. | ||
*/ | ||
LookupList.prototype.getDirective = function (directiveString) { | ||
/** | ||
* The regular expression is excluding certain directives due to the inability to configure those options in modern | ||
* browsers today (also those options seem unpractical): | ||
* | ||
* - The wildcard character "*", as per RFC 2616 (section 14.4), should match any unmatched language tag. | ||
* - Language tags that starts with a wildcard (e.g., "*-CA") should match the first supported locale of a country. | ||
* - A quality value equivalent to "0", as per RFC 2616 (section 3.9), should be considered as "not acceptable". | ||
* - We hardcode the support for the `419` UN M49 code (as country code) representing Latin America to support `es-419`. | ||
*/ | ||
var directiveMatch = directiveString.match(/^((?<matchedLanguageCode>([a-z]{2}))(-(?<matchedCountryCode>[a-z]{2}|419))?)(;q=(?<matchedQuality>(1(\.0{0,3})?)|(0(\.\d{0,3})?)))?$/i); | ||
if (!(directiveMatch === null || directiveMatch === void 0 ? void 0 : directiveMatch.groups)) { | ||
return undefined; // No regular expression match. | ||
} | ||
var _a = directiveMatch.groups, matchedLanguageCode = _a.matchedLanguageCode, matchedCountryCode = _a.matchedCountryCode, matchedQuality = _a.matchedQuality; | ||
var languageCode = matchedLanguageCode.toLowerCase(); | ||
var countryCode = matchedCountryCode ? matchedCountryCode.toUpperCase() : undefined; | ||
// Only `es-419` is supported in browsers - if any other languages are using `419` we filter them out. | ||
if (countryCode === '419' && languageCode !== 'es') { | ||
return undefined; | ||
} | ||
var quality = matchedQuality === undefined ? '1' : Number.parseFloat(matchedQuality).toString(); // Remove trailing zeros. | ||
var locale = countryCode ? "".concat(languageCode, "-").concat(countryCode) : undefined; | ||
return { languageCode: languageCode, locale: locale, quality: quality }; | ||
}; | ||
/** | ||
* Get a match from a data object. | ||
* | ||
* @param dataObject - A data object. | ||
* | ||
* @returns A match or undefined when there is no match. | ||
*/ | ||
LookupList.prototype.getMatch = function (dataObject) { | ||
var dataObjectEntries = Object.entries(dataObject); | ||
return dataObjectEntries.length === 0 | ||
? undefined | ||
: dataObjectEntries.sort().reverse()[0][1].values().next().value; | ||
}; | ||
return LookupList; | ||
}()); | ||
export default LookupList; | ||
var __read=this&&this.__read||function(e,t){var a="function"==typeof Symbol&&e[Symbol.iterator];if(!a)return e;var o,r,l=a.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(o=l.next()).done;)i.push(o.value)}catch(e){r={error:e}}finally{try{o&&!o.done&&(a=l.return)&&a.call(l)}finally{if(r)throw r.error}}return i},__spreadArray=this&&this.__spreadArray||function(e,t,a){if(a||2===arguments.length)for(var o,r=0,l=t.length;r<l;r++)!o&&r in t||(o||(o=Array.prototype.slice.call(t,0,r)),o[r]=t[r]);return e.concat(o||Array.prototype.slice.call(t))},__values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,a=t&&e[t],o=0;if(a)return a.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&o>=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};import Locale from"./locale.js";import LocaleList from"./locale-list.js";var LookupList=function(){function e(e,t,a){var o,r,l=this;this.localesAndLanguagesByQuality={},this.relatedLocaleLanguagesByQuality={},this.localeList=new LocaleList(__spreadArray([a],__read(t.filter((function(e){return e!==a}))),!1));var i=e.split(",").map((function(e){return l.getDirective(e.trim())})).filter((function(e){return void 0!==e})),n=i.findIndex((function(e){return"es-419"===e.locale}));if(n>=0){var s=i[n];i.splice(n,1);["es-AR","es-CL","es-CO","es-CR","es-HN","es-MX","es-PE","es-US","es-UY","es-VE"].forEach((function(e){i.push({languageCode:"es",locale:e,quality:s.quality})}))}try{for(var u=__values(i),c=u.next();!c.done;c=u.next()){var d=c.value,g=d.locale,y=d.languageCode,h=d.quality;this.localeList.languages.has(y)&&(g?this.localeList.locales.has(g)||!this.localeList.languages.has(y)?this.addLocale(h,g):this.addRelatedLocaleLanguage(h,y):this.addLanguage(h,y))}}catch(e){o={error:e}}finally{try{c&&!c.done&&(r=u.return)&&r.call(u)}finally{if(o)throw o.error}}}return e.prototype.getLocaleBasedMatch=function(){var e=this.getMatch(this.localesAndLanguagesByQuality);return e&&Locale.isLocale(e)?e:void 0},e.prototype.getLanguageBasedMatch=function(){var e=this.getMatch(this.localesAndLanguagesByQuality);return e&&!Locale.isLocale(e)?this.localeList.objects.find((function(t){return t.languageCode===e})).identifier:void 0},e.prototype.getRelatedLocaleBasedMatch=function(){var e=this.getMatch(this.relatedLocaleLanguagesByQuality);return e?this.localeList.objects.find((function(t){return t.languageCode===e})).identifier:void 0},e.prototype.addLanguage=function(e,t){this.localesAndLanguagesByQuality[e]||(this.localesAndLanguagesByQuality[e]=new Set),this.localesAndLanguagesByQuality[e].add(t)},e.prototype.addLocale=function(e,t){this.localesAndLanguagesByQuality[e]||(this.localesAndLanguagesByQuality[e]=new Set),this.localesAndLanguagesByQuality[e].add(t)},e.prototype.addRelatedLocaleLanguage=function(e,t){this.relatedLocaleLanguagesByQuality[e]||(this.relatedLocaleLanguagesByQuality[e]=new Set),this.relatedLocaleLanguagesByQuality[e].add(t)},e.prototype.getDirective=function(e){var t=e.match(/^((?<matchedLanguageCode>([a-z]{2}))(-(?<matchedCountryCode>[a-z]{2}|419))?)(;q=(?<matchedQuality>(1(\.0{0,3})?)|(0(\.\d{0,3})?)))?$/i);if(null==t?void 0:t.groups){var a=t.groups,o=a.matchedLanguageCode,r=a.matchedCountryCode,l=a.matchedQuality,i=o.toLowerCase(),n=r?r.toUpperCase():void 0;if("419"!==n||"es"===i){var s=void 0===l?"1":Number.parseFloat(l).toString();return{languageCode:i,locale:n?"".concat(i,"-").concat(n):void 0,quality:s}}}},e.prototype.getMatch=function(e){var t=Object.entries(e);return 0===t.length?void 0:t.sort().reverse()[0][1].values().next().value},e}();export default LookupList; |
@@ -1,103 +0,1 @@ | ||
import Locale from './locale'; | ||
import LookupList from './lookup-list'; | ||
/** Match type enumeration. */ | ||
export var MATCH_TYPES = { | ||
localeBased: 'localeBased', | ||
languageBased: 'languageBased', | ||
relatedLocaleBased: 'relatedLocaleBased', | ||
defaultLocale: 'defaultLocale', | ||
}; | ||
/** Resolve the preferred locale from an HTTP `Accept-Language` header. */ | ||
var ResolveAcceptLanguage = /** @class */ (function () { | ||
/** | ||
* Create a new `ResolveAcceptLanguage` object. | ||
* | ||
* All locale identifiers provided as parameters must following the BCP 47 `language`-`country` (case insensitive). | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers. The order will be used for matching where the first identifier will be more | ||
* likely to be matched than the last identifier. | ||
*/ | ||
function ResolveAcceptLanguage(acceptLanguageHeader, locales, defaultLocale) { | ||
// Check if the locales are valid. | ||
locales.forEach(function (locale) { | ||
if (!Locale.isLocale(locale, false)) { | ||
throw new Error("invalid locale identifier '".concat(locale, "'")); | ||
} | ||
}); | ||
// Check if the default locale is valid. | ||
if (!Locale.isLocale(defaultLocale, false)) { | ||
throw new Error("invalid default locale identifier '".concat(defaultLocale, "'")); | ||
} | ||
// Check if the default locale is included in the locales. | ||
if (!locales.some(function (locale) { return locale.toLowerCase() === defaultLocale.toLowerCase(); })) { | ||
throw new Error('the default locale must be included in the locales'); | ||
} | ||
this.defaultLocale = new Locale(defaultLocale).identifier; | ||
var lookupList = new LookupList(acceptLanguageHeader, locales, defaultLocale); | ||
// Check if the match if locale based. | ||
this.localeBasedMatch = lookupList.getLocaleBasedMatch(); | ||
if (this.localeBasedMatch) { | ||
return; | ||
} | ||
// Check if the match is language based. | ||
this.languageBasedMatch = lookupList.getLanguageBasedMatch(); | ||
if (this.languageBasedMatch) { | ||
return; | ||
} | ||
// Check if the match is related-locale based. | ||
this.relatedLocaleBasedMatch = lookupList.getRelatedLocaleBasedMatch(); | ||
if (this.relatedLocaleBasedMatch) { | ||
return; | ||
} | ||
} | ||
/** | ||
* Get the type of match. | ||
* | ||
* @returns The type of match. | ||
*/ | ||
ResolveAcceptLanguage.prototype.getMatchType = function () { | ||
return this.localeBasedMatch | ||
? MATCH_TYPES.localeBased | ||
: this.languageBasedMatch | ||
? MATCH_TYPES.languageBased | ||
: this.relatedLocaleBasedMatch | ||
? MATCH_TYPES.relatedLocaleBased | ||
: MATCH_TYPES.defaultLocale; | ||
}; | ||
/** | ||
* Get the matching locale. | ||
* | ||
* @returns The matching locale. | ||
*/ | ||
ResolveAcceptLanguage.prototype.getMatch = function () { | ||
var _a, _b, _c; | ||
return ((_c = (_b = (_a = this.localeBasedMatch) !== null && _a !== void 0 ? _a : this.languageBasedMatch) !== null && _b !== void 0 ? _b : this.relatedLocaleBasedMatch) !== null && _c !== void 0 ? _c : this.defaultLocale); | ||
}; | ||
return ResolveAcceptLanguage; | ||
}()); | ||
export { ResolveAcceptLanguage }; | ||
/** | ||
* Resolve the preferred locale from an HTTP `Accept-Language` header. | ||
* | ||
* All locale identifiers provided as parameters must following the BCP 47 `language`-`country` (case insensitive). | ||
* | ||
* @param acceptLanguageHeader - The value of an HTTP request `Accept-Language` header (also known as a "language priority list"). | ||
* @param locales - An array of locale identifiers that must include the default locale. The order will be used for matching where | ||
* the first identifier will be more likely to be matched than the last identifier. | ||
* @param defaultLocale - The default locale identifier when no match is found. | ||
* | ||
* @returns The locale identifier which was the best match, in case-normalized format. | ||
* | ||
* @example | ||
* // returns 'fr-CA' | ||
* resolveAcceptLanguage( | ||
* 'fr-CA;q=0.01,en-CA;q=0.1,en-US;q=0.001', | ||
* ['en-US', 'fr-CA'], | ||
* 'en-US' | ||
* ) | ||
*/ | ||
var resolveAcceptLanguage = function (acceptLanguageHeader, locales, defaultLocale) { | ||
return new ResolveAcceptLanguage(acceptLanguageHeader, locales, defaultLocale).getMatch(); | ||
}; | ||
export default resolveAcceptLanguage; | ||
import Locale from"./locale.js";import LookupList from"./lookup-list.js";export var MATCH_TYPES={localeBased:"localeBased",languageBased:"languageBased",relatedLocaleBased:"relatedLocaleBased",defaultLocale:"defaultLocale"};var ResolveAcceptLanguage=function(){function e(e,a,t){if(a.forEach((function(e){if(!Locale.isLocale(e,!1))throw new Error("invalid locale identifier '".concat(e,"'"))})),!Locale.isLocale(t,!1))throw new Error("invalid default locale identifier '".concat(t,"'"));if(!a.some((function(e){return e.toLowerCase()===t.toLowerCase()})))throw new Error("the default locale must be included in the locales");this.defaultLocale=new Locale(t).identifier;var l=new LookupList(e,a,t);this.localeBasedMatch=l.getLocaleBasedMatch(),this.localeBasedMatch||(this.languageBasedMatch=l.getLanguageBasedMatch(),this.languageBasedMatch||(this.relatedLocaleBasedMatch=l.getRelatedLocaleBasedMatch(),this.relatedLocaleBasedMatch))}return e.prototype.getMatchType=function(){return this.localeBasedMatch?MATCH_TYPES.localeBased:this.languageBasedMatch?MATCH_TYPES.languageBased:this.relatedLocaleBasedMatch?MATCH_TYPES.relatedLocaleBased:MATCH_TYPES.defaultLocale},e.prototype.getMatch=function(){var e,a,t;return null!==(t=null!==(a=null!==(e=this.localeBasedMatch)&&void 0!==e?e:this.languageBasedMatch)&&void 0!==a?a:this.relatedLocaleBasedMatch)&&void 0!==t?t:this.defaultLocale},e}();export{ResolveAcceptLanguage};var resolveAcceptLanguage=function(e,a,t){return new ResolveAcceptLanguage(e,a,t).getMatch()};export default resolveAcceptLanguage; |
{ | ||
"name": "resolve-accept-language", | ||
"version": "2.1.23", | ||
"version": "2.2.0", | ||
"description": "Resolve the preferred locale based on the value of an `Accept-Language` HTTP header.", | ||
@@ -45,6 +45,5 @@ "keywords": [ | ||
"scripts": { | ||
"build": "npm run prettier && npm run lint-fix && rm -Rf ./lib && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && npm run test", | ||
"lint-check": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx --ext .json .", | ||
"build": "npm run prettier && npm run lint-fix && rm -Rf ./lib && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && tsc -p tsconfig.build-scripts.json && node lib/build-scripts/build.js && npm run test", | ||
"depcheck": "depcheck", | ||
"lint-fix": "eslint --fix .", | ||
"lint-print-config": "eslint --print-config ./eslintrc.yaml", | ||
"prettier": "prettier --write .", | ||
@@ -55,6 +54,9 @@ "release": "dotenv -- release-it --only-version", | ||
"devDependencies": { | ||
"@eslint/js": "^8.57.0", | ||
"@release-it/conventional-changelog": "8.0.1", | ||
"@types/jest": "29.5.12", | ||
"@typescript-eslint/eslint-plugin": "7.0.2", | ||
"@typescript-eslint/parser": "7.0.2", | ||
"@types/node": "^20.11.24", | ||
"@typescript-eslint/eslint-plugin": "7.1.0", | ||
"@typescript-eslint/parser": "7.1.0", | ||
"depcheck": "^1.4.7", | ||
"dotenv-cli": "7.3.0", | ||
@@ -69,3 +71,3 @@ "eslint": "8.57.0", | ||
"eslint-plugin-json-files": "4.1.0", | ||
"eslint-plugin-prefer-arrow-functions": "3.3.1", | ||
"eslint-plugin-prefer-arrow-functions": "3.3.2", | ||
"eslint-plugin-prettier": "5.1.3", | ||
@@ -81,4 +83,4 @@ "eslint-plugin-tsdoc": "0.2.17", | ||
"release-it": "17.1.1", | ||
"terser": "^5.28.1", | ||
"ts-jest": "29.1.2", | ||
"ts-node": "10.9.2", | ||
"typescript": "5.3.3" | ||
@@ -85,0 +87,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
41210
30
400
4
1