@formatjs/intl-localematcher
Advanced tools
Comparing version 0.4.2 to 0.5.0
@@ -6,2 +6,2 @@ /** | ||
*/ | ||
export declare function BestAvailableLocale(availableLocales: Set<String>, locale: string): string | undefined; | ||
export declare function BestAvailableLocale(availableLocales: readonly string[], locale: string): string | undefined; |
@@ -12,3 +12,3 @@ "use strict"; | ||
while (true) { | ||
if (availableLocales.has(candidate)) { | ||
if (availableLocales.indexOf(candidate) > -1) { | ||
return candidate; | ||
@@ -15,0 +15,0 @@ } |
@@ -8,2 +8,2 @@ import { LookupMatcherResult } from './types'; | ||
*/ | ||
export declare function BestFitMatcher(availableLocales: Set<string>, requestedLocales: string[], getDefaultLocale: () => string): LookupMatcherResult; | ||
export declare function BestFitMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BestFitMatcher = void 0; | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
var utils_1 = require("./utils"); | ||
@@ -13,18 +12,2 @@ /** | ||
function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { | ||
var minimizedAvailableLocaleMap = {}; | ||
var availableLocaleMap = {}; | ||
var canonicalizedLocaleMap = {}; | ||
var minimizedAvailableLocales = new Set(); | ||
availableLocales.forEach(function (locale) { | ||
var minimizedLocale = new Intl.Locale(locale) | ||
.minimize() | ||
.toString(); | ||
var canonicalizedLocale = Intl.getCanonicalLocales(locale)[0] || locale; | ||
minimizedAvailableLocaleMap[minimizedLocale] = locale; | ||
availableLocaleMap[locale] = locale; | ||
canonicalizedLocaleMap[canonicalizedLocale] = locale; | ||
minimizedAvailableLocales.add(minimizedLocale); | ||
minimizedAvailableLocales.add(locale); | ||
minimizedAvailableLocales.add(canonicalizedLocale); | ||
}); | ||
var foundLocale; | ||
@@ -34,27 +17,9 @@ var extension; | ||
var l = requestedLocales_1[_i]; | ||
if (foundLocale) { | ||
var matchedLocale = (0, utils_1.findBestMatch)(l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''), availableLocales); | ||
if (matchedLocale) { | ||
foundLocale = matchedLocale; | ||
var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
extension = l.slice(noExtensionLocale.length, l.length) || undefined; | ||
break; | ||
} | ||
var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
if (l !== noExtensionLocale) { | ||
extension = l.slice(noExtensionLocale.length, l.length); | ||
} | ||
if (availableLocales.has(noExtensionLocale)) { | ||
foundLocale = noExtensionLocale; | ||
break; | ||
} | ||
if (minimizedAvailableLocales.has(noExtensionLocale)) { | ||
foundLocale = noExtensionLocale; | ||
break; | ||
} | ||
var locale = new Intl.Locale(noExtensionLocale); | ||
var maximizedRequestedLocale = locale.maximize().toString(); | ||
var minimizedRequestedLocale = locale.minimize().toString(); | ||
// Check minimized locale | ||
if (minimizedAvailableLocales.has(minimizedRequestedLocale)) { | ||
foundLocale = minimizedRequestedLocale; | ||
break; | ||
} | ||
// Lookup algo on maximized locale | ||
foundLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(minimizedAvailableLocales, maximizedRequestedLocale); | ||
} | ||
@@ -65,6 +30,3 @@ if (!foundLocale) { | ||
return { | ||
locale: availableLocaleMap[foundLocale] || | ||
canonicalizedLocaleMap[foundLocale] || | ||
minimizedAvailableLocaleMap[foundLocale] || | ||
foundLocale, | ||
locale: foundLocale, | ||
extension: extension, | ||
@@ -71,0 +33,0 @@ }; |
@@ -8,2 +8,2 @@ import { LookupMatcherResult } from './types'; | ||
*/ | ||
export declare function LookupMatcher(availableLocales: Set<string>, requestedLocales: string[], getDefaultLocale: () => string): LookupMatcherResult; | ||
export declare function LookupMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LookupMatcher = void 0; | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
var utils_1 = require("./utils"); | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
/** | ||
@@ -7,0 +7,0 @@ * https://tc39.es/ecma402/#sec-lookupmatcher |
@@ -6,2 +6,2 @@ /** | ||
*/ | ||
export declare function LookupSupportedLocales(availableLocales: Set<string>, requestedLocales: string[]): string[]; | ||
export declare function LookupSupportedLocales(availableLocales: string[], requestedLocales: string[]): string[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LookupSupportedLocales = void 0; | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
var utils_1 = require("./utils"); | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
/** | ||
@@ -7,0 +7,0 @@ * https://tc39.es/ecma402/#sec-lookupsupportedlocales |
@@ -11,5 +11,5 @@ export interface ResolveLocaleResult { | ||
[k in K]: any; | ||
}>(availableLocales: Set<string>, requestedLocales: string[], options: { | ||
}>(availableLocales: Set<string> | readonly string[], requestedLocales: readonly string[], options: { | ||
localeMatcher: string; | ||
[k: string]: string; | ||
}, relevantExtensionKeys: K[], localeData: Record<string, D | undefined>, getDefaultLocale: () => string): ResolveLocaleResult; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResolveLocale = void 0; | ||
var BestFitMatcher_1 = require("./BestFitMatcher"); | ||
var LookupMatcher_1 = require("./LookupMatcher"); | ||
var BestFitMatcher_1 = require("./BestFitMatcher"); | ||
var UnicodeExtensionValue_1 = require("./UnicodeExtensionValue"); | ||
var utils_1 = require("./utils"); | ||
var UnicodeExtensionValue_1 = require("./UnicodeExtensionValue"); | ||
/** | ||
@@ -15,6 +15,6 @@ * https://tc39.es/ecma402/#sec-resolvelocale | ||
if (matcher === 'lookup') { | ||
r = (0, LookupMatcher_1.LookupMatcher)(availableLocales, requestedLocales, getDefaultLocale); | ||
r = (0, LookupMatcher_1.LookupMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale); | ||
} | ||
else { | ||
r = (0, BestFitMatcher_1.BestFitMatcher)(availableLocales, requestedLocales, getDefaultLocale); | ||
r = (0, BestFitMatcher_1.BestFitMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale); | ||
} | ||
@@ -21,0 +21,0 @@ var foundLocale = r.locale; |
export declare const UNICODE_EXTENSION_SEQUENCE_REGEX: RegExp; | ||
export declare function invariant(condition: boolean, message: string, Err?: any): asserts condition; | ||
export declare function findMatchingDistance(desired: string, supported: string): number; | ||
export declare function findBestMatch(desired: string, supportedLocales: readonly string[], threshold?: number): string | undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; | ||
exports.findBestMatch = exports.findMatchingDistance = exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; | ||
var tslib_1 = require("tslib"); | ||
var languageMatching_1 = require("./languageMatching"); | ||
var regions_generated_1 = require("./regions.generated"); | ||
exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; | ||
@@ -12,1 +15,145 @@ function invariant(condition, message, Err) { | ||
exports.invariant = invariant; | ||
// This is effectively 2 languages in 2 different regions not even in the same cluster | ||
var DEFAULT_MATCHING_THRESHOLD = 840; | ||
var PROCESSED_DATA; | ||
function processData() { | ||
var _a, _b; | ||
if (!PROCESSED_DATA) { | ||
var paradigmLocales = (_b = (_a = languageMatching_1.data.supplemental.languageMatching['written-new'][0]) === null || _a === void 0 ? void 0 : _a.paradigmLocales) === null || _b === void 0 ? void 0 : _b._locales.split(' '); | ||
var matchVariables = languageMatching_1.data.supplemental.languageMatching['written-new'].slice(1, 5); | ||
var data = languageMatching_1.data.supplemental.languageMatching['written-new'].slice(5); | ||
var matches = data.map(function (d) { | ||
var key = Object.keys(d)[0]; | ||
var value = d[key]; | ||
return { | ||
supported: key, | ||
desired: value._desired, | ||
distance: +value._distance, | ||
oneway: value.oneway === 'true' ? true : false, | ||
}; | ||
}, {}); | ||
PROCESSED_DATA = { | ||
matches: matches, | ||
matchVariables: matchVariables.reduce(function (all, d) { | ||
var key = Object.keys(d)[0]; | ||
var value = d[key]; | ||
all[key.slice(1)] = value._value.split('+'); | ||
return all; | ||
}, {}), | ||
paradigmLocales: tslib_1.__spreadArray(tslib_1.__spreadArray([], paradigmLocales, true), paradigmLocales.map(function (l) { | ||
return new Intl.Locale(l.replace(/_/g, '-')).maximize().toString(); | ||
}), true), | ||
}; | ||
} | ||
return PROCESSED_DATA; | ||
} | ||
function isMatched(locale, languageMatchInfoLocale, matchVariables) { | ||
var _a = languageMatchInfoLocale.split('-'), language = _a[0], script = _a[1], region = _a[2]; | ||
var matches = true; | ||
if (region && region[0] === '$') { | ||
var shouldInclude = region[1] !== '!'; | ||
var matchRegions = shouldInclude | ||
? matchVariables[region.slice(1)] | ||
: matchVariables[region.slice(2)]; | ||
var expandedMatchedRegions = matchRegions | ||
.map(function (r) { return regions_generated_1.regions[r] || [r]; }) | ||
.reduce(function (all, list) { return tslib_1.__spreadArray(tslib_1.__spreadArray([], all, true), list, true); }, []); | ||
matches && (matches = !(expandedMatchedRegions.indexOf(locale.region || '') > 1 != | ||
shouldInclude)); | ||
} | ||
else { | ||
matches && (matches = locale.region | ||
? region === '*' || region === locale.region | ||
: true); | ||
} | ||
matches && (matches = locale.script ? script === '*' || script === locale.script : true); | ||
matches && (matches = locale.language | ||
? language === '*' || language === locale.language | ||
: true); | ||
return matches; | ||
} | ||
function serializeLSR(lsr) { | ||
return [lsr.language, lsr.script, lsr.region].filter(Boolean).join('-'); | ||
} | ||
function findMatchingDistanceForLSR(desired, supported, data) { | ||
for (var _i = 0, _a = data.matches; _i < _a.length; _i++) { | ||
var d = _a[_i]; | ||
var matches = isMatched(desired, d.desired, data.matchVariables) && | ||
isMatched(supported, d.supported, data.matchVariables); | ||
if (!d.oneway && !matches) { | ||
matches = | ||
isMatched(desired, d.supported, data.matchVariables) && | ||
isMatched(supported, d.desired, data.matchVariables); | ||
} | ||
if (matches) { | ||
var distance = d.distance * 10; | ||
if (data.paradigmLocales.indexOf(serializeLSR(desired)) > -1 != | ||
data.paradigmLocales.indexOf(serializeLSR(supported)) > -1) { | ||
return distance - 1; | ||
} | ||
return distance; | ||
} | ||
} | ||
throw new Error('No matching distance found'); | ||
} | ||
function findMatchingDistance(desired, supported) { | ||
var desiredLocale = new Intl.Locale(desired).maximize(); | ||
var supportedLocale = new Intl.Locale(supported).maximize(); | ||
var desiredLSR = { | ||
language: desiredLocale.language, | ||
script: desiredLocale.script || '', | ||
region: desiredLocale.region || '', | ||
}; | ||
var supportedLSR = { | ||
language: supportedLocale.language, | ||
script: supportedLocale.script || '', | ||
region: supportedLocale.region || '', | ||
}; | ||
var matchingDistance = 0; | ||
var data = processData(); | ||
if (desiredLSR.language !== supportedLSR.language) { | ||
matchingDistance += findMatchingDistanceForLSR({ | ||
language: desiredLocale.language, | ||
script: '', | ||
region: '', | ||
}, { | ||
language: supportedLocale.language, | ||
script: '', | ||
region: '', | ||
}, data); | ||
} | ||
if (desiredLSR.script !== supportedLSR.script) { | ||
matchingDistance += findMatchingDistanceForLSR({ | ||
language: desiredLocale.language, | ||
script: desiredLSR.script, | ||
region: '', | ||
}, { | ||
language: supportedLocale.language, | ||
script: desiredLSR.script, | ||
region: '', | ||
}, data); | ||
} | ||
if (desiredLSR.region !== supportedLSR.region) { | ||
matchingDistance += findMatchingDistanceForLSR(desiredLSR, supportedLSR, data); | ||
} | ||
return matchingDistance; | ||
} | ||
exports.findMatchingDistance = findMatchingDistance; | ||
function findBestMatch(desired, supportedLocales, threshold) { | ||
if (threshold === void 0) { threshold = DEFAULT_MATCHING_THRESHOLD; } | ||
var bestMatch = undefined; | ||
var lowestDistance = Infinity; | ||
supportedLocales.forEach(function (supported, i) { | ||
// Add some weight to the distance based on the order of the supported locales | ||
var distance = findMatchingDistance(desired, supported) + i; | ||
if (distance < lowestDistance) { | ||
lowestDistance = distance; | ||
bestMatch = supported; | ||
} | ||
}); | ||
if (lowestDistance >= threshold) { | ||
return; | ||
} | ||
return bestMatch; | ||
} | ||
exports.findBestMatch = findBestMatch; |
@@ -7,7 +7,3 @@ "use strict"; | ||
function match(requestedLocales, availableLocales, defaultLocale, opts) { | ||
var locales = availableLocales.reduce(function (all, l) { | ||
all.add(l); | ||
return all; | ||
}, new Set()); | ||
return (0, ResolveLocale_1.ResolveLocale)(locales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { | ||
return (0, ResolveLocale_1.ResolveLocale)(availableLocales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { | ||
localeMatcher: (opts === null || opts === void 0 ? void 0 : opts.algorithm) || 'best fit', | ||
@@ -14,0 +10,0 @@ }, [], {}, function () { return defaultLocale; }).locale; |
@@ -6,2 +6,2 @@ /** | ||
*/ | ||
export declare function BestAvailableLocale(availableLocales: Set<String>, locale: string): string | undefined; | ||
export declare function BestAvailableLocale(availableLocales: readonly string[], locale: string): string | undefined; |
@@ -0,1 +1,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BestAvailableLocale = void 0; | ||
/** | ||
@@ -6,6 +9,6 @@ * https://tc39.es/ecma402/#sec-bestavailablelocale | ||
*/ | ||
export function BestAvailableLocale(availableLocales, locale) { | ||
function BestAvailableLocale(availableLocales, locale) { | ||
var candidate = locale; | ||
while (true) { | ||
if (availableLocales.has(candidate)) { | ||
if (availableLocales.indexOf(candidate) > -1) { | ||
return candidate; | ||
@@ -23,1 +26,2 @@ } | ||
} | ||
exports.BestAvailableLocale = BestAvailableLocale; |
@@ -8,2 +8,2 @@ import { LookupMatcherResult } from './types'; | ||
*/ | ||
export declare function BestFitMatcher(availableLocales: Set<string>, requestedLocales: string[], getDefaultLocale: () => string): LookupMatcherResult; | ||
export declare function BestFitMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult; |
@@ -1,3 +0,5 @@ | ||
import { BestAvailableLocale } from './BestAvailableLocale'; | ||
import { UNICODE_EXTENSION_SEQUENCE_REGEX } from './utils'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BestFitMatcher = void 0; | ||
var utils_1 = require("./utils"); | ||
/** | ||
@@ -9,19 +11,3 @@ * https://tc39.es/ecma402/#sec-bestfitmatcher | ||
*/ | ||
export function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { | ||
var minimizedAvailableLocaleMap = {}; | ||
var availableLocaleMap = {}; | ||
var canonicalizedLocaleMap = {}; | ||
var minimizedAvailableLocales = new Set(); | ||
availableLocales.forEach(function (locale) { | ||
var minimizedLocale = new Intl.Locale(locale) | ||
.minimize() | ||
.toString(); | ||
var canonicalizedLocale = Intl.getCanonicalLocales(locale)[0] || locale; | ||
minimizedAvailableLocaleMap[minimizedLocale] = locale; | ||
availableLocaleMap[locale] = locale; | ||
canonicalizedLocaleMap[canonicalizedLocale] = locale; | ||
minimizedAvailableLocales.add(minimizedLocale); | ||
minimizedAvailableLocales.add(locale); | ||
minimizedAvailableLocales.add(canonicalizedLocale); | ||
}); | ||
function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { | ||
var foundLocale; | ||
@@ -31,27 +17,9 @@ var extension; | ||
var l = requestedLocales_1[_i]; | ||
if (foundLocale) { | ||
var matchedLocale = (0, utils_1.findBestMatch)(l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''), availableLocales); | ||
if (matchedLocale) { | ||
foundLocale = matchedLocale; | ||
var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
extension = l.slice(noExtensionLocale.length, l.length) || undefined; | ||
break; | ||
} | ||
var noExtensionLocale = l.replace(UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
if (l !== noExtensionLocale) { | ||
extension = l.slice(noExtensionLocale.length, l.length); | ||
} | ||
if (availableLocales.has(noExtensionLocale)) { | ||
foundLocale = noExtensionLocale; | ||
break; | ||
} | ||
if (minimizedAvailableLocales.has(noExtensionLocale)) { | ||
foundLocale = noExtensionLocale; | ||
break; | ||
} | ||
var locale = new Intl.Locale(noExtensionLocale); | ||
var maximizedRequestedLocale = locale.maximize().toString(); | ||
var minimizedRequestedLocale = locale.minimize().toString(); | ||
// Check minimized locale | ||
if (minimizedAvailableLocales.has(minimizedRequestedLocale)) { | ||
foundLocale = minimizedRequestedLocale; | ||
break; | ||
} | ||
// Lookup algo on maximized locale | ||
foundLocale = BestAvailableLocale(minimizedAvailableLocales, maximizedRequestedLocale); | ||
} | ||
@@ -62,8 +30,6 @@ if (!foundLocale) { | ||
return { | ||
locale: availableLocaleMap[foundLocale] || | ||
canonicalizedLocaleMap[foundLocale] || | ||
minimizedAvailableLocaleMap[foundLocale] || | ||
foundLocale, | ||
locale: foundLocale, | ||
extension: extension, | ||
}; | ||
} | ||
exports.BestFitMatcher = BestFitMatcher; |
@@ -0,1 +1,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CanonicalizeLocaleList = void 0; | ||
/** | ||
@@ -5,5 +8,6 @@ * http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist | ||
*/ | ||
export function CanonicalizeLocaleList(locales) { | ||
function CanonicalizeLocaleList(locales) { | ||
// TODO | ||
return Intl.getCanonicalLocales(locales); | ||
} | ||
exports.CanonicalizeLocaleList = CanonicalizeLocaleList; |
@@ -8,2 +8,2 @@ import { LookupMatcherResult } from './types'; | ||
*/ | ||
export declare function LookupMatcher(availableLocales: Set<string>, requestedLocales: string[], getDefaultLocale: () => string): LookupMatcherResult; | ||
export declare function LookupMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult; |
@@ -1,3 +0,6 @@ | ||
import { UNICODE_EXTENSION_SEQUENCE_REGEX } from './utils'; | ||
import { BestAvailableLocale } from './BestAvailableLocale'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LookupMatcher = void 0; | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
var utils_1 = require("./utils"); | ||
/** | ||
@@ -9,8 +12,8 @@ * https://tc39.es/ecma402/#sec-lookupmatcher | ||
*/ | ||
export function LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) { | ||
function LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) { | ||
var result = { locale: '' }; | ||
for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { | ||
var locale = requestedLocales_1[_i]; | ||
var noExtensionLocale = locale.replace(UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
var availableLocale = BestAvailableLocale(availableLocales, noExtensionLocale); | ||
var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); | ||
if (availableLocale) { | ||
@@ -27,1 +30,2 @@ result.locale = availableLocale; | ||
} | ||
exports.LookupMatcher = LookupMatcher; |
@@ -6,2 +6,2 @@ /** | ||
*/ | ||
export declare function LookupSupportedLocales(availableLocales: Set<string>, requestedLocales: string[]): string[]; | ||
export declare function LookupSupportedLocales(availableLocales: string[], requestedLocales: string[]): string[]; |
@@ -1,3 +0,6 @@ | ||
import { UNICODE_EXTENSION_SEQUENCE_REGEX } from './utils'; | ||
import { BestAvailableLocale } from './BestAvailableLocale'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LookupSupportedLocales = void 0; | ||
var BestAvailableLocale_1 = require("./BestAvailableLocale"); | ||
var utils_1 = require("./utils"); | ||
/** | ||
@@ -8,8 +11,8 @@ * https://tc39.es/ecma402/#sec-lookupsupportedlocales | ||
*/ | ||
export function LookupSupportedLocales(availableLocales, requestedLocales) { | ||
function LookupSupportedLocales(availableLocales, requestedLocales) { | ||
var subset = []; | ||
for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { | ||
var locale = requestedLocales_1[_i]; | ||
var noExtensionLocale = locale.replace(UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
var availableLocale = BestAvailableLocale(availableLocales, noExtensionLocale); | ||
var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ''); | ||
var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); | ||
if (availableLocale) { | ||
@@ -21,1 +24,2 @@ subset.push(availableLocale); | ||
} | ||
exports.LookupSupportedLocales = LookupSupportedLocales; |
@@ -11,5 +11,5 @@ export interface ResolveLocaleResult { | ||
[k in K]: any; | ||
}>(availableLocales: Set<string>, requestedLocales: string[], options: { | ||
}>(availableLocales: Set<string> | readonly string[], requestedLocales: readonly string[], options: { | ||
localeMatcher: string; | ||
[k: string]: string; | ||
}, relevantExtensionKeys: K[], localeData: Record<string, D | undefined>, getDefaultLocale: () => string): ResolveLocaleResult; |
@@ -1,16 +0,19 @@ | ||
import { LookupMatcher } from './LookupMatcher'; | ||
import { BestFitMatcher } from './BestFitMatcher'; | ||
import { invariant } from './utils'; | ||
import { UnicodeExtensionValue } from './UnicodeExtensionValue'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResolveLocale = void 0; | ||
var BestFitMatcher_1 = require("./BestFitMatcher"); | ||
var LookupMatcher_1 = require("./LookupMatcher"); | ||
var UnicodeExtensionValue_1 = require("./UnicodeExtensionValue"); | ||
var utils_1 = require("./utils"); | ||
/** | ||
* https://tc39.es/ecma402/#sec-resolvelocale | ||
*/ | ||
export function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) { | ||
function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) { | ||
var matcher = options.localeMatcher; | ||
var r; | ||
if (matcher === 'lookup') { | ||
r = LookupMatcher(availableLocales, requestedLocales, getDefaultLocale); | ||
r = (0, LookupMatcher_1.LookupMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale); | ||
} | ||
else { | ||
r = BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale); | ||
r = (0, BestFitMatcher_1.BestFitMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale); | ||
} | ||
@@ -22,12 +25,12 @@ var foundLocale = r.locale; | ||
var key = relevantExtensionKeys_1[_i]; | ||
invariant(foundLocale in localeData, "Missing locale data for ".concat(foundLocale)); | ||
(0, utils_1.invariant)(foundLocale in localeData, "Missing locale data for ".concat(foundLocale)); | ||
var foundLocaleData = localeData[foundLocale]; | ||
invariant(typeof foundLocaleData === 'object' && foundLocaleData !== null, "locale data ".concat(key, " must be an object")); | ||
(0, utils_1.invariant)(typeof foundLocaleData === 'object' && foundLocaleData !== null, "locale data ".concat(key, " must be an object")); | ||
var keyLocaleData = foundLocaleData[key]; | ||
invariant(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array")); | ||
(0, utils_1.invariant)(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array")); | ||
var value = keyLocaleData[0]; | ||
invariant(typeof value === 'string' || value === null, "value must be string or null but got ".concat(typeof value, " in key ").concat(key)); | ||
(0, utils_1.invariant)(typeof value === 'string' || value === null, "value must be string or null but got ".concat(typeof value, " in key ").concat(key)); | ||
var supportedExtensionAddition = ''; | ||
if (r.extension) { | ||
var requestedValue = UnicodeExtensionValue(r.extension, key); | ||
var requestedValue = (0, UnicodeExtensionValue_1.UnicodeExtensionValue)(r.extension, key); | ||
if (requestedValue !== undefined) { | ||
@@ -48,3 +51,3 @@ if (requestedValue !== '') { | ||
var optionsValue = options[key]; | ||
invariant(typeof optionsValue === 'string' || | ||
(0, utils_1.invariant)(typeof optionsValue === 'string' || | ||
typeof optionsValue === 'undefined' || | ||
@@ -77,1 +80,2 @@ optionsValue === null, 'optionsValue must be String, Undefined or Null'); | ||
} | ||
exports.ResolveLocale = ResolveLocale; |
@@ -1,1 +0,2 @@ | ||
export {}; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,2 +0,5 @@ | ||
import { invariant } from './utils'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.UnicodeExtensionValue = void 0; | ||
var utils_1 = require("./utils"); | ||
/** | ||
@@ -7,4 +10,4 @@ * https://tc39.es/ecma402/#sec-unicodeextensionvalue | ||
*/ | ||
export function UnicodeExtensionValue(extension, key) { | ||
invariant(key.length === 2, 'key must have 2 elements'); | ||
function UnicodeExtensionValue(extension, key) { | ||
(0, utils_1.invariant)(key.length === 2, 'key must have 2 elements'); | ||
var size = extension.length; | ||
@@ -48,1 +51,2 @@ var searchValue = "-".concat(key, "-"); | ||
} | ||
exports.UnicodeExtensionValue = UnicodeExtensionValue; |
export declare const UNICODE_EXTENSION_SEQUENCE_REGEX: RegExp; | ||
export declare function invariant(condition: boolean, message: string, Err?: any): asserts condition; | ||
export declare function findMatchingDistance(desired: string, supported: string): number; | ||
export declare function findBestMatch(desired: string, supportedLocales: readonly string[], threshold?: number): string | undefined; |
@@ -1,3 +0,9 @@ | ||
export var UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; | ||
export function invariant(condition, message, Err) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.findBestMatch = exports.findMatchingDistance = exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; | ||
var tslib_1 = require("tslib"); | ||
var languageMatching_1 = require("./languageMatching"); | ||
var regions_generated_1 = require("./regions.generated"); | ||
exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; | ||
function invariant(condition, message, Err) { | ||
if (Err === void 0) { Err = Error; } | ||
@@ -8,1 +14,146 @@ if (!condition) { | ||
} | ||
exports.invariant = invariant; | ||
// This is effectively 2 languages in 2 different regions not even in the same cluster | ||
var DEFAULT_MATCHING_THRESHOLD = 840; | ||
var PROCESSED_DATA; | ||
function processData() { | ||
var _a, _b; | ||
if (!PROCESSED_DATA) { | ||
var paradigmLocales = (_b = (_a = languageMatching_1.data.supplemental.languageMatching['written-new'][0]) === null || _a === void 0 ? void 0 : _a.paradigmLocales) === null || _b === void 0 ? void 0 : _b._locales.split(' '); | ||
var matchVariables = languageMatching_1.data.supplemental.languageMatching['written-new'].slice(1, 5); | ||
var data = languageMatching_1.data.supplemental.languageMatching['written-new'].slice(5); | ||
var matches = data.map(function (d) { | ||
var key = Object.keys(d)[0]; | ||
var value = d[key]; | ||
return { | ||
supported: key, | ||
desired: value._desired, | ||
distance: +value._distance, | ||
oneway: value.oneway === 'true' ? true : false, | ||
}; | ||
}, {}); | ||
PROCESSED_DATA = { | ||
matches: matches, | ||
matchVariables: matchVariables.reduce(function (all, d) { | ||
var key = Object.keys(d)[0]; | ||
var value = d[key]; | ||
all[key.slice(1)] = value._value.split('+'); | ||
return all; | ||
}, {}), | ||
paradigmLocales: tslib_1.__spreadArray(tslib_1.__spreadArray([], paradigmLocales, true), paradigmLocales.map(function (l) { | ||
return new Intl.Locale(l.replace(/_/g, '-')).maximize().toString(); | ||
}), true), | ||
}; | ||
} | ||
return PROCESSED_DATA; | ||
} | ||
function isMatched(locale, languageMatchInfoLocale, matchVariables) { | ||
var _a = languageMatchInfoLocale.split('-'), language = _a[0], script = _a[1], region = _a[2]; | ||
var matches = true; | ||
if (region && region[0] === '$') { | ||
var shouldInclude = region[1] !== '!'; | ||
var matchRegions = shouldInclude | ||
? matchVariables[region.slice(1)] | ||
: matchVariables[region.slice(2)]; | ||
var expandedMatchedRegions = matchRegions | ||
.map(function (r) { return regions_generated_1.regions[r] || [r]; }) | ||
.reduce(function (all, list) { return tslib_1.__spreadArray(tslib_1.__spreadArray([], all, true), list, true); }, []); | ||
matches && (matches = !(expandedMatchedRegions.indexOf(locale.region || '') > 1 != | ||
shouldInclude)); | ||
} | ||
else { | ||
matches && (matches = locale.region | ||
? region === '*' || region === locale.region | ||
: true); | ||
} | ||
matches && (matches = locale.script ? script === '*' || script === locale.script : true); | ||
matches && (matches = locale.language | ||
? language === '*' || language === locale.language | ||
: true); | ||
return matches; | ||
} | ||
function serializeLSR(lsr) { | ||
return [lsr.language, lsr.script, lsr.region].filter(Boolean).join('-'); | ||
} | ||
function findMatchingDistanceForLSR(desired, supported, data) { | ||
for (var _i = 0, _a = data.matches; _i < _a.length; _i++) { | ||
var d = _a[_i]; | ||
var matches = isMatched(desired, d.desired, data.matchVariables) && | ||
isMatched(supported, d.supported, data.matchVariables); | ||
if (!d.oneway && !matches) { | ||
matches = | ||
isMatched(desired, d.supported, data.matchVariables) && | ||
isMatched(supported, d.desired, data.matchVariables); | ||
} | ||
if (matches) { | ||
var distance = d.distance * 10; | ||
if (data.paradigmLocales.indexOf(serializeLSR(desired)) > -1 != | ||
data.paradigmLocales.indexOf(serializeLSR(supported)) > -1) { | ||
return distance - 1; | ||
} | ||
return distance; | ||
} | ||
} | ||
throw new Error('No matching distance found'); | ||
} | ||
function findMatchingDistance(desired, supported) { | ||
var desiredLocale = new Intl.Locale(desired).maximize(); | ||
var supportedLocale = new Intl.Locale(supported).maximize(); | ||
var desiredLSR = { | ||
language: desiredLocale.language, | ||
script: desiredLocale.script || '', | ||
region: desiredLocale.region || '', | ||
}; | ||
var supportedLSR = { | ||
language: supportedLocale.language, | ||
script: supportedLocale.script || '', | ||
region: supportedLocale.region || '', | ||
}; | ||
var matchingDistance = 0; | ||
var data = processData(); | ||
if (desiredLSR.language !== supportedLSR.language) { | ||
matchingDistance += findMatchingDistanceForLSR({ | ||
language: desiredLocale.language, | ||
script: '', | ||
region: '', | ||
}, { | ||
language: supportedLocale.language, | ||
script: '', | ||
region: '', | ||
}, data); | ||
} | ||
if (desiredLSR.script !== supportedLSR.script) { | ||
matchingDistance += findMatchingDistanceForLSR({ | ||
language: desiredLocale.language, | ||
script: desiredLSR.script, | ||
region: '', | ||
}, { | ||
language: supportedLocale.language, | ||
script: desiredLSR.script, | ||
region: '', | ||
}, data); | ||
} | ||
if (desiredLSR.region !== supportedLSR.region) { | ||
matchingDistance += findMatchingDistanceForLSR(desiredLSR, supportedLSR, data); | ||
} | ||
return matchingDistance; | ||
} | ||
exports.findMatchingDistance = findMatchingDistance; | ||
function findBestMatch(desired, supportedLocales, threshold) { | ||
if (threshold === void 0) { threshold = DEFAULT_MATCHING_THRESHOLD; } | ||
var bestMatch = undefined; | ||
var lowestDistance = Infinity; | ||
supportedLocales.forEach(function (supported, i) { | ||
// Add some weight to the distance based on the order of the supported locales | ||
var distance = findMatchingDistance(desired, supported) + i; | ||
if (distance < lowestDistance) { | ||
lowestDistance = distance; | ||
bestMatch = supported; | ||
} | ||
}); | ||
if (lowestDistance >= threshold) { | ||
return; | ||
} | ||
return bestMatch; | ||
} | ||
exports.findBestMatch = findBestMatch; |
@@ -1,13 +0,15 @@ | ||
import { CanonicalizeLocaleList } from './abstract/CanonicalizeLocaleList'; | ||
import { ResolveLocale } from './abstract/ResolveLocale'; | ||
export function match(requestedLocales, availableLocales, defaultLocale, opts) { | ||
var locales = availableLocales.reduce(function (all, l) { | ||
all.add(l); | ||
return all; | ||
}, new Set()); | ||
return ResolveLocale(locales, CanonicalizeLocaleList(requestedLocales), { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResolveLocale = exports.LookupSupportedLocales = exports.match = void 0; | ||
var CanonicalizeLocaleList_1 = require("./abstract/CanonicalizeLocaleList"); | ||
var ResolveLocale_1 = require("./abstract/ResolveLocale"); | ||
function match(requestedLocales, availableLocales, defaultLocale, opts) { | ||
return (0, ResolveLocale_1.ResolveLocale)(availableLocales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { | ||
localeMatcher: (opts === null || opts === void 0 ? void 0 : opts.algorithm) || 'best fit', | ||
}, [], {}, function () { return defaultLocale; }).locale; | ||
} | ||
export { LookupSupportedLocales } from './abstract/LookupSupportedLocales'; | ||
export { ResolveLocale } from './abstract/ResolveLocale'; | ||
exports.match = match; | ||
var LookupSupportedLocales_1 = require("./abstract/LookupSupportedLocales"); | ||
Object.defineProperty(exports, "LookupSupportedLocales", { enumerable: true, get: function () { return LookupSupportedLocales_1.LookupSupportedLocales; } }); | ||
var ResolveLocale_2 = require("./abstract/ResolveLocale"); | ||
Object.defineProperty(exports, "ResolveLocale", { enumerable: true, get: function () { return ResolveLocale_2.ResolveLocale; } }); |
{ | ||
"name": "@formatjs/intl-localematcher", | ||
"version": "0.4.2", | ||
"version": "0.5.0", | ||
"description": "Intl.LocaleMatcher ponyfill", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
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
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
803909
24854
51
1