index.js 7.6 KB

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