@formatjs/intl-getcanonicallocales 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare function getCanonicalLocales(locales?: string[] | string): string[];
1
+ export declare function getCanonicalLocales(locales?: string[] | string | Intl.Locale | Intl.Locale[] | ArrayLike<string | Intl.Locale>): string[];
2
2
  export * from "./src/emitter.js";
3
3
  export { isStructurallyValidLanguageTag, isUnicodeLanguageSubtag, isUnicodeRegionSubtag, isUnicodeScriptSubtag, parseUnicodeLanguageId, parseUnicodeLocaleId } from "./src/parser.js";
4
4
  export * from "./src/types.js";
package/index.js CHANGED
@@ -2,19 +2,58 @@ import { CanonicalizeUnicodeLocaleId } from "./src/canonicalizer.js";
2
2
  import { emitUnicodeLocaleId } from "./src/emitter.js";
3
3
  import { parseUnicodeLocaleId } from "./src/parser.js";
4
4
  /**
5
+ * Check if value is an Intl.Locale object by checking for [[InitializedLocale]] internal slot
6
+ * We detect this by checking if it's an Intl.Locale instance
7
+ *
8
+ * Per ECMA-402 #sec-canonicalizelocalelist step 7.c:
9
+ * "If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
10
+ * Let tag be kValue.[[Locale]]"
11
+ *
12
+ * https://tc39.es/ecma402/#sec-canonicalizelocalelist
13
+ */
14
+ function isLocaleObject(value) {
15
+ return typeof value === "object" && value !== null && typeof value.toString === "function" && typeof value.baseName === "string" && typeof value.language === "string";
16
+ }
17
+ /**
5
18
  * https://tc39.es/ecma402/#sec-canonicalizelocalelist
6
19
  * @param locales
7
20
  */
8
21
  function CanonicalizeLocaleList(locales) {
22
+ // Step 1-2: If locales is undefined, return empty list
9
23
  if (locales === undefined) {
10
24
  return [];
11
25
  }
12
26
  const seen = [];
13
- if (typeof locales === "string") {
27
+ // Step 3-4: Handle string or Locale object by wrapping in array
28
+ // Per spec: "If Type(locales) is String or Type(locales) is Object and locales has an
29
+ // [[InitializedLocale]] internal slot, then Let O be CreateArrayFromList(« locales »)"
30
+ if (typeof locales === "string" || isLocaleObject(locales)) {
14
31
  locales = [locales];
15
32
  }
16
- for (const locale of locales) {
17
- const canonicalizedTag = emitUnicodeLocaleId(CanonicalizeUnicodeLocaleId(parseUnicodeLocaleId(locale)));
33
+ // Step 5-6: Convert to object and get length for array-like objects
34
+ // Per spec: "Let O be ? ToObject(locales)" and "Let len be ? ToLength(? Get(O, "length"))"
35
+ const O = Object(locales);
36
+ const len = typeof O.length === "number" ? O.length : 0;
37
+ // Step 7: Iterate through elements
38
+ for (let k = 0; k < len; k++) {
39
+ // Check if property exists
40
+ if (!(k in O)) {
41
+ continue;
42
+ }
43
+ const kValue = O[k];
44
+ // Step 7c-d: Extract locale string
45
+ let tag;
46
+ if (typeof kValue === "string") {
47
+ tag = kValue;
48
+ } else if (isLocaleObject(kValue)) {
49
+ // For Intl.Locale objects, use toString() which returns the canonicalized locale
50
+ tag = kValue.toString();
51
+ } else {
52
+ throw new TypeError(`Invalid locale type: expected string or Intl.Locale, got ${typeof kValue}`);
53
+ }
54
+ // Step 7e-g: Validate and canonicalize
55
+ const canonicalizedTag = emitUnicodeLocaleId(CanonicalizeUnicodeLocaleId(parseUnicodeLocaleId(tag)));
56
+ // Step 7h: Deduplicate
18
57
  if (seen.indexOf(canonicalizedTag) < 0) {
19
58
  seen.push(canonicalizedTag);
20
59
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formatjs/intl-getcanonicallocales",
3
3
  "description": "Intl.getCanonicalLocales polyfill",
4
- "version": "3.1.2",
4
+ "version": "3.2.0",
5
5
  "license": "MIT",
6
6
  "author": "Long Ho <holevietlong@gmail.com>",
7
7
  "type": "module",
@@ -13,7 +13,7 @@
13
13
  "./should-polyfill.js": "./should-polyfill.js"
14
14
  },
15
15
  "dependencies": {
16
- "tslib": "^2.8.0"
16
+ "tslib": "^2.8.1"
17
17
  },
18
18
  "bugs": "https://github.com/formatjs/formatjs/issues",
19
19
  "homepage": "https://github.com/formatjs/formatjs#readme",
package/polyfill.iife.js CHANGED
@@ -9408,17 +9408,36 @@
9408
9408
  }
9409
9409
 
9410
9410
  // packages/intl-getcanonicallocales/index.ts
9411
+ function isLocaleObject(value) {
9412
+ return typeof value === "object" && value !== null && typeof value.toString === "function" && typeof value.baseName === "string" && typeof value.language === "string";
9413
+ }
9411
9414
  function CanonicalizeLocaleList(locales) {
9412
9415
  if (locales === void 0) {
9413
9416
  return [];
9414
9417
  }
9415
9418
  const seen = [];
9416
- if (typeof locales === "string") {
9419
+ if (typeof locales === "string" || isLocaleObject(locales)) {
9417
9420
  locales = [locales];
9418
9421
  }
9419
- for (const locale of locales) {
9422
+ const O = Object(locales);
9423
+ const len = typeof O.length === "number" ? O.length : 0;
9424
+ for (let k = 0; k < len; k++) {
9425
+ if (!(k in O)) {
9426
+ continue;
9427
+ }
9428
+ const kValue = O[k];
9429
+ let tag;
9430
+ if (typeof kValue === "string") {
9431
+ tag = kValue;
9432
+ } else if (isLocaleObject(kValue)) {
9433
+ tag = kValue.toString();
9434
+ } else {
9435
+ throw new TypeError(
9436
+ `Invalid locale type: expected string or Intl.Locale, got ${typeof kValue}`
9437
+ );
9438
+ }
9420
9439
  const canonicalizedTag = emitUnicodeLocaleId(
9421
- CanonicalizeUnicodeLocaleId(parseUnicodeLocaleId(locale))
9440
+ CanonicalizeUnicodeLocaleId(parseUnicodeLocaleId(tag))
9422
9441
  );
9423
9442
  if (seen.indexOf(canonicalizedTag) < 0) {
9424
9443
  seen.push(canonicalizedTag);
@@ -1,5 +1,3 @@
1
- /* @generated */
2
- // prettier-ignore
3
1
  export declare const languageAlias: Record<string, string>;
4
2
  export declare const territoryAlias: Record<string, string>;
5
3
  export declare const scriptAlias: Record<string, string>;
@@ -1,3 +1 @@
1
- /* @generated */
2
- // prettier-ignore
3
1
  export declare const likelySubtags: Record<string, string>;