Skip to content

Commit b061251

Browse files
committed
Merge tag '2.0.6' into pro-personal
2 parents 5b5e336 + 061cf0e commit b061251

35 files changed

+1073
-328
lines changed

CHANGELOG.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
- **Support for Custom/Predefined Extensions:**
2424
- Pass custom regexes or predefined extensions as a list to `UAParser()`
2525

26-
- **Support for CLI Parsing:**
27-
- Parse a user-agent directly from the command line using `npx ua-parser-js "[User-Agent]"`
26+
- **Support for CLI Processing:**
27+
- Directly parse user-agent strings from the command line:
28+
`npx ua-parser-js "<User-Agent>"`
29+
- Process batch data from files:
30+
`npx ua-parser-js --input-file=log.txt >> result.json` or
31+
`npx ua-parser-js --input-file=log.txt --output-file=result.json`
2832

2933
- **Enhanced Detection with Client Hints:**
3034
- `withClientHints()`: Improves detection accuracy by leveraging client hints
@@ -65,6 +69,20 @@
6569

6670
---
6771

72+
## Version 2.0.6
73+
- Add new CLI feature: processing batch user-agent data from file and output as JSON
74+
- Fix `setUA()`: trim leading space from user-agent string input
75+
- Replace `undici` dependency with node's internal `Headers`
76+
- Add new browser: Bing, Qwant
77+
- Add new device vendor: Hisense, Wiko
78+
- Improve browser detection: Mozilla, Pale Moon
79+
- Improve CPU detection: 68k
80+
- Improve device detection: Apple, BlackBerry, Huawei, Nokia, Xiaomi
81+
- Improve OS detection: iOS 26
82+
- `extensions` submodule:
83+
- Add new fetcher: Discordbot, KeybaseBot, Slackbot, Slackbot-LinkExpanding, Slack-ImgProxy, Twitterbot
84+
- Add new crawler: Qwantbot-news, SurdotlyBot, SwiftBot
85+
6886
## Version 2.0.5
6987

7088
- Add new browser: Zalo

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ https://docs.uaparser.dev
2222
import { UAParser } from '@ua-parser-js/pro-personal';
2323
```
2424

25+
```js
26+
import { isFrozenUA } from '@ua-parser-js/pro-personal/helpers';
27+
```
28+
2529
# License
2630

2731
UAParser.js PRO Personal
2832

29-
Copyright (c) 2023-2024 Faisal Salman <<f@faisalman.com>>
33+
Copyright (c) 2023-2025 Faisal Salman <<f@faisalman.com>>

dist/ua-parser.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ua-parser.min.mjs

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

dist/ua-parser.pack.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ua-parser.pack.mjs

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 3 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
{
22
"title": "UAParser.js PRO Personal",
33
"name": "@ua-parser-js/pro-personal",
4-
"version": "2.0.5",
4+
"version": "2.0.6",
55
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
66
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
77
"keywords": [
88
"user-agent",
99
"client-hints",
10-
"parser",
1110
"browser",
1211
"engine",
1312
"os",
1413
"device",
1514
"cpu",
16-
"jquery-plugin",
17-
"ecosystem:jquery",
1815
"ua-parser-js",
1916
"browser-detection",
2017
"device-detection",
2118
"os-detection",
22-
"bot-detection"
19+
"bot-detection",
20+
"ai-detection",
21+
"app-detection",
22+
"crawler-detection"
2323
],
2424
"homepage": "https://uaparser.dev",
2525
"contributors": [
@@ -220,14 +220,13 @@
220220
"test:eslint": "eslint src && eslint script",
221221
"test:jshint": "jshint src/main",
222222
"test:lockfile-lint": "npx lockfile-lint -p package-lock.json",
223-
"test:mocha": "mocha test/unit",
223+
"test:mocha": "mocha --recursive test/unit",
224224
"test:playwright": "npx playwright install && playwright test test/e2e --browser all"
225225
},
226226
"dependencies": {
227227
"detect-europe-js": "^0.1.2",
228228
"is-standalone-pwa": "^0.1.1",
229-
"ua-is-frozen": "^0.1.2",
230-
"undici": "^7.12.0"
229+
"ua-is-frozen": "^0.1.2"
231230
},
232231
"devDependencies": {
233232
"@babel/parser": "7.15.8",

script/cli.js

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,94 @@
11
#!/usr/bin/env node
22

3-
const UAParser = require('ua-parser-js');
4-
console.log(JSON.stringify(process.argv.slice(2).map(ua => UAParser(ua)), null, 4));
3+
try {
4+
const fs = require('node:fs');
5+
const path = require('node:path');
6+
const { performance } = require('node:perf_hooks');
7+
const readline = require('node:readline');
8+
const { parseArgs } = require('node:util');
9+
const UAParser = require('../src/main/ua-parser');
10+
const { Bots, Emails, ExtraDevices, InApps, Vehicles } = require('../src/extensions/ua-parser-extensions');
11+
12+
if (!process.argv[2].startsWith('-')) {
13+
14+
const results = process.argv.slice(2).map(ua => UAParser(ua));
15+
console.log(JSON.stringify(results, null, 4));
16+
process.exit(0);
17+
18+
} else if (['-h', '--help'].includes(process.argv[2])) {
19+
20+
console.log('Usage: npx ua-parser-js <string>');
21+
console.log(' or npx ua-parser-js --input-file <filepath> [--output-file <filepath>]');
22+
console.log('-i, --input-file');
23+
console.log('-o, --output-file');
24+
process.exit(0);
25+
26+
} else {
27+
28+
const startPerf = performance.now();
29+
const {
30+
values: {
31+
'input-file': inputFile,
32+
'output-file': outputFile
33+
},
34+
} = parseArgs({
35+
options: {
36+
'input-file': { type: 'string', short: 'i' },
37+
'output-file': { type: 'string', short: 'o' }
38+
}
39+
});
40+
41+
if (!inputFile) {
42+
console.error('Input file must be present');
43+
process.exit(1);
44+
}
45+
46+
const inputPath = path.resolve(__dirname, inputFile);
47+
const outputPath = outputFile ? path.resolve(__dirname, outputFile) : null;
48+
49+
if (!fs.existsSync(inputPath)) {
50+
console.error(`Input file not found: ${inputPath}`);
51+
process.exit(1);
52+
}
53+
54+
const inputStream = fs.createReadStream(inputPath, 'utf8');
55+
const rl = readline.createInterface({
56+
input: inputStream,
57+
crlfDelay: Infinity
58+
});
59+
60+
const outputStream = outputPath ? fs.createWriteStream(outputPath, { encoding : 'utf8' }) : process.stdout;
61+
62+
const uap = new UAParser([Bots, Emails, ExtraDevices, InApps, Vehicles]);
63+
let lineNumber = 0;
64+
65+
outputStream.write('[\n');
66+
67+
rl.on('line', line => {
68+
const result = uap.setUA(line).getResult();
69+
const json = JSON.stringify(result, null, 4);
70+
if (lineNumber > 0) outputStream.write(',\n');
71+
outputStream.write(json);
72+
lineNumber++;
73+
});
74+
75+
rl.on('close', () => {
76+
outputStream.write('\n]');
77+
if (outputPath) {
78+
outputStream.end(() => {
79+
const finishPerf = performance.now();
80+
console.log(`Done!`);
81+
console.log(`Number of lines found: ${lineNumber}`);
82+
console.log(`Task finished in: ${(finishPerf - startPerf).toFixed(3)}ms`);
83+
console.log(`Output written to: ${outputPath}`);
84+
process.exit(0);
85+
});
86+
} else {
87+
process.exit(0);
88+
}
89+
});
90+
}
91+
} catch (err) {
92+
console.error(err);
93+
process.exit(1);
94+
}

src/enums/ua-parser-enums.d.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Source: /src/enums/ua-parser-enums.js
44

55
///////////////////////////////////////////////
6-
/* Enums for UAParser.js v2.0.5
6+
/* Enums for UAParser.js v2.0.6
77
https://github.com/faisalman/ua-parser-js
88
Author: Faisal Salman <f@faisalman.com>
99
UAParser.js PRO Personal License */
@@ -24,6 +24,7 @@ export const BrowserName: Readonly<{
2424
AVG: 'AVG Secure Browser',
2525
BAIDU: 'Baidu Browser',
2626
BASILISK: 'Basilisk',
27+
BING: 'Bing',
2728
BLAZER: 'Blazer',
2829
BOLT: 'Bolt',
2930
BOWSER: 'Bowser',
@@ -129,6 +130,7 @@ export const BrowserName: Readonly<{
129130
QUARK: 'Quark',
130131
QUPZILLA: 'QupZilla',
131132
QUTEBROWSER: 'qutebrowser',
133+
QWANT: 'Qwant',
132134
REKONQ: 'rekonq',
133135
ROCKMELT: 'Rockmelt',
134136
SAFARI: 'Safari',
@@ -243,6 +245,7 @@ export const DeviceVendor: Readonly<{
243245
GEEKSPHONE: 'GeeksPhone',
244246
GENERIC: 'Generic',
245247
GOOGLE: 'Google',
248+
HISENSE: 'Hisense',
246249
HMD: 'HMD',
247250
HP: 'HP',
248251
HTC: 'HTC',
@@ -291,6 +294,7 @@ export const DeviceVendor: Readonly<{
291294
VIVO: 'Vivo',
292295
VIZIO: 'Vizio',
293296
VODAFONE: 'Vodafone',
297+
WIKO: 'Wiko',
294298
XBOX: 'Xbox',
295299
XIAOMI: 'Xiaomi',
296300
ZEBRA: 'Zebra',
@@ -489,6 +493,7 @@ export const Extension: Readonly<{
489493
DUCKDUCKGO_BOT: 'DuckDuckBot',
490494
DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
491495
ELASTIC: 'Elastic',
496+
ELASTIC_SWIFTYPE_BOT: 'Swiftbot',
492497
EXALEAD_EXABOT: 'Exabot',
493498
FIRECRAWL_AGENT: 'FirecrawlAgent',
494499
FREESPOKE: 'Freespoke',
@@ -538,6 +543,7 @@ export const Extension: Readonly<{
538543
PERPLEXITY_BOT: 'PerplexityBot',
539544
QIHOO_360_SPIDER: '360Spider',
540545
QWANT_BOT: 'Qwantbot',
546+
QWANT_BOT_NEWS: 'Qwantbot-news',
541547
REPLICATE_BOT: 'Replicate-Bot',
542548
RUNPOD_BOT: 'RunPod-Bot',
543549
SB_INTUITIONS_BOT: 'SBIntuitionsBot',
@@ -551,6 +557,7 @@ export const Extension: Readonly<{
551557
SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
552558
SOGOU_WEB_SPIDER: 'Sogou web spider',
553559
STARTPAGE: 'Startpage',
560+
SURLY_BOT: 'SurdotlyBot',
554561
TIMPI_BOT: 'Timpibot',
555562
TOGETHER_BOT: 'Together-Bot',
556563
TURNITIN_BOT: 'TurnitinBot',
@@ -631,6 +638,7 @@ export const Extension: Readonly<{
631638
BLUESKY: 'Bluesky',
632639
BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
633640
COHERE_AI: 'Cohere-AI',
641+
DISCORD_BOT: 'Discordbot',
634642
DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
635643
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
636644
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
@@ -643,6 +651,7 @@ export const Extension: Readonly<{
643651
HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
644652
IFRAMELY: 'Iframely',
645653
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
654+
KEYBASE_BOT: 'KeybaseBot',
646655
META_EXTERNALFETCHER: 'meta-externalfetcher',
647656
META_WHATSAPP: 'WhatsApp',
648657
MICROSOFT_BINGPREVIEW: 'BingPreview',
@@ -654,6 +663,9 @@ export const Extension: Readonly<{
654663
PERPLEXITY_USER: 'Perplexity-User',
655664
PINTEREST_BOT: 'Pinterestbot',
656665
SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
666+
SLACK_BOT: 'Slackbot',
667+
SLACK_BOT_LINKEXPANDING: 'Slackbot-LinkExpanding',
668+
SLACK_IMGPROXY: 'Slack-ImgProxy',
657669
SNAP_URL_PREVIEW: 'Snap URL Preview',
658670
SKYPE_URIPREVIEW: 'SkypeUriPreview',
659671
TELEGRAM_BOT: 'TelegramBot',
@@ -663,6 +675,7 @@ export const Extension: Readonly<{
663675
VERCEL_BOT: 'Vercelbot',
664676
VERCEL_FLAGS: 'vercelflags',
665677
VERCEL_TRACING: 'verceltracing',
678+
X_TWITTERBOT: 'Twitterbot',
666679
YANDEX_CALENDAR: 'YandexCalendar',
667680
YANDEX_DIRECT: 'YandexDirect',
668681
YANDEX_DIRECTDYN: 'YandexDirectDyn',

0 commit comments

Comments
 (0)