Compare commits

..

No commits in common. "master" and "2.0.4" have entirely different histories.

34 changed files with 1142 additions and 3372 deletions

View File

@ -65,35 +65,6 @@
--- ---
## Version 2.0.5
- Add new browser: Zalo
- Add new CPU arch: alpha
- Add new device vendor: Philips
- Improve device detection: Pico
- Fix parsing error on pages with modified Array prototypes
- Improve type declarations:
- Replace `node-fetch` dependency with `undici`
- Replace hardcoded string values with enum from `enum` submodule
- `enums` submodule:
- Add `Extension` enum for `extensions` submodule
- Type declaration file now automatically generated using build script
- Naming adjustments:
- `Browser` => `BrowserName`
- `CPU` => `CPUArch`
- `Device` => `DeviceType`
- `Vendor` => `DeviceVendor`
- `Engine` => `EngineName`
- `OS` => `OSName`
- `extensions` submodule:
- Add new crawlers:
APIs-Google, Algolia Crawler, Algolia Crawler Renderscript, Baidu-ADS, BLEXBot, botify, Bravebot, Claude-Web, cohere-training-data-crawler, contxbot, Cotoyogi, Coveobot, CriteoBot, DeepSeekBot, DuckDuckGo-Favicons-Bot, Elastic, FirecrawlAgent, Freespoke, Google-CloudVertexBot, HuggingFace-Bot, Kagibot, Kangaroo Bot, marginalia, msnbot, OnCrawl, Replicate-Bot, RunPod-Bot, SBIntuitionsBot, SeekportBot, Siteimprove, Sogou Pic Spider, TikTokSpider, TwinAgent, v0bot, webzio, Webzio-Extended, xAI-Bot, YandexAccessibilityBot, YandexAdditionalBot, YandexAdNet, YandexBot MirrorDetector, YandexBlogs, YandexComBot, YandexFavicons, YandexImageResizer, YandexImages, YandexMarket, YandexMetrika, YandexMedia, YandexMobileBot, YandexMobileScreenShotBot, YandexNews, YandexOntoDB, YandexOntoDBAPI, YandexPartner, YandexRCA, YandexRenderResourcesBot, YandexScreenshotBot, YandexSpravBot, YandexTracker, YandexVertis, YandexVerticals, YandexVideo, YandexVideoParser, YandexWebmaster, YepBot, ZumBot
- Add new fetchers:
Asana, bitlybot, Blueno, BufferLinkPreviewBot, Chrome-Lighthouse, Gemini-Deep-Research, HubSpot Page Fetcher, kakaotalk-scrap, vercel-favicon-bot, vercel-screenshot-bot, vercelflags, verceltracing, YaDirectFetcher, YandexCalendar, YandexDirect, YandexDirectDyn, YandexForDomain, YandexPagechecker, YandexSearchShop, YandexSitelinks, YandexUserproxy
- `helpers` submodule:
- Add some crawler to `isAIBot()`:
Bravebot, cohere-training-data-crawler, FirecrawlAgent, HuggingFace-Bot, Kangaroo Bot, PanguBot, Replicate-Bot, RunPod-Bot, TikTokSpider, Together-Bot, v0bot, xAI-Bot
## Version 2.0.4 ## Version 2.0.4
- Add new browser: Edge WebView, Edge WebView2 - Add new browser: Edge WebView, Edge WebView2
@ -269,16 +240,6 @@
--- ---
## Version 0.7.41 / 1.0.41
- Add new browser: Daum, Ladybird
- Add new device vendor: HMD
- Add new engine: LibWeb
- Add new os: Windows IoT, Ubuntu Touch
- Improve cpu detection: ARM, x86
- Improve device vendor detection: Apple, Archos, Generic, Google, Honor, Huawei, Infinix, Nvidia, Lenovo, Nokia, OnePlus, Xiaomi
- Improve device type detection: smarttv, wearables
- Improve os detection: Linux, Symbian
## Version 0.7.40 / 1.0.40 ## Version 0.7.40 / 1.0.40
- Add new browser: 115, LibreWolf, Slimboat, Slimjet - Add new browser: 115, LibreWolf, Slimboat, Slimjet
- Add new device: Advan, Cat, Energizer, IMO, Micromax, Smartfren - Add new device: Advan, Cat, Energizer, IMO, Micromax, Smartfren

View File

@ -12,12 +12,13 @@
<a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/v/ua-parser-js.svg?logo=npm&color=red&style=for-the-badge"></a> <a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/v/ua-parser-js.svg?logo=npm&color=red&style=for-the-badge"></a>
<a href="https://cdnjs.com/libraries/UAParser.js"><img src="https://img.shields.io/cdnjs/v/UAParser.js.svg?color=orange&style=for-the-badge"></a> <a href="https://cdnjs.com/libraries/UAParser.js"><img src="https://img.shields.io/cdnjs/v/UAParser.js.svg?color=orange&style=for-the-badge"></a>
<img src="https://img.shields.io/ossf-scorecard/github.com/faisalman/ua-parser-js?label=openssf%20scorecard&style=for-the-badge"> <img src="https://img.shields.io/ossf-scorecard/github.com/faisalman/ua-parser-js?label=openssf%20scorecard&style=for-the-badge">
<a target="_blank" href="https://discord.gg/stt86vmr"><img alt="Discord invite" src="https://dcbadge.limes.pink/api/server/https://discord.gg/stt86vmr"></a>
</p> </p>
# UAParser.js # UAParser.js
The most comprehensive, compact, and up-to-date JavaScript library to detect user's browser, OS, CPU, and device type/model. Also detect bots, apps, and more. Runs seamlessly in the browser (client-side) or Node.js (server-side). The most comprehensive, compact, & up-to-date isomorphic JavaScript library to detect
user's Browser, Engine, OS, CPU, and Device type/model. Runs either in browser
(client-side) or node.js (server-side).
# Demo # Demo
@ -32,7 +33,7 @@ The most comprehensive, compact, and up-to-date JavaScript library to detect use
Before upgrading from `v0.7` / `v1.0`, please read [CHANGELOG](CHANGELOG.md) to Before upgrading from `v0.7` / `v1.0`, please read [CHANGELOG](CHANGELOG.md) to
see what's new & breaking. see what's new & breaking.
# Package & Pricing # License Options
<table> <table>
<thead> <thead>
@ -45,8 +46,8 @@ see what's new & breaking.
<tbody> <tbody>
<tr> <tr>
<td>License options</td> <td>License options</td>
<td>MIT (v1.x)</td> <td>MIT (v0.7~v1.0)</td>
<td>AGPL (v2.x)</td> <td>AGPL (&gt;=v2.0)</td>
<td>PRO Personal</td> <td>PRO Personal</td>
<td>PRO Business</td> <td>PRO Business</td>
<td>PRO Enterprise</td> <td>PRO Enterprise</td>
@ -147,6 +148,14 @@ see what's new & breaking.
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>npm module</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr> <tr>
<td>TypeScript declarations</td> <td>TypeScript declarations</td>
<td><a href="#demo" title="Community version">⚠️</a></td> <td><a href="#demo" title="Community version">⚠️</a></td>
@ -156,23 +165,7 @@ see what's new & breaking.
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>npm module available</td> <td>Allows commercial use</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Direct downloads available</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Allows commercial usage</td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@ -188,27 +181,11 @@ see what's new & breaking.
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>No open-source obligations</td> <td>Unlimited use per 1 license</td>
<td></td>
<td><strong title="Copyleft license"></strong></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> <td><strong title="1 project per 1 license"></strong></td>
<tr>
<td>Unlimited end-products</td>
<td></td>
<td></td>
<td></td>
<td><strong title="1 end-product per license"></strong></td>
<td></td>
</tr>
<tr>
<td>Unlimited deployments</td>
<td></td>
<td></td>
<td></td>
<td><strong title="1 TLD or deliverable per license"></strong></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -229,8 +206,8 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>Price</td> <td>Price</td>
<td><strong title="Pay as you want">FREE<sup>*</sup> (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/1.0.x/license.md">License</a>)</strong></td> <td><strong title="Pay as you want">FREE (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/1.0.x/license.md">License</a>)</strong></td>
<td><strong title="Pay as you want">FREE<sup>*</sup> (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/master/LICENSE.md">License</a>)</strong></td> <td><strong title="Pay as you want">FREE (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/master/LICENSE.md">License</a>)</strong></td>
<td><strong title="$14 (one-time fee)">$14 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-personal/LICENSE.md">License</a>)</strong></td> <td><strong title="$14 (one-time fee)">$14 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-personal/LICENSE.md">License</a>)</strong></td>
<td><strong title="$29 (one-time fee)">$29 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-business/LICENSE.md">License</a>)</strong></td> <td><strong title="$29 (one-time fee)">$29 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-business/LICENSE.md">License</a>)</strong></td>
<td><strong title="$599 (one-time fee)">$599 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-enterprise/LICENSE.md">License</a>)</strong></td> <td><strong title="$599 (one-time fee)">$599 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-enterprise/LICENSE.md">License</a>)</strong></td>
@ -259,7 +236,10 @@ Made with [contributors-img](https://contrib.rocks).
## Backers & Sponsors ## Backers & Sponsors
Support the **open-source editions** of UAParser.js through one of the following options: <a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/organizations.svg?avatarHeight=64"></a>
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/individuals.svg?avatarHeight=64"></a>
You can support the open-source editions of UAParser.js through one of the following options:
[![OpenCollective](https://img.shields.io/badge/OpenCollective-dddddd?style=for-the-badge&logo=opencollective&color=dddddd [![OpenCollective](https://img.shields.io/badge/OpenCollective-dddddd?style=for-the-badge&logo=opencollective&color=dddddd
)](https://opencollective.com/ua-parser-js) )](https://opencollective.com/ua-parser-js)
@ -268,7 +248,4 @@ Support the **open-source editions** of UAParser.js through one of the following
[![PayPal](https://img.shields.io/badge/Paypal-003087?style=for-the-badge&logo=paypal&color=003087 [![PayPal](https://img.shields.io/badge/Paypal-003087?style=for-the-badge&logo=paypal&color=003087
)](https://paypal.me/faisalman) )](https://paypal.me/faisalman)
[![WeChat/Alipay](https://img.shields.io/badge/Other_Payment_Methods-Alipay_/_WeChat_Pay-09b83e?style=for-the-badge&logo=mastercard&color=09b83e [![WeChat/Alipay](https://img.shields.io/badge/Other_Payment_Methods-Alipay_/_WeChat_Pay-09b83e?style=for-the-badge&logo=mastercard&color=09b83e
)](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be) )](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be)
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/organizations.svg?avatarHeight=64"></a>
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/individuals.svg?avatarHeight=64"></a>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

132
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.5", "version": "2.0.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.5", "version": "2.0.4",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -23,10 +23,11 @@
], ],
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@types/node-fetch": "^2.6.12",
"detect-europe-js": "^0.1.2", "detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1", "is-standalone-pwa": "^0.1.1",
"ua-is-frozen": "^0.1.2", "node-fetch": "^2.7.0",
"undici": "^7.12.0" "ua-is-frozen": "^0.1.2"
}, },
"bin": { "bin": {
"ua-parser-js": "script/cli.js" "ua-parser-js": "script/cli.js"
@ -401,6 +402,23 @@
"integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
"dev": true "dev": true
}, },
"node_modules/@types/node": {
"version": "22.13.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
"dependencies": {
"undici-types": "~6.20.0"
}
},
"node_modules/@types/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@types/normalize-package-data": { "node_modules/@types/normalize-package-data": {
"version": "2.4.4", "version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
@ -501,6 +519,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -641,6 +664,17 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true "dev": true
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -719,6 +753,14 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/detect-europe-js": { "node_modules/detect-europe-js": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz", "resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz",
@ -969,6 +1011,19 @@
"flat": "cli.js" "flat": "cli.js"
} }
}, },
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -1536,6 +1591,25 @@
"node": ">=8.6" "node": ">=8.6"
} }
}, },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/min-indent": { "node_modules/min-indent": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@ -1889,6 +1963,25 @@
"node": "^10 || ^12 || >=13.7" "node": "^10 || ^12 || >=13.7"
} }
}, },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/normalize-package-data": { "node_modules/normalize-package-data": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@ -2620,6 +2713,11 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/trim-newlines": { "node_modules/trim-newlines": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
@ -2693,14 +2791,10 @@
"node": ">=0.8.0" "node": ">=0.8.0"
} }
}, },
"node_modules/undici": { "node_modules/undici-types": {
"version": "7.12.0", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.12.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
"license": "MIT",
"engines": {
"node": ">=20.18.1"
}
}, },
"node_modules/validate-npm-package-license": { "node_modules/validate-npm-package-license": {
"version": "3.0.4", "version": "3.0.4",
@ -2712,6 +2806,20 @@
"spdx-expression-parse": "^3.0.0" "spdx-expression-parse": "^3.0.0"
} }
}, },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which": { "node_modules/which": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@ -1,7 +1,7 @@
{ {
"title": "UAParser.js", "title": "UAParser.js",
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.5", "version": "2.0.4",
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)", "author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
"keywords": [ "keywords": [
@ -227,7 +227,8 @@
"detect-europe-js": "^0.1.2", "detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1", "is-standalone-pwa": "^0.1.1",
"ua-is-frozen": "^0.1.2", "ua-is-frozen": "^0.1.2",
"undici": "^7.12.0" "node-fetch": "^2.7.0",
"@types/node-fetch": "^2.6.12"
}, },
"devDependencies": { "devDependencies": {
"@babel/parser": "7.15.8", "@babel/parser": "7.15.8",

View File

@ -2,18 +2,15 @@
/* jshint esversion: 6 */ /* jshint esversion: 6 */
const fs = require('fs'); const fs = require('fs');
const defaultReplacements = { const generateMJS = (module) => {
mjs: [
[/const (.+?)\s*=\s*require\(\'\.(.+)\'\)/ig, 'import $1 from \'\.$2.mjs\''],
[/const (.+?)\s*=\s*require\(\'(.+)\'\)/ig, 'import $1 from \'$2\''],
[/module\.exports =/ig, 'export']
]
}
const generateFile = (module) => {
let { src, dest, title, replacements } = module; let { src, dest, title, replacements } = module;
let text = fs.readFileSync(src, 'utf-8'); let text = fs.readFileSync(src, 'utf-8');
replacements.push(
[/const (.+?)\s*=\s*require\(\'\.(.+)\'\)/ig, 'import $1 from \'\.$2.mjs\''],
[/const (.+?)\s*=\s*require\(\'(.+)\'\)/ig, 'import $1 from \'$2\''],
[/module\.exports =/ig, 'export']
);
replacements.forEach(rep => { replacements.forEach(rep => {
text = text.replace(rep[0], rep[1]); text = text.replace(rep[0], rep[1]);
}); });
@ -21,54 +18,42 @@ const generateFile = (module) => {
console.log(`Generate ${dest}`); console.log(`Generate ${dest}`);
fs.writeFileSync(dest, fs.writeFileSync(dest,
`// ${title} `// Generated ESM version of ${title}
// DO NOT EDIT THIS FILE! // DO NOT EDIT THIS FILE!
// Source: /${src} // Source: /${src}
${text}`, 'utf-8'); ${text}`, 'utf-8');
}; };
const files = [ const modules = [
{ {
src : 'src/main/ua-parser.js', src : 'src/main/ua-parser.js',
dest : 'src/main/ua-parser.mjs', dest : 'src/main/ua-parser.mjs',
title : 'Generated ESM version of ua-parser-js', title : 'ua-parser-js',
replacements : [ replacements : [
[/\(func[\s\S]+strict\';/ig, ''], [/\(func[\s\S]+strict\';/ig, ''],
[/esversion\: 3/ig, 'esversion: 6'], [/esversion\: 3/ig, 'esversion: 6'],
[/\/[\/\s]+export[\s\S]+/ig,'export {UAParser};'], [/\/[\/\s]+export[\s\S]+/ig,'export {UAParser};']
...defaultReplacements.mjs
] ]
}, },{
{
src : 'src/enums/ua-parser-enums.js', src : 'src/enums/ua-parser-enums.js',
dest :'src/enums/ua-parser-enums.mjs', dest :'src/enums/ua-parser-enums.mjs',
title : 'Generated ESM version of ua-parser-js/enums', title : 'ua-parser-js/enums',
replacements : [...defaultReplacements.mjs] replacements : []
},
{
src : 'src/enums/ua-parser-enums.js',
dest :'src/enums/ua-parser-enums.d.ts',
title : 'Generated type declarations of ua-parser-js/enums',
replacements : [
[/(const .+) = object\.freeze\(/ig, 'export $1: Readonly<'],
[/(const .+) =( .+;)/ig, 'export $1: typeof$2'],
[/}\);/ig, '}>;'],
[/module\.exports =.+/igs, '']
]
}, },
{ {
src : 'src/extensions/ua-parser-extensions.js', src : 'src/extensions/ua-parser-extensions.js',
dest : 'src/extensions/ua-parser-extensions.mjs', dest : 'src/extensions/ua-parser-extensions.mjs',
title : 'Generated ESM version of ua-parser-js/extensions', title : 'ua-parser-js/extensions',
replacements : [...defaultReplacements.mjs] replacements : []
}, },
{ {
src : 'src/helpers/ua-parser-helpers.js', src : 'src/helpers/ua-parser-helpers.js',
dest : 'src/helpers/ua-parser-helpers.mjs', dest : 'src/helpers/ua-parser-helpers.mjs',
title : 'Generated ESM version of ua-parser-js/helpers', title : 'ua-parser-js/helpers',
replacements : [...defaultReplacements.mjs] replacements : []
} }
]; ];
files.forEach(module => generateFile(module)); modules.forEach(module => generateMJS(module));

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.5 /* Enums for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -7,7 +7,7 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const BrowserName = Object.freeze({ const Browser = Object.freeze({
'115': '115', '115': '115',
'2345': '2345', '2345': '2345',
'360': '360', '360': '360',
@ -158,15 +158,10 @@ const BrowserName = Object.freeze({
WEIBO: 'Weibo', WEIBO: 'Weibo',
WHALE: 'Whale', WHALE: 'Whale',
WOLVIC: 'Wolvic', WOLVIC: 'Wolvic',
YANDEX: 'Yandex', YANDEX: 'Yandex'
ZALO: 'Zalo'
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `BrowserName` instead
*/
const Browser = BrowserName;
const BrowserType = Object.freeze({ const BrowserType = Object.freeze({
CRAWLER: 'crawler', CRAWLER: 'crawler',
@ -178,9 +173,8 @@ const BrowserType = Object.freeze({
LIBRARY: 'library' LIBRARY: 'library'
}); });
const CPUArch = Object.freeze({ const CPU = Object.freeze({
'68K': '68k', '68K': '68k',
ALPHA: 'alpha',
ARM : 'arm', ARM : 'arm',
ARM_64: 'arm64', ARM_64: 'arm64',
ARM_HF: 'armhf', ARM_HF: 'armhf',
@ -198,12 +192,8 @@ const CPUArch = Object.freeze({
X86: 'ia32', X86: 'ia32',
X86_64: 'amd64' X86_64: 'amd64'
}); });
/**
* @deprecated Use `CPUArch` instead
*/
const CPU = CPUArch;
const DeviceType = Object.freeze({ const Device = Object.freeze({
CONSOLE: 'console', CONSOLE: 'console',
DESKTOP: 'desktop', DESKTOP: 'desktop',
EMBEDDED: 'embedded', EMBEDDED: 'embedded',
@ -213,12 +203,8 @@ const DeviceType = Object.freeze({
WEARABLE: 'wearable', WEARABLE: 'wearable',
XR: 'xr' XR: 'xr'
}); });
/**
* @deprecated Use `DeviceType` instead
*/
const Device = DeviceType;
const DeviceVendor = Object.freeze({ const Vendor = Object.freeze({
ACER: 'Acer', ACER: 'Acer',
ADVAN: 'Advan', ADVAN: 'Advan',
ALCATEL: 'Alcatel', ALCATEL: 'Alcatel',
@ -266,7 +252,6 @@ const DeviceVendor = Object.freeze({
PALM: 'Palm', PALM: 'Palm',
PANASONIC: 'Panasonic', PANASONIC: 'Panasonic',
PEBBLE: 'Pebble', PEBBLE: 'Pebble',
PHILIPS: 'Philips',
PICO: 'Pico', PICO: 'Pico',
POLYTRON: 'Polytron', POLYTRON: 'Polytron',
REALME: 'Realme', REALME: 'Realme',
@ -281,7 +266,7 @@ const DeviceVendor = Object.freeze({
SPRINT: 'Sprint', SPRINT: 'Sprint',
TCL: 'TCL', TCL: 'TCL',
TECHNISAT: 'TechniSAT', TECHNISAT: 'TechniSAT',
TECNO: 'TECNO', TECNO: 'Tecno',
TESLA: 'Tesla', TESLA: 'Tesla',
ULEFONE: 'Ulefone', ULEFONE: 'Ulefone',
VIVO: 'Vivo', VIVO: 'Vivo',
@ -294,12 +279,8 @@ const DeviceVendor = Object.freeze({
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `DeviceVendor` instead
*/
const Vendor = DeviceVendor;
const EngineName = Object.freeze({ const Engine = Object.freeze({
AMAYA: 'Amaya', AMAYA: 'Amaya',
ARKWEB: 'ArkWeb', ARKWEB: 'ArkWeb',
BLINK: 'Blink', BLINK: 'Blink',
@ -321,12 +302,8 @@ const EngineName = Object.freeze({
W3M: 'w3m', W3M: 'w3m',
WEBKIT: 'WebKit' WEBKIT: 'WebKit'
}); });
/**
* @deprecated Use `EngineName` instead
*/
const Engine = EngineName;
const OSName = Object.freeze({ const OS = Object.freeze({
AIX: 'AIX', AIX: 'AIX',
AMIGA_OS: 'Amiga OS', AMIGA_OS: 'Amiga OS',
ANDROID: 'Android', ANDROID: 'Android',
@ -422,322 +399,13 @@ const OSName = Object.freeze({
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `OSName` instead
*/
const OS = OSName;
/*////////////////////////////////
* Enums for Extensions submodule
*///////////////////////////////
const Extension = Object.freeze({
BrowserName: {
CLI: {
CURL: 'curl',
ELINKS: 'ELinks',
HTTPIE: 'HTTPie',
LYNX: 'Lynx',
WGET: 'Wget'
},
Crawler: {
AHREFS_BOT: 'AhrefsBot',
AI2_BOT: 'AI2Bot',
AIHIT_BOT: 'aiHitBot',
ALGOLIA_CRAWLER: 'Algolia Crawler',
APPLE_BOT: 'Applebot',
APPLE_BOT_EXTENDED: 'Applebot-Extended',
ASK_TEOMA: 'Teoma',
AMAZON_BOT: 'Amazonbot',
AMAZON_CONTXBOT: 'contxbot',
ANTHROPIC_AI: 'anthropic-ai',
ANTHROPIC_CLAUDE_BOT: 'ClaudeBot',
ANTHROPIC_CLAUDE_SEARCHBOT: 'Claude-SearchBot',
ANTHROPIC_CLAUDE_WEB: 'Claude-Web',
ARCHIVEORG_BOT: 'archive.org_bot',
BAIDU_ADS: 'Baidu-ADS',
BAIDU_SPIDER: 'Baiduspider',
BAIDU_SPIDER_ADS: 'Baiduspider-ads',
BAIDU_SPIDER_CPRO: 'Baiduspider-cpro',
BAIDU_SPIDER_FAVO: 'Baiduspider-favo',
BAIDU_SPIDER_IMAGE: 'Baiduspider-image',
BAIDU_SPIDER_NEWS: 'Baiduspider-news',
BAIDU_SPIDER_RENDER: 'Baiduspider-render',
BAIDU_SPIDER_VIDEO: 'Baiduspider-video',
BLEX_BOT: 'BLEXBot',
BOTIFY: 'botify',
BRAVE_BOT: 'Bravebot',
BYTEDANCE_BYTESPIDER: 'Bytespider',
BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
COMMON_CRAWL_CCBOT: 'CCBot',
COCCOC_BOT_WEB: 'coccocbot-web',
COCCOC_BOT_IMAGE: 'coccocbot-image',
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
COTOYOGI: 'Cotoyogi',
COVEO_BOT: 'Coveobot',
CRITEO_BOT: 'CriteoBot',
DATAFORSEO_BOT: 'DataForSeoBot',
DAUM: 'Daum',
DAUM_DAUMOA: 'Daumoa',
DAUM_DAUMOA_IMAGE: 'Daumoa-image',
DEEPSEEK_BOT: 'DeepSeekBot',
DIFFBOT: 'Diffbot',
DUCKDUCKGO_BOT: 'DuckDuckBot',
DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
ELASTIC: 'Elastic',
EXALEAD_EXABOT: 'Exabot',
FIRECRAWL_AGENT: 'FirecrawlAgent',
FREESPOKE: 'Freespoke',
GOOGLE_ADSBOT: 'AdsBot-Google',
GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
GOOGLE_ADSENSE: 'AdSense',
GOOGLE_APIS: 'APIs-Google',
GOOGLE_BOT: 'Googlebot',
GOOGLE_BOT_IMAGE: 'Googlebot-Image',
GOOGLE_BOT_NEWS: 'Googlebot-News',
GOOGLE_BOT_VIDEO: 'Googlebot-Video',
GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
GOOGLE_EXTENDED: 'Google-Extended',
GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
GOOGLE_OTHER: 'GoogleOther',
GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
GOOGLE_OTHER_VIDEO: 'GoogleOther-Video',
GOOGLE_SAFETY: 'Google-Safety',
GOOGLE_STOREBOT: 'Storebot-Google',
HIVE_IMAGESIFTBOT: 'ImagesiftBot',
HUAWEI_PANGUBOT: 'PanguBot',
HUAWEI_PETALBOT: 'PetalBot',
HUGGINGFACE_BOT: 'HuggingFace-Bot',
HUNTER_VELENPUBLICWEBCRAWLER: 'VelenPublicWebCrawler',
IA_ARCHIVER: 'ia_archiver',
IASK_BOT: 'iAskBot',
KAGI_BOT: 'Kagibot',
KANGAROO_BOT: 'Kangaroo Bot',
LINE_SPIDER: 'Linespider',
LINKEDIN_BOT: 'LinkedInBot',
MAGPIE_CRAWLER: 'magpie-crawler',
MARGINALIA: 'marginalia',
META_EXTERNALAGENT: 'meta-externalagent',
META_FACEBOOKBOT: 'FacebookBot',
META_FACEBOOKCATALOG: 'facebookcatalog',
META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',
MAJESTIC_MJ12BOT: 'MJ12bot',
MICROSOFT_BINGBOT: 'Bingbot',
MICROSOFT_MSNBOT: 'msnbot',
MICROSOFT_ADIDXBOT: 'adidxbot',
MOJEEK_BOT: 'MojeekBot',
MOZ_DOTBOT: 'DotBot',
ONCRAWL: 'OnCrawl',
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
OPENAI_GPTBOT: 'GPTBot',
OPENAI_SEARCH_BOT: 'OAI-SearchBot',
PERPLEXITY_BOT: 'PerplexityBot',
QIHOO_360_SPIDER: '360Spider',
QWANT_BOT: 'Qwantbot',
REPLICATE_BOT: 'Replicate-Bot',
RUNPOD_BOT: 'RunPod-Bot',
SB_INTUITIONS_BOT: 'SBIntuitionsBot',
SEEKPORT_BOT: 'SeekportBot',
SEMRUSH_BOT: 'SemrushBot',
SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
SEMRUSH_BOT_CONTENTSHAKE: 'SemrushBot-OCOB',
SEMRUSH_BOT_SEO_CHECKER: 'SemrushBot-SI',
SEZNAM_BOT: 'SeznamBot',
SITEIMPROVE: 'Siteimprove',
SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
SOGOU_WEB_SPIDER: 'Sogou web spider',
STARTPAGE: 'Startpage',
TIMPI_BOT: 'Timpibot',
TOGETHER_BOT: 'Together-Bot',
TURNITIN_BOT: 'TurnitinBot',
TWIN_AGENT: 'TwinAgent',
VERCEL_V0BOT: 'v0bot',
WEBZIO: 'webzio',
WEBZIO_EXTENDED: 'Webzio-Extended',
WEBZIO_OMGILI: 'omgili',
WEBZIO_OMGILI_BOT: 'omgilibot',
XAI_BOT: 'xAI-Bot',
YAHOO_JAPAN: 'Y!J-BRW',
YAHOO_SLURP: 'Yahoo! Slurp',
YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
YANDEX_ADNET: 'YandexAdNet',
YANDEX_BLOGS: 'YandexBlogs',
YANDEX_BOT: 'YandexBot',
YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
YANDEX_COMBOT: 'YandexComBot',
YANDEX_FAVICONS: 'YandexFavicons',
YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
YANDEX_IMAGES: 'YandexImages',
YANDEX_MARKET: 'YandexMarket',
YANDEX_MEDIA: 'YandexMedia',
YANDEX_METRIKA: 'YandexMetrika',
YANDEX_MOBILE_BOT: 'YandexMobileBot',
YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
YANDEX_NEWS: 'YandexNews',
YANDEX_ONTODB: 'YandexOntoDB',
YANDEX_ONTODB_API: 'YandexOntoDBAPI',
YANDEX_PARTNER: 'YandexPartner',
YANDEX_RCA: 'YandexRCA',
YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
YANDEX_SPRAV_BOT: 'YandexSpravBot',
YANDEX_TRACKER: 'YandexTracker',
YANDEX_VERTICALS: 'YandexVerticals',
YANDEX_VERTIS: 'YandexVertis',
YANDEX_VIDEO: 'YandexVideo',
YANDEX_VIDEO_PARSER: 'YandexVideoParser',
YANDEX_WEBMASTER: 'YandexWebmaster',
YEP_BOT: 'YepBot',
YETI: 'Yeti',
YISOU_SPIDER: 'YisouSpider',
YOU_BOT: 'YouBot',
ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
ZUM_BOT: 'ZumBot'
},
Email: {
AIRMAIL: 'Airmail',
APPLE_MAIL: 'Mail',
BLUEMAIL: 'BlueMail',
DAUM_MAIL: 'DaumMail',
EVOLUTION: 'Evolution',
EM_CLIENT: 'eM Client',
FOXMAIL: 'Foxmail',
KMAIL: 'KMail',
KMAIL2: 'kmail2',
KONTACT: 'Kontact',
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
NAVER_MAILAPP: 'NaverMailApp',
POLYMAIL: 'Polymail',
PROTON_MAIL: 'ProtonMail',
SPARK_MAIL: 'SparkDesktop',
SPARROW: 'Sparrow',
THUNDERBIRD: 'Thunderbird',
YAHOO_MAIL: 'Yahoo',
ZIMBRA: 'Zimbra',
ZOHO_MAIL: 'ZohoMail-Desktop'
},
Fetcher: {
AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
ANTHROPIC_CLAUDE_USER: 'Claude-User',
ASANA: 'Asana',
BETTER_UPTIME_BOT: 'Better Uptime Bot',
BITLY_BOT: 'bitlybot',
BLUESKY: 'Bluesky',
BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
COHERE_AI: 'Cohere-AI',
DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
GOOGLE_PRODUCER: 'GoogleProducer',
GOOGLE_SITE_VERIFICATION: 'Google-Site-Verification',
HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
IFRAMELY: 'Iframely',
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
META_EXTERNALFETCHER: 'meta-externalfetcher',
META_WHATSAPP: 'WhatsApp',
MICROSOFT_BINGPREVIEW: 'BingPreview',
MICROSOFT_PREVIEW: 'MicrosoftPreview',
MISTRALAI_USER: 'MistralAI-User',
NAVER_BLUENO: 'Blueno',
ONCRAWL_ROGERBOT: 'rogerbot',
OPENAI_CHATGPT_USER: 'ChatGPT-User',
PERPLEXITY_USER: 'Perplexity-User',
PINTEREST_BOT: 'Pinterestbot',
SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
SNAP_URL_PREVIEW: 'Snap URL Preview',
SKYPE_URIPREVIEW: 'SkypeUriPreview',
TELEGRAM_BOT: 'TelegramBot',
UPTIMEROBOT: 'UptimeRobot',
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
VERCEL_BOT: 'Vercelbot',
VERCEL_FLAGS: 'vercelflags',
VERCEL_TRACING: 'verceltracing',
YANDEX_CALENDAR: 'YandexCalendar',
YANDEX_DIRECT: 'YandexDirect',
YANDEX_DIRECTDYN: 'YandexDirectDyn',
YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
YANDEX_FORDOMAIN: 'YandexForDomain',
YANDEX_PAGECHECKER: 'YandexPagechecker',
YANDEX_SEARCHSHOP: 'YandexSearchShop',
YANDEX_SITELINKS: 'YandexSitelinks',
YANDEX_USERPROXY: 'YandexUserproxy',
ZOOMINFO_BOT: 'Zoombot'
},
InApp: {
DISCORD: 'Discord',
EVERNOTE: 'Evernote',
FIGMA: 'Figma',
FLIPBOARD: 'Flipboard',
MATTERMOST: 'Mattermost',
TEAMS: 'Teams',
NOTION: 'Notion',
POSTMAN: 'Postman',
RAMBOX: 'Rambox',
ROCKETCHAT: 'Rocket.Chat',
SLACK: 'Slack',
TIKTOK_LITE: 'TikTok Lite',
VSCODE: 'VS Code',
YAHOO_JAPAN: 'Yahoo! Japan'
},
Library: {
ADOBE_AIR: 'AdobeAIR',
AIOHTTP: 'aiohttp',
APACHE_HTTPCLIENT: 'Apache-HttpClient',
AXIOS: 'axios',
GO_HTTP_CLIENT: 'go-http-client',
GOT: 'got',
GUZZLEHTTP: 'GuzzleHttp',
JAVA: 'Java',
JAVA_HTTPCLIENT: 'Java-http-client',
JSDOM: 'jsdom',
LIBWWW_PERL: 'libwww-perl',
LUA_RESTY_HTTP: 'lua-resty-http',
NEEDLE: 'Needle',
NUTCH: 'Nutch',
OKHTTP: 'OkHttp',
NODE_FETCH: 'node-fetch',
NODE_SUPERAGENT: 'node-superagent',
PHP_SOAP: 'PHP-SOAP',
POSTMAN_RUNTIME: 'PostmanRuntime',
PYTHON_HTTPX: 'python-httpx',
PYTHON_URLLIB: 'python-urllib',
PYTHON_URLLIB3: 'python-urllib3',
PYTHON_REQUESTS: 'python-requests',
SCRAPY: 'Scrapy'
}
},
DeviceVendor: {
Vehicle: {
BMW: 'BMW',
BYD: 'BYD',
JEEP: 'Jeep',
RIVIAN: 'Rivian',
TESLA: 'Tesla',
VOLVO: 'Volvo'
}
}
});
module.exports = { module.exports = {
Browser,// deprecated Browser,
CPU, // deprecated
Device, // deprecated
Vendor, // deprecated
Engine, // deprecated
OS, // deprecated
BrowserName,
BrowserType, BrowserType,
CPUArch, CPU,
DeviceType, Device,
DeviceVendor, Vendor,
EngineName, Engine,
OSName, OS
Extension
}; };

View File

@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js // Source: /src/enums/ua-parser-enums.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.5 /* Enums for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -11,7 +11,7 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const BrowserName = Object.freeze({ const Browser = Object.freeze({
'115': '115', '115': '115',
'2345': '2345', '2345': '2345',
'360': '360', '360': '360',
@ -162,15 +162,10 @@ const BrowserName = Object.freeze({
WEIBO: 'Weibo', WEIBO: 'Weibo',
WHALE: 'Whale', WHALE: 'Whale',
WOLVIC: 'Wolvic', WOLVIC: 'Wolvic',
YANDEX: 'Yandex', YANDEX: 'Yandex'
ZALO: 'Zalo'
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `BrowserName` instead
*/
const Browser = BrowserName;
const BrowserType = Object.freeze({ const BrowserType = Object.freeze({
CRAWLER: 'crawler', CRAWLER: 'crawler',
@ -182,9 +177,8 @@ const BrowserType = Object.freeze({
LIBRARY: 'library' LIBRARY: 'library'
}); });
const CPUArch = Object.freeze({ const CPU = Object.freeze({
'68K': '68k', '68K': '68k',
ALPHA: 'alpha',
ARM : 'arm', ARM : 'arm',
ARM_64: 'arm64', ARM_64: 'arm64',
ARM_HF: 'armhf', ARM_HF: 'armhf',
@ -202,12 +196,8 @@ const CPUArch = Object.freeze({
X86: 'ia32', X86: 'ia32',
X86_64: 'amd64' X86_64: 'amd64'
}); });
/**
* @deprecated Use `CPUArch` instead
*/
const CPU = CPUArch;
const DeviceType = Object.freeze({ const Device = Object.freeze({
CONSOLE: 'console', CONSOLE: 'console',
DESKTOP: 'desktop', DESKTOP: 'desktop',
EMBEDDED: 'embedded', EMBEDDED: 'embedded',
@ -217,12 +207,8 @@ const DeviceType = Object.freeze({
WEARABLE: 'wearable', WEARABLE: 'wearable',
XR: 'xr' XR: 'xr'
}); });
/**
* @deprecated Use `DeviceType` instead
*/
const Device = DeviceType;
const DeviceVendor = Object.freeze({ const Vendor = Object.freeze({
ACER: 'Acer', ACER: 'Acer',
ADVAN: 'Advan', ADVAN: 'Advan',
ALCATEL: 'Alcatel', ALCATEL: 'Alcatel',
@ -270,7 +256,6 @@ const DeviceVendor = Object.freeze({
PALM: 'Palm', PALM: 'Palm',
PANASONIC: 'Panasonic', PANASONIC: 'Panasonic',
PEBBLE: 'Pebble', PEBBLE: 'Pebble',
PHILIPS: 'Philips',
PICO: 'Pico', PICO: 'Pico',
POLYTRON: 'Polytron', POLYTRON: 'Polytron',
REALME: 'Realme', REALME: 'Realme',
@ -285,7 +270,7 @@ const DeviceVendor = Object.freeze({
SPRINT: 'Sprint', SPRINT: 'Sprint',
TCL: 'TCL', TCL: 'TCL',
TECHNISAT: 'TechniSAT', TECHNISAT: 'TechniSAT',
TECNO: 'TECNO', TECNO: 'Tecno',
TESLA: 'Tesla', TESLA: 'Tesla',
ULEFONE: 'Ulefone', ULEFONE: 'Ulefone',
VIVO: 'Vivo', VIVO: 'Vivo',
@ -298,12 +283,8 @@ const DeviceVendor = Object.freeze({
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `DeviceVendor` instead
*/
const Vendor = DeviceVendor;
const EngineName = Object.freeze({ const Engine = Object.freeze({
AMAYA: 'Amaya', AMAYA: 'Amaya',
ARKWEB: 'ArkWeb', ARKWEB: 'ArkWeb',
BLINK: 'Blink', BLINK: 'Blink',
@ -325,12 +306,8 @@ const EngineName = Object.freeze({
W3M: 'w3m', W3M: 'w3m',
WEBKIT: 'WebKit' WEBKIT: 'WebKit'
}); });
/**
* @deprecated Use `EngineName` instead
*/
const Engine = EngineName;
const OSName = Object.freeze({ const OS = Object.freeze({
AIX: 'AIX', AIX: 'AIX',
AMIGA_OS: 'Amiga OS', AMIGA_OS: 'Amiga OS',
ANDROID: 'Android', ANDROID: 'Android',
@ -426,322 +403,13 @@ const OSName = Object.freeze({
// TODO : test! // TODO : test!
}); });
/**
* @deprecated Use `OSName` instead
*/
const OS = OSName;
/*////////////////////////////////
* Enums for Extensions submodule
*///////////////////////////////
const Extension = Object.freeze({
BrowserName: {
CLI: {
CURL: 'curl',
ELINKS: 'ELinks',
HTTPIE: 'HTTPie',
LYNX: 'Lynx',
WGET: 'Wget'
},
Crawler: {
AHREFS_BOT: 'AhrefsBot',
AI2_BOT: 'AI2Bot',
AIHIT_BOT: 'aiHitBot',
ALGOLIA_CRAWLER: 'Algolia Crawler',
APPLE_BOT: 'Applebot',
APPLE_BOT_EXTENDED: 'Applebot-Extended',
ASK_TEOMA: 'Teoma',
AMAZON_BOT: 'Amazonbot',
AMAZON_CONTXBOT: 'contxbot',
ANTHROPIC_AI: 'anthropic-ai',
ANTHROPIC_CLAUDE_BOT: 'ClaudeBot',
ANTHROPIC_CLAUDE_SEARCHBOT: 'Claude-SearchBot',
ANTHROPIC_CLAUDE_WEB: 'Claude-Web',
ARCHIVEORG_BOT: 'archive.org_bot',
BAIDU_ADS: 'Baidu-ADS',
BAIDU_SPIDER: 'Baiduspider',
BAIDU_SPIDER_ADS: 'Baiduspider-ads',
BAIDU_SPIDER_CPRO: 'Baiduspider-cpro',
BAIDU_SPIDER_FAVO: 'Baiduspider-favo',
BAIDU_SPIDER_IMAGE: 'Baiduspider-image',
BAIDU_SPIDER_NEWS: 'Baiduspider-news',
BAIDU_SPIDER_RENDER: 'Baiduspider-render',
BAIDU_SPIDER_VIDEO: 'Baiduspider-video',
BLEX_BOT: 'BLEXBot',
BOTIFY: 'botify',
BRAVE_BOT: 'Bravebot',
BYTEDANCE_BYTESPIDER: 'Bytespider',
BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
COMMON_CRAWL_CCBOT: 'CCBot',
COCCOC_BOT_WEB: 'coccocbot-web',
COCCOC_BOT_IMAGE: 'coccocbot-image',
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
COTOYOGI: 'Cotoyogi',
COVEO_BOT: 'Coveobot',
CRITEO_BOT: 'CriteoBot',
DATAFORSEO_BOT: 'DataForSeoBot',
DAUM: 'Daum',
DAUM_DAUMOA: 'Daumoa',
DAUM_DAUMOA_IMAGE: 'Daumoa-image',
DEEPSEEK_BOT: 'DeepSeekBot',
DIFFBOT: 'Diffbot',
DUCKDUCKGO_BOT: 'DuckDuckBot',
DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
ELASTIC: 'Elastic',
EXALEAD_EXABOT: 'Exabot',
FIRECRAWL_AGENT: 'FirecrawlAgent',
FREESPOKE: 'Freespoke',
GOOGLE_ADSBOT: 'AdsBot-Google',
GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
GOOGLE_ADSENSE: 'AdSense',
GOOGLE_APIS: 'APIs-Google',
GOOGLE_BOT: 'Googlebot',
GOOGLE_BOT_IMAGE: 'Googlebot-Image',
GOOGLE_BOT_NEWS: 'Googlebot-News',
GOOGLE_BOT_VIDEO: 'Googlebot-Video',
GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
GOOGLE_EXTENDED: 'Google-Extended',
GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
GOOGLE_OTHER: 'GoogleOther',
GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
GOOGLE_OTHER_VIDEO: 'GoogleOther-Video',
GOOGLE_SAFETY: 'Google-Safety',
GOOGLE_STOREBOT: 'Storebot-Google',
HIVE_IMAGESIFTBOT: 'ImagesiftBot',
HUAWEI_PANGUBOT: 'PanguBot',
HUAWEI_PETALBOT: 'PetalBot',
HUGGINGFACE_BOT: 'HuggingFace-Bot',
HUNTER_VELENPUBLICWEBCRAWLER: 'VelenPublicWebCrawler',
IA_ARCHIVER: 'ia_archiver',
IASK_BOT: 'iAskBot',
KAGI_BOT: 'Kagibot',
KANGAROO_BOT: 'Kangaroo Bot',
LINE_SPIDER: 'Linespider',
LINKEDIN_BOT: 'LinkedInBot',
MAGPIE_CRAWLER: 'magpie-crawler',
MARGINALIA: 'marginalia',
META_EXTERNALAGENT: 'meta-externalagent',
META_FACEBOOKBOT: 'FacebookBot',
META_FACEBOOKCATALOG: 'facebookcatalog',
META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',
MAJESTIC_MJ12BOT: 'MJ12bot',
MICROSOFT_BINGBOT: 'Bingbot',
MICROSOFT_MSNBOT: 'msnbot',
MICROSOFT_ADIDXBOT: 'adidxbot',
MOJEEK_BOT: 'MojeekBot',
MOZ_DOTBOT: 'DotBot',
ONCRAWL: 'OnCrawl',
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
OPENAI_GPTBOT: 'GPTBot',
OPENAI_SEARCH_BOT: 'OAI-SearchBot',
PERPLEXITY_BOT: 'PerplexityBot',
QIHOO_360_SPIDER: '360Spider',
QWANT_BOT: 'Qwantbot',
REPLICATE_BOT: 'Replicate-Bot',
RUNPOD_BOT: 'RunPod-Bot',
SB_INTUITIONS_BOT: 'SBIntuitionsBot',
SEEKPORT_BOT: 'SeekportBot',
SEMRUSH_BOT: 'SemrushBot',
SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
SEMRUSH_BOT_CONTENTSHAKE: 'SemrushBot-OCOB',
SEMRUSH_BOT_SEO_CHECKER: 'SemrushBot-SI',
SEZNAM_BOT: 'SeznamBot',
SITEIMPROVE: 'Siteimprove',
SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
SOGOU_WEB_SPIDER: 'Sogou web spider',
STARTPAGE: 'Startpage',
TIMPI_BOT: 'Timpibot',
TOGETHER_BOT: 'Together-Bot',
TURNITIN_BOT: 'TurnitinBot',
TWIN_AGENT: 'TwinAgent',
VERCEL_V0BOT: 'v0bot',
WEBZIO: 'webzio',
WEBZIO_EXTENDED: 'Webzio-Extended',
WEBZIO_OMGILI: 'omgili',
WEBZIO_OMGILI_BOT: 'omgilibot',
XAI_BOT: 'xAI-Bot',
YAHOO_JAPAN: 'Y!J-BRW',
YAHOO_SLURP: 'Yahoo! Slurp',
YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
YANDEX_ADNET: 'YandexAdNet',
YANDEX_BLOGS: 'YandexBlogs',
YANDEX_BOT: 'YandexBot',
YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
YANDEX_COMBOT: 'YandexComBot',
YANDEX_FAVICONS: 'YandexFavicons',
YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
YANDEX_IMAGES: 'YandexImages',
YANDEX_MARKET: 'YandexMarket',
YANDEX_MEDIA: 'YandexMedia',
YANDEX_METRIKA: 'YandexMetrika',
YANDEX_MOBILE_BOT: 'YandexMobileBot',
YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
YANDEX_NEWS: 'YandexNews',
YANDEX_ONTODB: 'YandexOntoDB',
YANDEX_ONTODB_API: 'YandexOntoDBAPI',
YANDEX_PARTNER: 'YandexPartner',
YANDEX_RCA: 'YandexRCA',
YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
YANDEX_SPRAV_BOT: 'YandexSpravBot',
YANDEX_TRACKER: 'YandexTracker',
YANDEX_VERTICALS: 'YandexVerticals',
YANDEX_VERTIS: 'YandexVertis',
YANDEX_VIDEO: 'YandexVideo',
YANDEX_VIDEO_PARSER: 'YandexVideoParser',
YANDEX_WEBMASTER: 'YandexWebmaster',
YEP_BOT: 'YepBot',
YETI: 'Yeti',
YISOU_SPIDER: 'YisouSpider',
YOU_BOT: 'YouBot',
ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
ZUM_BOT: 'ZumBot'
},
Email: {
AIRMAIL: 'Airmail',
APPLE_MAIL: 'Mail',
BLUEMAIL: 'BlueMail',
DAUM_MAIL: 'DaumMail',
EVOLUTION: 'Evolution',
EM_CLIENT: 'eM Client',
FOXMAIL: 'Foxmail',
KMAIL: 'KMail',
KMAIL2: 'kmail2',
KONTACT: 'Kontact',
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
NAVER_MAILAPP: 'NaverMailApp',
POLYMAIL: 'Polymail',
PROTON_MAIL: 'ProtonMail',
SPARK_MAIL: 'SparkDesktop',
SPARROW: 'Sparrow',
THUNDERBIRD: 'Thunderbird',
YAHOO_MAIL: 'Yahoo',
ZIMBRA: 'Zimbra',
ZOHO_MAIL: 'ZohoMail-Desktop'
},
Fetcher: {
AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
ANTHROPIC_CLAUDE_USER: 'Claude-User',
ASANA: 'Asana',
BETTER_UPTIME_BOT: 'Better Uptime Bot',
BITLY_BOT: 'bitlybot',
BLUESKY: 'Bluesky',
BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
COHERE_AI: 'Cohere-AI',
DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
GOOGLE_PRODUCER: 'GoogleProducer',
GOOGLE_SITE_VERIFICATION: 'Google-Site-Verification',
HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
IFRAMELY: 'Iframely',
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
META_EXTERNALFETCHER: 'meta-externalfetcher',
META_WHATSAPP: 'WhatsApp',
MICROSOFT_BINGPREVIEW: 'BingPreview',
MICROSOFT_PREVIEW: 'MicrosoftPreview',
MISTRALAI_USER: 'MistralAI-User',
NAVER_BLUENO: 'Blueno',
ONCRAWL_ROGERBOT: 'rogerbot',
OPENAI_CHATGPT_USER: 'ChatGPT-User',
PERPLEXITY_USER: 'Perplexity-User',
PINTEREST_BOT: 'Pinterestbot',
SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
SNAP_URL_PREVIEW: 'Snap URL Preview',
SKYPE_URIPREVIEW: 'SkypeUriPreview',
TELEGRAM_BOT: 'TelegramBot',
UPTIMEROBOT: 'UptimeRobot',
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
VERCEL_BOT: 'Vercelbot',
VERCEL_FLAGS: 'vercelflags',
VERCEL_TRACING: 'verceltracing',
YANDEX_CALENDAR: 'YandexCalendar',
YANDEX_DIRECT: 'YandexDirect',
YANDEX_DIRECTDYN: 'YandexDirectDyn',
YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
YANDEX_FORDOMAIN: 'YandexForDomain',
YANDEX_PAGECHECKER: 'YandexPagechecker',
YANDEX_SEARCHSHOP: 'YandexSearchShop',
YANDEX_SITELINKS: 'YandexSitelinks',
YANDEX_USERPROXY: 'YandexUserproxy',
ZOOMINFO_BOT: 'Zoombot'
},
InApp: {
DISCORD: 'Discord',
EVERNOTE: 'Evernote',
FIGMA: 'Figma',
FLIPBOARD: 'Flipboard',
MATTERMOST: 'Mattermost',
TEAMS: 'Teams',
NOTION: 'Notion',
POSTMAN: 'Postman',
RAMBOX: 'Rambox',
ROCKETCHAT: 'Rocket.Chat',
SLACK: 'Slack',
TIKTOK_LITE: 'TikTok Lite',
VSCODE: 'VS Code',
YAHOO_JAPAN: 'Yahoo! Japan'
},
Library: {
ADOBE_AIR: 'AdobeAIR',
AIOHTTP: 'aiohttp',
APACHE_HTTPCLIENT: 'Apache-HttpClient',
AXIOS: 'axios',
GO_HTTP_CLIENT: 'go-http-client',
GOT: 'got',
GUZZLEHTTP: 'GuzzleHttp',
JAVA: 'Java',
JAVA_HTTPCLIENT: 'Java-http-client',
JSDOM: 'jsdom',
LIBWWW_PERL: 'libwww-perl',
LUA_RESTY_HTTP: 'lua-resty-http',
NEEDLE: 'Needle',
NUTCH: 'Nutch',
OKHTTP: 'OkHttp',
NODE_FETCH: 'node-fetch',
NODE_SUPERAGENT: 'node-superagent',
PHP_SOAP: 'PHP-SOAP',
POSTMAN_RUNTIME: 'PostmanRuntime',
PYTHON_HTTPX: 'python-httpx',
PYTHON_URLLIB: 'python-urllib',
PYTHON_URLLIB3: 'python-urllib3',
PYTHON_REQUESTS: 'python-requests',
SCRAPY: 'Scrapy'
}
},
DeviceVendor: {
Vehicle: {
BMW: 'BMW',
BYD: 'BYD',
JEEP: 'Jeep',
RIVIAN: 'Rivian',
TESLA: 'Tesla',
VOLVO: 'Volvo'
}
}
});
export { export {
Browser,// deprecated Browser,
CPU, // deprecated
Device, // deprecated
Vendor, // deprecated
Engine, // deprecated
OS, // deprecated
BrowserName,
BrowserType, BrowserType,
CPUArch, CPU,
DeviceType, Device,
DeviceVendor, Vendor,
EngineName, Engine,
OSName, OS
Extension
}; };

View File

@ -1,4 +1,4 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.5 // Type definitions for Helpers submodule of UAParser.js v2.0.4
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.5 /* Extensions for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -43,31 +43,20 @@ const Crawlers = Object.freeze({
// AhrefsBot - https://ahrefs.com/robot // AhrefsBot - https://ahrefs.com/robot
// Amazonbot - https://developer.amazon.com/amazonbot // Amazonbot - https://developer.amazon.com/amazonbot
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
// Bravebot - https://search.brave.com/help/brave-search-crawler
// CCBot - https://commoncrawl.org/faq // CCBot - https://commoncrawl.org/faq
// contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
// Coveobot - https://connect.coveo.com/s/article/19648
// CriteoBot - https://www.criteo.com/criteo-crawler/
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html // DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot // GPTBot - https://platform.openai.com/docs/gptbot
// iAskBot - https://iask.ai // iAskBot - https://iask.ai
// Kagibot - https://kagi.com/bot
// Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
// LinkedInBot - http://www.linkedin.com // LinkedInBot - http://www.linkedin.com
// MJ12bot - https://mj12bot.com/ // MJ12bot - https://mj12bot.com/
// MojeekBot - https://www.mojeek.com/bot.html // MojeekBot - https://www.mojeek.com/bot.html
// Onespot - https://www.onespot.com/identifying-traffic.html // Onespot - https://www.onespot.com/identifying-traffic.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots // OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot // PerplexityBot - https://perplexity.ai/perplexitybot
// SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro // SeznamBot - http://napoveda.seznam.cz/seznambot-intro
// YepBot - https://yep.com/yepbot/ /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
/((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|yep)bot)\/([\w\.-]+)/i,
// Algolia Crawler
/(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
// Applebot - http://apple.com/go/applebot // Applebot - http://apple.com/go/applebot
/(applebot(?:-extended)?)\/?([\w\.]*)/i, /(applebot(?:-extended)?)\/?([\w\.]*)/i,
@ -76,7 +65,7 @@ const Crawlers = Object.freeze({
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
// ClaudeBot (Anthropic) // ClaudeBot (Anthropic)
/(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i, /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine // Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i, /(coccocbot-(?:image|web))\/([\w\.]+)/i,
@ -94,9 +83,6 @@ const Crawlers = Object.freeze({
// Internet Archive (archive.org) // Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// OnCrawl
/(oncrawl) mobile\/([\w\.]+)/i,
// Qwantbot - https://help.qwant.com/bot // Qwantbot - https://help.qwant.com/bot
/(qwantbot)[-\w]*\/?([\w\.]*)/i, /(qwantbot)[-\w]*\/?([\w\.]*)/i,
@ -110,38 +96,30 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i, /(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i, /(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver) // Yeti (Naver)
/(yeti)\/([\w\.]+)/i, /(yeti)\/([\w\.]+)/i,
// aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot
// Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/ /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|startpageprivateimageproxy|webzio-extended|(?:chatglm-|line|screaming frog seo |yisou)spider)\/?([\w\.]*)/i
// Freespoke - https://docs.freespoke.com/search/bot/
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
], ],
[NAME, VERSION, [TYPE, CRAWLER]],
[ [NAME, VERSION, [TYPE, CRAWLER]],
// YandexBot MirrorDetector
/(yandexbot\/([\w\.]+); mirrordetector)/i
],
[[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
[ [
// Google Bots // Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i, /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// AI2Bot - https://allenai.org/crawler // AI2Bot - https://allenai.org/crawler
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot // DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot // Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// ImagesiftBot - https://imagesift.com/about // ImagesiftBot - https://imagesift.com/about
// Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553 // Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// v0bot - https://vercel.com/docs/bot-management
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i
/\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
], ],
[NAME, [TYPE, CRAWLER]] [NAME, [TYPE, CRAWLER]]
] ]
@ -256,17 +234,16 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({ const Fetchers = Object.freeze({
browser : [ browser : [
[ [
// Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/ // DuckAssistBot - https://duckduckgo.com/duckassistbot/
// Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// Google Site Verifier / Meta / Yahoo! Japan // Google Site Verifier / Meta / Yahoo! Japan
// Iframely - https://iframely.com/docs/about // Iframely - https://iframely.com/docs/about
// Perplexity-User - https://docs.perplexity.ai/guides/bots // Perplexity-User - https://docs.perplexity.ai/guides/bots
// MistralAI-User - https://docs.mistral.ai/robots/ // MistralAI-User - https://docs.mistral.ai/robots/
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i, /(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
// Bluesky // Bluesky
/(bluesky) cardyb\/([\w\.]+)/i, /(bluesky) cardyb\/([\w\.]+)/i,
@ -283,8 +260,8 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]], [NAME, VERSION, [TYPE, FETCHER]],
[ [
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i
], ],
[NAME, [TYPE, FETCHER]], [NAME, [TYPE, FETCHER]],
], ],
@ -427,8 +404,8 @@ const Vehicles = Object.freeze({
const Bots = Object.freeze({ const Bots = Object.freeze({
browser : [ browser : [
...CLIs.browser, ...CLIs.browser,
...Fetchers.browser,
...Crawlers.browser, ...Crawlers.browser,
...Fetchers.browser,
...Libraries.browser ...Libraries.browser
], ],
os : [ os : [

View File

@ -3,7 +3,7 @@
// Source: /src/extensions/ua-parser-extensions.js // Source: /src/extensions/ua-parser-extensions.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.5 /* Extensions for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -47,31 +47,20 @@ const Crawlers = Object.freeze({
// AhrefsBot - https://ahrefs.com/robot // AhrefsBot - https://ahrefs.com/robot
// Amazonbot - https://developer.amazon.com/amazonbot // Amazonbot - https://developer.amazon.com/amazonbot
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
// Bravebot - https://search.brave.com/help/brave-search-crawler
// CCBot - https://commoncrawl.org/faq // CCBot - https://commoncrawl.org/faq
// contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
// Coveobot - https://connect.coveo.com/s/article/19648
// CriteoBot - https://www.criteo.com/criteo-crawler/
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html // DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot // GPTBot - https://platform.openai.com/docs/gptbot
// iAskBot - https://iask.ai // iAskBot - https://iask.ai
// Kagibot - https://kagi.com/bot
// Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
// LinkedInBot - http://www.linkedin.com // LinkedInBot - http://www.linkedin.com
// MJ12bot - https://mj12bot.com/ // MJ12bot - https://mj12bot.com/
// MojeekBot - https://www.mojeek.com/bot.html // MojeekBot - https://www.mojeek.com/bot.html
// Onespot - https://www.onespot.com/identifying-traffic.html // Onespot - https://www.onespot.com/identifying-traffic.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots // OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot // PerplexityBot - https://perplexity.ai/perplexitybot
// SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro // SeznamBot - http://napoveda.seznam.cz/seznambot-intro
// YepBot - https://yep.com/yepbot/ /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
/((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|yep)bot)\/([\w\.-]+)/i,
// Algolia Crawler
/(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
// Applebot - http://apple.com/go/applebot // Applebot - http://apple.com/go/applebot
/(applebot(?:-extended)?)\/?([\w\.]*)/i, /(applebot(?:-extended)?)\/?([\w\.]*)/i,
@ -80,7 +69,7 @@ const Crawlers = Object.freeze({
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
// ClaudeBot (Anthropic) // ClaudeBot (Anthropic)
/(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i, /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine // Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i, /(coccocbot-(?:image|web))\/([\w\.]+)/i,
@ -98,9 +87,6 @@ const Crawlers = Object.freeze({
// Internet Archive (archive.org) // Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// OnCrawl
/(oncrawl) mobile\/([\w\.]+)/i,
// Qwantbot - https://help.qwant.com/bot // Qwantbot - https://help.qwant.com/bot
/(qwantbot)[-\w]*\/?([\w\.]*)/i, /(qwantbot)[-\w]*\/?([\w\.]*)/i,
@ -114,38 +100,30 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i, /(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i, /(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver) // Yeti (Naver)
/(yeti)\/([\w\.]+)/i, /(yeti)\/([\w\.]+)/i,
// aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot
// Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/ /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|startpageprivateimageproxy|webzio-extended|(?:chatglm-|line|screaming frog seo |yisou)spider)\/?([\w\.]*)/i
// Freespoke - https://docs.freespoke.com/search/bot/
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
], ],
[NAME, VERSION, [TYPE, CRAWLER]],
[ [NAME, VERSION, [TYPE, CRAWLER]],
// YandexBot MirrorDetector
/(yandexbot\/([\w\.]+); mirrordetector)/i
],
[[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
[ [
// Google Bots // Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i, /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// AI2Bot - https://allenai.org/crawler // AI2Bot - https://allenai.org/crawler
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot // DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot // Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// ImagesiftBot - https://imagesift.com/about // ImagesiftBot - https://imagesift.com/about
// Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553 // Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// v0bot - https://vercel.com/docs/bot-management
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i
/\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
], ],
[NAME, [TYPE, CRAWLER]] [NAME, [TYPE, CRAWLER]]
] ]
@ -260,17 +238,16 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({ const Fetchers = Object.freeze({
browser : [ browser : [
[ [
// Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/ // DuckAssistBot - https://duckduckgo.com/duckassistbot/
// Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// Google Site Verifier / Meta / Yahoo! Japan // Google Site Verifier / Meta / Yahoo! Japan
// Iframely - https://iframely.com/docs/about // Iframely - https://iframely.com/docs/about
// Perplexity-User - https://docs.perplexity.ai/guides/bots // Perplexity-User - https://docs.perplexity.ai/guides/bots
// MistralAI-User - https://docs.mistral.ai/robots/ // MistralAI-User - https://docs.mistral.ai/robots/
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i, /(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
// Bluesky // Bluesky
/(bluesky) cardyb\/([\w\.]+)/i, /(bluesky) cardyb\/([\w\.]+)/i,
@ -287,8 +264,8 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]], [NAME, VERSION, [TYPE, FETCHER]],
[ [
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i
], ],
[NAME, [TYPE, FETCHER]], [NAME, [TYPE, FETCHER]],
], ],
@ -431,8 +408,8 @@ const Vehicles = Object.freeze({
const Bots = Object.freeze({ const Bots = Object.freeze({
browser : [ browser : [
...CLIs.browser, ...CLIs.browser,
...Fetchers.browser,
...Crawlers.browser, ...Crawlers.browser,
...Fetchers.browser,
...Libraries.browser ...Libraries.browser
], ],
os : [ os : [

View File

@ -1,15 +1,27 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.5 // Type definitions for Helpers submodule of UAParser.js v2.0.4
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>
import type { IResult } from "../main/ua-parser"; import type { IResult } from "../main/ua-parser";
export function getDeviceVendor(model: string): string | undefined; declare function getDeviceVendor(model: string): string | undefined;
export function isAppleSilicon(resultOrUA: IResult | string): boolean; declare function isAppleSilicon(resultOrUA: IResult | string): boolean;
export function isAIBot(resultOrUA: IResult | string): boolean; declare function isAIBot(resultOrUA: IResult | string): boolean;
export function isBot(resultOrUA: IResult | string): boolean; declare function isBot(resultOrUA: IResult | string): boolean;
export function isChromeFamily(resultOrUA: IResult | string): boolean; declare function isChromeFamily(resultOrUA: IResult | string): boolean;
export function isElectron(): boolean; declare function isElectron(): boolean;
export function isFromEU(): boolean; declare function isFromEU(): boolean;
export function isFrozenUA(ua: string): boolean; declare function isFrozenUA(ua: string): boolean;
export function isStandalonePWA(): boolean; declare function isStandalonePWA(): boolean;
export {
getDeviceVendor,
isAppleSilicon,
isAIBot,
isBot,
isChromeFamily,
isElectron,
isFromEU,
isFrozenUA,
isStandalonePWA
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.5 /* Helpers for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -8,12 +8,11 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const { UAParser } = require('../main/ua-parser'); const { UAParser } = require('../main/ua-parser');
const { CPUArch, OSName, EngineName, Extension, BrowserType } = require('../enums/ua-parser-enums'); const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
const { Bots, Crawlers } = require('../extensions/ua-parser-extensions'); const { Bots } = require('../extensions/ua-parser-extensions');
const { isFromEU } = require('detect-europe-js'); const { isFromEU } = require('detect-europe-js');
const { isFrozenUA } = require('ua-is-frozen'); const { isFrozenUA } = require('ua-is-frozen');
const { isStandalonePWA } = require('is-standalone-pwa'); const { isStandalonePWA } = require('is-standalone-pwa');
const { Crawler } = Extension.BrowserName;
const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value; const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value;
@ -21,8 +20,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
const isAppleSilicon = (resultOrUA) => { const isAppleSilicon = (resultOrUA) => {
const res = toResult(resultOrUA); const res = toResult(resultOrUA);
if (res.os.is(OSName.MACOS)) { if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPUArch.ARM)) { if (res.cpu.is(CPU.ARM)) {
return true; return true;
} }
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') { if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
@ -45,129 +44,88 @@ const isAppleSilicon = (resultOrUA) => {
const isAIBot = (resultOrUA) => [ const isAIBot = (resultOrUA) => [
// AI2 // AI2
Crawler.AI2_BOT, 'ai2bot',
// Amazon // Amazon
Crawler.AMAZON_BOT, 'amazonbot',
// Anthropic // Anthropic
Crawler.ANTHROPIC_AI, 'anthropic-ai',
Crawler.ANTHROPIC_CLAUDE_BOT, 'claude-web',
Crawler.ANTHROPIC_CLAUDE_SEARCHBOT, 'claudebot',
Crawler.ANTHROPIC_CLAUDE_WEB,
// Apple // Apple
Crawler.APPLE_BOT, 'applebot',
Crawler.APPLE_BOT_EXTENDED, 'applebot-extended',
// Brave
Crawler.BRAVE_BOT,
// ByteDance // ByteDance
Crawler.BYTEDANCE_BYTESPIDER, 'bytespider',
Crawler.BYTEDANCE_TIKTOKSPIDER,
// Cohere
Crawler.COHERE_TRAINING_DATA_CRAWLER,
// Common Crawl // Common Crawl
Crawler.COMMON_CRAWL_CCBOT, 'ccbot',
// Coveo
Crawler.COVEO_BOT,
// DataForSeo // DataForSeo
Crawler.DATAFORSEO_BOT, 'dataforseobot',
// DeepSeek
Crawler.DEEPSEEK_BOT,
// Diffbot // Diffbot
Crawler.DIFFBOT, 'diffbot',
// Google // Google
Crawler.GOOGLE_EXTENDED, 'googleother',
Crawler.GOOGLE_OTHER, 'googleother-image',
Crawler.GOOGLE_OTHER_IMAGE, 'googleother-video',
Crawler.GOOGLE_OTHER_VIDEO, 'google-extended',
Crawler.GOOGLE_CLOUDVERTEXBOT,
// Hive AI // Hive AI
Crawler.HIVE_IMAGESIFTBOT, 'imagesiftbot',
// Huawei // Huawei
Crawler.HUAWEI_PETALBOT, 'petalbot',
Crawler.HUAWEI_PANGUBOT,
// Hugging Face
Crawler.HUGGINGFACE_BOT,
// Kangaroo
Crawler.KANGAROO_BOT,
// Mendable.ai
Crawler.FIRECRAWL_AGENT,
// Meta // Meta
Crawler.META_FACEBOOKBOT, 'facebookbot',
Crawler.META_EXTERNALAGENT, 'meta-externalagent',
// OpenAI // OpenAI
Crawler.OPENAI_GPTBOT, 'gptbot',
Crawler.OPENAI_SEARCH_BOT, 'oai-searchbot',
// Perplexity // Perplexity
Crawler.PERPLEXITY_BOT, 'perplexitybot',
// Replicate
Crawler.REPLICATE_BOT,
// Runpod
Crawler.RUNPOD_BOT,
// SB Intuitions
Crawler.SB_INTUITIONS_BOT,
// Semrush // Semrush
Crawler.SEMRUSH_BOT_CONTENTSHAKE, 'semrushbot-ocob',
// Timpi // Timpi
Crawler.TIMPI_BOT, 'timpibot',
// Together AI
Crawler.TOGETHER_BOT,
// Velen.io // Velen.io
Crawler.HUNTER_VELENPUBLICWEBCRAWLER, 'velenpublicwebcrawler',
// Vercel
Crawler.VERCEL_V0BOT,
// Webz.io // Webz.io
Crawler.WEBZIO_OMGILI, 'omgili',
Crawler.WEBZIO_OMGILI_BOT, 'omgilibot',
Crawler.WEBZIO_EXTENDED, 'webzio-extended',
// X
Crawler.XAI_BOT,
// You.com // You.com
Crawler.YOU_BOT, 'youbot',
// Zhipu AI // Zhipu AI
Crawler.ZHIPU_CHATGLM_SPIDER 'chatglm-spider',
]
.map((s) => s.toLowerCase()) // Zyte
.includes(String(toResult(resultOrUA, Crawlers).browser.name).toLowerCase()); 'scrapy'
].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
const isBot = (resultOrUA) => [ const isBot = (resultOrUA) => [
BrowserType.CLI, 'cli',
BrowserType.CRAWLER, 'crawler',
BrowserType.FETCHER, 'fetcher',
BrowserType.LIBRARY 'library'
].includes(toResult(resultOrUA, Bots).browser.type); ].includes(toResult(resultOrUA, Bots).browser.type);
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK); const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser / electron\//i.test(navigator?.userAgent)); // browser

View File

@ -3,7 +3,7 @@
// Source: /src/helpers/ua-parser-helpers.js // Source: /src/helpers/ua-parser-helpers.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.5 /* Helpers for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -12,12 +12,11 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
import { UAParser } from '../main/ua-parser.mjs'; import { UAParser } from '../main/ua-parser.mjs';
import { CPUArch, OSName, EngineName, Extension, BrowserType } from '../enums/ua-parser-enums.mjs'; import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
import { Bots, Crawlers } from '../extensions/ua-parser-extensions.mjs'; import { Bots } from '../extensions/ua-parser-extensions.mjs';
import { isFromEU } from 'detect-europe-js'; import { isFromEU } from 'detect-europe-js';
import { isFrozenUA } from 'ua-is-frozen'; import { isFrozenUA } from 'ua-is-frozen';
import { isStandalonePWA } from 'is-standalone-pwa'; import { isStandalonePWA } from 'is-standalone-pwa';
const { Crawler } = Extension.BrowserName;
const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value; const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value;
@ -25,8 +24,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
const isAppleSilicon = (resultOrUA) => { const isAppleSilicon = (resultOrUA) => {
const res = toResult(resultOrUA); const res = toResult(resultOrUA);
if (res.os.is(OSName.MACOS)) { if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPUArch.ARM)) { if (res.cpu.is(CPU.ARM)) {
return true; return true;
} }
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') { if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
@ -49,129 +48,88 @@ const isAppleSilicon = (resultOrUA) => {
const isAIBot = (resultOrUA) => [ const isAIBot = (resultOrUA) => [
// AI2 // AI2
Crawler.AI2_BOT, 'ai2bot',
// Amazon // Amazon
Crawler.AMAZON_BOT, 'amazonbot',
// Anthropic // Anthropic
Crawler.ANTHROPIC_AI, 'anthropic-ai',
Crawler.ANTHROPIC_CLAUDE_BOT, 'claude-web',
Crawler.ANTHROPIC_CLAUDE_SEARCHBOT, 'claudebot',
Crawler.ANTHROPIC_CLAUDE_WEB,
// Apple // Apple
Crawler.APPLE_BOT, 'applebot',
Crawler.APPLE_BOT_EXTENDED, 'applebot-extended',
// Brave
Crawler.BRAVE_BOT,
// ByteDance // ByteDance
Crawler.BYTEDANCE_BYTESPIDER, 'bytespider',
Crawler.BYTEDANCE_TIKTOKSPIDER,
// Cohere
Crawler.COHERE_TRAINING_DATA_CRAWLER,
// Common Crawl // Common Crawl
Crawler.COMMON_CRAWL_CCBOT, 'ccbot',
// Coveo
Crawler.COVEO_BOT,
// DataForSeo // DataForSeo
Crawler.DATAFORSEO_BOT, 'dataforseobot',
// DeepSeek
Crawler.DEEPSEEK_BOT,
// Diffbot // Diffbot
Crawler.DIFFBOT, 'diffbot',
// Google // Google
Crawler.GOOGLE_EXTENDED, 'googleother',
Crawler.GOOGLE_OTHER, 'googleother-image',
Crawler.GOOGLE_OTHER_IMAGE, 'googleother-video',
Crawler.GOOGLE_OTHER_VIDEO, 'google-extended',
Crawler.GOOGLE_CLOUDVERTEXBOT,
// Hive AI // Hive AI
Crawler.HIVE_IMAGESIFTBOT, 'imagesiftbot',
// Huawei // Huawei
Crawler.HUAWEI_PETALBOT, 'petalbot',
Crawler.HUAWEI_PANGUBOT,
// Hugging Face
Crawler.HUGGINGFACE_BOT,
// Kangaroo
Crawler.KANGAROO_BOT,
// Mendable.ai
Crawler.FIRECRAWL_AGENT,
// Meta // Meta
Crawler.META_FACEBOOKBOT, 'facebookbot',
Crawler.META_EXTERNALAGENT, 'meta-externalagent',
// OpenAI // OpenAI
Crawler.OPENAI_GPTBOT, 'gptbot',
Crawler.OPENAI_SEARCH_BOT, 'oai-searchbot',
// Perplexity // Perplexity
Crawler.PERPLEXITY_BOT, 'perplexitybot',
// Replicate
Crawler.REPLICATE_BOT,
// Runpod
Crawler.RUNPOD_BOT,
// SB Intuitions
Crawler.SB_INTUITIONS_BOT,
// Semrush // Semrush
Crawler.SEMRUSH_BOT_CONTENTSHAKE, 'semrushbot-ocob',
// Timpi // Timpi
Crawler.TIMPI_BOT, 'timpibot',
// Together AI
Crawler.TOGETHER_BOT,
// Velen.io // Velen.io
Crawler.HUNTER_VELENPUBLICWEBCRAWLER, 'velenpublicwebcrawler',
// Vercel
Crawler.VERCEL_V0BOT,
// Webz.io // Webz.io
Crawler.WEBZIO_OMGILI, 'omgili',
Crawler.WEBZIO_OMGILI_BOT, 'omgilibot',
Crawler.WEBZIO_EXTENDED, 'webzio-extended',
// X
Crawler.XAI_BOT,
// You.com // You.com
Crawler.YOU_BOT, 'youbot',
// Zhipu AI // Zhipu AI
Crawler.ZHIPU_CHATGLM_SPIDER 'chatglm-spider',
]
.map((s) => s.toLowerCase()) // Zyte
.includes(String(toResult(resultOrUA, Crawlers).browser.name).toLowerCase()); 'scrapy'
].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
const isBot = (resultOrUA) => [ const isBot = (resultOrUA) => [
BrowserType.CLI, 'cli',
BrowserType.CRAWLER, 'crawler',
BrowserType.FETCHER, 'fetcher',
BrowserType.LIBRARY 'library'
].includes(toResult(resultOrUA, Bots).browser.type); ].includes(toResult(resultOrUA, Bots).browser.type);
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK); const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser / electron\//i.test(navigator?.userAgent)); // browser

View File

@ -1,9 +1,9 @@
// Type definitions for UAParser.js v2.0.5 // Type definitions for UAParser.js v2.0.4
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>
import type { Headers } from "undici"; import type { IncomingHttpHeaders } from 'http';
import { BrowserType, CPUArch, DeviceType, EngineName } from "../enums/ua-parser-enums"; import type { Headers as FetchAPIHeaders } from 'node-fetch';
declare namespace UAParser { declare namespace UAParser {
@ -18,21 +18,21 @@ declare namespace UAParser {
name?: string; name?: string;
version?: string; version?: string;
major?: string; major?: string;
type?: typeof BrowserType[keyof typeof BrowserType]; type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library';
} }
interface ICPU extends IData<ICPU> { interface ICPU extends IData<ICPU> {
architecture?: typeof CPUArch[keyof typeof CPUArch]; architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'avr32' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'pa-risc' | 'ppc' | 'sparc' | 'sparc64';
} }
interface IDevice extends IData<IDevice> { interface IDevice extends IData<IDevice> {
type?: typeof DeviceType[keyof typeof DeviceType]; type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable' | 'xr' | 'embedded';
vendor?: string; vendor?: string;
model?: string; model?: string;
} }
interface IEngine extends IData<IEngine> { interface IEngine extends IData<IEngine> {
name?: typeof EngineName[keyof typeof EngineName]; name?: 'Amaya' | 'ArkWeb' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Servo' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
version?: string; version?: string;
} }
@ -53,7 +53,7 @@ declare namespace UAParser {
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[]; type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os'; type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os';
type UAParserExt = Partial<Record<UAParserProps, RegexMap>> | Partial<Record<UAParserProps, RegexMap>>[]; type UAParserExt = Partial<Record<UAParserProps, RegexMap>> | Partial<Record<UAParserProps, RegexMap>>[];
export type UAParserHeaders = Record<string, string | string[] | undefined> | Headers; type UAParserHeaders = Record<string, string> | IncomingHttpHeaders | FetchAPIHeaders;
export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: UAParserHeaders): IResult; export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: UAParserHeaders): IResult;
export function UAParser(uastring?: string, headers?: UAParserHeaders): IResult; export function UAParser(uastring?: string, headers?: UAParserHeaders): IResult;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.5 /* UAParser.js v2.0.4
Copyright © 2012-2025 Faisal Salman <f@faisalman.com> Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@ -19,7 +19,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.5', var LIBVERSION = '2.0.4',
UA_MAX_LENGTH = 500, UA_MAX_LENGTH = 500,
USER_AGENT = 'user-agent', USER_AGENT = 'user-agent',
EMPTY = '', EMPTY = '',
@ -188,8 +188,6 @@
}, },
setProps = function (arr) { setProps = function (arr) {
for (var i in arr) { for (var i in arr) {
if (!arr.hasOwnProperty(i)) continue;
var propName = arr[i]; var propName = arr[i];
if (typeof propName == OBJ_TYPE && propName.length == 2) { if (typeof propName == OBJ_TYPE && propName.length == 2) {
this[propName[0]] = propName[1]; this[propName[0]] = propName[1];
@ -457,8 +455,6 @@
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [ ], [NAME, [TYPE, INAPP]], [
/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium /(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [ ], [NAME, VERSION], [
@ -540,15 +536,15 @@
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
], [[ARCHITECTURE, 'arm']], [ ], [[ARCHITECTURE, 'arm']], [
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
/ sun4\w[;\)]/i // SPARC / sun4\w[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [ ], [[ARCHITECTURE, 'sparc']], [
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i, ], [[ARCHITECTURE, lowerize]]
/((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
/winnt.+\[axp/i
], [[ARCHITECTURE, 'alpha']]
], ],
device : [[ device : [[
@ -772,8 +768,7 @@
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL /; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
/(hp) ([\w ]+\w)/i, // HP iPAQ /(hp) ([\w ]+\w)/i, // HP iPAQ
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
/(oppo) ?([\w ]+) bui/i, // OPPO /(oppo) ?([\w ]+) bui/i // OPPO
/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
], [VENDOR, MODEL, [TYPE, MOBILE]], [ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(kobo)\s(ereader|touch)/i, // Kobo /(kobo)\s(ereader|touch)/i, // Kobo
@ -800,7 +795,6 @@
// SMARTTVS // SMARTTVS
/////////////////// ///////////////////
/(philips)[\w ]+tv/i, // Philips
/smart-tv.+(samsung)/i // Samsung /smart-tv.+(samsung)/i // Samsung
], [VENDOR, [TYPE, SMARTTV]], [ ], [VENDOR, [TYPE, SMARTTV]], [
/hbbtv.+maple;(\d+)/i /hbbtv.+maple;(\d+)/i
@ -838,6 +832,11 @@
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [ ], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
// SmartTV from Unidentified Vendors
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
], [MODEL, [TYPE, SMARTTV]], [
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
], [[TYPE, SMARTTV]], [
/////////////////// ///////////////////
// CONSOLES // CONSOLES
@ -884,7 +883,7 @@
/droid.+; (glass) \d/i // Google Glass /droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
/(pico) ([\w ]+) os\d/i // Pico /(pico) (4|neo3(?: link|pro)?)/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [ ], [VENDOR, MODEL, [TYPE, XR]], [
/(quest( \d| pro)?s?).+vr/i // Meta Quest /(quest( \d| pro)?s?).+vr/i // Meta Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
@ -908,10 +907,6 @@
// MIXED (GENERIC) // MIXED (GENERIC)
/////////////////// ///////////////////
/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
], [MODEL, [TYPE, SMARTTV]], [
/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
], [[TYPE, SMARTTV]], [
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [ ], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
@ -1268,7 +1263,7 @@
case UA_ENGINE: case UA_ENGINE:
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
if (brands) { if (brands) {
for (var i=0; i<brands.length; i++) { for (var i in brands) {
var brandName = brands[i].brand || brands[i], var brandName = brands[i].brand || brands[i],
brandVersion = brands[i].version; brandVersion = brands[i].version;
if (this.itemType == UA_BROWSER && if (this.itemType == UA_BROWSER &&
@ -1390,22 +1385,11 @@
extensions = undefined; extensions = undefined;
} }
if (headers) { // Convert Headers object into a plain object
if (typeof headers.append === FUNC_TYPE) { if (headers && typeof headers.append === FUNC_TYPE) {
// Convert Headers object into a plain object var kv = {};
var kv = {}; headers.forEach(function (v, k) { kv[k] = v; });
headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; }); headers = kv;
headers = kv;
} else {
// Normalize headers field name into lowercase
var normalized = {};
for (var header in headers) {
if (headers.hasOwnProperty(header)) {
normalized[String(header).toLowerCase()] = headers[header];
}
}
headers = normalized;
}
} }
if (!(this instanceof UAParser)) { if (!(this instanceof UAParser)) {

View File

@ -3,7 +3,7 @@
// Source: /src/main/ua-parser.js // Source: /src/main/ua-parser.js
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.5 /* UAParser.js v2.0.4
Copyright © 2012-2025 Faisal Salman <f@faisalman.com> Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@ -21,7 +21,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.5', var LIBVERSION = '2.0.4',
UA_MAX_LENGTH = 500, UA_MAX_LENGTH = 500,
USER_AGENT = 'user-agent', USER_AGENT = 'user-agent',
EMPTY = '', EMPTY = '',
@ -190,8 +190,6 @@
}, },
setProps = function (arr) { setProps = function (arr) {
for (var i in arr) { for (var i in arr) {
if (!arr.hasOwnProperty(i)) continue;
var propName = arr[i]; var propName = arr[i];
if (typeof propName == OBJ_TYPE && propName.length == 2) { if (typeof propName == OBJ_TYPE && propName.length == 2) {
this[propName[0]] = propName[1]; this[propName[0]] = propName[1];
@ -459,8 +457,6 @@
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [ ], [NAME, [TYPE, INAPP]], [
/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium /(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [ ], [NAME, VERSION], [
@ -542,15 +538,15 @@
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
], [[ARCHITECTURE, 'arm']], [ ], [[ARCHITECTURE, 'arm']], [
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
/ sun4\w[;\)]/i // SPARC / sun4\w[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [ ], [[ARCHITECTURE, 'sparc']], [
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i, ], [[ARCHITECTURE, lowerize]]
/((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
/winnt.+\[axp/i
], [[ARCHITECTURE, 'alpha']]
], ],
device : [[ device : [[
@ -774,8 +770,7 @@
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL /; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
/(hp) ([\w ]+\w)/i, // HP iPAQ /(hp) ([\w ]+\w)/i, // HP iPAQ
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
/(oppo) ?([\w ]+) bui/i, // OPPO /(oppo) ?([\w ]+) bui/i // OPPO
/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
], [VENDOR, MODEL, [TYPE, MOBILE]], [ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(kobo)\s(ereader|touch)/i, // Kobo /(kobo)\s(ereader|touch)/i, // Kobo
@ -802,7 +797,6 @@
// SMARTTVS // SMARTTVS
/////////////////// ///////////////////
/(philips)[\w ]+tv/i, // Philips
/smart-tv.+(samsung)/i // Samsung /smart-tv.+(samsung)/i // Samsung
], [VENDOR, [TYPE, SMARTTV]], [ ], [VENDOR, [TYPE, SMARTTV]], [
/hbbtv.+maple;(\d+)/i /hbbtv.+maple;(\d+)/i
@ -840,6 +834,11 @@
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [ ], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
// SmartTV from Unidentified Vendors
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
], [MODEL, [TYPE, SMARTTV]], [
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
], [[TYPE, SMARTTV]], [
/////////////////// ///////////////////
// CONSOLES // CONSOLES
@ -886,7 +885,7 @@
/droid.+; (glass) \d/i // Google Glass /droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
/(pico) ([\w ]+) os\d/i // Pico /(pico) (4|neo3(?: link|pro)?)/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [ ], [VENDOR, MODEL, [TYPE, XR]], [
/(quest( \d| pro)?s?).+vr/i // Meta Quest /(quest( \d| pro)?s?).+vr/i // Meta Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
@ -910,10 +909,6 @@
// MIXED (GENERIC) // MIXED (GENERIC)
/////////////////// ///////////////////
/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
], [MODEL, [TYPE, SMARTTV]], [
/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
], [[TYPE, SMARTTV]], [
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [ ], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
@ -1270,7 +1265,7 @@
case UA_ENGINE: case UA_ENGINE:
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
if (brands) { if (brands) {
for (var i=0; i<brands.length; i++) { for (var i in brands) {
var brandName = brands[i].brand || brands[i], var brandName = brands[i].brand || brands[i],
brandVersion = brands[i].version; brandVersion = brands[i].version;
if (this.itemType == UA_BROWSER && if (this.itemType == UA_BROWSER &&
@ -1392,22 +1387,11 @@
extensions = undefined; extensions = undefined;
} }
if (headers) { // Convert Headers object into a plain object
if (typeof headers.append === FUNC_TYPE) { if (headers && typeof headers.append === FUNC_TYPE) {
// Convert Headers object into a plain object var kv = {};
var kv = {}; headers.forEach(function (v, k) { kv[k] = v; });
headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; }); headers = kv;
headers = kv;
} else {
// Normalize headers field name into lowercase
var normalized = {};
for (var header in headers) {
if (headers.hasOwnProperty(header)) {
normalized[String(header).toLowerCase()] = headers[header];
}
}
headers = normalized;
}
} }
if (!(this instanceof UAParser)) { if (!(this instanceof UAParser)) {

View File

@ -1,242 +0,0 @@
const UACHTests = [
{
desc: 'Avast Secure Browser',
headers : {
'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
},
expect: {
browser : {
name : 'Avast Secure Browser',
version : '131',
major : '131',
type : undefined
}
}
},
{
desc: 'Brave',
headers : {
'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"'
},
expect: {
browser : {
name : 'Brave',
version : '132',
major : '132',
type : undefined
}
}
},
{
desc: 'Chrome',
headers : {
'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"'
},
expect: {
browser : {
name : 'Chrome',
version : '111',
major : '111',
type : undefined
}
}
},
{
desc: 'Chrome Headless',
headers : {
'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"'
},
expect: {
browser : {
name : 'Chrome Headless',
version : '124',
major : '124',
type : undefined
}
}
},
{
desc: 'Chrome WebView',
headers : {
'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
},
expect: {
browser : {
name : 'Chrome WebView',
version : '123',
major : '123',
type : undefined
}
}
},
{
desc: 'DuckDuckGo',
headers : {
'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
},
expect : {
browser : {
name : 'DuckDuckGo',
version : '131',
major : '131',
type : undefined
}
}
},
{
desc: 'Edge',
headers : {
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"'
},
expect: {
browser : {
name : 'Edge',
version : '120',
major : '120',
type : undefined
}
}
},
{
desc: 'Edge WebView2',
headers : {
'sec-ch-ua': '" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103", "Microsoft Edge WebView2";v="104"'
},
expect: {
browser : {
name : 'Edge WebView2',
version : '104',
major : '104',
type : undefined
}
}
},
{
desc: 'Huawei Browser',
headers : {
'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"'
},
expect: {
browser : {
name : 'Huawei Browser',
version : '114',
major : '114',
type : undefined
}
}
},
{
desc: 'MIUI Browser',
headers : {
'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
},
expect: {
browser : {
name : 'MIUI Browser',
version : '123',
major : '123',
type : undefined
}
}
},
{
desc: 'Oculus Browser',
headers : {
'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"'
},
expect: {
browser : {
name : 'Oculus Browser',
version : '36',
major : '36',
type : undefined
}
}
},
{
desc: 'Opera',
headers : {
'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"'
},
expect: {
browser : {
name : 'Opera',
version : '116',
major : '116',
type : undefined
}
}
},
{
desc: 'Opera GX',
headers : {
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"'
},
expect: {
browser : {
name : 'Opera GX',
version : '114',
major : '114',
type : undefined
}
}
},
{
desc: 'Opera Mobi',
headers : {
'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"'
},
expect: {
browser : {
name : 'Opera Mobi',
version : '86',
major : '86',
type : undefined
}
}
},
{
desc: 'Opera Mobi',
headers : {
'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"'
},
expect: {
browser : {
name : 'Opera Mobi',
version : '87',
major : '87',
type : undefined
}
}
},
{
desc: 'Samsung Internet',
headers : {
'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"'
},
expect: {
browser : {
name : 'Samsung Internet',
version : '27.0',
major : '27',
type : undefined
}
}
},
{
desc: 'Yandex',
headers : {
'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"'
},
expect: {
browser : {
name : 'Yandex',
version : '24.12',
major : '24',
type : undefined
}
}
}
];
module.exports = UACHTests;

View File

@ -2695,27 +2695,5 @@
"major" : "10", "major" : "10",
"type" : "inapp" "type" : "inapp"
} }
},
{
"desc" : "Zalo on iOS",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Zalo/20.05.01 Mobile/15E148",
"expect" :
{
"name" : "Zalo",
"version" : "20.05.01",
"major" : "20",
"type" : "inapp"
}
},
{
"desc" : "Zalo on Android",
"ua" : "Mozilla/5.0 (Linux; Android 10; Vsmart Live Build/QKQ1.190918.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 Zalo/20.04.02.r1",
"expect" :
{
"name" : "Zalo",
"version" : "20.04.02.r1",
"major" : "20",
"type" : "inapp"
}
} }
] ]

View File

@ -87,22 +87,6 @@
"architecture" : "amd64" "architecture" : "amd64"
} }
}, },
{
"desc" : "Alpha",
"ua" : "Mozilla/3.01 (WinNT; I) [AXP]",
"expect" :
{
"architecture" : "alpha"
}
},
{
"desc" : "Alpha",
"ua" : "Mozilla/5.0 (X11; OpenBSD alpha; rv:78.0) Gecko/20100101 Firefox/78.0",
"expect" :
{
"architecture" : "alpha"
}
},
{ {
"desc" : "ARM", "desc" : "ARM",
"ua" : "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537", "ua" : "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537",

View File

@ -122,6 +122,42 @@
"type": "undefined" "type": "undefined"
} }
}, },
{
"desc": "Philips SmartTV",
"ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PFL6606K/02 SmartTV (2011)",
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PFL6606K/02 SmartTV (2013)",
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PHS5301/12 SmartTV (2016)",
"ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en",
"expect": {
"vendor": "Philips",
"model": "32PHS5301/12",
"type": "smarttv"
}
},
{ {
"desc": "Samsung SmartTV", "desc": "Samsung SmartTV",
"ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42",

View File

@ -1,83 +0,0 @@
[
{
"desc": "Philips S616",
"ua": "Mozilla/5.0 (Linux; Android 5.1; Philips S616 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Mobile Safari/537.36",
"expect": {
"vendor": "Philips",
"model": "S616",
"type": "mobile"
}
},
{
"desc": "Philips W8510",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Philips W8510 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.68 Mobile Safari/537.36",
"expect": {
"vendor": "Philips",
"model": "W8510",
"type": "mobile"
}
},
{
"desc": "Philips SmartTV",
"ua": "Mozilla/5.0 (Linux; Android 11; PHILIPS 4k TV Build/RTXC.231010.082.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36",
"expect": {
"vendor": "PHILIPS",
"model": "undefined",
"type": "smarttv"
}
},
{
"desc": "Philips SmartTV",
"ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PFL6606K/02 SmartTV (2011)",
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PFL6606K/02 SmartTV (2013)",
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
"expect": {
"vendor": "Philips",
"model": "",
"type": "smarttv"
}
},
{
"desc": "Philips 32PHS5301/12 SmartTV (2016)",
"ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en",
"expect": {
"vendor": "Philips",
"model": "32PHS5301/12",
"type": "smarttv"
}
},
{
"desc": "Philips PH0M_EA_T32",
"ua": "Mozilla/5.0 (Linux; Android 10; Philips FHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.186 Mobile Safari/537.36",
"expect": {
"vendor": "Philips",
"model": "undefined",
"type": "smarttv"
}
},
{
"desc": "Philips PH3M_AL_T32",
"ua": "Mozilla/5.0 (Linux; Android 11; Philips Google TV TA7 Build/RTM5.220609.199; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.58 Mobile Safari/537.36",
"expect": {
"vendor": "Philips",
"model": "undefined",
"type": "smarttv"
}
}
]

View File

@ -25,23 +25,5 @@
"model": "Neo3 Link", "model": "Neo3 Link",
"type": "xr" "type": "xr"
} }
},
{
"desc": "Pico Neo 3",
"ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 OS5.12.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.48 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
"expect": {
"vendor": "Pico",
"model": "Neo 3",
"type": "xr"
}
},
{
"desc": "Pico Neo 3 Pro",
"ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 Pro OS5.9.9.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.46 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
"expect": {
"vendor": "Pico",
"model": "Neo 3 Pro",
"type": "xr"
}
} }
] ]

View File

@ -79,26 +79,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Algolia Crawler",
"ua" : "Algolia Crawler/v2.183.0",
"expect" :
{
"name" : "Algolia Crawler",
"version" : "v2.183.0",
"type" : "crawler"
}
},
{
"desc" : "Algolia Crawler Renderscript",
"ua" : "Algolia Crawler Renderscript",
"expect" :
{
"name" : "Algolia Crawler Renderscript",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Applebot", "desc" : "Applebot",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4 (Applebot/0.1;+http://www.apple.com/go/applebot)", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4 (Applebot/0.1;+http://www.apple.com/go/applebot)",
@ -159,16 +139,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Baidu ADS",
"ua" : "Baidu-ADS",
"expect" :
{
"name" : "Baidu-ADS",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Baiduspider", "desc" : "Baiduspider",
"ua" : "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)", "ua" : "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
@ -259,36 +229,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "BLEXBot",
"ua" : "Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)",
"expect" :
{
"name" : "BLEXBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "botify",
"ua" : "Desktop: Mozilla/5.0 (compatible; botify; http://botify.com)",
"expect" :
{
"name" : "botify",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "Bravebot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bravebot/1.0; +https://search.brave.com/help/brave-search-crawler) Chrome/W.X.Y.Z Safari/537.36",
"expect" :
{
"name" : "Bravebot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Bytespider", "desc" : "Bytespider",
"ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider", "ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider",
@ -329,26 +269,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Claude-SearchBot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Claude-SearchBot/1.0; +Claude-SearchBot@anthropic.com)",
"expect" :
{
"name" : "Claude-SearchBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "ClaudeWeb",
"ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
"expect" :
{
"name" : "Claude-Web",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Coc Coc Bot (web)", "desc" : "Coc Coc Bot (web)",
"ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)", "ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)",
@ -370,55 +290,15 @@
} }
}, },
{ {
"desc" : "cohere-training-data-crawler", "desc" : "ClaudeWeb",
"ua" : "cohere-training-data-crawler (+crawler@cohere.ai)", "ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
"expect" : "expect" :
{ {
"name" : "cohere-training-data-crawler", "name" : "Claude-Web",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "contxbot",
"ua" : "Mozilla/5.0 (compatible;contxbot/1.0)",
"expect" :
{
"name" : "contxbot",
"version" : "1.0", "version" : "1.0",
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Cotoyogi",
"ua" : "Mozilla/5.0 (compatible; Cotoyogi/4.0; +https://ds.rois.ac.jp/center8/crawler/)",
"expect" :
{
"name" : "Cotoyogi",
"version" : "4.0",
"type" : "crawler"
}
},
{
"desc" : "Coveobot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) (compatible; Coveobot/2.0;+http://www.coveo.com/bot.html)",
"expect" :
{
"name" : "Coveobot",
"version" : "2.0",
"type" : "crawler"
}
},
{
"desc" : "CriteoBot",
"ua" : "CriteoBot/0.1 (+https://www.criteo.com/criteo-crawler/)",
"expect" :
{
"name" : "CriteoBot",
"version" : "0.1",
"type" : "crawler"
}
},
{ {
"desc" : "DataForSEO", "desc" : "DataForSEO",
"ua" : "Mozilla/5.0 (compatible; DataForSeoBot; +https://dataforseo.com/dataforseo-bot)", "ua" : "Mozilla/5.0 (compatible; DataForSeoBot; +https://dataforseo.com/dataforseo-bot)",
@ -459,16 +339,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "DeepSeekBot",
"ua" : "DeepSeekBot",
"expect" :
{
"name" : "DeepSeekBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Diffbot", "desc" : "Diffbot",
"ua" : "Diffbot/0.1", "ua" : "Diffbot/0.1",
@ -499,26 +369,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "DuckDuckGo-Favicons-Bot",
"ua" : "DuckDuckGo-Favicons-Bot/1.0",
"expect" :
{
"name" : "DuckDuckGo-Favicons-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Elastic",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/124.0.6367.29 Safari/537.36 Elastic/Synthetics",
"expect" :
{
"name" : "Elastic",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Exabot", "desc" : "Exabot",
"ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)", "ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)",
@ -559,36 +409,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "FirecrawlAgent",
"ua" : "Mozilla/5.0 (compatible; FirecrawlAgent/1.0)",
"expect" :
{
"name" : "FirecrawlAgent",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Freespoke",
"ua" : "Mozilla/5.0 (compatible; Freespoke/2.0; +https://docs.freespoke.com/search/bot)",
"expect" :
{
"name" : "Freespoke",
"version" : "2.0",
"type" : "crawler"
}
},
{
"desc" : "APIs-Google",
"ua" : "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)",
"expect" :
{
"name" : "APIs-Google",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Googlebot-Video", "desc" : "Googlebot-Video",
"ua" : "Googlebot-Video/1.0", "ua" : "Googlebot-Video/1.0",
@ -689,16 +509,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Google-CloudVertexBot",
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.183 Mobile Safari/537.36 (compatible; Google-CloudVertexBot; +https://cloud.google.com/enterprise-search)",
"expect" :
{
"name" : "Google-CloudVertexBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Google-Safety", "desc" : "Google-Safety",
"ua" : "Google-Safety", "ua" : "Google-Safety",
@ -719,16 +529,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "HuggingFace-Bot",
"ua" : "Mozilla/5.0 (compatible; HuggingFace-Bot/1.0; +https://huggingface.co/)",
"expect" :
{
"name" : "HuggingFace-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "iAskBot", "desc" : "iAskBot",
"ua" : "Mozilla/5.0 AppleWebKit/605.1.15 (KHTML, like Gecko; compatible; iAskBot/1.0; +https://iask.ai/) Chrome/120.0.6099.119 Safari/605.1.15", "ua" : "Mozilla/5.0 AppleWebKit/605.1.15 (KHTML, like Gecko; compatible; iAskBot/1.0; +https://iask.ai/) Chrome/120.0.6099.119 Safari/605.1.15",
@ -749,26 +549,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Kagibot",
"ua" : "Mozilla/5.0 (compatible; Kagibot/1.0; +https://kagi.com/bot)",
"expect" :
{
"name" : "Kagibot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Kangaroo Bot",
"ua" : "Mozilla/5.0 (compatible; Kangaroo Bot/1.0)",
"expect" :
{
"name" : "Kangaroo Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Linespider", "desc" : "Linespider",
"ua" : "Mozilla/5.0 (compatible; Linespider/1.1; +https://lin.ee/4dwXkTH)", "ua" : "Mozilla/5.0 (compatible; Linespider/1.1; +https://lin.ee/4dwXkTH)",
@ -799,16 +579,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Marginalia Search",
"ua" : "search.marginalia.nu",
"expect" :
{
"name" : "marginalia",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Meta-ExternalAgent", "desc" : "Meta-ExternalAgent",
"ua" : "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)", "ua" : "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
@ -840,16 +610,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "msnbot",
"ua" : "msnbot/2.0b (+http://search.msn.com/msnbot.htm)",
"expect" :
{
"name" : "msnbot",
"version" : "2.0b",
"type" : "crawler"
}
},
{ {
"desc" : "Omgili", "desc" : "Omgili",
"ua" : "omgili/0.5 +https://omgili.com", "ua" : "omgili/0.5 +https://omgili.com",
@ -870,16 +630,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "OnCrawl",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4 (compatible; OnCrawl Mobile/1.0; +http://www.oncrawl.com/)",
"expect" :
{
"name" : "OnCrawl",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Onespot", "desc" : "Onespot",
"ua" : "Mozilla/5.0 (compatible; Onespot-ScraperBot/1.0; +https://www.onespot.com/identifying-traffic.html)", "ua" : "Mozilla/5.0 (compatible; Onespot-ScraperBot/1.0; +https://www.onespot.com/identifying-traffic.html)",
@ -900,16 +650,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "PanguBot",
"ua" : "Mozilla/5.0 (compatible; PanguBot/1.0)",
"expect" :
{
"name" : "PanguBot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "PerplexityBot", "desc" : "PerplexityBot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)",
@ -970,46 +710,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Replicate-Bot",
"ua" : "Mozilla/5.0 (compatible; Replicate-Bot/1.0; +https://replicate.com/)",
"expect" :
{
"name" : "Replicate-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "RunPod-Bot",
"ua" : "Mozilla/5.0 (compatible; RunPod-Bot/1.0; +https://runpod.io/)",
"expect" :
{
"name" : "RunPod-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "SBIntuitionsBot",
"ua" : "Mozilla/5.0 (compatible; SBIntuitionsBot/0.1;+https://www.sbintuitions.co.jp/bot/)",
"expect" :
{
"name" : "SBIntuitionsBot",
"version" : "0.1",
"type" : "crawler"
}
},
{
"desc" : "SeekportBot",
"ua" : "Mozilla/5.0 (compatible; SeekportBot; +https://bot.seekport.com)",
"expect" :
{
"name" : "SeekportBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "SemrushBot", "desc" : "SemrushBot",
"ua" : "Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)", "ua" : "Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)",
@ -1061,27 +761,7 @@
} }
}, },
{ {
"desc" : "Siteimprove", "desc" : "Sogou",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; SiteCheck-sitecrawl by Siteimprove.com; +https://siteimprove.com/bots) Chrome/[VERSION] Safari/537.36",
"expect" :
{
"name" : "Siteimprove",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "Sogou Pic Spider",
"ua" : "Sogou Pic Spider/3.0( http://www.sogou.com/docs/help/webmasters.htm#07)",
"expect" :
{
"name" : "Sogou Pic Spider",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "Sogou web spider",
"ua" : "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "ua" : "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)",
"expect" : "expect" :
{ {
@ -1110,16 +790,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "TikTokSpider",
"ua" : "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; TikTokSpider; ttspider-feedback@tiktok.com)",
"expect" :
{
"name" : "TikTokSpider",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Timpibot", "desc" : "Timpibot",
"ua" : "Timpibot/0.8 (+http://www.timpi.io)", "ua" : "Timpibot/0.8 (+http://www.timpi.io)",
@ -1130,16 +800,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Together-Bot",
"ua" : "Mozilla/5.0 (compatible; Together-Bot/1.0; +https://together.ai/)",
"expect" :
{
"name" : "Together-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "TurnitinBot", "desc" : "TurnitinBot",
"ua" : "TurnitinBot (https://turnitin.com/robot/crawlerinfo.html)", "ua" : "TurnitinBot (https://turnitin.com/robot/crawlerinfo.html)",
@ -1150,26 +810,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "TwinAgent",
"ua" : "TwinAgent/1.0",
"expect" :
{
"name" : "TwinAgent",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "xAI-Bot",
"ua" : "Mozilla/5.0 (compatible; xAI-Bot/1.0; +https://x.ai/)",
"expect" :
{
"name" : "xAI-Bot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "VelenPublicWebCrawler", "desc" : "VelenPublicWebCrawler",
"ua" : "Mozilla/5.0 (compatible; VelenPublicWebCrawler/1.0; +https://velen.io)", "ua" : "Mozilla/5.0 (compatible; VelenPublicWebCrawler/1.0; +https://velen.io)",
@ -1180,36 +820,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "v0bot",
"ua" : "v0bot",
"expect" :
{
"name" : "v0bot",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "webzio",
"ua" : "webzio (+https://webz.io/bot.html)",
"expect" :
{
"name" : "webzio",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "Webzio-Extended",
"ua" : "Mozilla/5.0 (compatible; Webzio-Extended/1.0; +https://www.webzio.com/bot.html)",
"expect" :
{
"name" : "Webzio-Extended",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Yahoo! Japan", "desc" : "Yahoo! Japan",
"ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)", "ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)",
@ -1230,46 +840,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "YandexAccessibilityBot",
"ua" : "Mozilla/5.0 (compatible; YandexAccessibilityBot/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexAccessibilityBot",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexAdditionalBot",
"ua" : "Mozilla/5.0 (compatible; YandexAdditionalBot/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexAdditionalBot",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexAdNet",
"ua" : "Mozilla/5.0 (compatible; YandexAdNet/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexAdNet",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexBlogs",
"ua" : "Mozilla/5.0 (compatible; YandexBlogs/0.99; robot; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexBlogs",
"version" : "0.99",
"type" : "crawler"
}
},
{ {
"desc" : "YandexBot", "desc" : "YandexBot",
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)", "ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)",
@ -1280,256 +850,6 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "YandexBot MirrorDetector",
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; MirrorDetector; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexBot MirrorDetector",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexComBot",
"ua" : "Mozilla/5.0 (compatible; YandexComBot/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexComBot",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexFavicons",
"ua" : "Mozilla/5.0 (compatible; YandexFavicons/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexFavicons",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexImageResizer",
"ua" : "Mozilla/5.0 (compatible; YandexImageResizer/2.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexImageResizer",
"version" : "2.0",
"type" : "crawler"
}
},
{
"desc" : "YandexImages",
"ua" : "Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexImages",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexMarket",
"ua" : "Mozilla/5.0 (compatible; YandexMarket/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexMarket",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexMetrika",
"ua" : "Mozilla/5.0 (compatible; YandexMetrika/2.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexMetrika",
"version" : "2.0",
"type" : "crawler"
}
},
{
"desc" : "YandexMedia",
"ua" : "Mozilla/5.0 (compatible; YandexMedia/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexMedia",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexMobileBot",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4 (compatible; YandexMobileBot/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexMobileBot",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexMobileScreenShotBot",
"ua" : "Mozilla/5.0 (compatible; YandexMobileScreenShotBot/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexMobileScreenShotBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexNews",
"ua" : "Mozilla/5.0 (compatible; YandexNews/4.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexNews",
"version" : "4.0",
"type" : "crawler"
}
},
{
"desc" : "YandexOntoDB",
"ua" : "Mozilla/5.0 (compatible; YandexOntoDB/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexOntoDB",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexOntoDBAPI",
"ua" : "Mozilla/5.0 (compatible; YandexOntoDBAPI/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexOntoDBAPI",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexPartner",
"ua" : "Mozilla/5.0 (compatible; YandexPartner/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexPartner",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexRCA",
"ua" : "Mozilla/5.0 (compatible; YandexRCA/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexRCA",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexRenderResourcesBot",
"ua" : "Mozilla/5.0 (compatible; YandexRenderResourcesBot/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexRenderResourcesBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexScreenshotBot",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36 (compatible; YandexScreenshotBot/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexScreenshotBot",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexSpravBot",
"ua" : "Mozilla/5.0 (compatible; YandexSpravBot/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexSpravBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexTracker",
"ua" : "Mozilla/5.0 (compatible; YandexTracker/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexTracker",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexVertis",
"ua" : "Mozilla/5.0 (compatible; YandexVertis/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexVertis",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexVerticals",
"ua" : "Mozilla/5.0 (compatible; YandexVerticals/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexVerticals",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexVideo",
"ua" : "Mozilla/5.0 (compatible; YandexVideo/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexVideo",
"version" : "3.0",
"type" : "crawler"
}
},
{
"desc" : "YandexVideoParser",
"ua" : "Mozilla/5.0 (compatible; YandexVideoParser/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexVideoParser",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "YandexWebmaster",
"ua" : "Mozilla/5.0 (compatible; YandexWebmaster/2.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexWebmaster",
"version" : "2.0",
"type" : "crawler"
}
},
{
"desc" : "YepBot",
"ua" : "Mozilla/5.0 (compatible; YepBot/1.0; +http://yep.com/yepbot/)",
"expect" :
{
"name" : "YepBot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Yeti", "desc" : "Yeti",
"ua" : "Mozilla/5.0 (compatible; Yeti/1.1; +http://naver.me/spd)", "ua" : "Mozilla/5.0 (compatible; Yeti/1.1; +http://naver.me/spd)",
@ -1569,15 +889,5 @@
"version" : "undefined", "version" : "undefined",
"type" : "crawler" "type" : "crawler"
} }
},
{
"desc" : "ZumBot",
"ua" : "Mozilla/5.0 (compatible; ZumBot/1.0; http://help.zum.com/inquiry)",
"expect" :
{
"name" : "ZumBot",
"version" : "1.0",
"type" : "crawler"
}
} }
] ]

View File

@ -9,16 +9,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "Asana",
"ua" : "Asana/1.4.0 WebsiteMetadataRetriever",
"expect" :
{
"name" : "Asana",
"version" : "1.4.0",
"type" : "fetcher"
}
},
{ {
"desc" : "Better Uptime Bot", "desc" : "Better Uptime Bot",
"ua" : "Better Uptime Bot Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", "ua" : "Better Uptime Bot Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
@ -39,26 +29,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "Bit.ly",
"ua" : "bitlybot/3.0 (+http://bit.ly/)",
"expect" :
{
"name" : "bitlybot",
"version" : "3.0",
"type" : "fetcher"
}
},
{
"desc" : "Blueno",
"ua" : "acebookexternalhit/1.1 (compatible; Blueno/1.0; +http://naver.me/scrap)",
"expect" :
{
"name" : "Blueno",
"version" : "1.0",
"type" : "fetcher"
}
},
{ {
"desc" : "Bluesky", "desc" : "Bluesky",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app) Chrome/100.0.0.0 Safari/537.36", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app) Chrome/100.0.0.0 Safari/537.36",
@ -69,16 +39,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "BufferLinkPreviewBot",
"ua" : "BufferLinkPreviewBot/1.0 (+https://scraper.buffer.com/about/bots/link-preview-bot)",
"expect" :
{
"name" : "BufferLinkPreviewBot",
"version" : "1.0",
"type" : "fetcher"
}
},
{ {
"desc" : "ChatGPT-User", "desc" : "ChatGPT-User",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot",
@ -89,36 +49,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "Chrome-Lighthouse",
"ua" : "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
"expect" :
{
"name" : "Chrome-Lighthouse",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Claude-User",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Claude-User/1.0; +Claude-User@anthropic.com)",
"expect" :
{
"name" : "Claude-User",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "Cohere-AI",
"ua" : "Mozilla/5.0 (compatible; Cohere-AI/1.0; +https://cohere.com/)",
"expect" :
{
"name" : "Cohere-AI",
"version" : "1.0",
"type" : "fetcher"
}
},
{ {
"desc" : "DuckAssistBot", "desc" : "DuckAssistBot",
"ua" : "DuckAssistBot/1.2; (+http://duckduckgo.com/duckassistbot.html)", "ua" : "DuckAssistBot/1.2; (+http://duckduckgo.com/duckassistbot.html)",
@ -129,16 +59,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "Gemini-Deep-Research",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Gemini-Deep-Research; +https://gemini.google/overview/deep-research/) Chrome/135.0.0.0 Safari/537.36",
"expect" :
{
"name" : "Gemini-Deep-Research",
"version" : "undefined",
"type" : "fetcher"
}
},
{ {
"desc" : "Google FeedFetcher", "desc" : "Google FeedFetcher",
"ua" : "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)", "ua" : "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)",
@ -209,16 +129,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "HubSpot Page Fetcher",
"ua" : "HubSpot Page Fetcher/1.0 http://www.hubspot.com/ web-crawlers@hubspot.com",
"expect" :
{
"name" : "HubSpot Page Fetcher",
"version" : "1.0",
"type" : "fetcher"
}
},
{ {
"desc" : "Iframely", "desc" : "Iframely",
"ua" : "Iframely/1.3.1 (+https://iframely.com/docs/about)", "ua" : "Iframely/1.3.1 (+https://iframely.com/docs/about)",
@ -229,16 +139,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "kakaotalk-scrap",
"ua" : "facebookexternalhit/1.1; kakaotalk-scrap/1.0; +https://devtalk.kakao.com/t/scrap/33984",
"expect" :
{
"name" : "kakaotalk-scrap",
"version" : "1.0",
"type" : "fetcher"
}
},
{ {
"desc" : "Meta-ExternalFetcher", "desc" : "Meta-ExternalFetcher",
"ua" : "meta-externalfetcher/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)", "ua" : "meta-externalfetcher/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
@ -349,26 +249,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "vercel-favicon-bot",
"ua" : "vercel-favicon-bot",
"expect" :
{
"name" : "vercel-favicon-bot",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "vercel-screenshot-bot",
"ua" : "vercel-screenshot-bot",
"expect" :
{
"name" : "vercel-screenshot-bot",
"version" : "undefined",
"type" : "fetcher"
}
},
{ {
"desc" : "Vercelbot", "desc" : "Vercelbot",
"ua" : "Vercelbot (+https://vercel.com)", "ua" : "Vercelbot (+https://vercel.com)",
@ -379,26 +259,6 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "vercelflags",
"ua" : "vercelflags",
"expect" :
{
"name" : "vercelflags",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "verceltracing",
"ua" : "verceltracing",
"expect" :
{
"name" : "verceltracing",
"version" : "undefined",
"type" : "fetcher"
}
},
{ {
"desc" : "WhatsApp", "desc" : "WhatsApp",
"ua" : "WhatsApp/2.23.20.0", "ua" : "WhatsApp/2.23.20.0",
@ -408,105 +268,5 @@
"version" : "2.23.20.0", "version" : "2.23.20.0",
"type" : "fetcher" "type" : "fetcher"
} }
},
{
"desc" : "YaDirectFetcher",
"ua" : "Mozilla/5.0 (compatible; YaDirectFetcher/1.0; Dyatel; +http://yandex.com/bots)",
"expect" :
{
"name" : "YaDirectFetcher",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexCalendar",
"ua" : "Mozilla/5.0 (compatible; YandexCalendar/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexCalendar",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexDirect",
"ua" : "Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexDirect",
"version" : "3.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexDirectDyn",
"ua" : "Mozilla/5.0 (compatible; YandexDirectDyn/1.0; +http://yandex.com/bots",
"expect" :
{
"name" : "YandexDirectDyn",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexForDomain",
"ua" : "Mozilla/5.0 (compatible; YandexForDomain/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexForDomain",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexPagechecker",
"ua" : "Mozilla/5.0 (compatible; YandexPagechecker/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexPagechecker",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexSearchShop",
"ua" : "Mozilla/5.0 (compatible; YandexSearchShop/1.0; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexSearchShop",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "YandexSitelinks",
"ua" : "Mozilla/5.0 (compatible; YandexSitelinks; Dyatel; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexSitelinks",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "YandexUserproxy",
"ua" : "Mozilla/5.0 (compatible; YandexUserproxy; robot; +http://yandex.com/bots)",
"expect" :
{
"name" : "YandexUserproxy",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Zoombot",
"ua" : "Mozilla/5.0 (compatible; Zoombot/1.0; +https://zoom.us; crawler@domain.com)",
"expect" :
{
"name" : "Zoombot",
"version" : "1.0",
"type" : "fetcher"
}
} }
] ]

View File

@ -1,5 +1,5 @@
import { UAParser } from '../../src/main/ua-parser.mjs'; import { UAParser } from '../../src/main/ua-parser.mjs';
import { CPUArch, DeviceType, EngineName } from '../../src/enums/ua-parser-enums.mjs'; import { CPU, Device, Engine } from '../../src/enums/ua-parser-enums.mjs';
import * as assert from 'assert'; import * as assert from 'assert';
describe('Returns', () => { describe('Returns', () => {
@ -19,8 +19,8 @@ describe('Returns', () => {
describe('Enums', () => { describe('Enums', () => {
it('Can use enum', () => { it('Can use enum', () => {
const { cpu, device, engine } = UAParser('Mozilla/5.0 (X11; U; Linux armv7l; en-GB; rv:1.9.2a1pre) Gecko/20090928 Firefox/3.5 Maemo Browser 1.4.1.22 RX-51 N900'); const { cpu, device, engine } = UAParser('Mozilla/5.0 (X11; U; Linux armv7l; en-GB; rv:1.9.2a1pre) Gecko/20090928 Firefox/3.5 Maemo Browser 1.4.1.22 RX-51 N900');
assert.strictEqual(cpu.is(CPUArch.ARM), true); assert.strictEqual(cpu.is(CPU.ARM), true);
assert.strictEqual(device.is(DeviceType.MOBILE), true); assert.strictEqual(device.is(Device.MOBILE), true);
assert.strictEqual(engine.is(EngineName.GECKO), true); assert.strictEqual(engine.is(Engine.GECKO), true);
}); });
}); });

View File

@ -5,8 +5,6 @@ const traverse = require('@babel/traverse').default;
const safe = require('safe-regex'); const safe = require('safe-regex');
const { UAParser } = require('../../src/main/ua-parser'); const { UAParser } = require('../../src/main/ua-parser');
const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries, Vehicles } = require('../../src/extensions/ua-parser-extensions'); const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries, Vehicles } = require('../../src/extensions/ua-parser-extensions');
const { BrowserType, OSName, Extension } = require('../../src/enums/ua-parser-enums');
const { CLI, Crawler, Email, Fetcher, Library } = Extension.BrowserName;
describe('Extensions', () => { describe('Extensions', () => {
[ [
@ -44,29 +42,29 @@ describe('Extensions', () => {
const jsdom = 'Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/20.0.3'; const jsdom = 'Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/20.0.3';
const scrapy = 'Scrapy/1.5.0 (+https://scrapy.org)'; const scrapy = 'Scrapy/1.5.0 (+https://scrapy.org)';
assert.equal(UAParser(scrapy, Bots).browser.name, Library.SCRAPY); assert.equal(UAParser(scrapy, Bots).browser.name, 'Scrapy');
const emailParser = new UAParser(Emails); const emailParser = new UAParser(Emails);
assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: Email.MICROSOFT_OUTLOOK, version: "16.0.9126", major: "16", type: BrowserType.EMAIL}); assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: "Microsoft Outlook", version: "16.0.9126", major: "16", type: "email"});
assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: Email.THUNDERBIRD, version: "78.13.0", major: "78", type: BrowserType.EMAIL}); assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: "Thunderbird", version: "78.13.0", major: "78", type: "email"});
const libraryParser = new UAParser(Libraries); const libraryParser = new UAParser(Libraries);
assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: Library.AXIOS, version: "1.3.5", major: "1", type: BrowserType.LIBRARY}); assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "library"});
assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: Library.JSDOM, version: "20.0.3", major: "20", type: BrowserType.LIBRARY}); assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "library"});
assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: Library.SCRAPY, version: "1.5.0", major: "1", type: BrowserType.LIBRARY}); assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "library"});
// Bluesky // Bluesky
const bluesky = 'Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)'; const bluesky = 'Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)';
assert.deepEqual(new UAParser(bluesky, Bots).getBrowser(), { assert.deepEqual(new UAParser(bluesky, Bots).getBrowser(), {
name: Fetcher.BLUESKY, name: 'Bluesky',
version: '1.1', version: '1.1',
major: '1', major: '1',
type: BrowserType.FETCHER type: 'fetcher'
}); });
const whatsapp = "WhatsApp/2.0 A"; const whatsapp = "WhatsApp/2.0 A";
assert.deepEqual(new UAParser(whatsapp, Fetchers).getOS(), { assert.deepEqual(new UAParser(whatsapp, Fetchers).getOS(), {
name : OSName.ANDROID, name : 'Android',
version : undefined version : undefined
}); });
}); });
@ -79,14 +77,14 @@ describe('Merge', () => {
// try merging crawlers & CLIs // try merging crawlers & CLIs
const crawlersAndCLIs = { browser : [...Crawlers.browser, ...CLIs.browser]}; const crawlersAndCLIs = { browser : [...Crawlers.browser, ...CLIs.browser]};
const crawlersAndCLIsParser = new UAParser(crawlersAndCLIs); const crawlersAndCLIsParser = new UAParser(crawlersAndCLIs);
assert.deepEqual(crawlersAndCLIsParser.setUA(wget).getBrowser(), {name: CLI.WGET, version: "1.21.1", major: "1", type: BrowserType.CLI}); assert.deepEqual(crawlersAndCLIsParser.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
assert.deepEqual(crawlersAndCLIsParser.setUA(facebookBot).getBrowser(), {name: Crawler.META_FACEBOOKBOT, version: "1.0", major: "1", type: BrowserType.CRAWLER}); assert.deepEqual(crawlersAndCLIsParser.setUA(facebookBot).getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
// alternative merge options // alternative merge options
const crawlersAndCLIsParser2 = new UAParser([Crawlers, CLIs]); const crawlersAndCLIsParser2 = new UAParser([Crawlers, CLIs]);
const crawlersAndCLIsParser3 = new UAParser(facebookBot, [Crawlers, CLIs]); const crawlersAndCLIsParser3 = new UAParser(facebookBot, [Crawlers, CLIs]);
assert.deepEqual(crawlersAndCLIsParser2.setUA(wget).getBrowser(), {name: CLI.WGET, version: "1.21.1", major: "1", type: BrowserType.CLI}); assert.deepEqual(crawlersAndCLIsParser2.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
assert.deepEqual(crawlersAndCLIsParser3.getBrowser(), {name: Crawler.META_FACEBOOKBOT, version: "1.0", major: "1", type: BrowserType.CRAWLER}); assert.deepEqual(crawlersAndCLIsParser3.getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
}); });
}); });

View File

@ -2,7 +2,6 @@ const assert = require('assert');
const { UAParser } = require('../../src/main/ua-parser'); const { UAParser } = require('../../src/main/ua-parser');
const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../../src/helpers/ua-parser-helpers'); const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../../src/helpers/ua-parser-helpers');
const { Bots, Emails } = require('../../src/extensions/ua-parser-extensions'); const { Bots, Emails } = require('../../src/extensions/ua-parser-extensions');
const { DeviceVendor } = require('../../src/enums/ua-parser-enums');
describe('getDeviceVendor', () => { describe('getDeviceVendor', () => {
it('Can guess the device vendor from a model name', () => { it('Can guess the device vendor from a model name', () => {
@ -12,10 +11,10 @@ describe('getDeviceVendor', () => {
const modelNexus = 'Nexus 6P'; const modelNexus = 'Nexus 6P';
const modelAquos = 'AQUOS-TVX19B'; const modelAquos = 'AQUOS-TVX19B';
assert.equal(getDeviceVendor(modelSM), DeviceVendor.SAMSUNG); assert.equal(getDeviceVendor(modelSM), 'Samsung');
assert.equal(getDeviceVendor(modelRedmi), DeviceVendor.XIAOMI); assert.equal(getDeviceVendor(modelRedmi), 'Xiaomi');
assert.equal(getDeviceVendor(modelNexus), DeviceVendor.HUAWEI); assert.equal(getDeviceVendor(modelNexus), 'Huawei');
assert.equal(getDeviceVendor(modelAquos), DeviceVendor.SHARP); assert.equal(getDeviceVendor(modelAquos), 'Sharp');
}); });
}); });

View File

@ -10,7 +10,7 @@ var cpus = require('../data/ua/cpu/cpu-all.json');
var devices = readJsonFiles('test/data/ua/device'); var devices = readJsonFiles('test/data/ua/device');
var engines = require('../data/ua/engine/engine-all.json'); var engines = require('../data/ua/engine/engine-all.json');
var os = readJsonFiles('test/data/ua/os'); var os = readJsonFiles('test/data/ua/os');
var { Headers } = require('undici'); var { Headers } = require('node-fetch');
function readJsonFiles(dir) { function readJsonFiles(dir) {
var list = []; var list = [];
@ -91,34 +91,6 @@ describe('Returns', function () {
}); });
done(); done();
}); });
it('works even when Array.prototype has been mangled', function(done) {
const result = withMangledArrayProto(() => new UAParser('').getResult());
function withMangledArrayProto(fn, key = 'isEmpty', value = function() { return this.length === 0; }) {
const originalValue = Array.prototype[key];
const restore = Object.hasOwnProperty.call(Array.prototype, key)
? () => Array.prototype[key] = originalValue
: () => delete Array.prototype[key];
Array.prototype[key] = value;
const result = fn();
restore();
return result;
}
assert.deepEqual(result,
{
ua : '',
browser: { name: undefined, version: undefined, major: undefined, type: undefined },
cpu: { architecture: undefined },
device: { vendor: undefined, model: undefined, type: undefined },
engine: { name: undefined, version: undefined},
os: { name: undefined, version: undefined }
});
done();
});
}); });
describe('Extending Regex', function () { describe('Extending Regex', function () {
@ -381,18 +353,4 @@ describe('Read user-agent data from req.headers', function () {
const { browser } = UAParser(reqHeaders); const { browser } = UAParser(reqHeaders);
assert.strictEqual(browser.is('Midori'), true); assert.strictEqual(browser.is('Midori'), true);
}); });
});
it('Headers field name should be case insensitive', function () {
const hEaDeRs = {
'uSeR-aGenT' : 'Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+'
};
const { browser } = UAParser(hEaDeRs);
assert.strictEqual(browser.toString(), "Midori 0.2.2");
});
it('Empty headers should not raise any error', function () {
const emptyHeaders = {};
const { browser } = UAParser(emptyHeaders);
assert.strictEqual(browser.toString(), "undefined");
});
});

View File

@ -1,7 +1,5 @@
const assert = require('assert'); const assert = require('assert');
const { UAParser } = require('../../src/main/ua-parser'); const { UAParser } = require('../../src/main/ua-parser');
const { BrowserName, CPUArch, DeviceType, DeviceVendor, EngineName, OSName } = require('../../src/enums/ua-parser-enums');
const UACHTests = require('../data/ua-ch/headers');
describe('Map UA-CH headers', () => { describe('Map UA-CH headers', () => {
@ -27,27 +25,27 @@ describe('Map UA-CH headers', () => {
it('Can read from client-hints headers using `withClientHints()`', () => { it('Can read from client-hints headers using `withClientHints()`', () => {
assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"); assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36");
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "93.0.1.2"); assert.strictEqual(uap.browser.version, "93.0.1.2");
assert.strictEqual(uap.browser.major, "93"); assert.strictEqual(uap.browser.major, "93");
assert.strictEqual(browser.name, BrowserName.CHROME); assert.strictEqual(browser.name, "Chrome");
assert.strictEqual(browser.version, "93.0.1.2"); assert.strictEqual(browser.version, "93.0.1.2");
assert.strictEqual(browser.major, "93"); assert.strictEqual(browser.major, "93");
assert.strictEqual(uap.cpu.architecture, CPUArch.ARM_64); assert.strictEqual(uap.cpu.architecture, "arm64");
assert.strictEqual(cpu.architecture, CPUArch.ARM_64); assert.strictEqual(cpu.architecture, "arm64");
assert.strictEqual(uap.device.type, DeviceType.MOBILE); assert.strictEqual(uap.device.type, "mobile");
assert.strictEqual(uap.device.model, "Pixel 99"); assert.strictEqual(uap.device.model, "Pixel 99");
assert.strictEqual(uap.device.vendor, DeviceVendor.GOOGLE); assert.strictEqual(uap.device.vendor, "Google");
assert.strictEqual(device.type, DeviceType.MOBILE); assert.strictEqual(device.type, "mobile");
assert.strictEqual(device.model, "Pixel 99"); assert.strictEqual(device.model, "Pixel 99");
assert.strictEqual(device.vendor, DeviceVendor.GOOGLE); assert.strictEqual(device.vendor, "Google");
assert.strictEqual(uap.engine.name, EngineName.BLINK); assert.strictEqual(uap.engine.name, 'Blink');
assert.strictEqual(uap.engine.version, '93.0.1.2'); assert.strictEqual(uap.engine.version, '93.0.1.2');
assert.strictEqual(engine.name, EngineName.BLINK); assert.strictEqual(engine.name, 'Blink');
assert.strictEqual(engine.version, '93.0.1.2'); assert.strictEqual(engine.version, '93.0.1.2');
assert.strictEqual(uap.os.name, OSName.WINDOWS); assert.strictEqual(uap.os.name, "Windows");
assert.strictEqual(uap.os.version, "11"); assert.strictEqual(uap.os.version, "11");
assert.strictEqual(os.name, OSName.WINDOWS); assert.strictEqual(os.name, "Windows");
assert.strictEqual(os.version, "11"); assert.strictEqual(os.version, "11");
}); });
@ -60,16 +58,16 @@ describe('Map UA-CH headers', () => {
engine = new UAParser(headers).getEngine(); engine = new UAParser(headers).getEngine();
os = new UAParser(headers).getOS(); os = new UAParser(headers).getOS();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "110.0.0.0"); assert.strictEqual(uap.browser.version, "110.0.0.0");
assert.strictEqual(uap.browser.major, "110"); assert.strictEqual(uap.browser.major, "110");
assert.strictEqual(uap.cpu.architecture, CPUArch.X86_64); assert.strictEqual(uap.cpu.architecture, "amd64");
assert.strictEqual(uap.device.type, undefined); assert.strictEqual(uap.device.type, undefined);
assert.strictEqual(uap.device.model, undefined); assert.strictEqual(uap.device.model, undefined);
assert.strictEqual(uap.device.vendor, undefined); assert.strictEqual(uap.device.vendor, undefined);
assert.strictEqual(uap.engine.name, EngineName.BLINK); assert.strictEqual(uap.engine.name, 'Blink');
assert.strictEqual(uap.engine.version, '110.0.0.0'); assert.strictEqual(uap.engine.version, '110.0.0.0');
assert.strictEqual(uap.os.name, OSName.LINUX); assert.strictEqual(uap.os.name, "Linux");
assert.strictEqual(uap.os.version, undefined); assert.strictEqual(uap.os.version, undefined);
}); });
@ -82,16 +80,16 @@ describe('Map UA-CH headers', () => {
uap = UAParser(headers2).withClientHints(); uap = UAParser(headers2).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "110.0.0.0"); assert.strictEqual(uap.browser.version, "110.0.0.0");
assert.strictEqual(uap.browser.major, "110"); assert.strictEqual(uap.browser.major, "110");
assert.strictEqual(uap.cpu.architecture, CPUArch.X86_64); assert.strictEqual(uap.cpu.architecture, "amd64");
assert.strictEqual(uap.device.type, DeviceType.MOBILE); assert.strictEqual(uap.device.type, "mobile");
assert.strictEqual(uap.device.model, undefined); assert.strictEqual(uap.device.model, undefined);
assert.strictEqual(uap.device.vendor, undefined); assert.strictEqual(uap.device.vendor, undefined);
assert.strictEqual(uap.engine.name, EngineName.BLINK); assert.strictEqual(uap.engine.name, 'Blink');
assert.strictEqual(uap.engine.version, '110.0.0.0'); assert.strictEqual(uap.engine.version, '110.0.0.0');
assert.strictEqual(uap.os.name, OSName.LINUX); assert.strictEqual(uap.os.name, "Linux");
assert.strictEqual(uap.os.version, undefined); assert.strictEqual(uap.os.version, undefined);
}); });
@ -118,10 +116,10 @@ describe('Map UA-CH headers', () => {
} }
*/ */
assert.strictEqual(ua.os.is(OSName.MACOS), true); assert.strictEqual(ua.os.is("macOS"), true);
assert.strictEqual(ua.cpu.is(CPUArch.ARM), true); assert.strictEqual(ua.cpu.is("arm"), true);
assert.strictEqual(ua.device.is(DeviceType.MOBILE), false); assert.strictEqual(ua.device.is("mobile"), false);
assert.strictEqual(ua.device.is(DeviceType.TABLET), false); assert.strictEqual(ua.device.is("tablet"), false);
}); });
}); });
@ -140,11 +138,11 @@ describe('Map UA-CH headers', () => {
}; };
UAParser(FFVR).withClientHints().then(ua => { UAParser(FFVR).withClientHints().then(ua => {
assert.strictEqual(ua.device.type, DeviceType.XR); assert.strictEqual(ua.device.type, 'xr');
}); });
UAParser(FFEInk).withClientHints().then(ua => { UAParser(FFEInk).withClientHints().then(ua => {
assert.strictEqual(ua.device.type, DeviceType.TABLET); assert.strictEqual(ua.device.type, 'tablet');
}); });
@ -170,7 +168,7 @@ describe('Map UA-CH headers', () => {
uap = UAParser(headers2).withClientHints(); uap = UAParser(headers2).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, undefined); assert.strictEqual(uap.browser.version, undefined);
assert.strictEqual(uap.browser.major, undefined); assert.strictEqual(uap.browser.major, undefined);
}); });
@ -197,37 +195,258 @@ describe('Map UA-CH headers', () => {
}; };
uap = UAParser(headers3a).withClientHints(); uap = UAParser(headers3a).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "120.0.6099.132"); assert.strictEqual(uap.browser.version, "120.0.6099.132");
uap = UAParser(headers3b).withClientHints(); uap = UAParser(headers3b).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "120.0.6099.132"); assert.strictEqual(uap.browser.version, "120.0.6099.132");
uap = UAParser(headers3c).withClientHints(); uap = UAParser(headers3c).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.CHROME); assert.strictEqual(uap.browser.name, "Chrome");
assert.strictEqual(uap.browser.version, "120.0.6099.132"); assert.strictEqual(uap.browser.version, "120.0.6099.132");
uap = UAParser(headers3d).withClientHints(); uap = UAParser(headers3d).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.EDGE); assert.strictEqual(uap.browser.name, "Edge");
assert.strictEqual(uap.browser.version, "120.0.6099.133"); assert.strictEqual(uap.browser.version, "120.0.6099.133");
uap = UAParser(headers3e).withClientHints(); uap = UAParser(headers3e).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.EDGE); assert.strictEqual(uap.browser.name, "Edge");
assert.strictEqual(uap.browser.version, "120.0.6099.133"); assert.strictEqual(uap.browser.version, "120.0.6099.133");
uap = UAParser(headers3f).withClientHints(); uap = UAParser(headers3f).withClientHints();
assert.strictEqual(uap.browser.name, BrowserName.EDGE); assert.strictEqual(uap.browser.name, "Edge");
assert.strictEqual(uap.browser.version, "120.0.6099.133"); assert.strictEqual(uap.browser.version, "120.0.6099.133");
}); });
}); });
describe('UA-CH Headers tests', () => { describe('UA-CH Headers tests', () => {
UACHTests.forEach(test => { [
it(`Test for ${test.desc}`, () => { {
const { browser } = UAParser(test.headers).withClientHints(); headers : {
assert.deepEqual(browser, test.expect.browser); 'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
}); },
expect: {
browser : {
name : 'Avast Secure Browser',
version : '131',
major : '131',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"'
},
expect: {
browser : {
name : 'Brave',
version : '132',
major : '132',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"'
},
expect: {
browser : {
name : 'Chrome',
version : '111',
major : '111',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"'
},
expect: {
browser : {
name : 'Chrome Headless',
version : '124',
major : '124',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
},
expect: {
browser : {
name : 'Chrome WebView',
version : '123',
major : '123',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
},
expect : {
browser : {
name : 'DuckDuckGo',
version : '131',
major : '131',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"'
},
expect: {
browser : {
name : 'Edge',
version : '120',
major : '120',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103", "Microsoft Edge WebView2";v="104"'
},
expect: {
browser : {
name : 'Edge WebView2',
version : '104',
major : '104',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"'
},
expect: {
browser : {
name : 'Huawei Browser',
version : '114',
major : '114',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
},
expect: {
browser : {
name : 'MIUI Browser',
version : '123',
major : '123',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"'
},
expect: {
browser : {
name : 'Oculus Browser',
version : '36',
major : '36',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"'
},
expect: {
browser : {
name : 'Opera',
version : '116',
major : '116',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"'
},
expect: {
browser : {
name : 'Opera GX',
version : '114',
major : '114',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"'
},
expect: {
browser : {
name : 'Opera Mobi',
version : '86',
major : '86',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"'
},
expect: {
browser : {
name : 'Opera Mobi',
version : '87',
major : '87',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"'
},
expect: {
browser : {
name : 'Samsung Internet',
version : '27.0',
major : '27',
type : undefined
}
}
},
{
headers : {
'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"'
},
expect: {
browser : {
name : 'Yandex',
version : '24.12',
major : '24',
type : undefined
}
}
},
]
.forEach(test => {
const { browser } = UAParser(test.headers).withClientHints();
assert.deepEqual(browser, test.expect.browser);
}); });
}); });
@ -236,169 +455,169 @@ describe('Identify vendor & type of device from given model name', () => {
{ {
model: '220733SG', model: '220733SG',
expect: { expect: {
vendor : DeviceVendor.XIAOMI, vendor : 'Xiaomi',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: '5087Z', model: '5087Z',
expect: { expect: {
vendor : DeviceVendor.TCL, vendor : 'TCL',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: '9137W', model: '9137W',
expect: { expect: {
vendor : DeviceVendor.TCL, vendor : 'TCL',
type : DeviceType.TABLET type : 'tablet'
} }
}, },
{ {
model: 'BE2015', model: 'BE2015',
expect: { expect: {
vendor : DeviceVendor.ONEPLUS, vendor : 'OnePlus',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'CPH2389', model: 'CPH2389',
expect: { expect: {
vendor : DeviceVendor.ONEPLUS, vendor : 'OnePlus',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Infinix X669C', model: 'Infinix X669C',
expect: { expect: {
vendor : DeviceVendor.INFINIX, vendor : 'Infinix',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'itel L6502', model: 'itel L6502',
expect: { expect: {
vendor : DeviceVendor.ITEL, vendor : 'itel',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Lenovo TB-X606F', model: 'Lenovo TB-X606F',
expect: { expect: {
vendor : DeviceVendor.LENOVO, vendor : 'Lenovo',
type : DeviceType.TABLET type : 'tablet'
} }
}, },
{ {
model: 'LM-Q720', model: 'LM-Q720',
expect: { expect: {
vendor : DeviceVendor.LG, vendor : 'LG',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'M2003J15SC', model: 'M2003J15SC',
expect: { expect: {
vendor : DeviceVendor.XIAOMI, vendor : 'Xiaomi',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'MAR-LX1A', model: 'MAR-LX1A',
expect: { expect: {
vendor : DeviceVendor.HUAWEI, vendor : 'Huawei',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'moto g(20)', model: 'moto g(20)',
expect: { expect: {
vendor : DeviceVendor.MOTOROLA, vendor : 'Motorola',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Nokia C210', model: 'Nokia C210',
expect: { expect: {
vendor : DeviceVendor.NOKIA, vendor : 'Nokia',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Pixel 8', model: 'Pixel 8',
expect: { expect: {
vendor : DeviceVendor.GOOGLE, vendor : 'Google',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Redmi Note 9S', model: 'Redmi Note 9S',
expect: { expect: {
vendor : DeviceVendor.XIAOMI, vendor : 'Xiaomi',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'RMX3830', model: 'RMX3830',
expect: { expect: {
vendor : DeviceVendor.REALME, vendor : 'Realme',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'SM-S536DL', model: 'SM-S536DL',
expect: { expect: {
vendor : DeviceVendor.SAMSUNG, vendor : 'Samsung',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'SM-S546VL', model: 'SM-S546VL',
expect: { expect: {
vendor : DeviceVendor.SAMSUNG, vendor : 'Samsung',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'SM-T875', model: 'SM-T875',
expect: { expect: {
vendor : DeviceVendor.SAMSUNG, vendor : 'Samsung',
type : DeviceType.TABLET type : 'tablet'
} }
}, },
{ {
model: 'STK-L21', model: 'STK-L21',
expect: { expect: {
vendor : DeviceVendor.HUAWEI, vendor : 'Huawei',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'T430W', model: 'T430W',
expect: { expect: {
vendor : DeviceVendor.TCL, vendor : 'TCL',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'TECNO KI5k', model: 'TECNO KI5k',
expect: { expect: {
vendor : DeviceVendor.TECNO, vendor : 'TECNO',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'vivo 1820', model: 'vivo 1820',
expect: { expect: {
vendor : DeviceVendor.VIVO, vendor : 'Vivo',
type : DeviceType.MOBILE type : 'mobile'
} }
}, },
{ {
model: 'Xbox', model: 'Xbox',
expect: { expect: {
vendor : DeviceVendor.MICROSOFT, vendor : 'Microsoft',
type : DeviceType.CONSOLE type : 'console'
} }
} }
] ]