ua-browser 1.4.0-beta.0 → 1.4.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/README.en.md +2 -0
- package/README.md +2 -0
- package/dist/index.cjs +227 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +225 -112
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,85 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "1.4.0
|
|
3
|
+
version: "1.4.0"};
|
|
4
|
+
|
|
5
|
+
// src/constants/os.ts
|
|
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
|
+
// Linux must come before Chrome OS: Chrome OS UAs contain "X11", so Linux matches first,
|
|
15
|
+
// then Chrome OS overrides it.
|
|
16
|
+
{ name: "Linux", detect: /(Linux|X11)/, versionPattern: null },
|
|
17
|
+
{ name: "Chrome OS", detect: /CrOS/, versionPattern: null },
|
|
18
|
+
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
19
|
+
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
20
|
+
{
|
|
21
|
+
name: "MacOS",
|
|
22
|
+
detect: /Macintosh/,
|
|
23
|
+
versionPattern: /Mac OS X -?([\d_.]+)/,
|
|
24
|
+
versionNames: {
|
|
25
|
+
"10.9": "Mavericks",
|
|
26
|
+
"10.10": "Yosemite",
|
|
27
|
+
"10.11": "El Capitan",
|
|
28
|
+
"10.12": "Sierra",
|
|
29
|
+
"10.13": "High Sierra",
|
|
30
|
+
"10.14": "Mojave",
|
|
31
|
+
"10.15": "Catalina",
|
|
32
|
+
"11": "Big Sur",
|
|
33
|
+
"12": "Monterey",
|
|
34
|
+
"13": "Ventura",
|
|
35
|
+
"14": "Sonoma",
|
|
36
|
+
"15": "Sequoia"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
// visionOS / tvOS must come AFTER iOS: their UAs also contain "like Mac OS X",
|
|
40
|
+
// so they need to override iOS via the last-match-wins iteration.
|
|
41
|
+
{ name: "visionOS", detect: /visionOS/, versionPattern: /visionOS ([\d_]+)/ },
|
|
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.
|
|
47
|
+
{
|
|
48
|
+
name: "HarmonyOS",
|
|
49
|
+
detect: /HarmonyOS/,
|
|
50
|
+
versionPattern: [/HarmonyOS[\s/]([\d.]+)/, /Android ([\d.]+)[;)]/],
|
|
51
|
+
versionLookup: { "10": "2", "11": "3", "12": "3", "13": "4" }
|
|
52
|
+
},
|
|
53
|
+
// OpenHarmony (open-source base) must come after HarmonyOS to override any earlier match.
|
|
54
|
+
{ name: "OpenHarmony", detect: /OpenHarmony/, versionPattern: /OpenHarmony[\s/]([\d.]+)/ },
|
|
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.
|
|
58
|
+
{
|
|
59
|
+
name: "Windows",
|
|
60
|
+
detect: /Windows/,
|
|
61
|
+
versionPattern: /Windows NT ([\d.]+)/,
|
|
62
|
+
versionLookup: {
|
|
63
|
+
"10": "10",
|
|
64
|
+
"6.4": "10",
|
|
65
|
+
"6.3": "8.1",
|
|
66
|
+
"6.2": "8",
|
|
67
|
+
"6.1": "7",
|
|
68
|
+
"6.0": "Vista",
|
|
69
|
+
"5.2": "XP",
|
|
70
|
+
"5.1": "XP",
|
|
71
|
+
"5.0": "2000"
|
|
72
|
+
},
|
|
73
|
+
versionNames: {
|
|
74
|
+
"7": "Windows 7",
|
|
75
|
+
"8": "Windows 8",
|
|
76
|
+
"8.1": "Windows 8.1",
|
|
77
|
+
"10": "Windows 10",
|
|
78
|
+
"11": "Windows 11"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
82
|
+
];
|
|
4
83
|
|
|
5
84
|
// src/constants/browsers.ts
|
|
6
85
|
var BROWSER_DEFS = [
|
|
@@ -147,7 +226,7 @@ function detectBrowser(ua) {
|
|
|
147
226
|
}
|
|
148
227
|
}
|
|
149
228
|
}
|
|
150
|
-
if (!best) return { browser: "unknown", version: "unknown" };
|
|
229
|
+
if (!best) return { browser: "unknown", version: "unknown", browserType: "unknown", priority: 0 };
|
|
151
230
|
let version = null;
|
|
152
231
|
if (best.chromeLookup) {
|
|
153
232
|
version = lookupFromChromeVersion(ua, best.chromeLookup);
|
|
@@ -156,7 +235,9 @@ function detectBrowser(ua) {
|
|
|
156
235
|
const patterns = Array.isArray(best.versionPattern) ? best.versionPattern : [best.versionPattern];
|
|
157
236
|
version = extractVersionFromPatterns(ua, patterns);
|
|
158
237
|
}
|
|
159
|
-
|
|
238
|
+
const p = best.priority;
|
|
239
|
+
const browserType = p >= 500 ? "app" : p >= 300 ? "brand" : "browser";
|
|
240
|
+
return { browser: best.name, version: version != null ? version : "unknown", browserType, priority: p };
|
|
160
241
|
}
|
|
161
242
|
|
|
162
243
|
// src/constants/engines.ts
|
|
@@ -172,8 +253,22 @@ var ENGINE_DEFS = [
|
|
|
172
253
|
];
|
|
173
254
|
|
|
174
255
|
// src/detectors/engine.ts
|
|
256
|
+
var ENGINE_VERSION_RE = {
|
|
257
|
+
WebKit: /AppleWebKit\/([\d.]+)/,
|
|
258
|
+
Blink: /AppleWebKit\/([\d.]+)/,
|
|
259
|
+
ArkWeb: /AppleWebKit\/([\d.]+)/,
|
|
260
|
+
Gecko: /Gecko\/([\d.]+)/,
|
|
261
|
+
Trident: /Trident\/([\d.]+)/,
|
|
262
|
+
Presto: /Presto\/([\d.]+)/,
|
|
263
|
+
KHTML: /KHTML\/([\d.]+)/
|
|
264
|
+
};
|
|
175
265
|
function detectEngine(ua, browser, version) {
|
|
176
|
-
var _a, _b;
|
|
266
|
+
var _a, _b, _c, _d;
|
|
267
|
+
if (browser === void 0 || version === void 0) {
|
|
268
|
+
const b = detectBrowser(ua);
|
|
269
|
+
browser = browser != null ? browser : b.browser;
|
|
270
|
+
version = version != null ? version : b.version;
|
|
271
|
+
}
|
|
177
272
|
let engine = "unknown";
|
|
178
273
|
for (const def of ENGINE_DEFS) {
|
|
179
274
|
if (def.detect.test(ua)) {
|
|
@@ -190,64 +285,19 @@ function detectEngine(ua, browser, version) {
|
|
|
190
285
|
if (browser === "Edge") {
|
|
191
286
|
engine = parseInt(version, 10) > 75 ? "Blink" : "EdgeHTML";
|
|
192
287
|
}
|
|
193
|
-
|
|
288
|
+
const engineVersion = ENGINE_VERSION_RE[engine] ? (_d = (_c = ENGINE_VERSION_RE[engine].exec(ua)) == null ? void 0 : _c[1]) != null ? _d : "unknown" : "unknown";
|
|
289
|
+
return { engine, engineVersion };
|
|
194
290
|
}
|
|
195
291
|
|
|
196
|
-
// src/constants/os.ts
|
|
197
|
-
var OS_DEFS = [
|
|
198
|
-
{ name: "WebOS", detect: /hpwOS/, versionPattern: /hpwOS\/([\d.]+)/ },
|
|
199
|
-
{ name: "Symbian", detect: /Symbian/, versionPattern: null },
|
|
200
|
-
{ name: "MeeGo", detect: /MeeGo/, versionPattern: null },
|
|
201
|
-
{ name: "BlackBerry", detect: /(BlackBerry|RIM)/, versionPattern: null },
|
|
202
|
-
{ name: "FreeBSD", detect: /FreeBSD/, versionPattern: null },
|
|
203
|
-
{ name: "Debian", detect: /Debian/, versionPattern: /Debian\/([\d.]+)/ },
|
|
204
|
-
{ name: "Ubuntu", detect: /Ubuntu/, versionPattern: null },
|
|
205
|
-
// Linux must come before Chrome OS: Chrome OS UAs contain "X11", so Linux matches first,
|
|
206
|
-
// then Chrome OS overrides it.
|
|
207
|
-
{ name: "Linux", detect: /(Linux|X11)/, versionPattern: null },
|
|
208
|
-
{ name: "Chrome OS", detect: /CrOS/, versionPattern: null },
|
|
209
|
-
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
210
|
-
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
211
|
-
{ name: "MacOS", detect: /Macintosh/, versionPattern: /Mac OS X -?([\d_.]+)/ },
|
|
212
|
-
// visionOS / tvOS must come AFTER iOS: their UAs also contain "like Mac OS X",
|
|
213
|
-
// so they need to override iOS via the last-match-wins iteration.
|
|
214
|
-
{ name: "visionOS", detect: /visionOS/, versionPattern: /visionOS ([\d_]+)/ },
|
|
215
|
-
{ name: "tvOS", detect: /Apple TV/, versionPattern: /OS ([\d_]+) like/ },
|
|
216
|
-
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
217
|
-
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
218
|
-
// first, then HarmonyOS overrides it. versionPattern tries direct extraction first (5.0+
|
|
219
|
-
// pure HarmonyOS UAs don't have Android token), then falls back to Android version + lookup.
|
|
220
|
-
{
|
|
221
|
-
name: "HarmonyOS",
|
|
222
|
-
detect: /HarmonyOS/,
|
|
223
|
-
versionPattern: [/HarmonyOS[\s/]([\d.]+)/, /Android ([\d.]+)[;)]/],
|
|
224
|
-
versionLookup: { "10": "2", "11": "3", "12": "3", "13": "4" }
|
|
225
|
-
},
|
|
226
|
-
// OpenHarmony (open-source base) must come after HarmonyOS to override any earlier match.
|
|
227
|
-
{ name: "OpenHarmony", detect: /OpenHarmony/, versionPattern: /OpenHarmony[\s/]([\d.]+)/ },
|
|
228
|
-
{ name: "KaiOS", detect: /KAIOS/, versionPattern: /KAIOS\/([\d.]+)/ },
|
|
229
|
-
// Windows must come before Windows Phone: Windows Phone UAs contain "Windows", so Windows
|
|
230
|
-
// matches first, then Windows Phone overrides it.
|
|
231
|
-
{
|
|
232
|
-
name: "Windows",
|
|
233
|
-
detect: /Windows/,
|
|
234
|
-
versionPattern: /Windows NT ([\d.]+)/,
|
|
235
|
-
versionLookup: {
|
|
236
|
-
"10": "10",
|
|
237
|
-
"6.4": "10",
|
|
238
|
-
"6.3": "8.1",
|
|
239
|
-
"6.2": "8",
|
|
240
|
-
"6.1": "7",
|
|
241
|
-
"6.0": "Vista",
|
|
242
|
-
"5.2": "XP",
|
|
243
|
-
"5.1": "XP",
|
|
244
|
-
"5.0": "2000"
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
248
|
-
];
|
|
249
|
-
|
|
250
292
|
// src/detectors/os.ts
|
|
293
|
+
function lookupVersionName(map, version) {
|
|
294
|
+
const parts = version.split(".");
|
|
295
|
+
for (let len = parts.length; len >= 1; len--) {
|
|
296
|
+
const key = parts.slice(0, len).join(".");
|
|
297
|
+
if (Object.prototype.hasOwnProperty.call(map, key)) return map[key];
|
|
298
|
+
}
|
|
299
|
+
return "unknown";
|
|
300
|
+
}
|
|
251
301
|
function detectOs(ua, windowsVersion) {
|
|
252
302
|
let matchedDef = null;
|
|
253
303
|
for (const def of OS_DEFS) {
|
|
@@ -255,7 +305,7 @@ function detectOs(ua, windowsVersion) {
|
|
|
255
305
|
matchedDef = def;
|
|
256
306
|
}
|
|
257
307
|
}
|
|
258
|
-
if (!matchedDef) return { os: "unknown", osVersion: "unknown" };
|
|
308
|
+
if (!matchedDef) return { os: "unknown", osVersion: "unknown", osVersionName: "unknown" };
|
|
259
309
|
let osVersion = "unknown";
|
|
260
310
|
if (matchedDef.versionPattern) {
|
|
261
311
|
const raw = Array.isArray(matchedDef.versionPattern) ? extractVersionFromPatterns(ua, matchedDef.versionPattern) : extractVersion(ua, matchedDef.versionPattern);
|
|
@@ -279,7 +329,8 @@ function detectOs(ua, windowsVersion) {
|
|
|
279
329
|
if (matchedDef.name === "Windows" && windowsVersion) {
|
|
280
330
|
osVersion = windowsVersion;
|
|
281
331
|
}
|
|
282
|
-
|
|
332
|
+
const osVersionName = matchedDef.versionNames ? lookupVersionName(matchedDef.versionNames, osVersion) : "unknown";
|
|
333
|
+
return { os: matchedDef.name, osVersion, osVersionName };
|
|
283
334
|
}
|
|
284
335
|
|
|
285
336
|
// src/constants/devices.ts
|
|
@@ -344,57 +395,93 @@ function detectDevice(ua, nav) {
|
|
|
344
395
|
}
|
|
345
396
|
return (_b = (_a = hwDetect()) != null ? _a : uaDetect()) != null ? _b : "PC";
|
|
346
397
|
}
|
|
398
|
+
var VENDOR_MAP = [
|
|
399
|
+
[/^SM-|^GT-|^SGH-|^SCH-|^SHW-|^SPH-|^SAMSUNG /i, "Samsung"],
|
|
400
|
+
[/^Pixel |^Nexus /, "Google"],
|
|
401
|
+
[/^moto |^motorola /i, "Motorola"],
|
|
402
|
+
[/^HONOR /i, "Honor"],
|
|
403
|
+
[/^ELS-|^LYA-|^HMA-|^VOG-|^ANA-|^CLT-|^JNY-|^NOH-|^PLK-|^BAH-|^BKL-|^COL-|^DUB-|^FIG-|^KIW-|^MAR-|^VTR-|^WAS-/i, "Huawei"],
|
|
404
|
+
[/^CPH/, "OPPO"],
|
|
405
|
+
[/^RMX/, "Realme"],
|
|
406
|
+
[/^V\d{4}[A-Z]|^vivo /i, "Vivo"],
|
|
407
|
+
[/^iqoo/i, "Vivo"],
|
|
408
|
+
[/^Redmi |^POCO |^Mi /, "Xiaomi"],
|
|
409
|
+
[/^2\d{9}|^2\d{3}[A-Z]/, "Xiaomi"],
|
|
410
|
+
[/^OnePlus |^IN2|^KB2|^LE2/i, "OnePlus"],
|
|
411
|
+
[/^LM-|^LGE |^LG-/i, "LG"],
|
|
412
|
+
[/^HTC/i, "HTC"],
|
|
413
|
+
[/^Nokia/i, "Nokia"],
|
|
414
|
+
[/^XQ-/, "Sony"],
|
|
415
|
+
[/^ASUS_|^ZB6|^ZS6|^ZE[56]/i, "Asus"],
|
|
416
|
+
[/^Quest /i, "Meta"]
|
|
417
|
+
];
|
|
418
|
+
var ANDROID_MODEL_RE = /Android [0-9.]+;(?:\s*U;)?(?:\s*[a-z]{2}[-_][a-zA-Z]{2,4};)?\s*([^;)]+?)(?:\s+Build\/|[;)])/;
|
|
419
|
+
function detectVendorModel(ua) {
|
|
420
|
+
if (/visionOS/.test(ua)) return { vendor: "Apple", model: "Apple Vision Pro" };
|
|
421
|
+
if (/iPhone/.test(ua)) return { vendor: "Apple", model: "iPhone" };
|
|
422
|
+
if (/iPad/.test(ua)) return { vendor: "Apple", model: "iPad" };
|
|
423
|
+
if (/iPod/.test(ua)) return { vendor: "Apple", model: "iPod touch" };
|
|
424
|
+
const m = ANDROID_MODEL_RE.exec(ua);
|
|
425
|
+
if (m) {
|
|
426
|
+
const model = m[1].trim();
|
|
427
|
+
for (const [re, vendor] of VENDOR_MAP) {
|
|
428
|
+
if (re.test(model)) return { vendor, model };
|
|
429
|
+
}
|
|
430
|
+
return { vendor: "unknown", model };
|
|
431
|
+
}
|
|
432
|
+
return { vendor: "unknown", model: "unknown" };
|
|
433
|
+
}
|
|
347
434
|
|
|
348
435
|
// src/constants/bots.ts
|
|
349
436
|
var BOT_DEFS = [
|
|
350
437
|
// Search engines
|
|
351
|
-
{ name: "Googlebot", detect: /Googlebot
|
|
352
|
-
{ name: "Bingbot", detect: /(bingbot|BingPreview)
|
|
353
|
-
{ name: "Baiduspider", detect: /(Baiduspider|BaiduMobaider)
|
|
354
|
-
{ name: "Bytespider", detect: /Bytespider
|
|
355
|
-
{ name: "YandexBot", detect: /YandexBot
|
|
356
|
-
{ name: "DuckDuckBot", detect: /DuckDuckBot
|
|
357
|
-
{ name: "Slurp", detect: /Slurp
|
|
358
|
-
{ name: "Sogou", detect: /(Sogou|sogou).*[Ss]pider
|
|
359
|
-
{ name: "360Spider", detect: /360Spider
|
|
360
|
-
{ name: "PetalBot", detect: /PetalBot
|
|
361
|
-
{ name: "Applebot-Extended", detect: /Applebot-Extended
|
|
362
|
-
{ name: "Applebot", detect: /Applebot
|
|
438
|
+
{ name: "Googlebot", detect: /Googlebot/, category: "search-engine" },
|
|
439
|
+
{ name: "Bingbot", detect: /(bingbot|BingPreview)/, category: "search-engine" },
|
|
440
|
+
{ name: "Baiduspider", detect: /(Baiduspider|BaiduMobaider)/, category: "search-engine" },
|
|
441
|
+
{ name: "Bytespider", detect: /Bytespider/, category: "search-engine" },
|
|
442
|
+
{ name: "YandexBot", detect: /YandexBot/, category: "search-engine" },
|
|
443
|
+
{ name: "DuckDuckBot", detect: /DuckDuckBot/, category: "search-engine" },
|
|
444
|
+
{ name: "Slurp", detect: /Slurp/, category: "search-engine" },
|
|
445
|
+
{ name: "Sogou", detect: /(Sogou|sogou).*[Ss]pider/, category: "search-engine" },
|
|
446
|
+
{ name: "360Spider", detect: /360Spider/, category: "search-engine" },
|
|
447
|
+
{ name: "PetalBot", detect: /PetalBot/, category: "search-engine" },
|
|
448
|
+
{ name: "Applebot-Extended", detect: /Applebot-Extended/, category: "search-engine" },
|
|
449
|
+
{ name: "Applebot", detect: /Applebot/, category: "search-engine" },
|
|
363
450
|
// Social media crawlers
|
|
364
|
-
{ name: "Facebookbot", detect: /(facebookexternalhit|FacebookBot)
|
|
365
|
-
{ name: "Twitterbot", detect: /Twitterbot
|
|
366
|
-
{ name: "LinkedInBot", detect: /LinkedInBot
|
|
367
|
-
{ name: "PinterestBot", detect: /Pinterest
|
|
451
|
+
{ name: "Facebookbot", detect: /(facebookexternalhit|FacebookBot)/, category: "social" },
|
|
452
|
+
{ name: "Twitterbot", detect: /Twitterbot/, category: "social" },
|
|
453
|
+
{ name: "LinkedInBot", detect: /LinkedInBot/, category: "social" },
|
|
454
|
+
{ name: "PinterestBot", detect: /Pinterest/, category: "social" },
|
|
368
455
|
// Messaging link preview bots
|
|
369
|
-
{ name: "Slackbot", detect: /Slackbot
|
|
370
|
-
{ name: "Discordbot", detect: /Discordbot
|
|
371
|
-
{ name: "TelegramBot", detect: /TelegramBot
|
|
372
|
-
{ name: "WhatsApp", detect: /WhatsApp
|
|
456
|
+
{ name: "Slackbot", detect: /Slackbot/, category: "link-preview" },
|
|
457
|
+
{ name: "Discordbot", detect: /Discordbot/, category: "link-preview" },
|
|
458
|
+
{ name: "TelegramBot", detect: /TelegramBot/, category: "link-preview" },
|
|
459
|
+
{ name: "WhatsApp", detect: /WhatsApp/, category: "link-preview" },
|
|
373
460
|
// SEO tools
|
|
374
|
-
{ name: "SemrushBot", detect: /SemrushBot
|
|
375
|
-
{ name: "AhrefsBot", detect: /AhrefsBot
|
|
376
|
-
{ name: "MJ12bot", detect: /MJ12bot
|
|
377
|
-
{ name: "ScreamingFrog", detect: /Screaming Frog
|
|
378
|
-
{ name: "DataForSeoBot", detect: /DataForSeoBot
|
|
461
|
+
{ name: "SemrushBot", detect: /SemrushBot/, category: "seo-tool" },
|
|
462
|
+
{ name: "AhrefsBot", detect: /AhrefsBot/, category: "seo-tool" },
|
|
463
|
+
{ name: "MJ12bot", detect: /MJ12bot/, category: "seo-tool" },
|
|
464
|
+
{ name: "ScreamingFrog", detect: /Screaming Frog/, category: "seo-tool" },
|
|
465
|
+
{ name: "DataForSeoBot", detect: /DataForSeoBot/, category: "seo-tool" },
|
|
379
466
|
// AI / LLM crawlers
|
|
380
|
-
{ name: "GPTBot", detect: /GPTBot
|
|
381
|
-
{ name: "OAI-SearchBot", detect: /OAI-SearchBot
|
|
382
|
-
{ name: "ChatGPT-User", detect: /ChatGPT-User
|
|
383
|
-
{ name: "ClaudeBot", detect: /ClaudeBot
|
|
384
|
-
{ name: "PerplexityBot", detect: /PerplexityBot
|
|
385
|
-
{ name: "CCBot", detect: /CCBot
|
|
386
|
-
{ name: "AdsBot", detect: /AdsBot-Google
|
|
387
|
-
{ name: "Google-Extended", detect: /Google-Extended
|
|
388
|
-
{ name: "Meta-ExternalAgent", detect: /meta-externalagent/i },
|
|
389
|
-
{ name: "Amazonbot", detect: /Amazonbot
|
|
390
|
-
{ name: "Diffbot", detect: /Diffbot
|
|
391
|
-
{ name: "cohere-ai", detect: /cohere-ai
|
|
392
|
-
{ name: "YouBot", detect: /YouBot
|
|
467
|
+
{ name: "GPTBot", detect: /GPTBot/, category: "ai-llm" },
|
|
468
|
+
{ name: "OAI-SearchBot", detect: /OAI-SearchBot/, category: "ai-llm" },
|
|
469
|
+
{ name: "ChatGPT-User", detect: /ChatGPT-User/, category: "ai-llm" },
|
|
470
|
+
{ name: "ClaudeBot", detect: /ClaudeBot/, category: "ai-llm" },
|
|
471
|
+
{ name: "PerplexityBot", detect: /PerplexityBot/, category: "ai-llm" },
|
|
472
|
+
{ name: "CCBot", detect: /CCBot/, category: "ai-llm" },
|
|
473
|
+
{ name: "AdsBot", detect: /AdsBot-Google/, category: "ai-llm" },
|
|
474
|
+
{ name: "Google-Extended", detect: /Google-Extended/, category: "ai-llm" },
|
|
475
|
+
{ name: "Meta-ExternalAgent", detect: /meta-externalagent/i, category: "ai-llm" },
|
|
476
|
+
{ name: "Amazonbot", detect: /Amazonbot/, category: "ai-llm" },
|
|
477
|
+
{ name: "Diffbot", detect: /Diffbot/, category: "ai-llm" },
|
|
478
|
+
{ name: "cohere-ai", detect: /cohere-ai/, category: "ai-llm" },
|
|
479
|
+
{ name: "YouBot", detect: /YouBot/, category: "ai-llm" },
|
|
393
480
|
// Monitoring / archiving
|
|
394
|
-
{ name: "UptimeRobot", detect: /UptimeRobot
|
|
395
|
-
{ name: "ia_archiver", detect: /ia_archiver
|
|
481
|
+
{ name: "UptimeRobot", detect: /UptimeRobot/, category: "monitoring" },
|
|
482
|
+
{ name: "ia_archiver", detect: /ia_archiver/, category: "monitoring" },
|
|
396
483
|
// Generic catch-all (must be last)
|
|
397
|
-
{ name: "GenericBot", detect: /(bot|crawler|spider|crawling|scraper)/i }
|
|
484
|
+
{ name: "GenericBot", detect: /(bot|crawler|spider|crawling|scraper)/i, category: "generic" }
|
|
398
485
|
];
|
|
399
486
|
|
|
400
487
|
// src/detectors/bot.ts
|
|
@@ -402,10 +489,10 @@ function detectBot(ua, customDefs) {
|
|
|
402
489
|
const defs = customDefs ? [...BOT_DEFS.slice(0, -1), ...customDefs, BOT_DEFS[BOT_DEFS.length - 1]] : BOT_DEFS;
|
|
403
490
|
for (const def of defs) {
|
|
404
491
|
if (def.detect.test(ua)) {
|
|
405
|
-
return { isBot: true, botName: def.name };
|
|
492
|
+
return { isBot: true, botName: def.name, botCategory: def.category };
|
|
406
493
|
}
|
|
407
494
|
}
|
|
408
|
-
return { isBot: false, botName: "unknown" };
|
|
495
|
+
return { isBot: false, botName: "unknown", botCategory: "unknown" };
|
|
409
496
|
}
|
|
410
497
|
|
|
411
498
|
// src/constants/arch.ts
|
|
@@ -549,14 +636,22 @@ function platformFromUA(ua) {
|
|
|
549
636
|
}
|
|
550
637
|
return "unknown";
|
|
551
638
|
}
|
|
639
|
+
function normalizeBCP47(raw) {
|
|
640
|
+
const parts = raw.replace(/_/g, "-").split("-");
|
|
641
|
+
return parts.map((p, i) => {
|
|
642
|
+
if (i === 0) return p.toLowerCase();
|
|
643
|
+
if (p.length === 4) return p[0].toUpperCase() + p.slice(1).toLowerCase();
|
|
644
|
+
return p.toUpperCase();
|
|
645
|
+
}).join("-");
|
|
646
|
+
}
|
|
552
647
|
function languageFromUA(ua) {
|
|
648
|
+
const kwMatch = /\bLanguage\/([a-zA-Z]{2,3}(?:[-_][a-zA-Z]{2,4}){1,2})\b/i.exec(ua);
|
|
649
|
+
if (kwMatch) return normalizeBCP47(kwMatch[1]);
|
|
553
650
|
const re = /[;(]\s*([a-z]{2,3}(?:[-_][A-Za-z]{2,4})+)\s*[;)]/g;
|
|
554
651
|
let m;
|
|
555
652
|
while ((m = re.exec(ua)) !== null) {
|
|
556
653
|
const parts = m[1].replace(/_/g, "-").split("-");
|
|
557
|
-
if (parts.length >= 2)
|
|
558
|
-
return `${parts[0].toLowerCase()}-${parts.slice(1).map((p) => p.toUpperCase()).join("-")}`;
|
|
559
|
-
}
|
|
654
|
+
if (parts.length >= 2) return normalizeBCP47(m[1]);
|
|
560
655
|
}
|
|
561
656
|
return "unknown";
|
|
562
657
|
}
|
|
@@ -564,14 +659,15 @@ function parseUA(ua, options = {}) {
|
|
|
564
659
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
565
660
|
const effectiveNav = (_a = options.ctx) != null ? _a : options.nav;
|
|
566
661
|
const effectiveWindowsVersion = (_c = (_b = options.ctx) == null ? void 0 : _b.windowsVersion) != null ? _c : options.windowsVersion;
|
|
567
|
-
const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua);
|
|
568
|
-
const { os: rawOs, osVersion: rawOsVersion } = detectOs(ua, effectiveWindowsVersion);
|
|
662
|
+
const { browser: rawBrowser, version: rawVersion, browserType } = detectBrowser(ua);
|
|
663
|
+
const { os: rawOs, osVersion: rawOsVersion, osVersionName } = detectOs(ua, effectiveWindowsVersion);
|
|
569
664
|
let os = rawOs;
|
|
570
665
|
let osVersion = rawOsVersion;
|
|
571
666
|
const device = detectDevice(ua, effectiveNav);
|
|
667
|
+
const { vendor, model } = detectVendorModel(ua);
|
|
572
668
|
const arch = detectArch(ua, (_d = options.ctx) != null ? _d : effectiveNav);
|
|
573
669
|
const nav = effectiveNav;
|
|
574
|
-
const { isBot, botName } = detectBot(ua, options.customBotDefs);
|
|
670
|
+
const { isBot, botName, botCategory } = detectBot(ua, options.customBotDefs);
|
|
575
671
|
const isHeadless = detectHeadless(ua);
|
|
576
672
|
const language = options.language || ((nav == null ? void 0 : nav.language) || (nav == null ? void 0 : nav.browserLanguage) ? getLanguage(nav) : "") || languageFromUA(ua);
|
|
577
673
|
const platform = (nav == null ? void 0 : nav.platform) || platformFromUA(ua);
|
|
@@ -668,22 +764,39 @@ function parseUA(ua, options = {}) {
|
|
|
668
764
|
}
|
|
669
765
|
}
|
|
670
766
|
}
|
|
671
|
-
const engine = detectEngine(ua, browser, version);
|
|
767
|
+
const { engine, engineVersion } = detectEngine(ua, browser, version);
|
|
672
768
|
const versionMajor = parseInt((_l = version.split(".")[0]) != null ? _l : "0", 10) || 0;
|
|
673
769
|
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
|
+
const finalOsVersionName = os === "MacOS" || os === "Windows" ? (() => {
|
|
771
|
+
var _a2;
|
|
772
|
+
const map = (_a2 = OS_DEFS.find((d) => d.name === os)) == null ? void 0 : _a2.versionNames;
|
|
773
|
+
if (!map) return "unknown";
|
|
774
|
+
const parts = osVersion.split(".");
|
|
775
|
+
for (let len = parts.length; len >= 1; len--) {
|
|
776
|
+
const key = parts.slice(0, len).join(".");
|
|
777
|
+
if (Object.prototype.hasOwnProperty.call(map, key)) return map[key];
|
|
778
|
+
}
|
|
779
|
+
return "unknown";
|
|
780
|
+
})() : osVersionName;
|
|
674
781
|
return {
|
|
675
782
|
browser,
|
|
676
783
|
version,
|
|
677
784
|
versionMajor,
|
|
785
|
+
browserType: browser === "Brave" ? "browser" : browserType,
|
|
678
786
|
engine,
|
|
787
|
+
engineVersion,
|
|
679
788
|
os,
|
|
680
789
|
osVersion,
|
|
790
|
+
osVersionName: finalOsVersionName,
|
|
681
791
|
device,
|
|
792
|
+
vendor,
|
|
793
|
+
model,
|
|
682
794
|
arch,
|
|
683
795
|
isWebview: isWebview(ua),
|
|
684
796
|
isHeadless,
|
|
685
797
|
isBot,
|
|
686
798
|
botName,
|
|
799
|
+
botCategory,
|
|
687
800
|
language,
|
|
688
801
|
platform,
|
|
689
802
|
connectionType
|
|
@@ -943,6 +1056,6 @@ uaBrowser.getLanguage = () => getLanguage(getNavContext());
|
|
|
943
1056
|
uaBrowser.VERSION = VERSION;
|
|
944
1057
|
var src_default = uaBrowser;
|
|
945
1058
|
|
|
946
|
-
export { ACCEPT_CH, VERSION, src_default as default, detectArch, detectBot, detectBrowser, detectHeadless, detectOs as detectOS, getEnvContext, getLanguage, getNavContext, getWindowsVersion, isWebview, parseHeaders, parseUA, satisfies };
|
|
1059
|
+
export { ACCEPT_CH, VERSION, src_default as default, detectArch, detectBot, detectBrowser, detectDevice, detectEngine, detectHeadless, detectOs as detectOS, detectVendorModel, getEnvContext, getLanguage, getNavContext, getWindowsVersion, isWebview, parseHeaders, parseUA, satisfies };
|
|
947
1060
|
//# sourceMappingURL=index.mjs.map
|
|
948
1061
|
//# sourceMappingURL=index.mjs.map
|