node_modules ignore

This commit is contained in:
oier committed 2025-05-08 23:43:47 +02:00
1 parent e19d52f172
commit 4574544c9f
65041 files changed
+10593536

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) 2023 FormatJS
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+3
View File
@@ -0,0 +1,3 @@
# Intl LocaleMatcher
We've migrated the docs to https://formatjs.io/docs/polyfills/intl-localematcher.
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-bestavailablelocale
* @param availableLocales
* @param locale
*/
export declare function BestAvailableLocale(availableLocales: readonly string[], locale: string): string | undefined;
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BestAvailableLocale = void 0;
/**
* https://tc39.es/ecma402/#sec-bestavailablelocale
* @param availableLocales
* @param locale
*/
function BestAvailableLocale(availableLocales, locale) {
var candidate = locale;
while (true) {
if (availableLocales.indexOf(candidate) > -1) {
return candidate;
}
var pos = candidate.lastIndexOf('-');
if (!~pos) {
return undefined;
}
if (pos >= 2 && candidate[pos - 2] === '-') {
pos -= 2;
}
candidate = candidate.slice(0, pos);
}
}
exports.BestAvailableLocale = BestAvailableLocale;
@@ -0,0 +1,8 @@
import { LookupMatcherResult } from './types';
/**
* https://tc39.es/ecma402/#sec-bestfitmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export declare function BestFitMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult;
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BestFitMatcher = void 0;
var utils_1 = require("./utils");
/**
* https://tc39.es/ecma402/#sec-bestfitmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) {
var foundLocale;
var extension;
var noExtensionLocales = [];
var noExtensionLocaleMap = requestedLocales.reduce(function (all, l) {
var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');
noExtensionLocales.push(noExtensionLocale);
all[noExtensionLocale] = l;
return all;
}, {});
var result = (0, utils_1.findBestMatch)(noExtensionLocales, availableLocales);
if (result.matchedSupportedLocale && result.matchedDesiredLocale) {
foundLocale = result.matchedSupportedLocale;
extension =
noExtensionLocaleMap[result.matchedDesiredLocale].slice(result.matchedDesiredLocale.length) || undefined;
}
if (!foundLocale) {
return { locale: getDefaultLocale() };
}
return {
locale: foundLocale,
extension: extension,
};
}
exports.BestFitMatcher = BestFitMatcher;
@@ -0,0 +1,5 @@
/**
* http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist
* @param locales
*/
export declare function CanonicalizeLocaleList(locales?: string | readonly string[]): string[];
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CanonicalizeLocaleList = void 0;
/**
* http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist
* @param locales
*/
function CanonicalizeLocaleList(locales) {
// TODO
return Intl.getCanonicalLocales(locales);
}
exports.CanonicalizeLocaleList = CanonicalizeLocaleList;
@@ -0,0 +1,8 @@
import { LookupMatcherResult } from './types';
/**
* https://tc39.es/ecma402/#sec-lookupmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export declare function LookupMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult;
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LookupMatcher = void 0;
var BestAvailableLocale_1 = require("./BestAvailableLocale");
var utils_1 = require("./utils");
/**
* https://tc39.es/ecma402/#sec-lookupmatcher
* @param availableLocales
* @param requestedLocales
* @param 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(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');
var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale);
if (availableLocale) {
result.locale = availableLocale;
if (locale !== noExtensionLocale) {
result.extension = locale.slice(noExtensionLocale.length, locale.length);
}
return result;
}
}
result.locale = getDefaultLocale();
return result;
}
exports.LookupMatcher = LookupMatcher;
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-lookupsupportedlocales
* @param availableLocales
* @param requestedLocales
*/
export declare function LookupSupportedLocales(availableLocales: string[], requestedLocales: string[]): string[];
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LookupSupportedLocales = void 0;
var BestAvailableLocale_1 = require("./BestAvailableLocale");
var utils_1 = require("./utils");
/**
* https://tc39.es/ecma402/#sec-lookupsupportedlocales
* @param availableLocales
* @param 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(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');
var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale);
if (availableLocale) {
subset.push(availableLocale);
}
}
return subset;
}
exports.LookupSupportedLocales = LookupSupportedLocales;
@@ -0,0 +1,14 @@
export interface ResolveLocaleResult {
locale: string;
dataLocale: string;
[k: string]: any;
}
/**
* https://tc39.es/ecma402/#sec-resolvelocale
*/
export declare function ResolveLocale<K extends string, D extends {
[k in K]: any;
}>(availableLocales: Set<string> | readonly string[], requestedLocales: readonly string[], options: {
localeMatcher: string;
[k: string]: string;
}, relevantExtensionKeys: K[], localeData: Record<string, D | undefined>, getDefaultLocale: () => string): ResolveLocaleResult;
@@ -0,0 +1,78 @@
"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
*/
function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) {
var matcher = options.localeMatcher;
var r;
if (matcher === 'lookup') {
r = (0, LookupMatcher_1.LookupMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale);
}
else {
r = (0, BestFitMatcher_1.BestFitMatcher)(Array.from(availableLocales), requestedLocales, getDefaultLocale);
}
var foundLocale = r.locale;
var result = { locale: '', dataLocale: foundLocale };
var supportedExtension = '-u';
for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) {
var key = relevantExtensionKeys_1[_i];
(0, utils_1.invariant)(foundLocale in localeData, "Missing locale data for ".concat(foundLocale));
var foundLocaleData = localeData[foundLocale];
(0, utils_1.invariant)(typeof foundLocaleData === 'object' && foundLocaleData !== null, "locale data ".concat(key, " must be an object"));
var keyLocaleData = foundLocaleData[key];
(0, utils_1.invariant)(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array"));
var value = keyLocaleData[0];
(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 = (0, UnicodeExtensionValue_1.UnicodeExtensionValue)(r.extension, key);
if (requestedValue !== undefined) {
if (requestedValue !== '') {
if (~keyLocaleData.indexOf(requestedValue)) {
value = requestedValue;
supportedExtensionAddition = "-".concat(key, "-").concat(value);
}
}
else if (~requestedValue.indexOf('true')) {
value = 'true';
supportedExtensionAddition = "-".concat(key);
}
}
}
if (key in options) {
var optionsValue = options[key];
(0, utils_1.invariant)(typeof optionsValue === 'string' ||
typeof optionsValue === 'undefined' ||
optionsValue === null, 'optionsValue must be String, Undefined or Null');
if (~keyLocaleData.indexOf(optionsValue)) {
if (optionsValue !== value) {
value = optionsValue;
supportedExtensionAddition = '';
}
}
}
result[key] = value;
supportedExtension += supportedExtensionAddition;
}
if (supportedExtension.length > 2) {
var privateIndex = foundLocale.indexOf('-x-');
if (privateIndex === -1) {
foundLocale = foundLocale + supportedExtension;
}
else {
var preExtension = foundLocale.slice(0, privateIndex);
var postExtension = foundLocale.slice(privateIndex, foundLocale.length);
foundLocale = preExtension + supportedExtension + postExtension;
}
foundLocale = Intl.getCanonicalLocales(foundLocale)[0];
}
result.locale = foundLocale;
return result;
}
exports.ResolveLocale = ResolveLocale;
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-unicodeextensionvalue
* @param extension
* @param key
*/
export declare function UnicodeExtensionValue(extension: string, key: string): string | undefined;
@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnicodeExtensionValue = void 0;
var utils_1 = require("./utils");
/**
* https://tc39.es/ecma402/#sec-unicodeextensionvalue
* @param extension
* @param key
*/
function UnicodeExtensionValue(extension, key) {
(0, utils_1.invariant)(key.length === 2, 'key must have 2 elements');
var size = extension.length;
var searchValue = "-".concat(key, "-");
var pos = extension.indexOf(searchValue);
if (pos !== -1) {
var start = pos + 4;
var end = start;
var k = start;
var done = false;
while (!done) {
var e = extension.indexOf('-', k);
var len = void 0;
if (e === -1) {
len = size - k;
}
else {
len = e - k;
}
if (len === 2) {
done = true;
}
else if (e === -1) {
end = size;
done = true;
}
else {
end = e;
k = e + 1;
}
}
return extension.slice(start, end);
}
searchValue = "-".concat(key);
pos = extension.indexOf(searchValue);
if (pos !== -1 && pos + 3 === size) {
return '';
}
return undefined;
}
exports.UnicodeExtensionValue = UnicodeExtensionValue;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
export declare const regions: Record<string, string[]>;
File diff suppressed because it is too large. Load diff
+5
View File
@@ -0,0 +1,5 @@
export interface LookupMatcherResult {
locale: string;
extension?: string;
nu?: string;
}
+2
View File
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
+10
View File
@@ -0,0 +1,10 @@
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;
interface LocaleMatchingResult {
distances: Record<string, Record<string, number>>;
matchedSupportedLocale?: string;
matchedDesiredLocale?: string;
}
export declare function findBestMatch(requestedLocales: readonly string[], supportedLocales: readonly string[], threshold?: number): LocaleMatchingResult;
export {};
+171
View File
@@ -0,0 +1,171 @@
"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; }
if (!condition) {
throw new Err(message);
}
}
exports.invariant = invariant;
// This is effectively 2 languages in 2 different regions in the same cluster
var DEFAULT_MATCHING_THRESHOLD = 838;
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(requestedLocales, supportedLocales, threshold) {
if (threshold === void 0) { threshold = DEFAULT_MATCHING_THRESHOLD; }
var lowestDistance = Infinity;
var result = {
matchedDesiredLocale: '',
distances: {},
};
requestedLocales.forEach(function (desired, i) {
if (!result.distances[desired]) {
result.distances[desired] = {};
}
supportedLocales.forEach(function (supported) {
// Add some weight to the distance based on the order of the supported locales
// Add penalty for the order of the requested locales, which currently is 0 since ECMA-402
// doesn't really have room for weighted locales like `en; q=0.1`
var distance = findMatchingDistance(desired, supported) + 0 + i * 40;
result.distances[desired][supported] = distance;
if (distance < lowestDistance) {
lowestDistance = distance;
result.matchedDesiredLocale = desired;
result.matchedSupportedLocale = supported;
}
});
});
if (lowestDistance >= threshold) {
result.matchedDesiredLocale = undefined;
result.matchedSupportedLocale = undefined;
}
return result;
}
exports.findBestMatch = findBestMatch;
+6
View File
@@ -0,0 +1,6 @@
export interface Opts {
algorithm: 'lookup' | 'best fit';
}
export declare function match(requestedLocales: readonly string[], availableLocales: readonly string[], defaultLocale: string, opts?: Opts): string;
export { LookupSupportedLocales } from './abstract/LookupSupportedLocales';
export { ResolveLocale } from './abstract/ResolveLocale';
+15
View File
@@ -0,0 +1,15 @@
"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;
}
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; } });
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-bestavailablelocale
* @param availableLocales
* @param locale
*/
export declare function BestAvailableLocale(availableLocales: readonly string[], locale: string): string | undefined;
@@ -0,0 +1,21 @@
/**
* https://tc39.es/ecma402/#sec-bestavailablelocale
* @param availableLocales
* @param locale
*/
export function BestAvailableLocale(availableLocales, locale) {
var candidate = locale;
while (true) {
if (availableLocales.indexOf(candidate) > -1) {
return candidate;
}
var pos = candidate.lastIndexOf('-');
if (!~pos) {
return undefined;
}
if (pos >= 2 && candidate[pos - 2] === '-') {
pos -= 2;
}
candidate = candidate.slice(0, pos);
}
}
@@ -0,0 +1,8 @@
import { LookupMatcherResult } from './types';
/**
* https://tc39.es/ecma402/#sec-bestfitmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export declare function BestFitMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult;
@@ -0,0 +1,31 @@
import { UNICODE_EXTENSION_SEQUENCE_REGEX, findBestMatch } from './utils';
/**
* https://tc39.es/ecma402/#sec-bestfitmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) {
var foundLocale;
var extension;
var noExtensionLocales = [];
var noExtensionLocaleMap = requestedLocales.reduce(function (all, l) {
var noExtensionLocale = l.replace(UNICODE_EXTENSION_SEQUENCE_REGEX, '');
noExtensionLocales.push(noExtensionLocale);
all[noExtensionLocale] = l;
return all;
}, {});
var result = findBestMatch(noExtensionLocales, availableLocales);
if (result.matchedSupportedLocale && result.matchedDesiredLocale) {
foundLocale = result.matchedSupportedLocale;
extension =
noExtensionLocaleMap[result.matchedDesiredLocale].slice(result.matchedDesiredLocale.length) || undefined;
}
if (!foundLocale) {
return { locale: getDefaultLocale() };
}
return {
locale: foundLocale,
extension: extension,
};
}
@@ -0,0 +1,5 @@
/**
* http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist
* @param locales
*/
export declare function CanonicalizeLocaleList(locales?: string | readonly string[]): string[];
@@ -0,0 +1,8 @@
/**
* http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist
* @param locales
*/
export function CanonicalizeLocaleList(locales) {
// TODO
return Intl.getCanonicalLocales(locales);
}
@@ -0,0 +1,8 @@
import { LookupMatcherResult } from './types';
/**
* https://tc39.es/ecma402/#sec-lookupmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export declare function LookupMatcher(availableLocales: readonly string[], requestedLocales: readonly string[], getDefaultLocale: () => string): LookupMatcherResult;
@@ -0,0 +1,25 @@
import { BestAvailableLocale } from './BestAvailableLocale';
import { UNICODE_EXTENSION_SEQUENCE_REGEX } from './utils';
/**
* https://tc39.es/ecma402/#sec-lookupmatcher
* @param availableLocales
* @param requestedLocales
* @param getDefaultLocale
*/
export 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);
if (availableLocale) {
result.locale = availableLocale;
if (locale !== noExtensionLocale) {
result.extension = locale.slice(noExtensionLocale.length, locale.length);
}
return result;
}
}
result.locale = getDefaultLocale();
return result;
}
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-lookupsupportedlocales
* @param availableLocales
* @param requestedLocales
*/
export declare function LookupSupportedLocales(availableLocales: string[], requestedLocales: string[]): string[];
@@ -0,0 +1,19 @@
import { BestAvailableLocale } from './BestAvailableLocale';
import { UNICODE_EXTENSION_SEQUENCE_REGEX } from './utils';
/**
* https://tc39.es/ecma402/#sec-lookupsupportedlocales
* @param availableLocales
* @param requestedLocales
*/
export 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);
if (availableLocale) {
subset.push(availableLocale);
}
}
return subset;
}
@@ -0,0 +1,14 @@
export interface ResolveLocaleResult {
locale: string;
dataLocale: string;
[k: string]: any;
}
/**
* https://tc39.es/ecma402/#sec-resolvelocale
*/
export declare function ResolveLocale<K extends string, D extends {
[k in K]: any;
}>(availableLocales: Set<string> | readonly string[], requestedLocales: readonly string[], options: {
localeMatcher: string;
[k: string]: string;
}, relevantExtensionKeys: K[], localeData: Record<string, D | undefined>, getDefaultLocale: () => string): ResolveLocaleResult;
@@ -0,0 +1,74 @@
import { BestFitMatcher } from './BestFitMatcher';
import { LookupMatcher } from './LookupMatcher';
import { UnicodeExtensionValue } from './UnicodeExtensionValue';
import { invariant } from './utils';
/**
* https://tc39.es/ecma402/#sec-resolvelocale
*/
export function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) {
var matcher = options.localeMatcher;
var r;
if (matcher === 'lookup') {
r = LookupMatcher(Array.from(availableLocales), requestedLocales, getDefaultLocale);
}
else {
r = BestFitMatcher(Array.from(availableLocales), requestedLocales, getDefaultLocale);
}
var foundLocale = r.locale;
var result = { locale: '', dataLocale: foundLocale };
var supportedExtension = '-u';
for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) {
var key = relevantExtensionKeys_1[_i];
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"));
var keyLocaleData = foundLocaleData[key];
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));
var supportedExtensionAddition = '';
if (r.extension) {
var requestedValue = UnicodeExtensionValue(r.extension, key);
if (requestedValue !== undefined) {
if (requestedValue !== '') {
if (~keyLocaleData.indexOf(requestedValue)) {
value = requestedValue;
supportedExtensionAddition = "-".concat(key, "-").concat(value);
}
}
else if (~requestedValue.indexOf('true')) {
value = 'true';
supportedExtensionAddition = "-".concat(key);
}
}
}
if (key in options) {
var optionsValue = options[key];
invariant(typeof optionsValue === 'string' ||
typeof optionsValue === 'undefined' ||
optionsValue === null, 'optionsValue must be String, Undefined or Null');
if (~keyLocaleData.indexOf(optionsValue)) {
if (optionsValue !== value) {
value = optionsValue;
supportedExtensionAddition = '';
}
}
}
result[key] = value;
supportedExtension += supportedExtensionAddition;
}
if (supportedExtension.length > 2) {
var privateIndex = foundLocale.indexOf('-x-');
if (privateIndex === -1) {
foundLocale = foundLocale + supportedExtension;
}
else {
var preExtension = foundLocale.slice(0, privateIndex);
var postExtension = foundLocale.slice(privateIndex, foundLocale.length);
foundLocale = preExtension + supportedExtension + postExtension;
}
foundLocale = Intl.getCanonicalLocales(foundLocale)[0];
}
result.locale = foundLocale;
return result;
}
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-unicodeextensionvalue
* @param extension
* @param key
*/
export declare function UnicodeExtensionValue(extension: string, key: string): string | undefined;
@@ -0,0 +1,46 @@
import { invariant } from './utils';
/**
* https://tc39.es/ecma402/#sec-unicodeextensionvalue
* @param extension
* @param key
*/
export function UnicodeExtensionValue(extension, key) {
invariant(key.length === 2, 'key must have 2 elements');
var size = extension.length;
var searchValue = "-".concat(key, "-");
var pos = extension.indexOf(searchValue);
if (pos !== -1) {
var start = pos + 4;
var end = start;
var k = start;
var done = false;
while (!done) {
var e = extension.indexOf('-', k);
var len = void 0;
if (e === -1) {
len = size - k;
}
else {
len = e - k;
}
if (len === 2) {
done = true;
}
else if (e === -1) {
end = size;
done = true;
}
else {
end = e;
k = e + 1;
}
}
return extension.slice(start, end);
}
searchValue = "-".concat(key);
pos = extension.indexOf(searchValue);
if (pos !== -1 && pos + 3 === size) {
return '';
}
return undefined;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
export declare const regions: Record<string, string[]>;
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,5 @@
export interface LookupMatcherResult {
locale: string;
extension?: string;
nu?: string;
}
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,10 @@
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;
interface LocaleMatchingResult {
distances: Record<string, Record<string, number>>;
matchedSupportedLocale?: string;
matchedDesiredLocale?: string;
}
export declare function findBestMatch(requestedLocales: readonly string[], supportedLocales: readonly string[], threshold?: number): LocaleMatchingResult;
export {};
+165
View File
@@ -0,0 +1,165 @@
import { __spreadArray } from "tslib";
import { data as jsonData } from './languageMatching';
import { regions } from './regions.generated';
export var UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi;
export function invariant(condition, message, Err) {
if (Err === void 0) { Err = Error; }
if (!condition) {
throw new Err(message);
}
}
// This is effectively 2 languages in 2 different regions in the same cluster
var DEFAULT_MATCHING_THRESHOLD = 838;
var PROCESSED_DATA;
function processData() {
var _a, _b;
if (!PROCESSED_DATA) {
var paradigmLocales = (_b = (_a = jsonData.supplemental.languageMatching['written-new'][0]) === null || _a === void 0 ? void 0 : _a.paradigmLocales) === null || _b === void 0 ? void 0 : _b._locales.split(' ');
var matchVariables = jsonData.supplemental.languageMatching['written-new'].slice(1, 5);
var data = jsonData.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: __spreadArray(__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[r] || [r]; })
.reduce(function (all, list) { return __spreadArray(__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');
}
export 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;
}
export function findBestMatch(requestedLocales, supportedLocales, threshold) {
if (threshold === void 0) { threshold = DEFAULT_MATCHING_THRESHOLD; }
var lowestDistance = Infinity;
var result = {
matchedDesiredLocale: '',
distances: {},
};
requestedLocales.forEach(function (desired, i) {
if (!result.distances[desired]) {
result.distances[desired] = {};
}
supportedLocales.forEach(function (supported) {
// Add some weight to the distance based on the order of the supported locales
// Add penalty for the order of the requested locales, which currently is 0 since ECMA-402
// doesn't really have room for weighted locales like `en; q=0.1`
var distance = findMatchingDistance(desired, supported) + 0 + i * 40;
result.distances[desired][supported] = distance;
if (distance < lowestDistance) {
lowestDistance = distance;
result.matchedDesiredLocale = desired;
result.matchedSupportedLocale = supported;
}
});
});
if (lowestDistance >= threshold) {
result.matchedDesiredLocale = undefined;
result.matchedSupportedLocale = undefined;
}
return result;
}
+6
View File
@@ -0,0 +1,6 @@
export interface Opts {
algorithm: 'lookup' | 'best fit';
}
export declare function match(requestedLocales: readonly string[], availableLocales: readonly string[], defaultLocale: string, opts?: Opts): string;
export { LookupSupportedLocales } from './abstract/LookupSupportedLocales';
export { ResolveLocale } from './abstract/ResolveLocale';
+9
View File
@@ -0,0 +1,9 @@
import { CanonicalizeLocaleList } from './abstract/CanonicalizeLocaleList';
import { ResolveLocale } from './abstract/ResolveLocale';
export function match(requestedLocales, availableLocales, defaultLocale, opts) {
return ResolveLocale(availableLocales, 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';
+30
View File
@@ -0,0 +1,30 @@
{
"name": "@formatjs/intl-localematcher",
"version": "0.5.4",
"description": "Intl.LocaleMatcher ponyfill",
"keywords": [
"intl",
"locale",
"formatjs",
"react-intl",
"i18n",
"ecma402",
"tc39"
],
"author": "Long Ho <holevietlong@gmail.com>",
"homepage": "https://github.com/formatjs/formatjs#readme",
"license": "MIT",
"main": "index.js",
"module": "lib/index.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/formatjs/formatjs.git"
},
"bugs": {
"url": "https://github.com/formatjs/formatjs/issues"
},
"dependencies": {
"tslib": "^2.4.0"
}
}