ua-browser 1.4.0 → 1.4.1
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/README.en.md +41 -0
- package/README.md +58 -1
- package/dist/index.cjs +126 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +126 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "1.4.
|
|
3
|
+
version: "1.4.1"};
|
|
4
4
|
|
|
5
5
|
// src/constants/os.ts
|
|
6
6
|
var OS_DEFS = [
|
|
7
|
-
{ name: "WebOS", detect: /hpwOS/, versionPattern: /hpwOS\/([\d.]+)/ },
|
|
8
|
-
{ name: "Symbian", detect: /Symbian/, versionPattern: null },
|
|
9
|
-
{ name: "MeeGo", detect: /MeeGo/, versionPattern: null },
|
|
10
|
-
{ name: "BlackBerry", detect: /(BlackBerry|RIM)/, versionPattern: null },
|
|
11
|
-
{ name: "FreeBSD", detect: /FreeBSD/, versionPattern: null },
|
|
12
|
-
{ name: "Debian", detect: /Debian/, versionPattern: /Debian\/([\d.]+)/ },
|
|
13
|
-
{ name: "Ubuntu", detect: /Ubuntu/, versionPattern: null },
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{ name: "
|
|
17
|
-
{ name: "
|
|
18
|
-
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
19
|
-
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
7
|
+
{ name: "WebOS", priority: 20, detect: /hpwOS/, versionPattern: /hpwOS\/([\d.]+)/ },
|
|
8
|
+
{ name: "Symbian", priority: 20, detect: /Symbian/, versionPattern: null },
|
|
9
|
+
{ name: "MeeGo", priority: 20, detect: /MeeGo/, versionPattern: null },
|
|
10
|
+
{ name: "BlackBerry", priority: 20, detect: /(BlackBerry|RIM)/, versionPattern: null },
|
|
11
|
+
{ name: "FreeBSD", priority: 20, detect: /FreeBSD/, versionPattern: null },
|
|
12
|
+
{ name: "Debian", priority: 20, detect: /Debian/, versionPattern: /Debian\/([\d.]+)/ },
|
|
13
|
+
{ name: "Ubuntu", priority: 20, detect: /Ubuntu/, versionPattern: null },
|
|
14
|
+
{ name: "Linux", priority: 10, detect: /(Linux|X11)/, versionPattern: null },
|
|
15
|
+
{ name: "Chrome OS", priority: 30, detect: /CrOS/, versionPattern: null },
|
|
16
|
+
{ name: "Tizen", priority: 20, detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
17
|
+
{ name: "iOS", priority: 20, detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
20
18
|
{
|
|
21
19
|
name: "MacOS",
|
|
20
|
+
priority: 20,
|
|
22
21
|
detect: /Macintosh/,
|
|
23
22
|
versionPattern: /Mac OS X -?([\d_.]+)/,
|
|
24
23
|
versionNames: {
|
|
@@ -36,27 +35,21 @@ var OS_DEFS = [
|
|
|
36
35
|
"15": "Sequoia"
|
|
37
36
|
}
|
|
38
37
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{ name: "
|
|
42
|
-
{ name: "tvOS", detect: /Apple TV/, versionPattern: /OS ([\d_]+) like/ },
|
|
43
|
-
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
44
|
-
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
45
|
-
// first, then HarmonyOS overrides it. versionPattern tries direct extraction first (5.0+
|
|
46
|
-
// pure HarmonyOS UAs don't have Android token), then falls back to Android version + lookup.
|
|
38
|
+
{ name: "visionOS", priority: 30, detect: /visionOS/, versionPattern: /visionOS ([\d_]+)/ },
|
|
39
|
+
{ name: "tvOS", priority: 30, detect: /Apple TV/, versionPattern: /OS ([\d_]+) like/ },
|
|
40
|
+
{ name: "Android", priority: 20, detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
47
41
|
{
|
|
48
42
|
name: "HarmonyOS",
|
|
43
|
+
priority: 30,
|
|
49
44
|
detect: /HarmonyOS/,
|
|
50
45
|
versionPattern: [/HarmonyOS[\s/]([\d.]+)/, /Android ([\d.]+)[;)]/],
|
|
51
|
-
versionLookup: { "10": "2", "11": "3", "12": "3", "13": "4" }
|
|
46
|
+
versionLookup: { "10": "2", "11": "3", "12": "3", "13": "4", "14": "4" }
|
|
52
47
|
},
|
|
53
|
-
|
|
54
|
-
{ name: "
|
|
55
|
-
{ name: "KaiOS", detect: /KAIOS/, versionPattern: /KAIOS\/([\d.]+)/ },
|
|
56
|
-
// Windows must come before Windows Phone: Windows Phone UAs contain "Windows", so Windows
|
|
57
|
-
// matches first, then Windows Phone overrides it.
|
|
48
|
+
{ name: "OpenHarmony", priority: 30, detect: /OpenHarmony/, versionPattern: /OpenHarmony[\s/]([\d.]+)/ },
|
|
49
|
+
{ name: "KaiOS", priority: 30, detect: /KAIOS/, versionPattern: /KAIOS\/([\d.]+)/ },
|
|
58
50
|
{
|
|
59
51
|
name: "Windows",
|
|
52
|
+
priority: 10,
|
|
60
53
|
detect: /Windows/,
|
|
61
54
|
versionPattern: /Windows NT ([\d.]+)/,
|
|
62
55
|
versionLookup: {
|
|
@@ -78,7 +71,7 @@ var OS_DEFS = [
|
|
|
78
71
|
"11": "Windows 11"
|
|
79
72
|
}
|
|
80
73
|
},
|
|
81
|
-
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
74
|
+
{ name: "Windows Phone", priority: 30, detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
82
75
|
];
|
|
83
76
|
|
|
84
77
|
// src/constants/browsers.ts
|
|
@@ -300,9 +293,11 @@ function lookupVersionName(map, version) {
|
|
|
300
293
|
}
|
|
301
294
|
function detectOs(ua, windowsVersion) {
|
|
302
295
|
let matchedDef = null;
|
|
296
|
+
let bestPriority = -1;
|
|
303
297
|
for (const def of OS_DEFS) {
|
|
304
|
-
if (def.detect.test(ua)) {
|
|
298
|
+
if (def.detect.test(ua) && def.priority > bestPriority) {
|
|
305
299
|
matchedDef = def;
|
|
300
|
+
bestPriority = def.priority;
|
|
306
301
|
}
|
|
307
302
|
}
|
|
308
303
|
if (!matchedDef) return { os: "unknown", osVersion: "unknown", osVersionName: "unknown" };
|
|
@@ -451,7 +446,7 @@ var BOT_DEFS = [
|
|
|
451
446
|
{ name: "Facebookbot", detect: /(facebookexternalhit|FacebookBot)/, category: "social" },
|
|
452
447
|
{ name: "Twitterbot", detect: /Twitterbot/, category: "social" },
|
|
453
448
|
{ name: "LinkedInBot", detect: /LinkedInBot/, category: "social" },
|
|
454
|
-
{ name: "PinterestBot", detect: /
|
|
449
|
+
{ name: "PinterestBot", detect: /Pinterestbot/i, category: "social" },
|
|
455
450
|
// Messaging link preview bots
|
|
456
451
|
{ name: "Slackbot", detect: /Slackbot/, category: "link-preview" },
|
|
457
452
|
{ name: "Discordbot", detect: /Discordbot/, category: "link-preview" },
|
|
@@ -580,6 +575,7 @@ var BRAND_TO_BROWSER = [
|
|
|
580
575
|
["Microsoft Edge", "Edge"],
|
|
581
576
|
["Opera", "Opera"],
|
|
582
577
|
["Vivaldi", "Vivaldi"],
|
|
578
|
+
["Brave", "Brave"],
|
|
583
579
|
["Google Chrome", "Chrome"],
|
|
584
580
|
["Chromium", "Chromium"]
|
|
585
581
|
];
|
|
@@ -644,6 +640,82 @@ function normalizeBCP47(raw) {
|
|
|
644
640
|
return p.toUpperCase();
|
|
645
641
|
}).join("-");
|
|
646
642
|
}
|
|
643
|
+
var ISO_639_1 = /* @__PURE__ */ new Set([
|
|
644
|
+
"af",
|
|
645
|
+
"am",
|
|
646
|
+
"ar",
|
|
647
|
+
"az",
|
|
648
|
+
"be",
|
|
649
|
+
"bg",
|
|
650
|
+
"bn",
|
|
651
|
+
"bs",
|
|
652
|
+
"ca",
|
|
653
|
+
"cs",
|
|
654
|
+
"cy",
|
|
655
|
+
"da",
|
|
656
|
+
"de",
|
|
657
|
+
"el",
|
|
658
|
+
"en",
|
|
659
|
+
"es",
|
|
660
|
+
"et",
|
|
661
|
+
"eu",
|
|
662
|
+
"fa",
|
|
663
|
+
"fi",
|
|
664
|
+
"fr",
|
|
665
|
+
"ga",
|
|
666
|
+
"gl",
|
|
667
|
+
"gu",
|
|
668
|
+
"he",
|
|
669
|
+
"hi",
|
|
670
|
+
"hr",
|
|
671
|
+
"hu",
|
|
672
|
+
"hy",
|
|
673
|
+
"id",
|
|
674
|
+
"is",
|
|
675
|
+
"it",
|
|
676
|
+
"ja",
|
|
677
|
+
"ka",
|
|
678
|
+
"kk",
|
|
679
|
+
"km",
|
|
680
|
+
"kn",
|
|
681
|
+
"ko",
|
|
682
|
+
"lt",
|
|
683
|
+
"lv",
|
|
684
|
+
"mk",
|
|
685
|
+
"ml",
|
|
686
|
+
"mn",
|
|
687
|
+
"mr",
|
|
688
|
+
"ms",
|
|
689
|
+
"mt",
|
|
690
|
+
"my",
|
|
691
|
+
"nb",
|
|
692
|
+
"ne",
|
|
693
|
+
"nl",
|
|
694
|
+
"no",
|
|
695
|
+
"pa",
|
|
696
|
+
"pl",
|
|
697
|
+
"pt",
|
|
698
|
+
"ro",
|
|
699
|
+
"ru",
|
|
700
|
+
"si",
|
|
701
|
+
"sk",
|
|
702
|
+
"sl",
|
|
703
|
+
"sq",
|
|
704
|
+
"sr",
|
|
705
|
+
"sv",
|
|
706
|
+
"sw",
|
|
707
|
+
"ta",
|
|
708
|
+
"te",
|
|
709
|
+
"th",
|
|
710
|
+
"tl",
|
|
711
|
+
"tr",
|
|
712
|
+
"uk",
|
|
713
|
+
"ur",
|
|
714
|
+
"uz",
|
|
715
|
+
"vi",
|
|
716
|
+
"zh",
|
|
717
|
+
"zu"
|
|
718
|
+
]);
|
|
647
719
|
function languageFromUA(ua) {
|
|
648
720
|
const kwMatch = /\bLanguage\/([a-zA-Z]{2,3}(?:[-_][a-zA-Z]{2,4}){1,2})\b/i.exec(ua);
|
|
649
721
|
if (kwMatch) return normalizeBCP47(kwMatch[1]);
|
|
@@ -653,6 +725,10 @@ function languageFromUA(ua) {
|
|
|
653
725
|
const parts = m[1].replace(/_/g, "-").split("-");
|
|
654
726
|
if (parts.length >= 2) return normalizeBCP47(m[1]);
|
|
655
727
|
}
|
|
728
|
+
const bare = /[;(]\s*([a-z]{2,3})\s*[;)]/g;
|
|
729
|
+
while ((m = bare.exec(ua)) !== null) {
|
|
730
|
+
if (ISO_639_1.has(m[1])) return m[1];
|
|
731
|
+
}
|
|
656
732
|
return "unknown";
|
|
657
733
|
}
|
|
658
734
|
function parseUA(ua, options = {}) {
|
|
@@ -709,20 +785,8 @@ function parseUA(ua, options = {}) {
|
|
|
709
785
|
const opVer = (_h = (_g = /OPR\/([\d.]+)/.exec(ua)) != null ? _g : /OPT\/([\d.]+)/.exec(ua)) != null ? _h : /Opera\/([\d.]+)/.exec(ua);
|
|
710
786
|
version = (_i = opVer == null ? void 0 : opVer[1]) != null ? _i : "unknown";
|
|
711
787
|
}
|
|
712
|
-
if (browser === "
|
|
713
|
-
|
|
714
|
-
if (m) {
|
|
715
|
-
browser = m[1];
|
|
716
|
-
version = m[2];
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
if (browser === "Firefox" && nav) {
|
|
720
|
-
try {
|
|
721
|
-
if (typeof clientInformation !== "undefined" || typeof u2f === "undefined") {
|
|
722
|
-
browser = "Firefox Nightly";
|
|
723
|
-
}
|
|
724
|
-
} catch (e) {
|
|
725
|
-
}
|
|
788
|
+
if (browser === "Firefox" && /Firefox\/[\d.]+a\d/.test(ua)) {
|
|
789
|
+
browser = "Firefox Nightly";
|
|
726
790
|
}
|
|
727
791
|
if (os === "iOS" && browser === "Safari") {
|
|
728
792
|
const m = /Version\/([\d.]+)/.exec(ua);
|
|
@@ -765,7 +829,8 @@ function parseUA(ua, options = {}) {
|
|
|
765
829
|
}
|
|
766
830
|
}
|
|
767
831
|
const { engine, engineVersion } = detectEngine(ua, browser, version);
|
|
768
|
-
const
|
|
832
|
+
const major = parseInt((_l = version.split(".")[0]) != null ? _l : "", 10);
|
|
833
|
+
const versionMajor = Number.isNaN(major) ? 0 : major;
|
|
769
834
|
const connectionType = (_p = (_o = (_n = (_m = options.ctx) != null ? _m : options.nav) == null ? void 0 : _n.connection) == null ? void 0 : _o.effectiveType) != null ? _p : "unknown";
|
|
770
835
|
const finalOsVersionName = os === "MacOS" || os === "Windows" ? (() => {
|
|
771
836
|
var _a2;
|
|
@@ -1006,7 +1071,7 @@ function deriveWindowsVersion2(platformVersion) {
|
|
|
1006
1071
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
1007
1072
|
}
|
|
1008
1073
|
function parseHeaders(headers) {
|
|
1009
|
-
var _a, _b, _c, _d, _e;
|
|
1074
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1010
1075
|
const normalised = {};
|
|
1011
1076
|
for (const key of Object.keys(headers)) {
|
|
1012
1077
|
normalised[key.toLowerCase()] = headers[key];
|
|
@@ -1023,12 +1088,24 @@ function parseHeaders(headers) {
|
|
|
1023
1088
|
const model = unquote(get("sec-ch-ua-model"));
|
|
1024
1089
|
const platformVersion = unquote(get("sec-ch-ua-platform-version"));
|
|
1025
1090
|
const platform = (_e = unquote(get("sec-ch-ua-platform"))) != null ? _e : "";
|
|
1091
|
+
const fullVersionListRaw = get("sec-ch-ua-full-version-list");
|
|
1092
|
+
const fullVersionList = [];
|
|
1093
|
+
if (fullVersionListRaw) {
|
|
1094
|
+
const re = /"([^"]+)";v="([^"]+)"/g;
|
|
1095
|
+
let m;
|
|
1096
|
+
while ((m = re.exec(fullVersionListRaw)) !== null) {
|
|
1097
|
+
fullVersionList.push({ brand: m[1], version: m[2] });
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1026
1100
|
const highEntropyData = {};
|
|
1027
1101
|
if (architecture !== void 0) highEntropyData.architecture = architecture;
|
|
1028
1102
|
if (bitness !== void 0) highEntropyData.bitness = bitness;
|
|
1029
1103
|
if (model !== void 0) highEntropyData.model = model;
|
|
1030
1104
|
if (platformVersion !== void 0) highEntropyData.platformVersion = platformVersion;
|
|
1105
|
+
if (fullVersionList.length > 0) highEntropyData.fullVersionList = fullVersionList;
|
|
1031
1106
|
const isMobile = get("sec-ch-ua-mobile") === "?1";
|
|
1107
|
+
const secCHUA = (_f = get("sec-ch-ua")) != null ? _f : "";
|
|
1108
|
+
const hasBrave = /"Brave"/.test(secCHUA);
|
|
1032
1109
|
const windowsVersion = platform === "Windows" ? deriveWindowsVersion2(platformVersion) : null;
|
|
1033
1110
|
const ctx = {
|
|
1034
1111
|
userAgent: ua,
|
|
@@ -1036,7 +1113,8 @@ function parseHeaders(headers) {
|
|
|
1036
1113
|
language,
|
|
1037
1114
|
maxTouchPoints: isMobile ? 1 : 0,
|
|
1038
1115
|
highEntropyData: Object.keys(highEntropyData).length > 0 ? highEntropyData : void 0,
|
|
1039
|
-
windowsVersion
|
|
1116
|
+
windowsVersion,
|
|
1117
|
+
hasBrave
|
|
1040
1118
|
};
|
|
1041
1119
|
return parseUA(ua, { ctx });
|
|
1042
1120
|
}
|