UNPKG

vuetify-nuxt-module

Version:
181 lines (180 loc) 5.91 kB
import process from "node:process"; export class BrowserInfo { constructor(name, version, os) { this.name = name; this.version = version; this.os = os; } type = "browser"; } export class NodeInfo { constructor(version) { this.version = version; } type = "node"; name = "node"; os = process.platform; } export class SearchBotDeviceInfo { constructor(name, version, os, bot) { this.name = name; this.version = version; this.os = os; this.bot = bot; } type = "bot-device"; } export class BotInfo { type = "bot"; bot = true; // NOTE: deprecated test name instead name = "bot"; version = null; os = null; } export class ReactNativeInfo { type = "react-native"; name = "react-native"; version = null; os = null; } const SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/; const SEARCHBOT_OS_REGEX = /(nuhk|curl|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ Jeeves\/Teoma|ia_archiver)/; const REQUIRED_VERSION_PARTS = 3; const userAgentRules = [ ["aol", /AOLShield\/([0-9\._]+)/], ["brave", /Brave\/([0-9\._]+)/], ["edge", /Edge\/([0-9\._]+)/], ["edge-ios", /EdgiOS\/([0-9\._]+)/], ["yandexbrowser", /YaBrowser\/([0-9\._]+)/], ["kakaotalk", /KAKAOTALK\s([0-9\.]+)/], ["samsung", /SamsungBrowser\/([0-9\.]+)/], ["silk", /\bSilk\/([0-9._-]+)\b/], ["miui", /MiuiBrowser\/([0-9\.]+)$/], ["beaker", /BeakerBrowser\/([0-9\.]+)/], ["edge-chromium", /EdgA?\/([0-9\.]+)/], [ "chromium-webview", /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/ ], ["chrome", /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/], ["phantomjs", /PhantomJS\/([0-9\.]+)(:?\s|$)/], ["crios", /CriOS\/([0-9\.]+)(:?\s|$)/], ["firefox", /Firefox\/([0-9\.]+)(?:\s|$)/], ["fxios", /FxiOS\/([0-9\.]+)/], ["opera-mini", /Opera Mini.*Version\/([0-9\.]+)/], ["opera", /Opera\/([0-9\.]+)(?:\s|$)/], ["opera", /OPR\/([0-9\.]+)(:?\s|$)/], ["pie", /^Microsoft Pocket Internet Explorer\/(\d+\.\d+)$/], ["pie", /^Mozilla\/\d\.\d+\s\(compatible;\s(?:MSP?IE|MSInternet Explorer) (\d+\.\d+);.*Windows CE.*\)$/], ["netfront", /^Mozilla\/\d\.\d+.*NetFront\/(\d.\d)/], ["ie", /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/], ["ie", /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/], ["ie", /MSIE\s(7\.0)/], ["bb10", /BB10;\sTouch.*Version\/([0-9\.]+)/], ["android", /Android\s([0-9\.]+)/], ["ios", /Version\/([0-9\._]+).*Mobile.*Safari.*/], ["safari", /Version\/([0-9\._]+).*Safari/], ["facebook", /FB[AS]V\/([0-9\.]+)/], ["instagram", /Instagram\s([0-9\.]+)/], ["ios-webview", /AppleWebKit\/([0-9\.]+).*Mobile/], ["ios-webview", /AppleWebKit\/([0-9\.]+).*Gecko\)$/], ["curl", /^curl\/([0-9\.]+)$/], ["searchbot", SEARCHBOX_UA_REGEX] ]; const operatingSystemRules = [ ["iOS", /iP(hone|od|ad)/], ["Android OS", /Android/], ["BlackBerry OS", /BlackBerry|BB10/], ["Windows Mobile", /IEMobile/], ["Amazon OS", /Kindle/], ["Windows 3.11", /Win16/], ["Windows 95", /(Windows 95)|(Win95)|(Windows_95)/], ["Windows 98", /(Windows 98)|(Win98)/], ["Windows 2000", /(Windows NT 5.0)|(Windows 2000)/], ["Windows XP", /(Windows NT 5.1)|(Windows XP)/], ["Windows Server 2003", /(Windows NT 5.2)/], ["Windows Vista", /(Windows NT 6.0)/], ["Windows 7", /(Windows NT 6.1)/], ["Windows 8", /(Windows NT 6.2)/], ["Windows 8.1", /(Windows NT 6.3)/], ["Windows 10", /(Windows NT 10.0)/], ["Windows ME", /Windows ME/], ["Windows CE", /Windows CE|WinCE|Microsoft Pocket Internet Explorer/], ["Open BSD", /OpenBSD/], ["Sun OS", /SunOS/], ["Chrome OS", /CrOS/], ["Linux", /(Linux)|(X11)/], ["Mac OS", /(Mac_PowerPC)|(Macintosh)/], ["QNX", /QNX/], ["BeOS", /BeOS/], ["OS/2", /OS\/2/] ]; export function detect(userAgent) { if (userAgent) return parseUserAgent(userAgent); if (typeof document === "undefined" && typeof navigator !== "undefined" && navigator.product === "ReactNative") return new ReactNativeInfo(); if (typeof navigator !== "undefined") return parseUserAgent(navigator.userAgent); return getNodeVersion(); } function matchUserAgent(ua) { return ua !== "" && userAgentRules.reduce( (matched, [browser, regex]) => { if (matched) return matched; const uaMatch = regex.exec(ua); return !!uaMatch && [browser, uaMatch]; }, false ); } export function browserName(ua) { const data = matchUserAgent(ua); return data ? data[0] : null; } export function parseUserAgent(ua) { const matchedRule = matchUserAgent(ua); if (!matchedRule) return null; const [name, match] = matchedRule; if (name === "searchbot") return new BotInfo(); let versionParts = match[1] && match[1].split(".").join("_").split("_").slice(0, 3); if (versionParts) { if (versionParts.length < REQUIRED_VERSION_PARTS) { versionParts = [ ...versionParts, ...createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length) ]; } } else { versionParts = []; } const version = versionParts.join("."); const os = detectOS(ua); const searchBotMatch = SEARCHBOT_OS_REGEX.exec(ua); if (searchBotMatch && searchBotMatch[1]) return new SearchBotDeviceInfo(name, version, os, searchBotMatch[1]); return new BrowserInfo(name, version, os); } export function detectOS(ua) { for (let ii = 0, count = operatingSystemRules.length; ii < count; ii++) { const [os, regex] = operatingSystemRules[ii]; const match = regex.exec(ua); if (match) return os; } return null; } export function getNodeVersion() { const isNode = typeof process !== "undefined" && process.version; return isNode ? new NodeInfo(process.version.slice(1)) : null; } function createVersionParts(count) { const output = []; for (let ii = 0; ii < count; ii++) output.push("0"); return output; }