Compare commits

...

7 Commits

13 changed files with 1281 additions and 720 deletions

View File

@ -211,6 +211,7 @@
"src"
],
"bin": "./script/cli.js",
"sideEffects": false,
"scripts": {
"build": "./script/build-dist.sh && ./script/build-esm.js",
"build+test": "npm run build && npm run test",

View File

@ -2,15 +2,18 @@
/* jshint esversion: 6 */
const fs = require('fs');
const generateMJS = (module) => {
let { src, dest, title, replacements } = module;
let text = fs.readFileSync(src, 'utf-8');
replacements.push(
const defaultReplacements = {
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 text = fs.readFileSync(src, 'utf-8');
replacements.forEach(rep => {
text = text.replace(rep[0], rep[1]);
});
@ -18,42 +21,54 @@ const generateMJS = (module) => {
console.log(`Generate ${dest}`);
fs.writeFileSync(dest,
`// Generated ESM version of ${title}
`// ${title}
// DO NOT EDIT THIS FILE!
// Source: /${src}
${text}`, 'utf-8');
};
const modules = [
const files = [
{
src : 'src/main/ua-parser.js',
dest : 'src/main/ua-parser.mjs',
title : 'ua-parser-js',
title : 'Generated ESM version of ua-parser-js',
replacements : [
[/\(func[\s\S]+strict\';/ig, ''],
[/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',
dest :'src/enums/ua-parser-enums.mjs',
title : 'ua-parser-js/enums',
replacements : []
title : 'Generated ESM version of ua-parser-js/enums',
replacements : [...defaultReplacements.mjs]
},
{
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',
dest : 'src/extensions/ua-parser-extensions.mjs',
title : 'ua-parser-js/extensions',
replacements : []
title : 'Generated ESM version of ua-parser-js/extensions',
replacements : [...defaultReplacements.mjs]
},
{
src : 'src/helpers/ua-parser-helpers.js',
dest : 'src/helpers/ua-parser-helpers.mjs',
title : 'ua-parser-js/helpers',
replacements : []
title : 'Generated ESM version of ua-parser-js/helpers',
replacements : [...defaultReplacements.mjs]
}
];
modules.forEach(module => generateMJS(module));
files.forEach(module => generateFile(module));

View File

@ -1,160 +1,171 @@
// Type definitions for Enums submodule of UAParser.js v2.0.4
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman>
// Generated type declarations of ua-parser-js/enums
// DO NOT EDIT THIS FILE!
// Source: /src/enums/ua-parser-enums.js
///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.4
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
export const BrowserName: Readonly<{
'115': "115",
'2345': "2345",
'360': "360",
ALIPAY: "Alipay",
AMAYA: "Amaya",
ANDROID: "Android Browser",
ARORA: "Arora",
AVANT: "Avant",
AVAST: "Avast Secure Browser",
AVG: "AVG Secure Browser",
BAIDU: "Baidu Browser",
BASILISK: "Basilisk",
BLAZER: "Blazer",
BOLT: "Bolt",
BOWSER: "Bowser",
BRAVE: "Brave",
CAMINO: "Camino",
CHIMERA: "Chimera",
CHROME: "Chrome",
CHROME_HEADLESS: "Chrome Headless",
CHROME_MOBILE: "Mobile Chrome",
CHROME_WEBVIEW: "Chrome WebView",
CHROMIUM: "Chromium",
COBALT: "Cobalt",
COC_COC: "Coc Coc",
CONKEROR: "Conkeror",
DAUM: "Daum",
DILLO: "Dillo",
DOLPHIN: "Dolphin",
'115': '115',
'2345': '2345',
'360': '360',
ALIPAY: 'Alipay',
AMAYA: 'Amaya',
ANDROID: 'Android Browser',
ARORA: 'Arora',
AVANT: 'Avant',
AVAST: 'Avast Secure Browser',
AVG: 'AVG Secure Browser',
BAIDU: 'Baidu Browser',
BASILISK: 'Basilisk',
BLAZER: 'Blazer',
BOLT: 'Bolt',
BOWSER: 'Bowser',
BRAVE: 'Brave',
CAMINO: 'Camino',
CHIMERA: 'Chimera',
CHROME: 'Chrome',
CHROME_HEADLESS: 'Chrome Headless',
CHROME_MOBILE: 'Mobile Chrome',
CHROME_WEBVIEW: 'Chrome WebView',
CHROMIUM: 'Chromium',
COBALT: 'Cobalt',
COC_COC: 'Coc Coc',
CONKEROR: 'Conkeror',
DAUM: 'Daum',
DILLO: 'Dillo',
DOLPHIN: 'Dolphin',
DOOBLE: 'Dooble',
DORIS: "Doris",
DRAGON: "Dragon",
DUCKDUCKGO: "DuckDuckGo",
ECOSIA: "Ecosia",
EDGE: "Edge",
EDGE_WEBVIEW: "Edge WebView",
EDGE_WEBVIEW2: "Edge WebView2",
EPIPHANY: "Epiphany",
FACEBOOK: "Facebook",
FALKON: "Falkon",
FIREBIRD: "Firebird",
FIREFOX: "Firefox",
FIREFOX_FOCUS: "Firefox Focus",
FIREFOX_MOBILE: "Mobile Firefox",
FIREFOX_REALITY: "Firefox Reality",
FENNEC: "Fennec",
FLOCK: "Flock",
FLOW: "Flow",
GO: "GoBrowser",
GOOGLE_SEARCH: "GSA",
HELIO: "Helio",
HEYTAP: "HeyTap",
HONOR: "Honor",
HUAWEI: "Huawei Browser",
ICAB: "iCab",
ICE: "ICE Browser",
ICEAPE: "IceApe",
ICECAT: "IceCat",
ICEDRAGON: "IceDragon",
ICEWEASEL: "IceWeasel",
IE: "IE",
INSTAGRAM: "Instagram",
IRIDIUM: "Iridium",
IRON: "Iron",
JASMINE: "Jasmine",
KONQUEROR: "Konqueror",
KAKAO: "KakaoTalk",
KHTML: "KHTML",
K_MELEON: "K-Meleon",
KLAR: "Klar",
KLARNA: "Klarna",
KINDLE: "Kindle",
LENOVO: "Smart Lenovo Browser",
LADYBIRD: "Ladybird",
LG: "LG Browser",
LIBREWOLF: "LibreWolf",
LIEBAO: "LBBROWSER",
LINE: "Line",
LINKEDIN: "LinkedIn",
LINKS: "Links",
LUNASCAPE: "Lunascape",
LYNX: "Lynx",
MAEMO: "Maemo Browser",
MAXTHON: "Maxthon",
MIDORI: "Midori",
MINIMO: "Minimo",
MIUI: "MIUI Browser",
MOZILLA: "Mozilla",
MOSAIC: "Mosaic",
NAVER: "Naver",
NETFRONT: "NetFront",
NETSCAPE: "Netscape",
NETSURF: "Netsurf",
NOKIA: "Nokia Browser",
OBIGO: "Obigo",
OCULUS: "Oculus Browser",
OMNIWEB: "OmniWeb",
OPERA: "Opera",
OPERA_COAST: "Opera Coast",
OPERA_GX: "Opera GX",
OPERA_MINI: "Opera Mini",
OPERA_MOBI: "Opera Mobi",
OPERA_TABLET: "Opera Tablet",
OPERA_TOUCH: "Opera Touch",
OTTER: "Otter",
OVI: "OviBrowser",
PALEMOON: "PaleMoon",
PHANTOMJS: "PhantomJS",
PHOENIX: "Phoenix",
PICOBROWSER: "Pico Browser",
POLARIS: "Polaris",
PUFFIN: "Puffin",
QQ: "QQBrowser",
QQ_LITE: "QQBrowserLite",
QUARK: "Quark",
QUPZILLA: "QupZilla",
QUTEBROWSER: "qutebrowser",
REKONQ: "rekonq",
ROCKMELT: "Rockmelt",
SAFARI: "Safari",
SAFARI_MOBILE: "Mobile Safari",
SAILFISH: "Sailfish Browser",
SAMSUNG: "Samsung Internet",
SEAMONKEY: "SeaMonkey",
SILK: "Silk",
SKYFIRE: "Skyfire",
SLEIPNIR: "Sleipnir",
SLIMBOAT: "SlimBoat",
SLIMBROWSER: "SlimBrowser",
SLIMJET: "Slimjet",
SNAPCHAT: "Snapchat",
SOGOU_EXPLORER: "Sogou Explorer",
SOGOU_MOBILE: "Sogou Mobile",
SURF: "Surf",
SWIFTFOX: "Swiftfox",
TESLA: "Tesla",
TIKTOK: "TikTok",
TIZEN: "Tizen Browser",
TWITTER: "Twitter",
UC: "UCBrowser",
UP: "UP.Browser",
VIVALDI: "Vivaldi",
VIVO: "Vivo Browser",
W3M: "w3m",
WATERFOX: "Waterfox",
WEBKIT: "WebKit",
WECHAT: "WeChat",
WEIBO: "Weibo",
WHALE: "Whale",
WOLVIC: "Wolvic",
YANDEX: "Yandex",
ZALO: "Zalo",
DORIS: 'Doris',
DRAGON: 'Dragon',
DUCKDUCKGO: 'DuckDuckGo',
ECOSIA: 'Ecosia',
EDGE: 'Edge',
EDGE_WEBVIEW: 'Edge WebView',
EDGE_WEBVIEW2: 'Edge WebView2',
EPIPHANY: 'Epiphany',
FACEBOOK: 'Facebook',
FALKON: 'Falkon',
FIREBIRD: 'Firebird',
FIREFOX: 'Firefox',
FIREFOX_FOCUS: 'Firefox Focus',
FIREFOX_MOBILE: 'Mobile Firefox',
FIREFOX_REALITY: 'Firefox Reality',
FENNEC: 'Fennec',
FLOCK: 'Flock',
FLOW: 'Flow',
GO: 'GoBrowser',
GOOGLE_SEARCH: 'GSA',
HELIO: 'Helio',
HEYTAP: 'HeyTap',
HONOR: 'Honor',
HUAWEI: 'Huawei Browser',
ICAB: 'iCab',
ICE: 'ICE Browser',
ICEAPE: 'IceApe',
ICECAT: 'IceCat',
ICEDRAGON: 'IceDragon',
ICEWEASEL: 'IceWeasel',
IE: 'IE',
INSTAGRAM: 'Instagram',
IRIDIUM: 'Iridium',
IRON: 'Iron',
JASMINE: 'Jasmine',
KONQUEROR: 'Konqueror',
KAKAO: 'KakaoTalk',
KHTML: 'KHTML',
K_MELEON: 'K-Meleon',
KLAR: 'Klar',
KLARNA: 'Klarna',
KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser',
LADYBIRD: 'Ladybird',
LG: 'LG Browser',
LIBREWOLF: 'LibreWolf',
LIEBAO: 'LBBROWSER',
LINE: 'Line',
LINKEDIN: 'LinkedIn',
LINKS: 'Links',
LUNASCAPE: 'Lunascape',
LYNX: 'Lynx',
MAEMO: 'Maemo Browser',
MAXTHON: 'Maxthon',
MIDORI: 'Midori',
MINIMO: 'Minimo',
MIUI: 'MIUI Browser',
MOZILLA: 'Mozilla',
MOSAIC: 'Mosaic',
NAVER: 'Naver',
NETFRONT: 'NetFront',
NETSCAPE: 'Netscape',
NETSURF: 'Netsurf',
NOKIA: 'Nokia Browser',
OBIGO: 'Obigo',
OCULUS: 'Oculus Browser',
OMNIWEB: 'OmniWeb',
OPERA: 'Opera',
OPERA_COAST: 'Opera Coast',
OPERA_GX: 'Opera GX',
OPERA_MINI: 'Opera Mini',
OPERA_MOBI: 'Opera Mobi',
OPERA_TABLET: 'Opera Tablet',
OPERA_TOUCH: 'Opera Touch',
OTTER: 'Otter',
OVI: 'OviBrowser',
PALEMOON: 'PaleMoon',
PHANTOMJS: 'PhantomJS',
PHOENIX: 'Phoenix',
PICOBROWSER: 'Pico Browser',
POLARIS: 'Polaris',
PUFFIN: 'Puffin',
QQ: 'QQBrowser',
QQ_LITE: 'QQBrowserLite',
QUARK: 'Quark',
QUPZILLA: 'QupZilla',
QUTEBROWSER: 'qutebrowser',
REKONQ: 'rekonq',
ROCKMELT: 'Rockmelt',
SAFARI: 'Safari',
SAFARI_MOBILE: 'Mobile Safari',
SAILFISH: 'Sailfish Browser',
SAMSUNG: 'Samsung Internet',
SEAMONKEY: 'SeaMonkey',
SILK: 'Silk',
SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir',
SLIMBOAT: 'SlimBoat',
SLIMBROWSER: 'SlimBrowser',
SLIMJET: 'Slimjet',
SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile',
SURF: 'Surf',
SWIFTFOX: 'Swiftfox',
TESLA: 'Tesla',
TIKTOK: 'TikTok',
TIZEN: 'Tizen Browser',
TWITTER: 'Twitter',
UC: 'UCBrowser',
UP: 'UP.Browser',
VIVALDI: 'Vivaldi',
VIVO: 'Vivo Browser',
W3M: 'w3m',
WATERFOX: 'Waterfox',
WEBKIT: 'WebKit',
WECHAT: 'WeChat',
WEIBO: 'Weibo',
WHALE: 'Whale',
WOLVIC: 'Wolvic',
YANDEX: 'Yandex',
ZALO: 'Zalo'
// TODO : test!
}>;
/**
* @deprecated Use `BrowserName` instead
@ -162,34 +173,34 @@ export const BrowserName: Readonly<{
export const Browser: typeof BrowserName;
export const BrowserType: Readonly<{
CRAWLER: "crawler",
CLI: "cli",
EMAIL: "email",
FETCHER: "fetcher",
INAPP: "inapp",
MEDIAPLAYER: "mediaplayer",
LIBRARY: "library",
CRAWLER: 'crawler',
CLI: 'cli',
EMAIL: 'email',
FETCHER: 'fetcher',
INAPP: 'inapp',
MEDIAPLAYER: 'mediaplayer',
LIBRARY: 'library'
}>;
export const CPUArch: Readonly<{
'68K': "68k",
ALPHA: "alpha",
ARM: "arm",
ARM_64: "arm64",
ARM_HF: "armhf",
AVR: "avr",
AVR_32: "avr32",
IA64: "ia64",
IRIX: "irix",
IRIX_64: "irix64",
MIPS: "mips",
MIPS_64: "mips64",
PA_RISC: "pa-risc",
PPC: "ppc",
SPARC: "sparc",
SPARC_64: "sparc64",
X86: "ia32",
X86_64: "amd64",
'68K': '68k',
ALPHA: 'alpha',
ARM : 'arm',
ARM_64: 'arm64',
ARM_HF: 'armhf',
AVR: 'avr',
AVR_32: 'avr32',
IA64: 'ia64',
IRIX: 'irix',
IRIX_64: 'irix64',
MIPS: 'mips',
MIPS_64: 'mips64',
PA_RISC: 'pa-risc',
PPC: 'ppc',
SPARC: 'sparc',
SPARC_64: 'sparc64',
X86: 'ia32',
X86_64: 'amd64'
}>;
/**
* @deprecated Use `CPUArch` instead
@ -197,14 +208,14 @@ export const CPUArch: Readonly<{
export const CPU: typeof CPUArch;
export const DeviceType: Readonly<{
CONSOLE: "console",
DESKTOP: "desktop",
EMBEDDED: "embedded",
MOBILE: "mobile",
SMARTTV: "smarttv",
TABLET: "tablet",
WEARABLE: "wearable",
XR: "xr"
CONSOLE: 'console',
DESKTOP: 'desktop',
EMBEDDED: 'embedded',
MOBILE: 'mobile',
SMARTTV: 'smarttv',
TABLET: 'tablet',
WEARABLE: 'wearable',
XR: 'xr'
}>;
/**
* @deprecated Use `DeviceType` instead
@ -212,78 +223,80 @@ export const DeviceType: Readonly<{
export const Device: typeof DeviceType;
export const DeviceVendor: Readonly<{
ACER: "Acer",
ADVAN: "Advan",
ALCATEL: "Alcatel",
APPLE: "Apple",
AMAZON: "Amazon",
ARCHOS: "Archos",
ASUS: "ASUS",
ATT: "AT&T",
BENQ: "BenQ",
BLACKBERRY: "BlackBerry",
BLU: "BLU",
CAT: "Cat",
DELL: "Dell",
ENERGIZER: "Energizer",
ESSENTIAL: "Essential",
FACEBOOK: "Facebook",
FAIRPHONE: "Fairphone",
GEEKSPHONE: "GeeksPhone",
GENERIC: "Generic",
GOOGLE: "Google",
HMD: "HMD",
HP: "HP",
HTC: "HTC",
HUAWEI: "Huawei",
IMO: "IMO",
INFINIX: "Infinix",
ITEL: "itel",
JOLLA: "Jolla",
KOBO: "Kobo",
LAVA: "Lava",
LENOVO: "Lenovo",
LG: "LG",
MEIZU: "Meizu",
MICROMAX: "Micromax",
MICROSOFT: "Microsoft",
MOTOROLA: "Motorola",
NEXIAN: "Nexian",
NINTENDO: "Nintendo",
NOKIA: "Nokia",
NOTHING: "Nothing",
NVIDIA: "Nvidia",
ONEPLUS: "OnePlus",
OPPO: "OPPO",
OUYA: "Ouya",
PALM: "Palm",
PANASONIC: "Panasonic",
PEBBLE: "Pebble",
PHILIPS: "Philips",
PICO: "Pico",
POLYTRON: "Polytron",
REALME: "Realme",
RETROID: "Retroid",
RIM: "RIM",
ROKU: "Roku",
SAMSUNG: "Samsung",
SHARP: "Sharp",
SIEMENS: "Siemens",
SMARTFREN: "Smartfren",
SONY: "Sony",
SPRINT: "Sprint",
TCL: "TCL",
TECHNISAT: "TechniSAT",
TECNO: "Tecno",
TESLA: "Tesla",
ULEFONE: "Ulefone",
VIVO: "Vivo",
VIZIO: "Vizio",
VODAFONE: "Vodafone",
XBOX: "Xbox",
XIAOMI: "Xiaomi",
ZEBRA: "Zebra",
ZTE: "ZTE",
ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel',
APPLE: 'Apple',
AMAZON: 'Amazon',
ARCHOS: 'Archos',
ASUS: 'ASUS',
ATT: 'AT&T',
BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry',
BLU: 'BLU',
CAT: 'Cat',
DELL: 'Dell',
ENERGIZER: 'Energizer',
ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone',
GEEKSPHONE: 'GeeksPhone',
GENERIC: 'Generic',
GOOGLE: 'Google',
HMD: 'HMD',
HP: 'HP',
HTC: 'HTC',
HUAWEI: 'Huawei',
IMO: 'IMO',
INFINIX: 'Infinix',
ITEL: 'itel',
JOLLA: 'Jolla',
KOBO: 'Kobo',
LAVA: 'Lava',
LENOVO: 'Lenovo',
LG: 'LG',
MEIZU: 'Meizu',
MICROMAX: 'Micromax',
MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola',
NEXIAN: 'Nexian',
NINTENDO: 'Nintendo',
NOKIA: 'Nokia',
NOTHING: 'Nothing',
NVIDIA: 'Nvidia',
ONEPLUS: 'OnePlus',
OPPO: 'OPPO',
OUYA: 'Ouya',
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
PHILIPS: 'Philips',
PICO: 'Pico',
POLYTRON: 'Polytron',
REALME: 'Realme',
RETROID: 'Retroid',
RIM: 'RIM',
ROKU: 'Roku',
SAMSUNG: 'Samsung',
SHARP: 'Sharp',
SIEMENS: 'Siemens',
SMARTFREN: 'Smartfren',
SONY: 'Sony',
SPRINT: 'Sprint',
TCL: 'TCL',
TECHNISAT: 'TechniSAT',
TECNO: 'Tecno',
TESLA: 'Tesla',
ULEFONE: 'Ulefone',
VIVO: 'Vivo',
VIZIO: 'Vizio',
VODAFONE: 'Vodafone',
XBOX: 'Xbox',
XIAOMI: 'Xiaomi',
ZEBRA: 'Zebra',
ZTE: 'ZTE',
// TODO : test!
}>;
/**
* @deprecated Use `DeviceVendor` instead
@ -291,26 +304,26 @@ export const DeviceVendor: Readonly<{
export const Vendor: typeof DeviceVendor;
export const EngineName: Readonly<{
AMAYA: "Amaya",
ARKWEB: "ArkWeb",
BLINK: "Blink",
EDGEHTML: "EdgeHTML",
FLOW: "Flow",
GECKO: "Gecko",
GOANNA: "Goanna",
ICAB: "iCab",
KHTML: "KHTML",
LIBWEB: "LibWeb",
LINKS: "Links",
LYNX: "Lynx",
NETFRONT: "NetFront",
NETSURF: "NetSurf",
PRESTO: "Presto",
SERVO: "Servo",
TASMAN: "Tasman",
TRIDENT: "Trident",
W3M: "w3m",
WEBKIT: "WebKit",
AMAYA: 'Amaya',
ARKWEB: 'ArkWeb',
BLINK: 'Blink',
EDGEHTML: 'EdgeHTML',
FLOW: 'Flow',
GECKO: 'Gecko',
GOANNA: 'Goanna',
ICAB: 'iCab',
KHTML: 'KHTML',
LIBWEB: 'LibWeb',
LINKS: 'Links',
LYNX: 'Lynx',
NETFRONT: 'NetFront',
NETSURF: 'NetSurf',
PRESTO: 'Presto',
SERVO: 'Servo',
TASMAN: 'Tasman',
TRIDENT: 'Trident',
W3M: 'w3m',
WEBKIT: 'WebKit'
}>;
/**
* @deprecated Use `EngineName` instead
@ -318,98 +331,100 @@ export const EngineName: Readonly<{
export const Engine: typeof EngineName;
export const OSName: Readonly<{
AIX: "AIX",
AMIGA_OS: "Amiga OS",
ANDROID: "Android",
ANDROID_X86: "Android-x86",
ARCAOS: "ArcaOS",
ARCH: "Arch",
BADA: "Bada",
BEOS: "BeOS",
BLACKBERRY: "BlackBerry",
CENTOS: "CentOS",
CHROME_OS: "Chrome OS",
CHROMECAST: "Chromecast",
CHROMECAST_ANDROID: "Chromecast Android",
CHROMECAST_FUCHSIA: "Chromecast Fuchsia",
CHROMECAST_LINUX: "Chromecast Linux",
CHROMECAST_SMARTSPEAKER: "Chromecast SmartSpeaker",
CONTIKI: "Contiki",
DEBIAN: "Debian",
DEEPIN: "Deepin",
DRAGONFLY: "DragonFly",
ELEMENTARY_OS: "elementary OS",
FEDORA: "Fedora",
FIREFOX_OS: "Firefox OS",
FREEBSD: "FreeBSD",
FUCHSIA: "Fuchsia",
GENTOO: "Gentoo",
GHOSTBSD: "GhostBSD",
GNU: "GNU",
HAIKU: "Haiku",
HARMONYOS: "HarmonyOS",
HP_UX: "HP-UX",
HURD: "Hurd",
IOS: "iOS",
JOLI: "Joli",
KAIOS: "KaiOS",
KNOPPIX: "Knoppix",
KUBUNTU: "Kubuntu",
LINPUS: "Linpus",
LINSPIRE: "Linspire",
LINUX: "Linux",
MACOS: "macOS",
MAEMO: "Maemo",
MAGEIA: "Mageia",
MANDRIVA: "Mandriva",
MANJARO: "Manjaro",
MEEGO: "MeeGo",
MINIX: "Minix",
MINT: "Mint",
MORPH_OS: "Morph OS",
NETBSD: "NetBSD",
NETRANGE: "NetRange",
NETTV: "NetTV",
NINTENDO: "Nintendo",
OPENHARMONY: "OpenHarmony",
OPENBSD: "OpenBSD",
OPENVMS: "OpenVMS",
OS2: "OS/2",
PALM: "Palm",
PC_BSD: "PC-BSD",
PCLINUXOS: "PCLinuxOS",
PICO: "Pico",
PLAN9: "Plan9",
PLAYSTATION: "PlayStation",
QNX: "QNX",
RASPBIAN: "Raspbian",
REDHAT: "RedHat",
RIM_TABLET_OS: "RIM Tablet OS",
RISC_OS: "RISC OS",
SABAYON: "Sabayon",
SAILFISH: "Sailfish",
SERENITYOS: "SerenityOS",
SERIES40: "Series40",
SLACKWARE: "Slackware",
SOLARIS: "Solaris",
SUSE: "SUSE",
SYMBIAN: "Symbian",
TIZEN: "Tizen",
UBUNTU: "Ubuntu",
UBUNTU_TOUCH: "Ubuntu Touch",
UNIX: "Unix",
VECTORLINUX: "VectorLinux",
WATCHOS: "watchOS",
WEBOS: "WebOS",
WINDOWS: "Windows",
WINDOWS_CE: "Windows CE",
WINDOWS_IOT: "Windows IoT",
WINDOWS_MOBILE: "Windows Mobile",
WINDOWS_PHONE: "Windows Phone",
WINDOWS_RT: "Windows RT",
XBOX: "Xbox",
XUBUNTU: "Xubuntu",
ZENWALK: "Zenwalk",
AIX: 'AIX',
AMIGA_OS: 'Amiga OS',
ANDROID: 'Android',
ANDROID_X86: 'Android-x86',
ARCAOS: 'ArcaOS',
ARCH: 'Arch',
BADA: 'Bada',
BEOS: 'BeOS',
BLACKBERRY: 'BlackBerry',
CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast',
CHROMECAST_ANDROID: 'Chromecast Android',
CHROMECAST_FUCHSIA: 'Chromecast Fuchsia',
CHROMECAST_LINUX: 'Chromecast Linux',
CHROMECAST_SMARTSPEAKER: 'Chromecast SmartSpeaker',
CONTIKI: 'Contiki',
DEBIAN: 'Debian',
DEEPIN: 'Deepin',
DRAGONFLY: 'DragonFly',
ELEMENTARY_OS: 'elementary OS',
FEDORA: 'Fedora',
FIREFOX_OS: 'Firefox OS',
FREEBSD: 'FreeBSD',
FUCHSIA: 'Fuchsia',
GENTOO: 'Gentoo',
GHOSTBSD: 'GhostBSD',
GNU: 'GNU',
HAIKU: 'Haiku',
HARMONYOS: 'HarmonyOS',
HP_UX: 'HP-UX',
HURD: 'Hurd',
IOS: 'iOS',
JOLI: 'Joli',
KAIOS: 'KaiOS',
KNOPPIX: 'Knoppix',
KUBUNTU: 'Kubuntu',
LINPUS: 'Linpus',
LINSPIRE: 'Linspire',
LINUX: 'Linux',
MACOS: 'macOS',
MAEMO: 'Maemo',
MAGEIA: 'Mageia',
MANDRIVA: 'Mandriva',
MANJARO: 'Manjaro',
MEEGO: 'MeeGo',
MINIX: 'Minix',
MINT: 'Mint',
MORPH_OS: 'Morph OS',
NETBSD: 'NetBSD',
NETRANGE: 'NetRange',
NETTV: 'NetTV',
NINTENDO: 'Nintendo',
OPENHARMONY: 'OpenHarmony',
OPENBSD: 'OpenBSD',
OPENVMS: 'OpenVMS',
OS2: 'OS/2',
PALM: 'Palm',
PC_BSD: 'PC-BSD',
PCLINUXOS: 'PCLinuxOS',
PICO: 'Pico',
PLAN9: 'Plan9',
PLAYSTATION: 'PlayStation',
QNX: 'QNX',
RASPBIAN: 'Raspbian',
REDHAT: 'RedHat',
RIM_TABLET_OS: 'RIM Tablet OS',
RISC_OS: 'RISC OS',
SABAYON: 'Sabayon',
SAILFISH: 'Sailfish',
SERENITYOS: 'SerenityOS',
SERIES40: 'Series40',
SLACKWARE: 'Slackware',
SOLARIS: 'Solaris',
SUSE: 'SUSE',
SYMBIAN: 'Symbian',
TIZEN: 'Tizen',
UBUNTU: 'Ubuntu',
UBUNTU_TOUCH: 'Ubuntu Touch',
UNIX: 'Unix',
VECTORLINUX: 'VectorLinux',
WATCHOS: 'watchOS',
WEBOS: 'WebOS',
WINDOWS: 'Windows',
WINDOWS_CE: 'Windows CE',
WINDOWS_IOT: 'Windows IoT',
WINDOWS_MOBILE: 'Windows Mobile',
WINDOWS_PHONE: 'Windows Phone',
WINDOWS_RT: 'Windows RT',
XBOX: 'Xbox',
XUBUNTU: 'Xubuntu',
ZENWALK: 'Zenwalk'
// TODO : test!
}>;
/**
* @deprecated Use `OSName` instead
@ -421,7 +436,7 @@ export const OS: typeof OSName;
*///////////////////////////////
export const Extension: Readonly<{
Browser: {
BrowserName: {
CLIs: {
CURL: 'curl',
ELINKS: 'ELinks',
@ -441,6 +456,9 @@ export const Extension: Readonly<{
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',
@ -457,8 +475,6 @@ export const Extension: Readonly<{
BYTEDANCE_SPIDER: 'Bytespider',
CC_BOT: 'CCBot',
CHATGLM_SPIDER: 'ChatGLM-Spider',
CLAUDE_WEB: 'Claude-Web',
CLAUDE_BOT: 'ClaudeBot',
COCCOC_BOT_WEB: 'coccocbot-web',
COCCOC_BOT_IMAGE: 'coccocbot-image',
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
@ -573,11 +589,13 @@ export const Extension: Readonly<{
},
Fetchers: {
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',
@ -667,3 +685,4 @@ export const Extension: Readonly<{
}
}
}>;

View File

@ -441,7 +441,6 @@ const Extension = Object.freeze({
WGET: 'wget'
},
Crawlers: {
'360_SPIDER': '360Spider',
AHREFS_BOT: 'AhrefsBot',
AI2_BOT: 'AI2Bot',
AIHIT_BOT: 'aiHitBot',
@ -452,6 +451,9 @@ const Extension = Object.freeze({
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',
@ -465,11 +467,9 @@ const Extension = Object.freeze({
BLEX_BOT: 'BLEXBot',
BOTIFY: 'botify',
BRAVE_BOT: 'Bravebot',
BYTEDANCE_SPIDER: 'Bytespider',
CC_BOT: 'CCBot',
CHATGLM_SPIDER: 'ChatGLM-Spider',
CLAUDE_WEB: 'Claude-Web',
CLAUDE_BOT: 'ClaudeBot',
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',
@ -491,10 +491,13 @@ const Extension = Object.freeze({
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',
@ -524,16 +527,16 @@ const Extension = Object.freeze({
MICROSOFT_ADIDXBOT: 'adidxbot',
MOJEEK_BOT: 'MojeekBot',
MOZ_DOTBOT: 'DotBot',
OMGILI: 'omgili',
OMGILI_BOT: 'omgilibot',
ONCRAWL: 'OnCrawl',
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
OPENAI_GPTBOT: 'GPTBot',
OPENAI_SEARCH: 'OAI-SearchBot',
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',
@ -548,15 +551,48 @@ const Extension = Object.freeze({
TOGETHER_BOT: 'Together-Bot',
TURNITIN_BOT: 'TurnitinBot',
TWIN_AGENT: 'TwinAgent',
XAI_BOT: 'xAI-Bot',
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'
},
Emails: {
@ -584,16 +620,18 @@ const Extension = Object.freeze({
},
Fetchers: {
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_IMAGE_PROXY: 'GoogleImageProxy',
GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
GOOGLE_PRODUCER: 'GoogleProducer',
@ -621,6 +659,15 @@ const Extension = Object.freeze({
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',
WHATSAPP: 'WhatsApp',
ZOOMINFO_BOT: 'Zoombot'
},

View File

@ -61,9 +61,10 @@ const Crawlers = Object.freeze({
// Onespot - https://www.onespot.com/identifying-traffic.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro
// YepBot - https://yep.com/yepbot/
/((?: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|semrush|seznam|yep)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,
@ -109,7 +110,7 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
/(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,
/(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,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
@ -119,9 +120,14 @@ const Crawlers = Object.freeze({
// 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]],
[
// YandexBot MirrorDetector
/(yandexbot\/([\w\.]+); mirrordetector)/i
],
[[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
[
// Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
@ -134,8 +140,8 @@ const Crawlers = Object.freeze({
// 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
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot
/\b((?:ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(?:image|video)?|baidu-ads|botify|bytespider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|yahoo! slurp)/i
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
/\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]]
]
@ -250,7 +256,7 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({
browser : [
[
// Asana / Bitlybot / Better Uptime / BingPreview / Blueno / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// 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
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
@ -260,7 +266,7 @@ const Fetchers = Object.freeze({
// Perplexity-User - https://docs.perplexity.ai/guides/bots
// MistralAI-User - https://docs.mistral.ai/robots/
// Yandex Bots - https://yandex.com/bots
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|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)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
/(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,
// Bluesky
/(bluesky) cardyb\/([\w\.]+)/i,
@ -277,8 +283,8 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]],
[
// Google Bots / Chrome-Lighthouse / Cohere / Gemini-Deep-Research / Snapchat / TikTokSpider / Vercelbot / Yandex Bots
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|cohere-ai|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|tiktokspider|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / TikTokSpider / Vercelbot / Yandex Bots
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|tiktokspider|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
],
[NAME, [TYPE, FETCHER]],
],

View File

@ -4,24 +4,12 @@
import type { IResult } from "../main/ua-parser";
declare function getDeviceVendor(model: string): string | undefined;
declare function isAppleSilicon(resultOrUA: IResult | string): boolean;
declare function isAIBot(resultOrUA: IResult | string): boolean;
declare function isBot(resultOrUA: IResult | string): boolean;
declare function isChromeFamily(resultOrUA: IResult | string): boolean;
declare function isElectron(): boolean;
declare function isFromEU(): boolean;
declare function isFrozenUA(ua: string): boolean;
declare function isStandalonePWA(): boolean;
export {
getDeviceVendor,
isAppleSilicon,
isAIBot,
isBot,
isChromeFamily,
isElectron,
isFromEU,
isFrozenUA,
isStandalonePWA
}
export function getDeviceVendor(model: string): string | undefined;
export function isAppleSilicon(resultOrUA: IResult | string): boolean;
export function isAIBot(resultOrUA: IResult | string): boolean;
export function isBot(resultOrUA: IResult | string): boolean;
export function isChromeFamily(resultOrUA: IResult | string): boolean;
export function isElectron(): boolean;
export function isFromEU(): boolean;
export function isFrozenUA(ua: string): boolean;
export function isStandalonePWA(): boolean;

View File

@ -8,7 +8,7 @@
/*jshint esversion: 6 */
const { UAParser } = require('../main/ua-parser');
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
const { CPUArch, OSName, EngineName, Extension } = require('../enums/ua-parser-enums');
const { Bots } = require('../extensions/ua-parser-extensions');
const { isFromEU } = require('detect-europe-js');
const { isFrozenUA } = require('ua-is-frozen');
@ -20,8 +20,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
const isAppleSilicon = (resultOrUA) => {
const res = toResult(resultOrUA);
if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPU.ARM)) {
if (res.os.is(OSName.MACOS)) {
if (res.cpu.is(CPUArch.ARM)) {
return true;
}
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
@ -41,121 +41,124 @@ const isAppleSilicon = (resultOrUA) => {
return false;
}
const Crawler = Extension.BrowserName.Crawlers;
const isAIBot = (resultOrUA) => [
// AI2
'ai2bot',
Crawler.AI2_BOT,
// Amazon
'amazonbot',
Crawler.AMAZON_BOT,
// Anthropic
'anthropic-ai',
'claude-web',
'claude-searchbot',
'claudebot',
Crawler.ANTHROPIC_AI,
Crawler.ANTHROPIC_CLAUDE_BOT,
Crawler.ANTHROPIC_CLAUDE_SEARCHBOT,
Crawler.ANTHROPIC_CLAUDE_WEB,
// Apple
'applebot',
'applebot-extended',
Crawler.APPLE_BOT,
Crawler.APPLE_BOT_EXTENDED,
// Brave
'bravebot',
Crawler.BRAVE_BOT,
// ByteDance
'bytespider',
'tiktokspider',
Crawler.BYTEDANCE_BYTESPIDER,
Crawler.BYTEDANCE_TIKTOKSPIDER,
// Cohere
'cohere-training-data-crawler',
Crawler.COHERE_TRAINING_DATA_CRAWLER,
// Common Crawl
'ccbot',
Crawler.COMMON_CRAWL_CCBOT,
// Coveo
'coveobot',
Crawler.COVEO_BOT,
// DataForSeo
'dataforseobot',
Crawler.DATAFORSEO_BOT,
// DeepSeek
'deepseekbot',
Crawler.DEEPSEEK_BOT,
// Diffbot
'diffbot',
Crawler.DIFFBOT,
// Google
'googleother',
'googleother-image',
'googleother-video',
'google-extended',
Crawler.GOOGLE_EXTENDED,
Crawler.GOOGLE_OTHER,
Crawler.GOOGLE_OTHER_IMAGE,
Crawler.GOOGLE_OTHER_VIDEO,
Crawler.GOOGLE_CLOUDVERTEXBOT,
// Hive AI
'imagesiftbot',
Crawler.HIVE_IMAGESIFTBOT,
// Huawei
'petalbot',
'pangubot',
Crawler.HUAWEI_PETALBOT,
Crawler.HUAWEI_PANGUBOT,
// Hugging Face
'huggingface-bot',
Crawler.HUGGINGFACE_BOT,
// Kangaroo
'kangaroo bot',
Crawler.KANGAROO_BOT,
// Mendable.ai
'firecrawlagent',
Crawler.FIRECRAWL_AGENT,
// Meta
'facebookbot',
'meta-externalagent',
Crawler.META_FACEBOOKBOT,
Crawler.META_EXTERNALAGENT,
// OpenAI
'gptbot',
'oai-searchbot',
Crawler.OPENAI_GPTBOT,
Crawler.OPENAI_SEARCH_BOT,
// Perplexity
'perplexitybot',
Crawler.PERPLEXITY_BOT,
// Replicate
'replicate-bot',
Crawler.REPLICATE_BOT,
// Runpod
'runpod-bot',
Crawler.RUNPOD_BOT,
// SB Intuitions
Crawler.SB_INTUITIONS_BOT,
// Semrush
'semrushbot-ocob',
Crawler.SEMRUSH_BOT_CONTENTSHAKE,
// Timpi
'timpibot',
Crawler.TIMPI_BOT,
// Together AI
'together-bot',
Crawler.TOGETHER_BOT,
// Velen.io
'velenpublicwebcrawler',
Crawler.HUNTER_VELENPUBLICWEBCRAWLER,
// Vercel
'v0bot',
Crawler.VERCEL_V0BOT,
// Webz.io
'omgili',
'omgilibot',
'webzio-extended',
Crawler.WEBZIO_OMGILI,
Crawler.WEBZIO_OMGILI_BOT,
Crawler.WEBZIO_EXTENDED,
// X
'xai-bot',
Crawler.XAI_BOT,
// You.com
'youbot',
Crawler.YOU_BOT,
// Zhipu AI
'chatglm-spider',
// Zyte
'scrapy'
].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
Crawler.ZHIPU_CHATGLM_SPIDER
]
.map((s) => s.toLowerCase())
.includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
const isBot = (resultOrUA) => [
'cli',
@ -164,7 +167,7 @@ const isBot = (resultOrUA) => [
'library'
].includes(toResult(resultOrUA, Bots).browser.type);
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser

View File

@ -3,7 +3,7 @@
// Definitions by: Faisal Salman <https://github.com/faisalman>
import type { Headers } from "undici";
import { BrowserType, CPU as CPUArch, Device as DeviceType, Engine as EngineName } from "../enums/ua-parser-enums";
import { BrowserType, CPUArch, DeviceType, EngineName } from "../enums/ua-parser-enums";
declare namespace UAParser {

242
test/data/ua-ch/headers.js Normal file
View File

@ -0,0 +1,242 @@
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

@ -329,6 +329,16 @@
"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)",
@ -569,6 +579,16 @@
"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",
"ua" : "Googlebot-Video/1.0",
@ -669,6 +689,16 @@
"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",
"ua" : "Google-Safety",
@ -960,6 +990,16 @@
"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)",
@ -1070,6 +1110,16 @@
"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",
"ua" : "Timpibot/0.8 (+http://www.timpi.io)",
@ -1140,6 +1190,26 @@
"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",
"ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)",
@ -1160,6 +1230,46 @@
"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",
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)",
@ -1170,6 +1280,246 @@
"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/)",

View File

@ -99,6 +99,26 @@
"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",
"ua" : "DuckAssistBot/1.2; (+http://duckduckgo.com/duckassistbot.html)",
@ -399,6 +419,96 @@
"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)",

View File

@ -1,5 +1,5 @@
import { UAParser } from '../../src/main/ua-parser.mjs';
import { CPU, Device, Engine } from '../../src/enums/ua-parser-enums.mjs';
import { CPUArch, DeviceType, EngineName } from '../../src/enums/ua-parser-enums.mjs';
import * as assert from 'assert';
describe('Returns', () => {
@ -19,8 +19,8 @@ describe('Returns', () => {
describe('Enums', () => {
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');
assert.strictEqual(cpu.is(CPU.ARM), true);
assert.strictEqual(device.is(Device.MOBILE), true);
assert.strictEqual(engine.is(Engine.GECKO), true);
assert.strictEqual(cpu.is(CPUArch.ARM), true);
assert.strictEqual(device.is(DeviceType.MOBILE), true);
assert.strictEqual(engine.is(EngineName.GECKO), true);
});
});

View File

@ -1,5 +1,6 @@
const assert = require('assert');
const { UAParser } = require('../../src/main/ua-parser');
const UACHTests = require('../data/ua-ch/headers');
describe('Map UA-CH headers', () => {
@ -221,233 +222,12 @@ describe('Map UA-CH headers', () => {
});
describe('UA-CH Headers tests', () => {
[
{
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
}
}
},
{
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 => {
UACHTests.forEach(test => {
it(`Test for ${test.desc}`, () => {
const { browser } = UAParser(test.headers).withClientHints();
assert.deepEqual(browser, test.expect.browser);
});
});
});
describe('Identify vendor & type of device from given model name', () => {