ua-browser 1.0.1 → 1.0.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.md +1 -1
- package/dist/index.cjs +19 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +19 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Detect browser, OS, device type, rendering engine, CPU architecture, bots, and h
|
|
|
16
16
|
- **Zero dependencies** — no runtime dependencies, tiny bundle size after gzip
|
|
17
17
|
- **Pure function** — `parseUA()` has no global state, works seamlessly with SSR / Node.js
|
|
18
18
|
- **TypeScript** — full type definitions with precise literal union types (`BrowserName`, `OsName`, etc.)
|
|
19
|
-
- **Tree-shakeable** —
|
|
19
|
+
- **Tree-shakeable** — named exports + `sideEffects: false`, unused code eliminated by Vite / Rollup / webpack 5+
|
|
20
20
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
// package.json
|
|
6
6
|
var package_default = {
|
|
7
|
-
version: "1.0.
|
|
7
|
+
version: "1.0.2"};
|
|
8
8
|
|
|
9
9
|
// src/constants/browsers.ts
|
|
10
10
|
var BROWSER_DEFS = [
|
|
@@ -197,23 +197,28 @@ var OS_DEFS = [
|
|
|
197
197
|
{ name: "Symbian", detect: /Symbian/, versionPattern: null },
|
|
198
198
|
{ name: "MeeGo", detect: /MeeGo/, versionPattern: null },
|
|
199
199
|
{ name: "BlackBerry", detect: /(BlackBerry|RIM)/, versionPattern: null },
|
|
200
|
-
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ },
|
|
201
200
|
{ name: "FreeBSD", detect: /FreeBSD/, versionPattern: null },
|
|
202
201
|
{ name: "Debian", detect: /Debian/, versionPattern: /Debian\/([\d.]+)/ },
|
|
203
202
|
{ name: "Ubuntu", detect: /Ubuntu/, versionPattern: null },
|
|
204
|
-
|
|
203
|
+
// Linux must come before Chrome OS: Chrome OS UAs contain "X11", so Linux matches first,
|
|
204
|
+
// then Chrome OS overrides it.
|
|
205
205
|
{ name: "Linux", detect: /(Linux|X11)/, versionPattern: null },
|
|
206
|
+
{ name: "Chrome OS", detect: /CrOS/, versionPattern: null },
|
|
206
207
|
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
207
208
|
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
208
209
|
{ name: "MacOS", detect: /Macintosh/, versionPattern: /Mac OS X -?([\d_.]+)/ },
|
|
210
|
+
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
211
|
+
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
212
|
+
// first, then HarmonyOS overrides it.
|
|
209
213
|
{
|
|
210
214
|
name: "HarmonyOS",
|
|
211
215
|
detect: /HarmonyOS/,
|
|
212
216
|
versionPattern: /Android ([\d.]+)[;)]/,
|
|
213
217
|
versionLookup: { "10": "2" }
|
|
214
218
|
},
|
|
215
|
-
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
216
219
|
{ name: "KaiOS", detect: /KAIOS/, versionPattern: /KAIOS\/([\d.]+)/ },
|
|
220
|
+
// Windows must come before Windows Phone: Windows Phone UAs contain "Windows", so Windows
|
|
221
|
+
// matches first, then Windows Phone overrides it.
|
|
217
222
|
{
|
|
218
223
|
name: "Windows",
|
|
219
224
|
detect: /Windows/,
|
|
@@ -229,7 +234,8 @@ var OS_DEFS = [
|
|
|
229
234
|
"5.1": "XP",
|
|
230
235
|
"5.0": "2000"
|
|
231
236
|
}
|
|
232
|
-
}
|
|
237
|
+
},
|
|
238
|
+
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
233
239
|
];
|
|
234
240
|
|
|
235
241
|
// src/detectors/os.ts
|
|
@@ -386,7 +392,8 @@ function parseUA(ua, options = {}) {
|
|
|
386
392
|
var _a, _b, _c, _d, _e;
|
|
387
393
|
const { nav, windowsVersion } = options;
|
|
388
394
|
const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua);
|
|
389
|
-
const { os, osVersion } = detectOs(ua, windowsVersion);
|
|
395
|
+
const { os, osVersion: rawOsVersion } = detectOs(ua, windowsVersion);
|
|
396
|
+
let osVersion = rawOsVersion;
|
|
390
397
|
const device = detectDevice(ua, nav);
|
|
391
398
|
const arch = detectArch(ua);
|
|
392
399
|
const { isBot, botName } = detectBot(ua);
|
|
@@ -453,6 +460,12 @@ function parseUA(ua, options = {}) {
|
|
|
453
460
|
} catch (e) {
|
|
454
461
|
}
|
|
455
462
|
}
|
|
463
|
+
if (os === "iOS" && browser === "Safari") {
|
|
464
|
+
const m = /Version\/([\d.]+)/.exec(ua);
|
|
465
|
+
if (m && parseInt(m[1], 10) > parseInt(osVersion, 10)) {
|
|
466
|
+
osVersion = m[1];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
456
469
|
const engine = detectEngine(ua, browser, version);
|
|
457
470
|
return {
|
|
458
471
|
browser,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/utils/windows-version.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.1\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } }\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion } = detectOs(ua, windowsVersion)\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import type { NavContext } from './navigator.js'\n\n/**\n * Asynchronously detect whether the Windows version is 10 or 11 using the\n * User-Agent Client Hints API (navigator.userAgentData).\n *\n * Returns '11', '10', or null (non-Windows / API unavailable / error).\n *\n * Because this is async, callers that need accurate Windows 11 detection\n * should await this result and pass it to parseUA() as `options.windowsVersion`.\n */\nexport async function getWindowsVersion(nav: NavContext): Promise<string | null> {\n if (!nav.userAgentData || nav.userAgentData.platform !== 'Windows') {\n return null\n }\n try {\n const data = await nav.userAgentData.getHighEntropyValues(['platformVersion'])\n const major = parseInt(data['platformVersion']?.split('.')[0] || '0', 10)\n return major >= 13 ? '11' : '10'\n } catch {\n return null\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/utils/windows-version.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.2\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\n// Detection uses last-match-wins: entries that appear later override earlier matches.\n// More specific OS entries must come AFTER the generic ones they supersede.\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n // Linux must come before Chrome OS: Chrome OS UAs contain \"X11\", so Linux matches first,\n // then Chrome OS overrides it.\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n // HarmonyOS must come after Android: HarmonyOS UAs include \"Android\", so Android matches\n // first, then HarmonyOS overrides it.\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n // Windows must come before Windows Phone: Windows Phone UAs contain \"Windows\", so Windows\n // matches first, then Windows Phone overrides it.\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion: rawOsVersion } = detectOs(ua, windowsVersion)\n let osVersion = rawOsVersion\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n // iOS 26+: Apple freezes \"CPU iPhone OS\" at the last iOS 18 value for web compatibility.\n // The Version/ token reliably reflects the real Safari/iOS version.\n // When Version/ major > CPU iPhone OS major, use Version/ as the real osVersion.\n if (os === 'iOS' && browser === 'Safari') {\n const m = /Version\\/([\\d.]+)/.exec(ua)\n if (m && parseInt(m[1], 10) > parseInt(osVersion, 10)) {\n osVersion = m[1]\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import type { NavContext } from './navigator.js'\n\n/**\n * Asynchronously detect whether the Windows version is 10 or 11 using the\n * User-Agent Client Hints API (navigator.userAgentData).\n *\n * Returns '11', '10', or null (non-Windows / API unavailable / error).\n *\n * Because this is async, callers that need accurate Windows 11 detection\n * should await this result and pass it to parseUA() as `options.windowsVersion`.\n */\nexport async function getWindowsVersion(nav: NavContext): Promise<string | null> {\n if (!nav.userAgentData || nav.userAgentData.platform !== 'Windows') {\n return null\n }\n try {\n const data = await nav.userAgentData.getHighEntropyValues(['platformVersion'])\n const major = parseInt(data['platformVersion']?.split('.')[0] || '0', 10)\n return major >= 13 ? '11' : '10'\n } catch {\n return null\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
package/dist/index.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var uaBrowser=(function(){'use strict';var E={version:"1.0.1"};var S=[{name:"Safari",priority:10,detect:/Safari/,versionPattern:/Version\/([\d.]+)/},{name:"Chrome",priority:20,detect:/(Chrome|CriOS)/,versionPattern:[/Chrome\/([\d.]+)/,/CriOS\/([\d.]+)/]},{name:"IE",priority:30,detect:/(MSIE|Trident)/,versionPattern:[/MSIE ([\d.]+)/,/rv:([\d.]+)/]},{name:"Edge",priority:40,detect:/(Edge|Edg\/|EdgA|EdgiOS)/,versionPattern:[/Edge\/([\d.]+)/,/Edg\/([\d.]+)/,/EdgA\/([\d.]+)/,/EdgiOS\/([\d.]+)/]},{name:"Firefox",priority:50,detect:/(Firefox|FxiOS)/,versionPattern:[/Firefox\/([\d.]+)/,/FxiOS\/([\d.]+)/]},{name:"Firefox Focus",priority:55,detect:/Focus/,versionPattern:/Focus\/([\d.]+)/},{name:"Chromium",priority:60,detect:/Chromium/,versionPattern:/Chromium\/([\d.]+)/},{name:"Opera",priority:70,detect:/(Opera|OPR|OPT)/,versionPattern:[/Opera\/([\d.]+)/,/OPR\/([\d.]+)/,/OPT\/([\d.]+)/]},{name:"Vivaldi",priority:80,detect:/Vivaldi/,versionPattern:/Vivaldi\/([\d.]+)/},{name:"Yandex",priority:90,detect:/YaBrowser/,versionPattern:/YaBrowser\/([\d.]+)/},{name:"Samsung Internet",priority:92,detect:/SamsungBrowser/,versionPattern:/SamsungBrowser\/([\d.]+)/},{name:"DuckDuckGo",priority:94,detect:/DuckDuckGo\//,versionPattern:/DuckDuckGo\/([\d.]+)/},{name:"Puffin",priority:96,detect:/Puffin\//,versionPattern:/Puffin\/([\d.]+)/},{name:"Arora",priority:100,detect:/Arora/,versionPattern:/Arora\/([\d.]+)/},{name:"Lunascape",priority:110,detect:/Lunascape/,versionPattern:/Lunascape[\s]([\d.]+)/},{name:"QupZilla",priority:120,detect:/QupZilla/,versionPattern:/QupZilla[\s]([\d.]+)/},{name:"Coc Coc",priority:130,detect:/coc_coc_browser/,versionPattern:/coc_coc_browser\/([\d.]+)/},{name:"Kindle",priority:140,detect:/(Kindle|Silk\/)/,versionPattern:/Version\/([\d.]+)/},{name:"Iceweasel",priority:150,detect:/Iceweasel/,versionPattern:/Iceweasel\/([\d.]+)/},{name:"Konqueror",priority:160,detect:/Konqueror/,versionPattern:/Konqueror\/([\d.]+)/},{name:"Iceape",priority:170,detect:/Iceape/,versionPattern:/Iceape\/([\d.]+)/},{name:"SeaMonkey",priority:180,detect:/SeaMonkey/,versionPattern:/SeaMonkey\/([\d.]+)/},{name:"Epiphany",priority:190,detect:/Epiphany/,versionPattern:/Epiphany\/([\d.]+)/},{name:"Maxthon",priority:200,detect:/Maxthon/,versionPattern:/Maxthon\/([\d.]+)/},{name:"360",priority:300,detect:/(QihooBrowser|QHBrowser)/,versionPattern:/QihooBrowser\/([\d.]+)/},{name:"360SE",priority:310,detect:/360SE/,versionPattern:null,chromeLookup:{108:"14.0",86:"13.0",78:"12.0",69:"11.0",63:"10.0",55:"9.1",45:"8.1",42:"8.0",31:"7.0",21:"6.3"}},{name:"360EE",priority:320,detect:/360EE/,versionPattern:null,chromeLookup:{86:"13.0",78:"12.0",69:"11.0",63:"9.5",55:"9.0",50:"8.7",30:"7.5"}},{name:"UC",priority:330,detect:/(UCBrowser|UBrowser|UCWEB)/,versionPattern:/UC?Browser\/([\d.]+)/},{name:"QQBrowser",priority:340,detect:/QQBrowser/,versionPattern:/QQBrowser\/([\d.]+)/},{name:"QQ",priority:345,detect:/QQ\//,versionPattern:/QQ\/([\d.]+)/},{name:"Baidu",priority:350,detect:/(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/,versionPattern:[/BIDUBrowser[\s/]([\d.]+)/,/baiduboxapp\/([\d.]+)/]},{name:"Sogou",priority:360,detect:/(MetaSr|Sogou)/,versionPattern:[/SE ([\d.X]+)/,/SogouMobileBrowser\/([\d.]+)/]},{name:"Liebao",priority:370,detect:/(LBBROWSER|LieBaoFast)/,versionPattern:/LieBaoFast\/([\d.]+)/,chromeLookup:{57:"6.5",49:"6.0",46:"5.9",42:"5.3",39:"5.2",34:"5.0",29:"4.5",21:"4.0"}},{name:"2345Explorer",priority:380,detect:/2345Explorer/,versionPattern:[/2345Explorer\/([\d.]+)/,/Mb2345Browser\/([\d.]+)/],chromeLookup:{69:"10.0",55:"9.9"}},{name:"115Browser",priority:390,detect:/115Browser/,versionPattern:/115Browser\/([\d.]+)/},{name:"TheWorld",priority:400,detect:/TheWorld/,versionPattern:/TheWorld ([\d.]+)/},{name:"XiaoMi",priority:410,detect:/MiuiBrowser/,versionPattern:/MiuiBrowser\/([\d.]+)/},{name:"Vivo",priority:420,detect:/VivoBrowser/,versionPattern:/VivoBrowser\/([\d.]+)/},{name:"Huawei",priority:430,detect:/HuaweiBrowser/,versionPattern:[/HuaweiBrowser\/([\d.]+)/,/Version\/([\d.]+)/]},{name:"OPPO",priority:440,detect:/HeyTapBrowser/,versionPattern:/HeyTapBrowser\/([\d.]+)/},{name:"Quark",priority:450,detect:/Quark/,versionPattern:/Quark\/([\d.]+)/},{name:"Qiyu",priority:460,detect:/Qiyu/,versionPattern:/Qiyu\/([\d.]+)/},{name:"WechatWork",priority:500,detect:/wxwork\//,versionPattern:/wxwork\/([\d.]+)/},{name:"Wechat",priority:510,detect:/MicroMessenger/,versionPattern:/MicroMessenger\/([\d.]+)/},{name:"Taobao",priority:520,detect:/AliApp\(TB/,versionPattern:/AliApp\(TB\/([\d.]+)/},{name:"Alipay",priority:530,detect:/AliApp\(AP/,versionPattern:/AliApp\(AP\/([\d.]+)/},{name:"Weibo",priority:540,detect:/Weibo/,versionPattern:/weibo__([\d.]+)/},{name:"Douban",priority:550,detect:/com\.douban\.frodo/,versionPattern:/com\.douban\.frodo\/([\d.]+)/},{name:"Suning",priority:560,detect:/SNEBUY-APP/,versionPattern:/SNEBUY-APP([\d.]+)/},{name:"iQiYi",priority:570,detect:/IqiyiApp/,versionPattern:/IqiyiVersion\/([\d.]+)/},{name:"DingTalk",priority:580,detect:/DingTalk/,versionPattern:/DingTalk\/([\d.]+)/},{name:"Douyin",priority:590,detect:/aweme/,versionPattern:/app_version\/([\d.]+)/}];function v(e,r){let t=r.exec(e);if(!t)return null;let n=t[1];return n!=null&&n!==""?n:null}function k(e,r){for(let t of r){let n=v(e,t);if(n!==null)return n}return null}function O(e,r){let t=/Chrome\/([\d]+)/.exec(e);if(!t)return null;let n=t[1];return Object.prototype.hasOwnProperty.call(r,n)?r[n]:null}function D(e){let r=null;for(let n of S)n.detect.test(e)&&(r===null||n.priority>=r.priority)&&(r=n);if(!r)return {browser:"unknown",version:"unknown"};let t=null;if(r.chromeLookup&&(t=O(e,r.chromeLookup)),t===null&&r.versionPattern!==null){let n=Array.isArray(r.versionPattern)?r.versionPattern:[r.versionPattern];t=k(e,n);}return {browser:r.name,version:t!=null?t:"unknown"}}var A=[{name:"KHTML",detect:/KHTML\//},{name:"Trident",detect:/(Trident|NET CLR)/},{name:"Presto",detect:/Presto/},{name:"Gecko",detect:/Gecko\//},{name:"WebKit",detect:/AppleWebKit/}];function N(e,r,t){var o,s;let n="unknown";for(let d of A)d.detect.test(e)&&(n=d.name);return (n==="WebKit"&&/(Chrome|CriOS)/.test(e)&&parseInt((s=((o=/Chrome\/([\d]+)/.exec(e))!=null?o:[])[1])!=null?s:"0",10)>27||r==="Opera"&&parseInt(t,10)>12||r==="Yandex")&&(n="Blink"),r==="Edge"&&(n=parseInt(t,10)>75?"Blink":"EdgeHTML"),n}var T=[{name:"WebOS",detect:/hpwOS/,versionPattern:/hpwOS\/([\d.]+)/},{name:"Symbian",detect:/Symbian/,versionPattern:null},{name:"MeeGo",detect:/MeeGo/,versionPattern:null},{name:"BlackBerry",detect:/(BlackBerry|RIM)/,versionPattern:null},{name:"Windows Phone",detect:/(IEMobile|Windows Phone)/,versionPattern:/Windows Phone(?: OS)? ([\d.]+)/},{name:"FreeBSD",detect:/FreeBSD/,versionPattern:null},{name:"Debian",detect:/Debian/,versionPattern:/Debian\/([\d.]+)/},{name:"Ubuntu",detect:/Ubuntu/,versionPattern:null},{name:"Chrome OS",detect:/CrOS/,versionPattern:null},{name:"Linux",detect:/(Linux|X11)/,versionPattern:null},{name:"Tizen",detect:/Tizen/,versionPattern:/Tizen ([\d.]+)/},{name:"iOS",detect:/like Mac OS X/,versionPattern:/OS ([\d_]+) like/},{name:"MacOS",detect:/Macintosh/,versionPattern:/Mac OS X -?([\d_.]+)/},{name:"HarmonyOS",detect:/HarmonyOS/,versionPattern:/Android ([\d.]+)[;)]/,versionLookup:{10:"2"}},{name:"Android",detect:/(Android|Adr)/,versionPattern:/(?:Android|Adr) ([\d.]+)/},{name:"KaiOS",detect:/KAIOS/,versionPattern:/KAIOS\/([\d.]+)/},{name:"Windows",detect:/Windows/,versionPattern:/Windows NT ([\d.]+)/,versionLookup:{10:"10","6.4":"10","6.3":"8.1","6.2":"8","6.1":"7","6.0":"Vista","5.2":"XP","5.1":"XP","5.0":"2000"}}];function C(e,r){let t=null;for(let o of T)o.detect.test(e)&&(t=o);if(!t)return {os:"unknown",osVersion:"unknown"};let n="unknown";if(t.versionPattern){let o=v(e,t.versionPattern);if(o!==null){let s=o.replace(/_/g,".");if(t.versionLookup){let d=Object.prototype.hasOwnProperty.call(t.versionLookup,s)?t.versionLookup[s]:null;if(d!==null)n=d;else if(t.name==="Windows"){let u=parseInt(s,10);n=isNaN(u)?"unknown":u.toString();}}else n=s;}}return t.name==="Windows"&&r&&(n=r),{os:t.name,osVersion:n}}var M=[{name:"Mobile",detect:/(Mobi|iPh)/},{name:"Tablet",detect:/(Tablet|Pad)/}];function R(e,r){if(/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(e))return "TV";if((r==null?void 0:r.platform)==="MacIntel"&&r.maxTouchPoints>1||/iPad/.test(e)||/Android/.test(e)&&!/Mobile/.test(e))return "Tablet";for(let t of M)if(t.detect.test(e))return t.name;return "PC"}var _=[{name:"Googlebot",detect:/Googlebot/},{name:"Bingbot",detect:/(bingbot|BingPreview)/},{name:"Baiduspider",detect:/(Baiduspider|BaiduMobaider)/},{name:"Bytespider",detect:/Bytespider/},{name:"YandexBot",detect:/YandexBot/},{name:"DuckDuckBot",detect:/DuckDuckBot/},{name:"Slurp",detect:/Slurp/},{name:"Sogou",detect:/(Sogou|sogou).*[Ss]pider/},{name:"360Spider",detect:/360Spider/},{name:"PetalBot",detect:/PetalBot/},{name:"Applebot",detect:/Applebot/},{name:"Facebookbot",detect:/(facebookexternalhit|FacebookBot)/},{name:"Twitterbot",detect:/Twitterbot/},{name:"LinkedInBot",detect:/LinkedInBot/},{name:"SemrushBot",detect:/SemrushBot/},{name:"AhrefsBot",detect:/AhrefsBot/},{name:"MJ12bot",detect:/MJ12bot/},{name:"GPTBot",detect:/GPTBot/},{name:"ClaudeBot",detect:/ClaudeBot/},{name:"PerplexityBot",detect:/PerplexityBot/},{name:"CCBot",detect:/CCBot/},{name:"AdsBot",detect:/AdsBot-Google/},{name:"GenericBot",detect:/(bot|crawler|spider|crawling|scraper)/i}];function L(e){for(let r of _)if(r.detect.test(e))return {isBot:true,botName:r.name};return {isBot:false,botName:"unknown"}}var F=[{name:"arm64",detect:/(aarch64|arm64|ARM64)/},{name:"arm",detect:/\bARM\b/},{name:"x86_64",detect:/(x86_64|Win64|WOW64|x64;|amd64)/i},{name:"x86",detect:/(i[36]86|i686|x86;)/}];function I(e){for(let r of F)if(r.detect.test(e))return r.name;return "unknown"}var J=/(HeadlessChrome|Headless|PhantomJS|Electron\/|Playwright|jsdom\/|Selenium)/;function W(e){return J.test(e)}function y(){return typeof navigator=="undefined"?{userAgent:"",platform:"",language:"",maxTouchPoints:0}:navigator}function c(e,r){var t;try{return !!((t=e.mimeTypes)!=null&&t.namedItem(r))}catch(n){return false}}function f(e){var n,o;return ((o=(n=e.browserLanguage)!=null?n:e.language)!=null?o:"").replace(/-\w+/g,s=>s.toUpperCase())||"unknown"}function V(e,r={}){var B,w,x,P,b;let{nav:t,windowsVersion:n}=r,{browser:o,version:s}=D(e),{os:d,osVersion:u}=C(e,n),j=R(e,t),Q=I(e),{isBot:H,botName:G}=L(e),U=W(e),K=t?f(t):"unknown",Y=(B=t==null?void 0:t.platform)!=null?B:"unknown",i=o,p=s;if(t){let a=typeof chrome!="undefined"?chrome:void 0,h=/Chrome\/([\d]+)/.exec(e),g=h?parseInt(h[1],10):0;if(a)if(a.adblock2345||a.common2345)i="2345Explorer",p="unknown";else {let m=false;if(c(t,"application/360softmgrplugin")||c(t,"application/mozilla-npqihooquicklogin")||g>36&&typeof showModalDialog!="undefined"?m=true:g>45&&(m=c(t,"application/vnd.chromium.remoting-viewer"),!m&&g>=69&&(m=c(t,"application/hwepass2001.installepass2001")||c(t,"application/asx"))),m){let X=((w=t.connection)==null?void 0:w.saveData)===true;c(t,"application/gameplugin")||!X?i="360SE":i="360EE",p="unknown";}}}if(i==="Baidu"&&/(Opera|OPR|OPT)/.test(e)){i="Opera";let a=(P=(x=/OPR\/([\d.]+)/.exec(e))!=null?x:/OPT\/([\d.]+)/.exec(e))!=null?P:/Opera\/([\d.]+)/.exec(e);p=(b=a==null?void 0:a[1])!=null?b:"unknown";}if(i==="Chrome"&&/\S+Browser\//.test(e)){let a=/(\S+Browser)\/([\d.]+)/.exec(e);a&&(i=a[1],p=a[2]);}if(i==="Firefox"&&t)try{(typeof clientInformation!="undefined"||typeof u2f=="undefined")&&(i="Firefox Nightly");}catch(a){}if(i==="Wechat")try{typeof __wxjs_environment!="undefined"&&__wxjs_environment==="miniprogram"&&(i="Wechat Miniapp");}catch(a){}let q=N(e,i,p);return {browser:i,version:p,engine:q,os:d,osVersion:u,device:j,arch:Q,isWebview:/; wv/.test(e),isHeadless:U,isBot:H,botName:G,language:K,platform:Y}}var{version:Z}=E;var $=e=>/; wv/.test(e),ee=()=>{try{return typeof __wxjs_environment!="undefined"&&__wxjs_environment==="miniprogram"}catch(e){return false}};function l(e){let r=y();return V(e!=null?e:r.userAgent,{nav:r})}l.isWebview=$;l.isWechatMiniapp=ee;l.getLanguage=()=>f(y());l.VERSION=Z;var te=l;
|
|
2
|
-
return
|
|
1
|
+
var uaBrowser=(function(){'use strict';var E={version:"1.0.2"};var k=[{name:"Safari",priority:10,detect:/Safari/,versionPattern:/Version\/([\d.]+)/},{name:"Chrome",priority:20,detect:/(Chrome|CriOS)/,versionPattern:[/Chrome\/([\d.]+)/,/CriOS\/([\d.]+)/]},{name:"IE",priority:30,detect:/(MSIE|Trident)/,versionPattern:[/MSIE ([\d.]+)/,/rv:([\d.]+)/]},{name:"Edge",priority:40,detect:/(Edge|Edg\/|EdgA|EdgiOS)/,versionPattern:[/Edge\/([\d.]+)/,/Edg\/([\d.]+)/,/EdgA\/([\d.]+)/,/EdgiOS\/([\d.]+)/]},{name:"Firefox",priority:50,detect:/(Firefox|FxiOS)/,versionPattern:[/Firefox\/([\d.]+)/,/FxiOS\/([\d.]+)/]},{name:"Firefox Focus",priority:55,detect:/Focus/,versionPattern:/Focus\/([\d.]+)/},{name:"Chromium",priority:60,detect:/Chromium/,versionPattern:/Chromium\/([\d.]+)/},{name:"Opera",priority:70,detect:/(Opera|OPR|OPT)/,versionPattern:[/Opera\/([\d.]+)/,/OPR\/([\d.]+)/,/OPT\/([\d.]+)/]},{name:"Vivaldi",priority:80,detect:/Vivaldi/,versionPattern:/Vivaldi\/([\d.]+)/},{name:"Yandex",priority:90,detect:/YaBrowser/,versionPattern:/YaBrowser\/([\d.]+)/},{name:"Samsung Internet",priority:92,detect:/SamsungBrowser/,versionPattern:/SamsungBrowser\/([\d.]+)/},{name:"DuckDuckGo",priority:94,detect:/DuckDuckGo\//,versionPattern:/DuckDuckGo\/([\d.]+)/},{name:"Puffin",priority:96,detect:/Puffin\//,versionPattern:/Puffin\/([\d.]+)/},{name:"Arora",priority:100,detect:/Arora/,versionPattern:/Arora\/([\d.]+)/},{name:"Lunascape",priority:110,detect:/Lunascape/,versionPattern:/Lunascape[\s]([\d.]+)/},{name:"QupZilla",priority:120,detect:/QupZilla/,versionPattern:/QupZilla[\s]([\d.]+)/},{name:"Coc Coc",priority:130,detect:/coc_coc_browser/,versionPattern:/coc_coc_browser\/([\d.]+)/},{name:"Kindle",priority:140,detect:/(Kindle|Silk\/)/,versionPattern:/Version\/([\d.]+)/},{name:"Iceweasel",priority:150,detect:/Iceweasel/,versionPattern:/Iceweasel\/([\d.]+)/},{name:"Konqueror",priority:160,detect:/Konqueror/,versionPattern:/Konqueror\/([\d.]+)/},{name:"Iceape",priority:170,detect:/Iceape/,versionPattern:/Iceape\/([\d.]+)/},{name:"SeaMonkey",priority:180,detect:/SeaMonkey/,versionPattern:/SeaMonkey\/([\d.]+)/},{name:"Epiphany",priority:190,detect:/Epiphany/,versionPattern:/Epiphany\/([\d.]+)/},{name:"Maxthon",priority:200,detect:/Maxthon/,versionPattern:/Maxthon\/([\d.]+)/},{name:"360",priority:300,detect:/(QihooBrowser|QHBrowser)/,versionPattern:/QihooBrowser\/([\d.]+)/},{name:"360SE",priority:310,detect:/360SE/,versionPattern:null,chromeLookup:{108:"14.0",86:"13.0",78:"12.0",69:"11.0",63:"10.0",55:"9.1",45:"8.1",42:"8.0",31:"7.0",21:"6.3"}},{name:"360EE",priority:320,detect:/360EE/,versionPattern:null,chromeLookup:{86:"13.0",78:"12.0",69:"11.0",63:"9.5",55:"9.0",50:"8.7",30:"7.5"}},{name:"UC",priority:330,detect:/(UCBrowser|UBrowser|UCWEB)/,versionPattern:/UC?Browser\/([\d.]+)/},{name:"QQBrowser",priority:340,detect:/QQBrowser/,versionPattern:/QQBrowser\/([\d.]+)/},{name:"QQ",priority:345,detect:/QQ\//,versionPattern:/QQ\/([\d.]+)/},{name:"Baidu",priority:350,detect:/(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/,versionPattern:[/BIDUBrowser[\s/]([\d.]+)/,/baiduboxapp\/([\d.]+)/]},{name:"Sogou",priority:360,detect:/(MetaSr|Sogou)/,versionPattern:[/SE ([\d.X]+)/,/SogouMobileBrowser\/([\d.]+)/]},{name:"Liebao",priority:370,detect:/(LBBROWSER|LieBaoFast)/,versionPattern:/LieBaoFast\/([\d.]+)/,chromeLookup:{57:"6.5",49:"6.0",46:"5.9",42:"5.3",39:"5.2",34:"5.0",29:"4.5",21:"4.0"}},{name:"2345Explorer",priority:380,detect:/2345Explorer/,versionPattern:[/2345Explorer\/([\d.]+)/,/Mb2345Browser\/([\d.]+)/],chromeLookup:{69:"10.0",55:"9.9"}},{name:"115Browser",priority:390,detect:/115Browser/,versionPattern:/115Browser\/([\d.]+)/},{name:"TheWorld",priority:400,detect:/TheWorld/,versionPattern:/TheWorld ([\d.]+)/},{name:"XiaoMi",priority:410,detect:/MiuiBrowser/,versionPattern:/MiuiBrowser\/([\d.]+)/},{name:"Vivo",priority:420,detect:/VivoBrowser/,versionPattern:/VivoBrowser\/([\d.]+)/},{name:"Huawei",priority:430,detect:/HuaweiBrowser/,versionPattern:[/HuaweiBrowser\/([\d.]+)/,/Version\/([\d.]+)/]},{name:"OPPO",priority:440,detect:/HeyTapBrowser/,versionPattern:/HeyTapBrowser\/([\d.]+)/},{name:"Quark",priority:450,detect:/Quark/,versionPattern:/Quark\/([\d.]+)/},{name:"Qiyu",priority:460,detect:/Qiyu/,versionPattern:/Qiyu\/([\d.]+)/},{name:"WechatWork",priority:500,detect:/wxwork\//,versionPattern:/wxwork\/([\d.]+)/},{name:"Wechat",priority:510,detect:/MicroMessenger/,versionPattern:/MicroMessenger\/([\d.]+)/},{name:"Taobao",priority:520,detect:/AliApp\(TB/,versionPattern:/AliApp\(TB\/([\d.]+)/},{name:"Alipay",priority:530,detect:/AliApp\(AP/,versionPattern:/AliApp\(AP\/([\d.]+)/},{name:"Weibo",priority:540,detect:/Weibo/,versionPattern:/weibo__([\d.]+)/},{name:"Douban",priority:550,detect:/com\.douban\.frodo/,versionPattern:/com\.douban\.frodo\/([\d.]+)/},{name:"Suning",priority:560,detect:/SNEBUY-APP/,versionPattern:/SNEBUY-APP([\d.]+)/},{name:"iQiYi",priority:570,detect:/IqiyiApp/,versionPattern:/IqiyiVersion\/([\d.]+)/},{name:"DingTalk",priority:580,detect:/DingTalk/,versionPattern:/DingTalk\/([\d.]+)/},{name:"Douyin",priority:590,detect:/aweme/,versionPattern:/app_version\/([\d.]+)/}];function y(e,r){let t=r.exec(e);if(!t)return null;let n=t[1];return n!=null&&n!==""?n:null}function O(e,r){for(let t of r){let n=y(e,t);if(n!==null)return n}return null}function D(e,r){let t=/Chrome\/([\d]+)/.exec(e);if(!t)return null;let n=t[1];return Object.prototype.hasOwnProperty.call(r,n)?r[n]:null}function A(e){let r=null;for(let n of k)n.detect.test(e)&&(r===null||n.priority>=r.priority)&&(r=n);if(!r)return {browser:"unknown",version:"unknown"};let t=null;if(r.chromeLookup&&(t=D(e,r.chromeLookup)),t===null&&r.versionPattern!==null){let n=Array.isArray(r.versionPattern)?r.versionPattern:[r.versionPattern];t=O(e,n);}return {browser:r.name,version:t!=null?t:"unknown"}}var N=[{name:"KHTML",detect:/KHTML\//},{name:"Trident",detect:/(Trident|NET CLR)/},{name:"Presto",detect:/Presto/},{name:"Gecko",detect:/Gecko\//},{name:"WebKit",detect:/AppleWebKit/}];function T(e,r,t){var s,a;let n="unknown";for(let d of N)d.detect.test(e)&&(n=d.name);return (n==="WebKit"&&/(Chrome|CriOS)/.test(e)&&parseInt((a=((s=/Chrome\/([\d]+)/.exec(e))!=null?s:[])[1])!=null?a:"0",10)>27||r==="Opera"&&parseInt(t,10)>12||r==="Yandex")&&(n="Blink"),r==="Edge"&&(n=parseInt(t,10)>75?"Blink":"EdgeHTML"),n}var C=[{name:"WebOS",detect:/hpwOS/,versionPattern:/hpwOS\/([\d.]+)/},{name:"Symbian",detect:/Symbian/,versionPattern:null},{name:"MeeGo",detect:/MeeGo/,versionPattern:null},{name:"BlackBerry",detect:/(BlackBerry|RIM)/,versionPattern:null},{name:"FreeBSD",detect:/FreeBSD/,versionPattern:null},{name:"Debian",detect:/Debian/,versionPattern:/Debian\/([\d.]+)/},{name:"Ubuntu",detect:/Ubuntu/,versionPattern:null},{name:"Linux",detect:/(Linux|X11)/,versionPattern:null},{name:"Chrome OS",detect:/CrOS/,versionPattern:null},{name:"Tizen",detect:/Tizen/,versionPattern:/Tizen ([\d.]+)/},{name:"iOS",detect:/like Mac OS X/,versionPattern:/OS ([\d_]+) like/},{name:"MacOS",detect:/Macintosh/,versionPattern:/Mac OS X -?([\d_.]+)/},{name:"Android",detect:/(Android|Adr)/,versionPattern:/(?:Android|Adr) ([\d.]+)/},{name:"HarmonyOS",detect:/HarmonyOS/,versionPattern:/Android ([\d.]+)[;)]/,versionLookup:{10:"2"}},{name:"KaiOS",detect:/KAIOS/,versionPattern:/KAIOS\/([\d.]+)/},{name:"Windows",detect:/Windows/,versionPattern:/Windows NT ([\d.]+)/,versionLookup:{10:"10","6.4":"10","6.3":"8.1","6.2":"8","6.1":"7","6.0":"Vista","5.2":"XP","5.1":"XP","5.0":"2000"}},{name:"Windows Phone",detect:/(IEMobile|Windows Phone)/,versionPattern:/Windows Phone(?: OS)? ([\d.]+)/}];function M(e,r){let t=null;for(let s of C)s.detect.test(e)&&(t=s);if(!t)return {os:"unknown",osVersion:"unknown"};let n="unknown";if(t.versionPattern){let s=y(e,t.versionPattern);if(s!==null){let a=s.replace(/_/g,".");if(t.versionLookup){let d=Object.prototype.hasOwnProperty.call(t.versionLookup,a)?t.versionLookup[a]:null;if(d!==null)n=d;else if(t.name==="Windows"){let u=parseInt(a,10);n=isNaN(u)?"unknown":u.toString();}}else n=a;}}return t.name==="Windows"&&r&&(n=r),{os:t.name,osVersion:n}}var R=[{name:"Mobile",detect:/(Mobi|iPh)/},{name:"Tablet",detect:/(Tablet|Pad)/}];function _(e,r){if(/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(e))return "TV";if((r==null?void 0:r.platform)==="MacIntel"&&r.maxTouchPoints>1||/iPad/.test(e)||/Android/.test(e)&&!/Mobile/.test(e))return "Tablet";for(let t of R)if(t.detect.test(e))return t.name;return "PC"}var I=[{name:"Googlebot",detect:/Googlebot/},{name:"Bingbot",detect:/(bingbot|BingPreview)/},{name:"Baiduspider",detect:/(Baiduspider|BaiduMobaider)/},{name:"Bytespider",detect:/Bytespider/},{name:"YandexBot",detect:/YandexBot/},{name:"DuckDuckBot",detect:/DuckDuckBot/},{name:"Slurp",detect:/Slurp/},{name:"Sogou",detect:/(Sogou|sogou).*[Ss]pider/},{name:"360Spider",detect:/360Spider/},{name:"PetalBot",detect:/PetalBot/},{name:"Applebot",detect:/Applebot/},{name:"Facebookbot",detect:/(facebookexternalhit|FacebookBot)/},{name:"Twitterbot",detect:/Twitterbot/},{name:"LinkedInBot",detect:/LinkedInBot/},{name:"SemrushBot",detect:/SemrushBot/},{name:"AhrefsBot",detect:/AhrefsBot/},{name:"MJ12bot",detect:/MJ12bot/},{name:"GPTBot",detect:/GPTBot/},{name:"ClaudeBot",detect:/ClaudeBot/},{name:"PerplexityBot",detect:/PerplexityBot/},{name:"CCBot",detect:/CCBot/},{name:"AdsBot",detect:/AdsBot-Google/},{name:"GenericBot",detect:/(bot|crawler|spider|crawling|scraper)/i}];function V(e){for(let r of I)if(r.detect.test(e))return {isBot:true,botName:r.name};return {isBot:false,botName:"unknown"}}var L=[{name:"arm64",detect:/(aarch64|arm64|ARM64)/},{name:"arm",detect:/\bARM\b/},{name:"x86_64",detect:/(x86_64|Win64|WOW64|x64;|amd64)/i},{name:"x86",detect:/(i[36]86|i686|x86;)/}];function F(e){for(let r of L)if(r.detect.test(e))return r.name;return "unknown"}var Z=/(HeadlessChrome|Headless|PhantomJS|Electron\/|Playwright|jsdom\/|Selenium)/;function W(e){return Z.test(e)}function B(){return typeof navigator=="undefined"?{userAgent:"",platform:"",language:"",maxTouchPoints:0}:navigator}function c(e,r){var t;try{return !!((t=e.mimeTypes)!=null&&t.namedItem(r))}catch(n){return false}}function f(e){var n,s;return ((s=(n=e.browserLanguage)!=null?n:e.language)!=null?s:"").replace(/-\w+/g,a=>a.toUpperCase())||"unknown"}function j(e,r={}){var w,x,P,b,h;let{nav:t,windowsVersion:n}=r,{browser:s,version:a}=A(e),{os:d,osVersion:u}=M(e,n),g=u,Q=_(e,t),H=F(e),{isBot:G,botName:U}=V(e),K=W(e),Y=t?f(t):"unknown",q=(w=t==null?void 0:t.platform)!=null?w:"unknown",i=s,p=a;if(t){let o=typeof chrome!="undefined"?chrome:void 0,S=/Chrome\/([\d]+)/.exec(e),v=S?parseInt(S[1],10):0;if(o)if(o.adblock2345||o.common2345)i="2345Explorer",p="unknown";else {let m=false;if(c(t,"application/360softmgrplugin")||c(t,"application/mozilla-npqihooquicklogin")||v>36&&typeof showModalDialog!="undefined"?m=true:v>45&&(m=c(t,"application/vnd.chromium.remoting-viewer"),!m&&v>=69&&(m=c(t,"application/hwepass2001.installepass2001")||c(t,"application/asx"))),m){let z=((x=t.connection)==null?void 0:x.saveData)===true;c(t,"application/gameplugin")||!z?i="360SE":i="360EE",p="unknown";}}}if(i==="Baidu"&&/(Opera|OPR|OPT)/.test(e)){i="Opera";let o=(b=(P=/OPR\/([\d.]+)/.exec(e))!=null?P:/OPT\/([\d.]+)/.exec(e))!=null?b:/Opera\/([\d.]+)/.exec(e);p=(h=o==null?void 0:o[1])!=null?h:"unknown";}if(i==="Chrome"&&/\S+Browser\//.test(e)){let o=/(\S+Browser)\/([\d.]+)/.exec(e);o&&(i=o[1],p=o[2]);}if(i==="Firefox"&&t)try{(typeof clientInformation!="undefined"||typeof u2f=="undefined")&&(i="Firefox Nightly");}catch(o){}if(i==="Wechat")try{typeof __wxjs_environment!="undefined"&&__wxjs_environment==="miniprogram"&&(i="Wechat Miniapp");}catch(o){}if(d==="iOS"&&i==="Safari"){let o=/Version\/([\d.]+)/.exec(e);o&&parseInt(o[1],10)>parseInt(g,10)&&(g=o[1]);}let X=T(e,i,p);return {browser:i,version:p,engine:X,os:d,osVersion:g,device:Q,arch:H,isWebview:/; wv/.test(e),isHeadless:K,isBot:G,botName:U,language:Y,platform:q}}var{version:$}=E;var ee=e=>/; wv/.test(e),te=()=>{try{return typeof __wxjs_environment!="undefined"&&__wxjs_environment==="miniprogram"}catch(e){return false}};function l(e){let r=B();return j(e!=null?e:r.userAgent,{nav:r})}l.isWebview=ee;l.isWechatMiniapp=te;l.getLanguage=()=>f(B());l.VERSION=$;var re=l;
|
|
2
|
+
return re;})();//# sourceMappingURL=index.min.js.map
|
|
3
3
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/index.ts"],"names":["package_default","BROWSER_DEFS","extractVersion","ua","pattern","m","v","extractVersionFromPatterns","patterns","p","lookupFromChromeVersion","table","major","detectBrowser","best","def","version","ENGINE_DEFS","detectEngine","browser","_a","_b","engine","OS_DEFS","detectOs","windowsVersion","matchedDef","osVersion","raw","normalised","mapped","n","DEVICE_DEFS","detectDevice","nav","BOT_DEFS","detectBot","ARCH_DEFS","detectArch","HEADLESS_PATTERN","detectHeadless","getNavContext","getMimeType","type","e","getLanguage","w","parseUA","options","_c","_d","_e","rawBrowser","rawVersion","os","device","arch","isBot","botName","isHeadless","language","platform","chromeGlobal","chromeMatch","chromeMajor","is360","saveDataEnabled","opVer","VERSION","isWebview","isWechatMiniapp","uaBrowser","src_default"],"mappings":"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","file":"index.min.js","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.1\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } }\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion } = detectOs(ua, windowsVersion)\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/index.ts"],"names":["package_default","BROWSER_DEFS","extractVersion","ua","pattern","m","v","extractVersionFromPatterns","patterns","p","lookupFromChromeVersion","table","major","detectBrowser","best","def","version","ENGINE_DEFS","detectEngine","browser","_a","_b","engine","OS_DEFS","detectOs","windowsVersion","matchedDef","osVersion","raw","normalised","mapped","n","DEVICE_DEFS","detectDevice","nav","BOT_DEFS","detectBot","ARCH_DEFS","detectArch","HEADLESS_PATTERN","detectHeadless","getNavContext","getMimeType","type","e","getLanguage","w","parseUA","options","_c","_d","_e","rawBrowser","rawVersion","os","rawOsVersion","device","arch","isBot","botName","isHeadless","language","platform","chromeGlobal","chromeMatch","chromeMajor","is360","saveDataEnabled","opVer","VERSION","isWebview","isWechatMiniapp","uaBrowser","src_default"],"mappings":"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","file":"index.min.js","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.2\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\n// Detection uses last-match-wins: entries that appear later override earlier matches.\n// More specific OS entries must come AFTER the generic ones they supersede.\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n // Linux must come before Chrome OS: Chrome OS UAs contain \"X11\", so Linux matches first,\n // then Chrome OS overrides it.\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n // HarmonyOS must come after Android: HarmonyOS UAs include \"Android\", so Android matches\n // first, then HarmonyOS overrides it.\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n // Windows must come before Windows Phone: Windows Phone UAs contain \"Windows\", so Windows\n // matches first, then Windows Phone overrides it.\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion: rawOsVersion } = detectOs(ua, windowsVersion)\n let osVersion = rawOsVersion\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n // iOS 26+: Apple freezes \"CPU iPhone OS\" at the last iOS 18 value for web compatibility.\n // The Version/ token reliably reflects the real Safari/iOS version.\n // When Version/ major > CPU iPhone OS major, use Version/ as the real osVersion.\n if (os === 'iOS' && browser === 'Safari') {\n const m = /Version\\/([\\d.]+)/.exec(ua)\n if (m && parseInt(m[1], 10) > parseInt(osVersion, 10)) {\n osVersion = m[1]\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "1.0.
|
|
3
|
+
version: "1.0.2"};
|
|
4
4
|
|
|
5
5
|
// src/constants/browsers.ts
|
|
6
6
|
var BROWSER_DEFS = [
|
|
@@ -193,23 +193,28 @@ var OS_DEFS = [
|
|
|
193
193
|
{ name: "Symbian", detect: /Symbian/, versionPattern: null },
|
|
194
194
|
{ name: "MeeGo", detect: /MeeGo/, versionPattern: null },
|
|
195
195
|
{ name: "BlackBerry", detect: /(BlackBerry|RIM)/, versionPattern: null },
|
|
196
|
-
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ },
|
|
197
196
|
{ name: "FreeBSD", detect: /FreeBSD/, versionPattern: null },
|
|
198
197
|
{ name: "Debian", detect: /Debian/, versionPattern: /Debian\/([\d.]+)/ },
|
|
199
198
|
{ name: "Ubuntu", detect: /Ubuntu/, versionPattern: null },
|
|
200
|
-
|
|
199
|
+
// Linux must come before Chrome OS: Chrome OS UAs contain "X11", so Linux matches first,
|
|
200
|
+
// then Chrome OS overrides it.
|
|
201
201
|
{ name: "Linux", detect: /(Linux|X11)/, versionPattern: null },
|
|
202
|
+
{ name: "Chrome OS", detect: /CrOS/, versionPattern: null },
|
|
202
203
|
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
203
204
|
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
204
205
|
{ name: "MacOS", detect: /Macintosh/, versionPattern: /Mac OS X -?([\d_.]+)/ },
|
|
206
|
+
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
207
|
+
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
208
|
+
// first, then HarmonyOS overrides it.
|
|
205
209
|
{
|
|
206
210
|
name: "HarmonyOS",
|
|
207
211
|
detect: /HarmonyOS/,
|
|
208
212
|
versionPattern: /Android ([\d.]+)[;)]/,
|
|
209
213
|
versionLookup: { "10": "2" }
|
|
210
214
|
},
|
|
211
|
-
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
212
215
|
{ name: "KaiOS", detect: /KAIOS/, versionPattern: /KAIOS\/([\d.]+)/ },
|
|
216
|
+
// Windows must come before Windows Phone: Windows Phone UAs contain "Windows", so Windows
|
|
217
|
+
// matches first, then Windows Phone overrides it.
|
|
213
218
|
{
|
|
214
219
|
name: "Windows",
|
|
215
220
|
detect: /Windows/,
|
|
@@ -225,7 +230,8 @@ var OS_DEFS = [
|
|
|
225
230
|
"5.1": "XP",
|
|
226
231
|
"5.0": "2000"
|
|
227
232
|
}
|
|
228
|
-
}
|
|
233
|
+
},
|
|
234
|
+
{ name: "Windows Phone", detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\d.]+)/ }
|
|
229
235
|
];
|
|
230
236
|
|
|
231
237
|
// src/detectors/os.ts
|
|
@@ -382,7 +388,8 @@ function parseUA(ua, options = {}) {
|
|
|
382
388
|
var _a, _b, _c, _d, _e;
|
|
383
389
|
const { nav, windowsVersion } = options;
|
|
384
390
|
const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua);
|
|
385
|
-
const { os, osVersion } = detectOs(ua, windowsVersion);
|
|
391
|
+
const { os, osVersion: rawOsVersion } = detectOs(ua, windowsVersion);
|
|
392
|
+
let osVersion = rawOsVersion;
|
|
386
393
|
const device = detectDevice(ua, nav);
|
|
387
394
|
const arch = detectArch(ua);
|
|
388
395
|
const { isBot, botName } = detectBot(ua);
|
|
@@ -449,6 +456,12 @@ function parseUA(ua, options = {}) {
|
|
|
449
456
|
} catch (e) {
|
|
450
457
|
}
|
|
451
458
|
}
|
|
459
|
+
if (os === "iOS" && browser === "Safari") {
|
|
460
|
+
const m = /Version\/([\d.]+)/.exec(ua);
|
|
461
|
+
if (m && parseInt(m[1], 10) > parseInt(osVersion, 10)) {
|
|
462
|
+
osVersion = m[1];
|
|
463
|
+
}
|
|
464
|
+
}
|
|
452
465
|
const engine = detectEngine(ua, browser, version);
|
|
453
466
|
return {
|
|
454
467
|
browser,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/utils/windows-version.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.1\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } }\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion } = detectOs(ua, windowsVersion)\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import type { NavContext } from './navigator.js'\n\n/**\n * Asynchronously detect whether the Windows version is 10 or 11 using the\n * User-Agent Client Hints API (navigator.userAgentData).\n *\n * Returns '11', '10', or null (non-Windows / API unavailable / error).\n *\n * Because this is async, callers that need accurate Windows 11 detection\n * should await this result and pass it to parseUA() as `options.windowsVersion`.\n */\nexport async function getWindowsVersion(nav: NavContext): Promise<string | null> {\n if (!nav.userAgentData || nav.userAgentData.platform !== 'Windows') {\n return null\n }\n try {\n const data = await nav.userAgentData.getHighEntropyValues(['platformVersion'])\n const major = parseInt(data['platformVersion']?.split('.')[0] || '0', 10)\n return major >= 13 ? '11' : '10'\n } catch {\n return null\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/constants/browsers.ts","../src/utils/extract.ts","../src/detectors/browser.ts","../src/constants/engines.ts","../src/detectors/engine.ts","../src/constants/os.ts","../src/detectors/os.ts","../src/constants/devices.ts","../src/detectors/device.ts","../src/constants/bots.ts","../src/detectors/bot.ts","../src/constants/arch.ts","../src/detectors/arch.ts","../src/detectors/headless.ts","../src/utils/navigator.ts","../src/parse.ts","../src/utils/windows-version.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["{\n \"name\": \"ua-browser\",\n \"version\": \"1.0.2\",\n \"description\": \"uaBrowser - Browser, OS, engine and device detection from user agent strings. Supports Node.js. Zero dependencies.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"release\": \"pnpm build && changeset publish\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src --ext .ts\",\n \"typecheck\": \"tsc -p tsconfig.build.json --noEmit\",\n \"docs:dev\": \"pnpm build && vitepress dev docs\",\n \"docs:build\": \"pnpm build && vitepress build docs\",\n \"docs:preview\": \"vitepress preview docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yangtianxia/ua-browser.git\"\n },\n \"keywords\": [\n \"uaBrowser\",\n \"userAgent\",\n \"javascript\",\n \"typescript\",\n \"browser-detection\",\n \"user-agent-parser\"\n ],\n \"author\": \"yangtianxia\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/yangtianxia/ua-browser/issues\"\n },\n \"homepage\": \"https://github.com/yangtianxia/ua-browser#readme\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.4\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-import\": \"^2.29.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.4.0\",\n \"vitepress\": \"^1.6.4\",\n \"vitest\": \"^1.6.0\",\n \"vue\": \"^3.5.32\"\n }\n}\n","import type { BrowserName } from '../types.js'\n\nexport interface BrowserDef {\n name: BrowserName\n /** Detection regex — must match the UA for this browser to be a candidate. */\n detect: RegExp\n /**\n * Version extraction: capture-group regex (or array tried in order).\n * null = no direct version pattern (use chromeLookup only, or lookup table browsers).\n */\n versionPattern: RegExp | RegExp[] | null\n /** Chrome major-version → browser display version lookup (e.g. 360SE/EE, Liebao). */\n chromeLookup?: Record<string, string>\n /**\n * Detection priority. When multiple entries match the same UA, the one with\n * the highest priority wins. Explicit and verifiable — no reverse-iteration magic.\n */\n priority: number\n}\n\nexport const BROWSER_DEFS: readonly BrowserDef[] = [\n // ── Generic / low-priority base browsers ──────────────────────────────────\n { name: 'Safari', priority: 10, detect: /Safari/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Chrome', priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\\/([\\d.]+)/, /CriOS\\/([\\d.]+)/] },\n { name: 'IE', priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\\d.]+)/, /rv:([\\d.]+)/] },\n { name: 'Edge', priority: 40, detect: /(Edge|Edg\\/|EdgA|EdgiOS)/, versionPattern: [/Edge\\/([\\d.]+)/, /Edg\\/([\\d.]+)/, /EdgA\\/([\\d.]+)/, /EdgiOS\\/([\\d.]+)/] },\n { name: 'Firefox', priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\\/([\\d.]+)/, /FxiOS\\/([\\d.]+)/] },\n { name: 'Firefox Focus', priority: 55, detect: /Focus/, versionPattern: /Focus\\/([\\d.]+)/ },\n { name: 'Chromium', priority: 60, detect: /Chromium/, versionPattern: /Chromium\\/([\\d.]+)/ },\n { name: 'Opera', priority: 70, detect: /(Opera|OPR|OPT)/, versionPattern: [/Opera\\/([\\d.]+)/, /OPR\\/([\\d.]+)/, /OPT\\/([\\d.]+)/] },\n { name: 'Vivaldi', priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\\/([\\d.]+)/ },\n { name: 'Yandex', priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\\/([\\d.]+)/ },\n { name: 'Samsung Internet', priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\\/([\\d.]+)/ },\n { name: 'DuckDuckGo', priority: 94, detect: /DuckDuckGo\\//, versionPattern: /DuckDuckGo\\/([\\d.]+)/ },\n { name: 'Puffin', priority: 96, detect: /Puffin\\//, versionPattern: /Puffin\\/([\\d.]+)/ },\n { name: 'Arora', priority: 100, detect: /Arora/, versionPattern: /Arora\\/([\\d.]+)/ },\n { name: 'Lunascape', priority: 110, detect: /Lunascape/, versionPattern: /Lunascape[\\s]([\\d.]+)/ },\n { name: 'QupZilla', priority: 120, detect: /QupZilla/, versionPattern: /QupZilla[\\s]([\\d.]+)/ },\n { name: 'Coc Coc', priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\\/([\\d.]+)/ },\n { name: 'Kindle', priority: 140, detect: /(Kindle|Silk\\/)/, versionPattern: /Version\\/([\\d.]+)/ },\n { name: 'Iceweasel', priority: 150, detect: /Iceweasel/, versionPattern: /Iceweasel\\/([\\d.]+)/ },\n { name: 'Konqueror', priority: 160, detect: /Konqueror/, versionPattern: /Konqueror\\/([\\d.]+)/ },\n { name: 'Iceape', priority: 170, detect: /Iceape/, versionPattern: /Iceape\\/([\\d.]+)/ },\n { name: 'SeaMonkey', priority: 180, detect: /SeaMonkey/, versionPattern: /SeaMonkey\\/([\\d.]+)/ },\n { name: 'Epiphany', priority: 190, detect: /Epiphany/, versionPattern: /Epiphany\\/([\\d.]+)/ },\n { name: 'Maxthon', priority: 200, detect: /Maxthon/, versionPattern: /Maxthon\\/([\\d.]+)/ },\n\n // ── Chinese / Asian browsers — higher priority than generic Chrome ─────────\n { name: '360', priority: 300, detect: /(QihooBrowser|QHBrowser)/, versionPattern: /QihooBrowser\\/([\\d.]+)/ },\n { name: '360SE', priority: 310, detect: /360SE/, versionPattern: null,\n chromeLookup: { '108': '14.0', '86': '13.0', '78': '12.0', '69': '11.0',\n '63': '10.0', '55': '9.1', '45': '8.1', '42': '8.0', '31': '7.0', '21': '6.3' } },\n { name: '360EE', priority: 320, detect: /360EE/, versionPattern: null,\n chromeLookup: { '86': '13.0', '78': '12.0', '69': '11.0', '63': '9.5',\n '55': '9.0', '50': '8.7', '30': '7.5' } },\n { name: 'UC', priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\\/([\\d.]+)/ },\n { name: 'QQBrowser', priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\\/([\\d.]+)/ },\n { name: 'QQ', priority: 345, detect: /QQ\\//, versionPattern: /QQ\\/([\\d.]+)/ },\n { name: 'Baidu', priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\\s/]([\\d.]+)/, /baiduboxapp\\/([\\d.]+)/] },\n { name: 'Sogou', priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\\d.X]+)/, /SogouMobileBrowser\\/([\\d.]+)/] },\n { name: 'Liebao', priority: 370, detect: /(LBBROWSER|LieBaoFast)/, versionPattern: /LieBaoFast\\/([\\d.]+)/,\n chromeLookup: { '57': '6.5', '49': '6.0', '46': '5.9', '42': '5.3',\n '39': '5.2', '34': '5.0', '29': '4.5', '21': '4.0' } },\n { name: '2345Explorer', priority: 380, detect: /2345Explorer/, versionPattern: [/2345Explorer\\/([\\d.]+)/, /Mb2345Browser\\/([\\d.]+)/],\n chromeLookup: { '69': '10.0', '55': '9.9' } },\n { name: '115Browser', priority: 390, detect: /115Browser/, versionPattern: /115Browser\\/([\\d.]+)/ },\n { name: 'TheWorld', priority: 400, detect: /TheWorld/, versionPattern: /TheWorld ([\\d.]+)/ },\n { name: 'XiaoMi', priority: 410, detect: /MiuiBrowser/, versionPattern: /MiuiBrowser\\/([\\d.]+)/ },\n { name: 'Vivo', priority: 420, detect: /VivoBrowser/, versionPattern: /VivoBrowser\\/([\\d.]+)/ },\n { name: 'Huawei', priority: 430, detect: /HuaweiBrowser/, versionPattern: [/HuaweiBrowser\\/([\\d.]+)/, /Version\\/([\\d.]+)/] },\n { name: 'OPPO', priority: 440, detect: /HeyTapBrowser/, versionPattern: /HeyTapBrowser\\/([\\d.]+)/ },\n { name: 'Quark', priority: 450, detect: /Quark/, versionPattern: /Quark\\/([\\d.]+)/ },\n { name: 'Qiyu', priority: 460, detect: /Qiyu/, versionPattern: /Qiyu\\/([\\d.]+)/ },\n\n // ── App webviews — highest priority ───────────────────────────────────────\n { name: 'WechatWork', priority: 500, detect: /wxwork\\//, versionPattern: /wxwork\\/([\\d.]+)/ },\n { name: 'Wechat', priority: 510, detect: /MicroMessenger/, versionPattern: /MicroMessenger\\/([\\d.]+)/ },\n { name: 'Taobao', priority: 520, detect: /AliApp\\(TB/, versionPattern: /AliApp\\(TB\\/([\\d.]+)/ },\n { name: 'Alipay', priority: 530, detect: /AliApp\\(AP/, versionPattern: /AliApp\\(AP\\/([\\d.]+)/ },\n { name: 'Weibo', priority: 540, detect: /Weibo/, versionPattern: /weibo__([\\d.]+)/ },\n { name: 'Douban', priority: 550, detect: /com\\.douban\\.frodo/, versionPattern: /com\\.douban\\.frodo\\/([\\d.]+)/ },\n { name: 'Suning', priority: 560, detect: /SNEBUY-APP/, versionPattern: /SNEBUY-APP([\\d.]+)/ },\n { name: 'iQiYi', priority: 570, detect: /IqiyiApp/, versionPattern: /IqiyiVersion\\/([\\d.]+)/ },\n { name: 'DingTalk', priority: 580, detect: /DingTalk/, versionPattern: /DingTalk\\/([\\d.]+)/ },\n { name: 'Douyin', priority: 590, detect: /aweme/, versionPattern: /app_version\\/([\\d.]+)/ }\n] as const\n","/**\n * Extract the first capture group from `ua` using `pattern`.\n * Returns the matched string, or null if the pattern does not match.\n * Unlike String.replace(), this never returns the original input on no-match.\n */\nexport function extractVersion(ua: string, pattern: RegExp): string | null {\n const m = pattern.exec(ua)\n if (!m) return null\n const v = m[1]\n return v != null && v !== '' ? v : null\n}\n\n/**\n * Try each pattern in order; return the first non-null match, or null.\n */\nexport function extractVersionFromPatterns(ua: string, patterns: RegExp[]): string | null {\n for (const p of patterns) {\n const v = extractVersion(ua, p)\n if (v !== null) return v\n }\n return null\n}\n\n/**\n * Extract the Chrome major version from `ua` and look it up in a table.\n * Returns the mapped string on hit, or null on miss / no Chrome token.\n */\nexport function lookupFromChromeVersion(ua: string, table: Record<string, string>): string | null {\n const m = /Chrome\\/([\\d]+)/.exec(ua)\n if (!m) return null\n const major = m[1]\n return Object.prototype.hasOwnProperty.call(table, major) ? table[major] : null\n}\n","import type { BrowserName } from '../types.js'\nimport { BROWSER_DEFS } from '../constants/browsers.js'\nimport { extractVersionFromPatterns, lookupFromChromeVersion } from '../utils/extract.js'\n\nexport interface BrowserResult {\n browser: BrowserName\n version: string\n}\n\n/**\n * Detect the browser name and version from a user agent string.\n *\n * When multiple BROWSER_DEFS entries match the same UA, the one with\n * the highest `priority` value wins (ties go to the later definition).\n */\nexport function detectBrowser(ua: string): BrowserResult {\n let best: (typeof BROWSER_DEFS)[number] | null = null\n\n for (const def of BROWSER_DEFS) {\n if (def.detect.test(ua)) {\n if (best === null || def.priority >= best.priority) {\n best = def\n }\n }\n }\n\n if (!best) return { browser: 'unknown', version: 'unknown' }\n\n let version: string | null = null\n\n // 1. Try Chrome-version lookup table (for browsers like 360SE/EE that version by Chrome major)\n if (best.chromeLookup) {\n version = lookupFromChromeVersion(ua, best.chromeLookup)\n }\n\n // 2. Fall back to direct regex extraction\n if (version === null && best.versionPattern !== null) {\n const patterns = Array.isArray(best.versionPattern)\n ? best.versionPattern\n : [best.versionPattern]\n version = extractVersionFromPatterns(ua, patterns)\n }\n\n return { browser: best.name, version: version ?? 'unknown' }\n}\n","export interface EngineDef {\n name: string\n detect: RegExp\n}\n\nexport const ENGINE_DEFS: readonly EngineDef[] = [\n { name: 'KHTML', detect: /KHTML\\// },\n { name: 'Trident', detect: /(Trident|NET CLR)/ },\n { name: 'Presto', detect: /Presto/ },\n { name: 'Gecko', detect: /Gecko\\// },\n { name: 'WebKit', detect: /AppleWebKit/ }\n] as const\n","import type { EngineName } from '../types.js'\nimport { ENGINE_DEFS } from '../constants/engines.js'\n\n/**\n * Detect the rendering engine, with post-detection upgrades for Blink and EdgeHTML.\n *\n * @param ua - Raw user agent string\n * @param browser - Already-detected browser name (for Blink/EdgeHTML disambiguation)\n * @param version - Already-detected browser version string\n */\nexport function detectEngine(ua: string, browser: string, version: string): EngineName {\n let engine: EngineName = 'unknown'\n\n for (const def of ENGINE_DEFS) {\n if (def.detect.test(ua)) {\n engine = def.name as EngineName\n }\n }\n\n // Upgrade WebKit to Blink for Chrome 28+, Opera 15+, Yandex\n if (\n engine === 'WebKit' &&\n /(Chrome|CriOS)/.test(ua) &&\n parseInt((/Chrome\\/([\\d]+)/.exec(ua) ?? [])[1] ?? '0', 10) > 27\n ) {\n engine = 'Blink'\n } else if (browser === 'Opera' && parseInt(version, 10) > 12) {\n engine = 'Blink'\n } else if (browser === 'Yandex') {\n engine = 'Blink'\n }\n\n // Edge: Chromium-based Edge uses Blink (version > 75), legacy EdgeHTML below that\n if (browser === 'Edge') {\n engine = parseInt(version, 10) > 75 ? 'Blink' : 'EdgeHTML'\n }\n\n return engine\n}\n","import type { OsName } from '../types.js'\n\nexport interface OsDef {\n name: OsName\n detect: RegExp\n /** Capture-group regex for OS version extraction. null = no version. */\n versionPattern: RegExp | null\n /** Lookup table: raw version token → display version. */\n versionLookup?: Record<string, string>\n}\n\n// Detection uses last-match-wins: entries that appear later override earlier matches.\n// More specific OS entries must come AFTER the generic ones they supersede.\nexport const OS_DEFS: readonly OsDef[] = [\n { name: 'WebOS', detect: /hpwOS/, versionPattern: /hpwOS\\/([\\d.]+)/ },\n { name: 'Symbian', detect: /Symbian/, versionPattern: null },\n { name: 'MeeGo', detect: /MeeGo/, versionPattern: null },\n { name: 'BlackBerry', detect: /(BlackBerry|RIM)/, versionPattern: null },\n { name: 'FreeBSD', detect: /FreeBSD/, versionPattern: null },\n { name: 'Debian', detect: /Debian/, versionPattern: /Debian\\/([\\d.]+)/ },\n { name: 'Ubuntu', detect: /Ubuntu/, versionPattern: null },\n // Linux must come before Chrome OS: Chrome OS UAs contain \"X11\", so Linux matches first,\n // then Chrome OS overrides it.\n { name: 'Linux', detect: /(Linux|X11)/, versionPattern: null },\n { name: 'Chrome OS', detect: /CrOS/, versionPattern: null },\n { name: 'Tizen', detect: /Tizen/, versionPattern: /Tizen ([\\d.]+)/ },\n { name: 'iOS', detect: /like Mac OS X/, versionPattern: /OS ([\\d_]+) like/ },\n { name: 'MacOS', detect: /Macintosh/, versionPattern: /Mac OS X -?([\\d_.]+)/ },\n { name: 'Android', detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\\d.]+)/ },\n // HarmonyOS must come after Android: HarmonyOS UAs include \"Android\", so Android matches\n // first, then HarmonyOS overrides it.\n { name: 'HarmonyOS', detect: /HarmonyOS/, versionPattern: /Android ([\\d.]+)[;)]/,\n versionLookup: { '10': '2' } },\n { name: 'KaiOS', detect: /KAIOS/, versionPattern: /KAIOS\\/([\\d.]+)/ },\n // Windows must come before Windows Phone: Windows Phone UAs contain \"Windows\", so Windows\n // matches first, then Windows Phone overrides it.\n { name: 'Windows', detect: /Windows/, versionPattern: /Windows NT ([\\d.]+)/,\n versionLookup: {\n '10': '10', '6.4': '10', '6.3': '8.1', '6.2': '8',\n '6.1': '7', '6.0': 'Vista', '5.2': 'XP', '5.1': 'XP', '5.0': '2000'\n } },\n { name: 'Windows Phone', detect: /(IEMobile|Windows Phone)/, versionPattern: /Windows Phone(?: OS)? ([\\d.]+)/ },\n] as const\n","import type { OsName } from '../types.js'\nimport { OS_DEFS } from '../constants/os.js'\nimport { extractVersion } from '../utils/extract.js'\n\nexport interface OsResult {\n os: OsName\n osVersion: string\n}\n\n/**\n * Detect the operating system and its version from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param windowsVersion - Pre-resolved Windows 11/10 string from getWindowsVersion()\n * (avoids the async race condition of the old implementation)\n */\nexport function detectOs(ua: string, windowsVersion?: string | null): OsResult {\n let matchedDef: (typeof OS_DEFS)[number] | null = null\n\n // Iterate in array order; later entries have higher priority (same as BROWSER_DEFS)\n for (const def of OS_DEFS) {\n if (def.detect.test(ua)) {\n matchedDef = def\n }\n }\n\n if (!matchedDef) return { os: 'unknown', osVersion: 'unknown' }\n\n let osVersion = 'unknown'\n\n if (matchedDef.versionPattern) {\n const raw = extractVersion(ua, matchedDef.versionPattern)\n\n if (raw !== null) {\n // Normalise iOS underscore-separated version: \"17_4_1\" → \"17.4.1\"\n const normalised = raw.replace(/_/g, '.')\n\n if (matchedDef.versionLookup) {\n // Use lookup table if available (Windows NT, HarmonyOS)\n const mapped = Object.prototype.hasOwnProperty.call(matchedDef.versionLookup, normalised)\n ? matchedDef.versionLookup[normalised]\n : null\n\n if (mapped !== null) {\n osVersion = mapped\n } else if (matchedDef.name === 'Windows') {\n // For unknown Windows NT versions, fall back to the integer part\n const n = parseInt(normalised, 10)\n osVersion = isNaN(n) ? 'unknown' : n.toString()\n }\n } else {\n osVersion = normalised\n }\n }\n }\n\n // Windows 11 override — provided externally to avoid async race\n if (matchedDef.name === 'Windows' && windowsVersion) {\n osVersion = windowsVersion\n }\n\n return { os: matchedDef.name, osVersion }\n}\n","export interface DeviceDef {\n name: string\n detect: RegExp\n}\n\nexport const DEVICE_DEFS: readonly DeviceDef[] = [\n { name: 'Mobile', detect: /(Mobi|iPh)/ },\n { name: 'Tablet', detect: /(Tablet|Pad)/ }\n] as const\n","import type { DeviceName } from '../types.js'\nimport { DEVICE_DEFS } from '../constants/devices.js'\nimport type { NavContext } from '../utils/navigator.js'\n\n/**\n * Detect the device type from a user agent string.\n *\n * @param ua - Raw user agent string\n * @param nav - Optional nav context; used to detect iPad on modern macOS\n * (where the UA reports \"Macintosh\" but maxTouchPoints > 1)\n */\nexport function detectDevice(ua: string, nav?: Pick<NavContext, 'platform' | 'maxTouchPoints'>): DeviceName {\n // Smart TV — must come first; some TV UAs also contain Android/Linux tokens\n if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) {\n return 'TV'\n }\n\n // Modern iPad: platform='MacIntel' with touch points (iPadOS 13+)\n if (nav?.platform === 'MacIntel' && nav.maxTouchPoints > 1) {\n return 'Tablet'\n }\n\n // iPad in UA string (older iPads)\n if (/iPad/.test(ua)) {\n return 'Tablet'\n }\n\n // Android tablet: has Android but no Mobile marker\n if (/Android/.test(ua) && !/Mobile/.test(ua)) {\n return 'Tablet'\n }\n\n for (const def of DEVICE_DEFS) {\n if (def.detect.test(ua)) {\n return def.name as DeviceName\n }\n }\n\n return 'PC'\n}\n","export type BotName =\n | 'Googlebot'\n | 'Bingbot'\n | 'Baiduspider'\n | 'Bytespider'\n | 'YandexBot'\n | 'DuckDuckBot'\n | 'Slurp'\n | 'Sogou'\n | '360Spider'\n | 'Applebot'\n | 'Facebookbot'\n | 'Twitterbot'\n | 'LinkedInBot'\n | 'SemrushBot'\n | 'AhrefsBot'\n | 'MJ12bot'\n | 'PetalBot'\n | 'GPTBot'\n | 'ClaudeBot'\n | 'PerplexityBot'\n | 'CCBot'\n | 'AdsBot'\n | 'GenericBot'\n | 'unknown'\n\nexport interface BotDef {\n name: BotName\n detect: RegExp\n}\n\nexport const BOT_DEFS: readonly BotDef[] = [\n // Search engines\n { name: 'Googlebot', detect: /Googlebot/ },\n { name: 'Bingbot', detect: /(bingbot|BingPreview)/ },\n { name: 'Baiduspider', detect: /(Baiduspider|BaiduMobaider)/ },\n { name: 'Bytespider', detect: /Bytespider/ },\n { name: 'YandexBot', detect: /YandexBot/ },\n { name: 'DuckDuckBot', detect: /DuckDuckBot/ },\n { name: 'Slurp', detect: /Slurp/ },\n { name: 'Sogou', detect: /(Sogou|sogou).*[Ss]pider/ },\n { name: '360Spider', detect: /360Spider/ },\n { name: 'PetalBot', detect: /PetalBot/ },\n { name: 'Applebot', detect: /Applebot/ },\n // Social\n { name: 'Facebookbot', detect: /(facebookexternalhit|FacebookBot)/ },\n { name: 'Twitterbot', detect: /Twitterbot/ },\n { name: 'LinkedInBot', detect: /LinkedInBot/ },\n // SEO tools\n { name: 'SemrushBot', detect: /SemrushBot/ },\n { name: 'AhrefsBot', detect: /AhrefsBot/ },\n { name: 'MJ12bot', detect: /MJ12bot/ },\n // AI / LLM crawlers\n { name: 'GPTBot', detect: /GPTBot/ },\n { name: 'ClaudeBot', detect: /ClaudeBot/ },\n { name: 'PerplexityBot', detect: /PerplexityBot/ },\n { name: 'CCBot', detect: /CCBot/ },\n { name: 'AdsBot', detect: /AdsBot-Google/ },\n // Generic catch-all (must be last)\n { name: 'GenericBot', detect: /(bot|crawler|spider|crawling|scraper)/i }\n] as const\n","import { BOT_DEFS, type BotName } from '../constants/bots.js'\n\nexport interface BotResult {\n isBot: boolean\n botName: BotName\n}\n\n/**\n * Detect whether the UA belongs to a bot, crawler, or spider.\n * Returns the specific bot name when recognised, 'GenericBot' for generic patterns,\n * or 'unknown' for regular user agents.\n */\nexport function detectBot(ua: string): BotResult {\n for (const def of BOT_DEFS) {\n if (def.detect.test(ua)) {\n return { isBot: true, botName: def.name }\n }\n }\n return { isBot: false, botName: 'unknown' }\n}\n","export type ArchName = 'x86' | 'x86_64' | 'arm' | 'arm64' | 'unknown'\n\nexport interface ArchDef {\n name: ArchName\n detect: RegExp\n}\n\n/**\n * Ordered from most specific to least specific.\n * First match wins (unlike browser/OS detection which keeps highest priority).\n */\nexport const ARCH_DEFS: readonly ArchDef[] = [\n { name: 'arm64', detect: /(aarch64|arm64|ARM64)/ },\n { name: 'arm', detect: /\\bARM\\b/ },\n { name: 'x86_64', detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },\n { name: 'x86', detect: /(i[36]86|i686|x86;)/ }\n] as const\n","import { ARCH_DEFS, type ArchName } from '../constants/arch.js'\n\n/**\n * Detect the CPU architecture from a user agent string.\n * Returns 'unknown' when the UA provides no architecture hints.\n */\nexport function detectArch(ua: string): ArchName {\n for (const def of ARCH_DEFS) {\n if (def.detect.test(ua)) {\n return def.name\n }\n }\n return 'unknown'\n}\n","/**\n * Patterns that indicate a headless, automated, or embedded browser environment.\n *\n * | Pattern | Source |\n * |------------------|-----------------------------------------------------|\n * | HeadlessChrome | Chrome launched with --headless flag |\n * | Headless | Generic headless marker in some frameworks |\n * | PhantomJS | PhantomJS (deprecated but still used) |\n * | Electron | Electron apps (not strictly headless, but automated)|\n * | Playwright | Playwright automation framework |\n * | jsdom | Node.js DOM simulation (vitest, jest-environment) |\n * | Selenium | Some WebDriver/Selenium setups inject this token |\n */\nconst HEADLESS_PATTERN = /(HeadlessChrome|Headless|PhantomJS|Electron\\/|Playwright|jsdom\\/|Selenium)/\n\n/**\n * Detect whether the UA belongs to a headless or automation-driven browser.\n *\n * Note: modern Puppeteer/Playwright using stealth mode can hide these markers.\n * This catches the common/unmodified cases only.\n */\nexport function detectHeadless(ua: string): boolean {\n return HEADLESS_PATTERN.test(ua)\n}\n","/**\n * A subset of the Navigator interface that our detectors need.\n * Accepting NavContext as a parameter makes every detector pure and testable.\n */\nexport interface NavContext {\n userAgent: string\n platform: string\n language: string\n browserLanguage?: string\n maxTouchPoints: number\n mimeTypes?: MimeTypeArray\n connection?: { saveData?: boolean }\n userAgentData?: {\n platform: string\n getHighEntropyValues(hints: string[]): Promise<Record<string, string>>\n }\n}\n\n/** Build a NavContext from the real browser `navigator`, or return a safe default for Node.js. */\nexport function getNavContext(): NavContext {\n if (typeof navigator === 'undefined') {\n return { userAgent: '', platform: '', language: '', maxTouchPoints: 0 }\n }\n return navigator as unknown as NavContext\n}\n\n/** Safely query a MIME type from the nav context. Returns false in non-browser envs. */\nexport function getMimeType(nav: NavContext, type: string): boolean {\n try {\n return !!nav.mimeTypes?.namedItem(type)\n } catch {\n return false\n }\n}\n\n/** Returns the normalised browser language (e.g. \"zh-CN\" → \"zh-CN\", \"en-us\" → \"en-US\"). */\nexport function getLanguage(nav: NavContext): string {\n const raw = nav.browserLanguage ?? nav.language ?? ''\n const normalised = raw.replace(/-\\w+/g, (w) => w.toUpperCase())\n return normalised || 'unknown'\n}\n","import type { EnvOption, BrowserName } from './types.js'\nimport { detectBrowser } from './detectors/browser.js'\nimport { detectEngine } from './detectors/engine.js'\nimport { detectOs } from './detectors/os.js'\nimport { detectDevice } from './detectors/device.js'\nimport { detectBot } from './detectors/bot.js'\nimport { detectArch } from './detectors/arch.js'\nimport { detectHeadless } from './detectors/headless.js'\nimport { getMimeType, getLanguage, type NavContext } from './utils/navigator.js'\n\nexport interface ParseOptions {\n /** Nav context to use for language, platform, MIME-type checks, and device detection. */\n nav?: NavContext\n /** Pre-resolved Windows version string (from getWindowsVersion()). Pass to avoid async races. */\n windowsVersion?: string | null\n}\n\n/**\n * Parse a user agent string into a full browser/OS/engine/device description.\n *\n * Pure function — no global state, no singletons. All environment access is\n * supplied through `options.nav`; omit it for Node.js / testing contexts.\n */\nexport function parseUA(ua: string, options: ParseOptions = {}): EnvOption {\n const { nav, windowsVersion } = options\n\n const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua)\n const { os, osVersion: rawOsVersion } = detectOs(ua, windowsVersion)\n let osVersion = rawOsVersion\n const device = detectDevice(ua, nav)\n const arch = detectArch(ua)\n const { isBot, botName } = detectBot(ua)\n const isHeadless = detectHeadless(ua)\n const language = nav ? getLanguage(nav) : 'unknown'\n const platform = nav?.platform ?? 'unknown'\n\n let browser: BrowserName = rawBrowser\n let version = rawVersion\n\n // ── Post-detection overrides ────────────────────────────────────────────────\n\n // 360 browser disambiguation via Chrome global APIs and MIME types.\n // Only runs when a nav context is provided (browser environment).\n if (nav) {\n const chromeGlobal = typeof chrome !== 'undefined' ? chrome : undefined\n const chromeMatch = /Chrome\\/([\\d]+)/.exec(ua)\n const chromeMajor = chromeMatch ? parseInt(chromeMatch[1], 10) : 0\n\n if (chromeGlobal) {\n if (chromeGlobal.adblock2345 || chromeGlobal.common2345) {\n browser = '2345Explorer'\n version = 'unknown'\n } else {\n let is360 = false\n\n if (\n getMimeType(nav, 'application/360softmgrplugin') ||\n getMimeType(nav, 'application/mozilla-npqihooquicklogin') ||\n (chromeMajor > 36 && typeof showModalDialog !== 'undefined')\n ) {\n is360 = true\n } else if (chromeMajor > 45) {\n is360 = getMimeType(nav, 'application/vnd.chromium.remoting-viewer')\n if (!is360 && chromeMajor >= 69) {\n is360 =\n getMimeType(nav, 'application/hwepass2001.installepass2001') ||\n getMimeType(nav, 'application/asx')\n }\n }\n\n if (is360) {\n // 360EE only when saveData is explicitly enabled; default to 360SE\n const saveDataEnabled = nav.connection?.saveData === true\n if (getMimeType(nav, 'application/gameplugin') || !saveDataEnabled) {\n browser = '360SE'\n } else {\n browser = '360EE'\n }\n version = 'unknown' // re-derived below via browser lookup\n }\n }\n }\n }\n\n // Baidu UA can include Opera token — Opera takes priority\n if (browser === 'Baidu' && /(Opera|OPR|OPT)/.test(ua)) {\n browser = 'Opera'\n const opVer = /OPR\\/([\\d.]+)/.exec(ua) ?? /OPT\\/([\\d.]+)/.exec(ua) ?? /Opera\\/([\\d.]+)/.exec(ua)\n version = opVer?.[1] ?? 'unknown'\n }\n\n // Generic \"SomethingBrowser/x.y\" catch-all: Chrome-based third-party browsers\n // that embed their own token alongside Chrome\n if (browser === 'Chrome' && /\\S+Browser\\//.test(ua)) {\n const m = /(\\S+Browser)\\/([\\d.]+)/.exec(ua)\n if (m) {\n browser = m[1] as BrowserName\n version = m[2]\n }\n }\n\n // Firefox Nightly detection — only meaningful in a real browser environment.\n // The heuristic checks for globals that exist in Chrome (clientInformation) but\n // not in standard Firefox, or where u2f was removed in Nightly builds.\n // Skip entirely in Node.js (no nav = not a browser).\n if (browser === 'Firefox' && nav) {\n try {\n if (typeof clientInformation !== 'undefined' || typeof u2f === 'undefined') {\n browser = 'Firefox Nightly'\n }\n } catch {\n // globals not accessible — leave as Firefox\n }\n }\n\n // WeChat Miniapp detection\n if (browser === 'Wechat') {\n try {\n if (typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram') {\n browser = 'Wechat Miniapp'\n }\n } catch {\n // not in WeChat miniapp context\n }\n }\n\n // iOS 26+: Apple freezes \"CPU iPhone OS\" at the last iOS 18 value for web compatibility.\n // The Version/ token reliably reflects the real Safari/iOS version.\n // When Version/ major > CPU iPhone OS major, use Version/ as the real osVersion.\n if (os === 'iOS' && browser === 'Safari') {\n const m = /Version\\/([\\d.]+)/.exec(ua)\n if (m && parseInt(m[1], 10) > parseInt(osVersion, 10)) {\n osVersion = m[1]\n }\n }\n\n const engine = detectEngine(ua, browser, version)\n\n return {\n browser,\n version,\n engine,\n os,\n osVersion,\n device,\n arch,\n isWebview: /; wv/.test(ua),\n isHeadless,\n isBot,\n botName,\n language,\n platform\n }\n}\n","import type { NavContext } from './navigator.js'\n\n/**\n * Asynchronously detect whether the Windows version is 10 or 11 using the\n * User-Agent Client Hints API (navigator.userAgentData).\n *\n * Returns '11', '10', or null (non-Windows / API unavailable / error).\n *\n * Because this is async, callers that need accurate Windows 11 detection\n * should await this result and pass it to parseUA() as `options.windowsVersion`.\n */\nexport async function getWindowsVersion(nav: NavContext): Promise<string | null> {\n if (!nav.userAgentData || nav.userAgentData.platform !== 'Windows') {\n return null\n }\n try {\n const data = await nav.userAgentData.getHighEntropyValues(['platformVersion'])\n const major = parseInt(data['platformVersion']?.split('.')[0] || '0', 10)\n return major >= 13 ? '11' : '10'\n } catch {\n return null\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\nconst { version: VERSION } = pkg\nimport { parseUA } from './parse.js'\nimport { getNavContext, getLanguage } from './utils/navigator.js'\nimport type { EnvOption } from './types.js'\n\n// ── Named exports (tree-shakeable) ──────────────────────────────────────────\nexport type { EnvOption, BrowserName, OsName, EngineName, DeviceName, ArchName, BotName } from './types.js'\nexport { parseUA } from './parse.js'\nexport { getLanguage, getNavContext } from './utils/navigator.js'\nexport { getWindowsVersion } from './utils/windows-version.js'\nexport { detectBot } from './detectors/bot.js'\nexport { detectArch } from './detectors/arch.js'\nexport { detectHeadless } from './detectors/headless.js'\nexport { VERSION }\n\n/** Check whether a UA string indicates an Android webview environment. */\nexport const isWebview = (ua: string): boolean => /; wv/.test(ua)\n\n/** Check whether the current context is a WeChat mini-program. */\nexport const isWechatMiniapp = (): boolean => {\n try {\n return typeof __wxjs_environment !== 'undefined' && __wxjs_environment === 'miniprogram'\n } catch {\n return false\n }\n}\n\n// ── Default export — maintains v0.x call signature ──────────────────────────\n\n/**\n * Detect browser, OS, engine and device information.\n *\n * @param ua - Optional UA string override. Defaults to `navigator.userAgent`.\n */\nfunction uaBrowser(ua?: string): EnvOption {\n const nav = getNavContext()\n return parseUA(ua ?? nav.userAgent, { nav })\n}\n\nuaBrowser.isWebview = isWebview\nuaBrowser.isWechatMiniapp = isWechatMiniapp\nuaBrowser.getLanguage = (): string => getLanguage(getNavContext())\nuaBrowser.VERSION = VERSION\n\nexport default uaBrowser\n"]}
|
package/package.json
CHANGED