index.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. "use strict";
  2. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  3. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  4. if (ar || !(i in from)) {
  5. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  6. ar[i] = from[i];
  7. }
  8. }
  9. return to.concat(ar || Array.prototype.slice.call(from));
  10. };
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. exports.getNodeVersion = exports.detectOS = exports.parseUserAgent = exports.browserName = exports.detect = exports.ReactNativeInfo = exports.BotInfo = exports.SearchBotDeviceInfo = exports.NodeInfo = exports.BrowserInfo = void 0;
  13. var BrowserInfo = /** @class */ (function () {
  14. function BrowserInfo(name, version, os) {
  15. this.name = name;
  16. this.version = version;
  17. this.os = os;
  18. this.type = 'browser';
  19. }
  20. return BrowserInfo;
  21. }());
  22. exports.BrowserInfo = BrowserInfo;
  23. var NodeInfo = /** @class */ (function () {
  24. function NodeInfo(version) {
  25. this.version = version;
  26. this.type = 'node';
  27. this.name = 'node';
  28. this.os = process.platform;
  29. }
  30. return NodeInfo;
  31. }());
  32. exports.NodeInfo = NodeInfo;
  33. var SearchBotDeviceInfo = /** @class */ (function () {
  34. function SearchBotDeviceInfo(name, version, os, bot) {
  35. this.name = name;
  36. this.version = version;
  37. this.os = os;
  38. this.bot = bot;
  39. this.type = 'bot-device';
  40. }
  41. return SearchBotDeviceInfo;
  42. }());
  43. exports.SearchBotDeviceInfo = SearchBotDeviceInfo;
  44. var BotInfo = /** @class */ (function () {
  45. function BotInfo() {
  46. this.type = 'bot';
  47. this.bot = true; // NOTE: deprecated test name instead
  48. this.name = 'bot';
  49. this.version = null;
  50. this.os = null;
  51. }
  52. return BotInfo;
  53. }());
  54. exports.BotInfo = BotInfo;
  55. var ReactNativeInfo = /** @class */ (function () {
  56. function ReactNativeInfo() {
  57. this.type = 'react-native';
  58. this.name = 'react-native';
  59. this.version = null;
  60. this.os = null;
  61. }
  62. return ReactNativeInfo;
  63. }());
  64. exports.ReactNativeInfo = ReactNativeInfo;
  65. // tslint:disable-next-line:max-line-length
  66. var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
  67. var SEARCHBOT_OS_REGEX = /(nuhk|curl|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ Jeeves\/Teoma|ia_archiver)/;
  68. var REQUIRED_VERSION_PARTS = 3;
  69. var userAgentRules = [
  70. ['aol', /AOLShield\/([0-9\._]+)/],
  71. ['edge', /Edge\/([0-9\._]+)/],
  72. ['edge-ios', /EdgiOS\/([0-9\._]+)/],
  73. ['yandexbrowser', /YaBrowser\/([0-9\._]+)/],
  74. ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/],
  75. ['samsung', /SamsungBrowser\/([0-9\.]+)/],
  76. ['silk', /\bSilk\/([0-9._-]+)\b/],
  77. ['miui', /MiuiBrowser\/([0-9\.]+)$/],
  78. ['beaker', /BeakerBrowser\/([0-9\.]+)/],
  79. ['edge-chromium', /EdgA?\/([0-9\.]+)/],
  80. [
  81. 'chromium-webview',
  82. /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/,
  83. ],
  84. ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
  85. ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/],
  86. ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/],
  87. ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/],
  88. ['fxios', /FxiOS\/([0-9\.]+)/],
  89. ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/],
  90. ['opera', /Opera\/([0-9\.]+)(?:\s|$)/],
  91. ['opera', /OPR\/([0-9\.]+)(:?\s|$)/],
  92. ['pie', /^Microsoft Pocket Internet Explorer\/(\d+\.\d+)$/],
  93. ['pie', /^Mozilla\/\d\.\d+\s\(compatible;\s(?:MSP?IE|MSInternet Explorer) (\d+\.\d+);.*Windows CE.*\)$/],
  94. ['netfront', /^Mozilla\/\d\.\d+.*NetFront\/(\d.\d)/],
  95. ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
  96. ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
  97. ['ie', /MSIE\s(7\.0)/],
  98. ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/],
  99. ['android', /Android\s([0-9\.]+)/],
  100. ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/],
  101. ['safari', /Version\/([0-9\._]+).*Safari/],
  102. ['facebook', /FB[AS]V\/([0-9\.]+)/],
  103. ['instagram', /Instagram\s([0-9\.]+)/],
  104. ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/],
  105. ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
  106. ['curl', /^curl\/([0-9\.]+)$/],
  107. ['searchbot', SEARCHBOX_UA_REGEX],
  108. ];
  109. var operatingSystemRules = [
  110. ['iOS', /iP(hone|od|ad)/],
  111. ['Android OS', /Android/],
  112. ['BlackBerry OS', /BlackBerry|BB10/],
  113. ['Windows Mobile', /IEMobile/],
  114. ['Amazon OS', /Kindle/],
  115. ['Windows 3.11', /Win16/],
  116. ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/],
  117. ['Windows 98', /(Windows 98)|(Win98)/],
  118. ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/],
  119. ['Windows XP', /(Windows NT 5.1)|(Windows XP)/],
  120. ['Windows Server 2003', /(Windows NT 5.2)/],
  121. ['Windows Vista', /(Windows NT 6.0)/],
  122. ['Windows 7', /(Windows NT 6.1)/],
  123. ['Windows 8', /(Windows NT 6.2)/],
  124. ['Windows 8.1', /(Windows NT 6.3)/],
  125. ['Windows 10', /(Windows NT 10.0)/],
  126. ['Windows ME', /Windows ME/],
  127. ['Windows CE', /Windows CE|WinCE|Microsoft Pocket Internet Explorer/],
  128. ['Open BSD', /OpenBSD/],
  129. ['Sun OS', /SunOS/],
  130. ['Chrome OS', /CrOS/],
  131. ['Linux', /(Linux)|(X11)/],
  132. ['Mac OS', /(Mac_PowerPC)|(Macintosh)/],
  133. ['QNX', /QNX/],
  134. ['BeOS', /BeOS/],
  135. ['OS/2', /OS\/2/],
  136. ];
  137. function detect(userAgent) {
  138. if (!!userAgent) {
  139. return parseUserAgent(userAgent);
  140. }
  141. if (typeof document === 'undefined' &&
  142. typeof navigator !== 'undefined' &&
  143. navigator.product === 'ReactNative') {
  144. return new ReactNativeInfo();
  145. }
  146. if (typeof navigator !== 'undefined') {
  147. return parseUserAgent(navigator.userAgent);
  148. }
  149. return getNodeVersion();
  150. }
  151. exports.detect = detect;
  152. function matchUserAgent(ua) {
  153. // opted for using reduce here rather than Array#first with a regex.test call
  154. // this is primarily because using the reduce we only perform the regex
  155. // execution once rather than once for the test and for the exec again below
  156. // probably something that needs to be benchmarked though
  157. return (ua !== '' &&
  158. userAgentRules.reduce(function (matched, _a) {
  159. var browser = _a[0], regex = _a[1];
  160. if (matched) {
  161. return matched;
  162. }
  163. var uaMatch = regex.exec(ua);
  164. return !!uaMatch && [browser, uaMatch];
  165. }, false));
  166. }
  167. function browserName(ua) {
  168. var data = matchUserAgent(ua);
  169. return data ? data[0] : null;
  170. }
  171. exports.browserName = browserName;
  172. function parseUserAgent(ua) {
  173. var matchedRule = matchUserAgent(ua);
  174. if (!matchedRule) {
  175. return null;
  176. }
  177. var name = matchedRule[0], match = matchedRule[1];
  178. if (name === 'searchbot') {
  179. return new BotInfo();
  180. }
  181. // Do not use RegExp for split operation as some browser do not support it (See: http://blog.stevenlevithan.com/archives/cross-browser-split)
  182. var versionParts = match[1] && match[1].split('.').join('_').split('_').slice(0, 3);
  183. if (versionParts) {
  184. if (versionParts.length < REQUIRED_VERSION_PARTS) {
  185. versionParts = __spreadArray(__spreadArray([], versionParts, true), createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length), true);
  186. }
  187. }
  188. else {
  189. versionParts = [];
  190. }
  191. var version = versionParts.join('.');
  192. var os = detectOS(ua);
  193. var searchBotMatch = SEARCHBOT_OS_REGEX.exec(ua);
  194. if (searchBotMatch && searchBotMatch[1]) {
  195. return new SearchBotDeviceInfo(name, version, os, searchBotMatch[1]);
  196. }
  197. return new BrowserInfo(name, version, os);
  198. }
  199. exports.parseUserAgent = parseUserAgent;
  200. function detectOS(ua) {
  201. for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
  202. var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
  203. var match = regex.exec(ua);
  204. if (match) {
  205. return os;
  206. }
  207. }
  208. return null;
  209. }
  210. exports.detectOS = detectOS;
  211. function getNodeVersion() {
  212. var isNode = typeof process !== 'undefined' && process.version;
  213. return isNode ? new NodeInfo(process.version.slice(1)) : null;
  214. }
  215. exports.getNodeVersion = getNodeVersion;
  216. function createVersionParts(count) {
  217. var output = [];
  218. for (var ii = 0; ii < count; ii++) {
  219. output.push('0');
  220. }
  221. return output;
  222. }