ua-browser 1.4.0 → 1.4.2
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 +132 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +132 -49
- 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.2"};
|
|
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" },
|
|
@@ -468,14 +463,19 @@ var BOT_DEFS = [
|
|
|
468
463
|
{ name: "OAI-SearchBot", detect: /OAI-SearchBot/, category: "ai-llm" },
|
|
469
464
|
{ name: "ChatGPT-User", detect: /ChatGPT-User/, category: "ai-llm" },
|
|
470
465
|
{ name: "ClaudeBot", detect: /ClaudeBot/, category: "ai-llm" },
|
|
466
|
+
{ name: "Claude-User", detect: /Claude-User/, category: "ai-llm" },
|
|
467
|
+
{ name: "Claude-SearchBot", detect: /Claude-SearchBot/, category: "ai-llm" },
|
|
471
468
|
{ name: "PerplexityBot", detect: /PerplexityBot/, category: "ai-llm" },
|
|
472
469
|
{ name: "CCBot", detect: /CCBot/, category: "ai-llm" },
|
|
473
|
-
{ name: "AdsBot", detect: /AdsBot-Google/, category: "
|
|
470
|
+
{ name: "AdsBot", detect: /AdsBot-Google/, category: "search-engine" },
|
|
474
471
|
{ name: "Google-Extended", detect: /Google-Extended/, category: "ai-llm" },
|
|
475
472
|
{ name: "Meta-ExternalAgent", detect: /meta-externalagent/i, category: "ai-llm" },
|
|
476
473
|
{ name: "Amazonbot", detect: /Amazonbot/, category: "ai-llm" },
|
|
477
474
|
{ name: "Diffbot", detect: /Diffbot/, category: "ai-llm" },
|
|
478
475
|
{ name: "cohere-ai", detect: /cohere-ai/, category: "ai-llm" },
|
|
476
|
+
{ name: "MistralAI-User", detect: /MistralAI-User/, category: "ai-llm" },
|
|
477
|
+
{ name: "DeepSeekBot", detect: /DeepSeekBot/, category: "ai-llm" },
|
|
478
|
+
{ name: "XAI-Crawler", detect: /XAI-Crawler/, category: "ai-llm" },
|
|
479
479
|
{ name: "YouBot", detect: /YouBot/, category: "ai-llm" },
|
|
480
480
|
// Monitoring / archiving
|
|
481
481
|
{ name: "UptimeRobot", detect: /UptimeRobot/, category: "monitoring" },
|
|
@@ -580,6 +580,7 @@ var BRAND_TO_BROWSER = [
|
|
|
580
580
|
["Microsoft Edge", "Edge"],
|
|
581
581
|
["Opera", "Opera"],
|
|
582
582
|
["Vivaldi", "Vivaldi"],
|
|
583
|
+
["Brave", "Brave"],
|
|
583
584
|
["Google Chrome", "Chrome"],
|
|
584
585
|
["Chromium", "Chromium"]
|
|
585
586
|
];
|
|
@@ -644,6 +645,82 @@ function normalizeBCP47(raw) {
|
|
|
644
645
|
return p.toUpperCase();
|
|
645
646
|
}).join("-");
|
|
646
647
|
}
|
|
648
|
+
var ISO_639_1 = /* @__PURE__ */ new Set([
|
|
649
|
+
"af",
|
|
650
|
+
"am",
|
|
651
|
+
"ar",
|
|
652
|
+
"az",
|
|
653
|
+
"be",
|
|
654
|
+
"bg",
|
|
655
|
+
"bn",
|
|
656
|
+
"bs",
|
|
657
|
+
"ca",
|
|
658
|
+
"cs",
|
|
659
|
+
"cy",
|
|
660
|
+
"da",
|
|
661
|
+
"de",
|
|
662
|
+
"el",
|
|
663
|
+
"en",
|
|
664
|
+
"es",
|
|
665
|
+
"et",
|
|
666
|
+
"eu",
|
|
667
|
+
"fa",
|
|
668
|
+
"fi",
|
|
669
|
+
"fr",
|
|
670
|
+
"ga",
|
|
671
|
+
"gl",
|
|
672
|
+
"gu",
|
|
673
|
+
"he",
|
|
674
|
+
"hi",
|
|
675
|
+
"hr",
|
|
676
|
+
"hu",
|
|
677
|
+
"hy",
|
|
678
|
+
"id",
|
|
679
|
+
"is",
|
|
680
|
+
"it",
|
|
681
|
+
"ja",
|
|
682
|
+
"ka",
|
|
683
|
+
"kk",
|
|
684
|
+
"km",
|
|
685
|
+
"kn",
|
|
686
|
+
"ko",
|
|
687
|
+
"lt",
|
|
688
|
+
"lv",
|
|
689
|
+
"mk",
|
|
690
|
+
"ml",
|
|
691
|
+
"mn",
|
|
692
|
+
"mr",
|
|
693
|
+
"ms",
|
|
694
|
+
"mt",
|
|
695
|
+
"my",
|
|
696
|
+
"nb",
|
|
697
|
+
"ne",
|
|
698
|
+
"nl",
|
|
699
|
+
"no",
|
|
700
|
+
"pa",
|
|
701
|
+
"pl",
|
|
702
|
+
"pt",
|
|
703
|
+
"ro",
|
|
704
|
+
"ru",
|
|
705
|
+
"si",
|
|
706
|
+
"sk",
|
|
707
|
+
"sl",
|
|
708
|
+
"sq",
|
|
709
|
+
"sr",
|
|
710
|
+
"sv",
|
|
711
|
+
"sw",
|
|
712
|
+
"ta",
|
|
713
|
+
"te",
|
|
714
|
+
"th",
|
|
715
|
+
"tl",
|
|
716
|
+
"tr",
|
|
717
|
+
"uk",
|
|
718
|
+
"ur",
|
|
719
|
+
"uz",
|
|
720
|
+
"vi",
|
|
721
|
+
"zh",
|
|
722
|
+
"zu"
|
|
723
|
+
]);
|
|
647
724
|
function languageFromUA(ua) {
|
|
648
725
|
const kwMatch = /\bLanguage\/([a-zA-Z]{2,3}(?:[-_][a-zA-Z]{2,4}){1,2})\b/i.exec(ua);
|
|
649
726
|
if (kwMatch) return normalizeBCP47(kwMatch[1]);
|
|
@@ -653,6 +730,10 @@ function languageFromUA(ua) {
|
|
|
653
730
|
const parts = m[1].replace(/_/g, "-").split("-");
|
|
654
731
|
if (parts.length >= 2) return normalizeBCP47(m[1]);
|
|
655
732
|
}
|
|
733
|
+
const bare = /[;(]\s*([a-z]{2,3})\s*[;)]/g;
|
|
734
|
+
while ((m = bare.exec(ua)) !== null) {
|
|
735
|
+
if (ISO_639_1.has(m[1])) return m[1];
|
|
736
|
+
}
|
|
656
737
|
return "unknown";
|
|
657
738
|
}
|
|
658
739
|
function parseUA(ua, options = {}) {
|
|
@@ -709,20 +790,8 @@ function parseUA(ua, options = {}) {
|
|
|
709
790
|
const opVer = (_h = (_g = /OPR\/([\d.]+)/.exec(ua)) != null ? _g : /OPT\/([\d.]+)/.exec(ua)) != null ? _h : /Opera\/([\d.]+)/.exec(ua);
|
|
710
791
|
version = (_i = opVer == null ? void 0 : opVer[1]) != null ? _i : "unknown";
|
|
711
792
|
}
|
|
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
|
-
}
|
|
793
|
+
if (browser === "Firefox" && /Firefox\/[\d.]+a\d/.test(ua)) {
|
|
794
|
+
browser = "Firefox Nightly";
|
|
726
795
|
}
|
|
727
796
|
if (os === "iOS" && browser === "Safari") {
|
|
728
797
|
const m = /Version\/([\d.]+)/.exec(ua);
|
|
@@ -765,7 +834,8 @@ function parseUA(ua, options = {}) {
|
|
|
765
834
|
}
|
|
766
835
|
}
|
|
767
836
|
const { engine, engineVersion } = detectEngine(ua, browser, version);
|
|
768
|
-
const
|
|
837
|
+
const major = parseInt((_l = version.split(".")[0]) != null ? _l : "", 10);
|
|
838
|
+
const versionMajor = Number.isNaN(major) ? 0 : major;
|
|
769
839
|
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
840
|
const finalOsVersionName = os === "MacOS" || os === "Windows" ? (() => {
|
|
771
841
|
var _a2;
|
|
@@ -1006,7 +1076,7 @@ function deriveWindowsVersion2(platformVersion) {
|
|
|
1006
1076
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
1007
1077
|
}
|
|
1008
1078
|
function parseHeaders(headers) {
|
|
1009
|
-
var _a, _b, _c, _d, _e;
|
|
1079
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1010
1080
|
const normalised = {};
|
|
1011
1081
|
for (const key of Object.keys(headers)) {
|
|
1012
1082
|
normalised[key.toLowerCase()] = headers[key];
|
|
@@ -1023,12 +1093,24 @@ function parseHeaders(headers) {
|
|
|
1023
1093
|
const model = unquote(get("sec-ch-ua-model"));
|
|
1024
1094
|
const platformVersion = unquote(get("sec-ch-ua-platform-version"));
|
|
1025
1095
|
const platform = (_e = unquote(get("sec-ch-ua-platform"))) != null ? _e : "";
|
|
1096
|
+
const fullVersionListRaw = get("sec-ch-ua-full-version-list");
|
|
1097
|
+
const fullVersionList = [];
|
|
1098
|
+
if (fullVersionListRaw) {
|
|
1099
|
+
const re = /"([^"]+)";v="([^"]+)"/g;
|
|
1100
|
+
let m;
|
|
1101
|
+
while ((m = re.exec(fullVersionListRaw)) !== null) {
|
|
1102
|
+
fullVersionList.push({ brand: m[1], version: m[2] });
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1026
1105
|
const highEntropyData = {};
|
|
1027
1106
|
if (architecture !== void 0) highEntropyData.architecture = architecture;
|
|
1028
1107
|
if (bitness !== void 0) highEntropyData.bitness = bitness;
|
|
1029
1108
|
if (model !== void 0) highEntropyData.model = model;
|
|
1030
1109
|
if (platformVersion !== void 0) highEntropyData.platformVersion = platformVersion;
|
|
1110
|
+
if (fullVersionList.length > 0) highEntropyData.fullVersionList = fullVersionList;
|
|
1031
1111
|
const isMobile = get("sec-ch-ua-mobile") === "?1";
|
|
1112
|
+
const secCHUA = (_f = get("sec-ch-ua")) != null ? _f : "";
|
|
1113
|
+
const hasBrave = /"Brave"/.test(secCHUA);
|
|
1032
1114
|
const windowsVersion = platform === "Windows" ? deriveWindowsVersion2(platformVersion) : null;
|
|
1033
1115
|
const ctx = {
|
|
1034
1116
|
userAgent: ua,
|
|
@@ -1036,7 +1118,8 @@ function parseHeaders(headers) {
|
|
|
1036
1118
|
language,
|
|
1037
1119
|
maxTouchPoints: isMobile ? 1 : 0,
|
|
1038
1120
|
highEntropyData: Object.keys(highEntropyData).length > 0 ? highEntropyData : void 0,
|
|
1039
|
-
windowsVersion
|
|
1121
|
+
windowsVersion,
|
|
1122
|
+
hasBrave
|
|
1040
1123
|
};
|
|
1041
1124
|
return parseUA(ua, { ctx });
|
|
1042
1125
|
}
|