@naturalcycles/js-lib 15.86.0 → 15.86.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ua/ua.d.ts CHANGED
@@ -1,8 +1,47 @@
1
1
  /// <reference lib="dom" preserve="true" />
2
2
  export type UADeviceType = 'console' | 'mobile' | 'tablet' | 'smarttv' | 'wearable' | 'embedded';
3
+ /**
4
+ * Popular OS names as produced by the parser, for convenient comparisons
5
+ * (`os.name === UAOSName.iOS`) without magic strings.
6
+ *
7
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
8
+ */
9
+ export declare enum UAOSName {
10
+ iOS = "iOS",
11
+ Android = "Android",
12
+ MacOS = "Mac OS",
13
+ Windows = "Windows",
14
+ Linux = "Linux",
15
+ ChromiumOS = "Chromium OS",
16
+ WatchOS = "watchOS"
17
+ }
18
+ /**
19
+ * Popular browser names as produced by the parser, for convenient comparisons
20
+ * (`browser.name === UABrowserName.Safari`) without magic strings.
21
+ *
22
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
23
+ */
24
+ export declare enum UABrowserName {
25
+ Chrome = "Chrome",
26
+ ChromeWebView = "Chrome WebView",
27
+ ChromeHeadless = "Chrome Headless",
28
+ Safari = "Safari",
29
+ MobileSafari = "Mobile Safari",
30
+ Firefox = "Firefox",
31
+ Edge = "Edge",
32
+ Opera = "Opera",
33
+ SamsungInternet = "Samsung Internet",
34
+ Facebook = "Facebook",
35
+ Instagram = "Instagram",
36
+ /**
37
+ * Bare WebKit UA without a Safari token, typically an iOS in-app webview (e.g. WKWebView).
38
+ */
39
+ WebKit = "WebKit"
40
+ }
3
41
  export interface UABrowser {
4
42
  /**
5
43
  * E.g Chrome, Edge, Firefox, Safari, Mobile Safari, Opera, IE, UCBrowser, WeChat, ...
44
+ * Popular values are available as `UABrowserName`.
6
45
  */
7
46
  name: string | undefined;
8
47
  version: string | undefined;
@@ -39,6 +78,7 @@ export interface UAEngine {
39
78
  export interface UAOS {
40
79
  /**
41
80
  * E.g Windows, iOS, Mac OS, Android, Linux, Chromium OS, ...
81
+ * Popular values are available as `UAOSName`.
42
82
  */
43
83
  name: string | undefined;
44
84
  version: string | undefined;
@@ -88,6 +128,7 @@ export interface UAParserExtensions {
88
128
  * (with client-hints-based refinements, e.g. Brave and iPadOS detection).
89
129
  */
90
130
  export declare function parseUserAgent(userAgent?: string, extensions?: UAParserExtensions): UAResult;
131
+ export declare function uaParser(userAgent?: string, extensions?: UAParserExtensions): UAParser;
91
132
  /**
92
133
  * User-Agent parser.
93
134
  *
@@ -97,11 +138,13 @@ export declare function parseUserAgent(userAgent?: string, extensions?: UAParser
97
138
  */
98
139
  export declare class UAParser {
99
140
  constructor(ua?: string, extensions?: UAParserExtensions);
100
- constructor(extensions: UAParserExtensions);
101
141
  private ua;
102
142
  private readonly nav;
103
143
  private readonly rgxMap;
104
144
  private readonly isSelfNav;
145
+ private cachedBrowser?;
146
+ private cachedOs?;
147
+ private cachedDevice?;
105
148
  getBrowser(): UABrowser;
106
149
  getCPU(): UACpu;
107
150
  getDevice(): UADevice;
@@ -110,4 +153,31 @@ export declare class UAParser {
110
153
  getResult(): UAResult;
111
154
  getUA(): string;
112
155
  setUA(ua: string | undefined): this;
156
+ /**
157
+ * True if the OS is iOS.
158
+ * Note: desktop-mode iPads send a Mac-like UA and are not detected as iOS
159
+ * (except when parsing the browser's own UA, where client-hints refinements apply).
160
+ */
161
+ isIos(): boolean;
162
+ isAndroid(): boolean;
163
+ isMacOs(): boolean;
164
+ isWindows(): boolean;
165
+ /**
166
+ * True for 'Chrome', 'Chrome WebView' and 'Chrome Headless' (not for Chromium).
167
+ */
168
+ isChrome(): boolean;
169
+ /**
170
+ * True for 'Safari' and 'Mobile Safari' (not for bare-WebKit iOS in-app webviews).
171
+ */
172
+ isSafari(): boolean;
173
+ isFirefox(): boolean;
174
+ isEdge(): boolean;
175
+ /**
176
+ * True if the device type is 'mobile' (phones; tablets are 'tablet' - see isTablet).
177
+ */
178
+ isMobile(): boolean;
179
+ isTablet(): boolean;
180
+ private browser;
181
+ private os;
182
+ private device;
113
183
  }
package/dist/ua/ua.js CHANGED
@@ -10,6 +10,46 @@
10
10
  // Detects Browser, Engine, OS, CPU and Device type/model from a User-Agent string.
11
11
  // Supports browser & Node.js environments.
12
12
  /// <reference lib="dom" preserve="true" />
13
+ /**
14
+ * Popular OS names as produced by the parser, for convenient comparisons
15
+ * (`os.name === UAOSName.iOS`) without magic strings.
16
+ *
17
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
18
+ */
19
+ export var UAOSName;
20
+ (function (UAOSName) {
21
+ UAOSName["iOS"] = "iOS";
22
+ UAOSName["Android"] = "Android";
23
+ UAOSName["MacOS"] = "Mac OS";
24
+ UAOSName["Windows"] = "Windows";
25
+ UAOSName["Linux"] = "Linux";
26
+ UAOSName["ChromiumOS"] = "Chromium OS";
27
+ UAOSName["WatchOS"] = "watchOS";
28
+ })(UAOSName || (UAOSName = {}));
29
+ /**
30
+ * Popular browser names as produced by the parser, for convenient comparisons
31
+ * (`browser.name === UABrowserName.Safari`) without magic strings.
32
+ *
33
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
34
+ */
35
+ export var UABrowserName;
36
+ (function (UABrowserName) {
37
+ UABrowserName["Chrome"] = "Chrome";
38
+ UABrowserName["ChromeWebView"] = "Chrome WebView";
39
+ UABrowserName["ChromeHeadless"] = "Chrome Headless";
40
+ UABrowserName["Safari"] = "Safari";
41
+ UABrowserName["MobileSafari"] = "Mobile Safari";
42
+ UABrowserName["Firefox"] = "Firefox";
43
+ UABrowserName["Edge"] = "Edge";
44
+ UABrowserName["Opera"] = "Opera";
45
+ UABrowserName["SamsungInternet"] = "Samsung Internet";
46
+ UABrowserName["Facebook"] = "Facebook";
47
+ UABrowserName["Instagram"] = "Instagram";
48
+ /**
49
+ * Bare WebKit UA without a Safari token, typically an iOS in-app webview (e.g. WKWebView).
50
+ */
51
+ UABrowserName["WebKit"] = "WebKit";
52
+ })(UABrowserName || (UABrowserName = {}));
13
53
  /**
14
54
  * Parses the given User-Agent string into browser, engine, os, device and cpu information.
15
55
  *
@@ -19,6 +59,9 @@
19
59
  export function parseUserAgent(userAgent, extensions) {
20
60
  return new UAParser(userAgent, extensions).getResult();
21
61
  }
62
+ export function uaParser(userAgent, extensions) {
63
+ return new UAParser(userAgent, extensions);
64
+ }
22
65
  /**
23
66
  * User-Agent parser.
24
67
  *
@@ -28,10 +71,6 @@ export function parseUserAgent(userAgent, extensions) {
28
71
  */
29
72
  export class UAParser {
30
73
  constructor(ua, extensions) {
31
- if (typeof ua === 'object' && ua !== null) {
32
- extensions = ua;
33
- ua = undefined;
34
- }
35
74
  this.nav = typeof globalThis.window !== 'undefined' ? globalThis.navigator : undefined;
36
75
  this.rgxMap = extensions ? extend(regexes, extensions) : regexes;
37
76
  const initialUa = ua || this.nav?.userAgent || '';
@@ -44,6 +83,11 @@ export class UAParser {
44
83
  nav;
45
84
  rgxMap;
46
85
  isSelfNav;
86
+ // Lazily cached results shared by the is* helpers (so multiple checks cost one parse),
87
+ // reset by setUA(). The get* methods deliberately stay uncached and return fresh objects.
88
+ cachedBrowser;
89
+ cachedOs;
90
+ cachedDevice;
47
91
  getBrowser() {
48
92
  const browser = { name: undefined, version: undefined, major: undefined };
49
93
  rgxMapper(browser, this.ua, this.rgxMap.browser);
@@ -105,8 +149,63 @@ export class UAParser {
105
149
  setUA(ua) {
106
150
  ua ||= '';
107
151
  this.ua = ua.length > UA_MAX_LENGTH ? ua.replace(/^\s\s*/, '').slice(0, UA_MAX_LENGTH) : ua;
152
+ this.cachedBrowser = this.cachedOs = this.cachedDevice = undefined;
108
153
  return this;
109
154
  }
155
+ /**
156
+ * True if the OS is iOS.
157
+ * Note: desktop-mode iPads send a Mac-like UA and are not detected as iOS
158
+ * (except when parsing the browser's own UA, where client-hints refinements apply).
159
+ */
160
+ isIos() {
161
+ return this.os().name === UAOSName.iOS;
162
+ }
163
+ isAndroid() {
164
+ return this.os().name === UAOSName.Android;
165
+ }
166
+ isMacOs() {
167
+ return this.os().name === UAOSName.MacOS;
168
+ }
169
+ isWindows() {
170
+ return this.os().name === UAOSName.Windows;
171
+ }
172
+ /**
173
+ * True for 'Chrome', 'Chrome WebView' and 'Chrome Headless' (not for Chromium).
174
+ */
175
+ isChrome() {
176
+ return !!this.browser().name?.startsWith(UABrowserName.Chrome);
177
+ }
178
+ /**
179
+ * True for 'Safari' and 'Mobile Safari' (not for bare-WebKit iOS in-app webviews).
180
+ */
181
+ isSafari() {
182
+ const { name } = this.browser();
183
+ return name === UABrowserName.Safari || name === UABrowserName.MobileSafari;
184
+ }
185
+ isFirefox() {
186
+ return this.browser().name === UABrowserName.Firefox;
187
+ }
188
+ isEdge() {
189
+ return this.browser().name === UABrowserName.Edge;
190
+ }
191
+ /**
192
+ * True if the device type is 'mobile' (phones; tablets are 'tablet' - see isTablet).
193
+ */
194
+ isMobile() {
195
+ return this.device().type === MOBILE;
196
+ }
197
+ isTablet() {
198
+ return this.device().type === TABLET;
199
+ }
200
+ browser() {
201
+ return (this.cachedBrowser ??= this.getBrowser());
202
+ }
203
+ os() {
204
+ return (this.cachedOs ??= this.getOS());
205
+ }
206
+ device() {
207
+ return (this.cachedDevice ??= this.getDevice());
208
+ }
110
209
  }
111
210
  ///////////
112
211
  // Helpers
@@ -230,9 +329,9 @@ const ASUS = 'ASUS';
230
329
  const BLACKBERRY = 'BlackBerry';
231
330
  const BROWSER = 'Browser';
232
331
  const SUFFIX_BROWSER = ' Browser';
233
- const CHROME = 'Chrome';
234
- const EDGE = 'Edge';
235
- const FIREFOX = 'Firefox';
332
+ const CHROME = UABrowserName.Chrome;
333
+ const EDGE = UABrowserName.Edge;
334
+ const FIREFOX = UABrowserName.Firefox;
236
335
  const GOOGLE = 'Google';
237
336
  const HONOR = 'Honor';
238
337
  const HUAWEI = 'Huawei';
@@ -242,16 +341,16 @@ const MICROSOFT = 'Microsoft';
242
341
  const MOTOROLA = 'Motorola';
243
342
  const NVIDIA = 'Nvidia';
244
343
  const ONEPLUS = 'OnePlus';
245
- const OPERA = 'Opera';
344
+ const OPERA = UABrowserName.Opera;
246
345
  const OPPO = 'OPPO';
247
346
  const SAMSUNG = 'Samsung';
248
347
  const SHARP = 'Sharp';
249
348
  const SONY = 'Sony';
250
349
  const XIAOMI = 'Xiaomi';
251
350
  const ZEBRA = 'Zebra';
252
- const FACEBOOK = 'Facebook';
253
- const CHROMIUM_OS = 'Chromium OS';
254
- const MAC_OS = 'Mac OS';
351
+ const FACEBOOK = UABrowserName.Facebook;
352
+ const CHROMIUM_OS = UAOSName.ChromiumOS;
353
+ const MAC_OS = UAOSName.MacOS;
255
354
  ///////////////
256
355
  // String maps
257
356
  //////////////
@@ -289,11 +388,11 @@ const regexes = {
289
388
  [
290
389
  /\b(?:crmo|crios)\/([\w\.]+)/i, // Chrome for Android/iOS
291
390
  ],
292
- [VERSION, [NAME, 'Chrome']],
391
+ [VERSION, [NAME, CHROME]],
293
392
  [
294
393
  /edg(?:e|ios|a)?\/([\w\.]+)/i, // Microsoft Edge
295
394
  ],
296
- [VERSION, [NAME, 'Edge']],
395
+ [VERSION, [NAME, EDGE]],
297
396
  [
298
397
  // Presto based
299
398
  /(opera mini)\/([-\w\.]+)/i, // Opera Mini
@@ -415,7 +514,7 @@ const regexes = {
415
514
  [
416
515
  /samsungbrowser\/([\w\.]+)/i, // Samsung Internet
417
516
  ],
418
- [VERSION, [NAME, SAMSUNG + ' Internet']],
517
+ [VERSION, [NAME, UABrowserName.SamsungInternet]],
419
518
  [
420
519
  /metasr[\/ ]?([\d\.]+)/i, // Sogou Explorer
421
520
  ],
@@ -468,11 +567,11 @@ const regexes = {
468
567
  [
469
568
  /headlesschrome(?:\/([\w\.]+)| )/i, // Chrome Headless
470
569
  ],
471
- [VERSION, [NAME, CHROME + ' Headless']],
570
+ [VERSION, [NAME, UABrowserName.ChromeHeadless]],
472
571
  [
473
572
  / wv\).+(chrome)\/([\w\.]+)/i, // Chrome WebView
474
573
  ],
475
- [[NAME, CHROME + ' WebView'], VERSION],
574
+ [[NAME, UABrowserName.ChromeWebView], VERSION],
476
575
  [
477
576
  /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i, // Android Browser
478
577
  ],
@@ -484,7 +583,7 @@ const regexes = {
484
583
  [
485
584
  /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i, // Mobile Safari
486
585
  ],
487
- [VERSION, [NAME, 'Mobile Safari']],
586
+ [VERSION, [NAME, UABrowserName.MobileSafari]],
488
587
  [
489
588
  /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i, // Safari & Safari Mobile
490
589
  ],
@@ -1198,7 +1297,7 @@ const regexes = {
1198
1297
  ],
1199
1298
  [
1200
1299
  [VERSION, strMapper, windowsVersionMap],
1201
- [NAME, 'Windows'],
1300
+ [NAME, UAOSName.Windows],
1202
1301
  ],
1203
1302
  [
1204
1303
  // iOS/macOS
@@ -1208,7 +1307,7 @@ const regexes = {
1208
1307
  ],
1209
1308
  [
1210
1309
  [VERSION, /_/g, '.'],
1211
- [NAME, 'iOS'],
1310
+ [NAME, UAOSName.iOS],
1212
1311
  ],
1213
1312
  [
1214
1313
  /(mac os x) ?([\w\. ]*)/i,
@@ -1252,7 +1351,7 @@ const regexes = {
1252
1351
  [
1253
1352
  /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i, // watchOS
1254
1353
  ],
1255
- [VERSION, [NAME, 'watchOS']],
1354
+ [VERSION, [NAME, UAOSName.WatchOS]],
1256
1355
  [
1257
1356
  // Google Chromecast
1258
1357
  /crkey\/([\d\.]+)/i, // Google Chromecast
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.86.0",
4
+ "version": "15.86.1",
5
5
  "dependencies": {
6
6
  "tslib": "^2"
7
7
  },
package/src/ua/ua.ts CHANGED
@@ -16,9 +16,50 @@
16
16
 
17
17
  export type UADeviceType = 'console' | 'mobile' | 'tablet' | 'smarttv' | 'wearable' | 'embedded'
18
18
 
19
+ /**
20
+ * Popular OS names as produced by the parser, for convenient comparisons
21
+ * (`os.name === UAOSName.iOS`) without magic strings.
22
+ *
23
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
24
+ */
25
+ export enum UAOSName {
26
+ iOS = 'iOS',
27
+ Android = 'Android',
28
+ MacOS = 'Mac OS',
29
+ Windows = 'Windows',
30
+ Linux = 'Linux',
31
+ ChromiumOS = 'Chromium OS',
32
+ WatchOS = 'watchOS',
33
+ }
34
+
35
+ /**
36
+ * Popular browser names as produced by the parser, for convenient comparisons
37
+ * (`browser.name === UABrowserName.Safari`) without magic strings.
38
+ *
39
+ * Not exhaustive - the parser emits many more names; compare against a string for the rest.
40
+ */
41
+ export enum UABrowserName {
42
+ Chrome = 'Chrome',
43
+ ChromeWebView = 'Chrome WebView',
44
+ ChromeHeadless = 'Chrome Headless',
45
+ Safari = 'Safari',
46
+ MobileSafari = 'Mobile Safari',
47
+ Firefox = 'Firefox',
48
+ Edge = 'Edge',
49
+ Opera = 'Opera',
50
+ SamsungInternet = 'Samsung Internet',
51
+ Facebook = 'Facebook',
52
+ Instagram = 'Instagram',
53
+ /**
54
+ * Bare WebKit UA without a Safari token, typically an iOS in-app webview (e.g. WKWebView).
55
+ */
56
+ WebKit = 'WebKit',
57
+ }
58
+
19
59
  export interface UABrowser {
20
60
  /**
21
61
  * E.g Chrome, Edge, Firefox, Safari, Mobile Safari, Opera, IE, UCBrowser, WeChat, ...
62
+ * Popular values are available as `UABrowserName`.
22
63
  */
23
64
  name: string | undefined
24
65
  version: string | undefined
@@ -59,6 +100,7 @@ export interface UAEngine {
59
100
  export interface UAOS {
60
101
  /**
61
102
  * E.g Windows, iOS, Mac OS, Android, Linux, Chromium OS, ...
103
+ * Popular values are available as `UAOSName`.
62
104
  */
63
105
  name: string | undefined
64
106
  version: string | undefined
@@ -125,6 +167,10 @@ export function parseUserAgent(userAgent?: string, extensions?: UAParserExtensio
125
167
  return new UAParser(userAgent, extensions).getResult()
126
168
  }
127
169
 
170
+ export function uaParser(userAgent?: string, extensions?: UAParserExtensions): UAParser {
171
+ return new UAParser(userAgent, extensions)
172
+ }
173
+
128
174
  /**
129
175
  * User-Agent parser.
130
176
  *
@@ -133,14 +179,7 @@ export function parseUserAgent(userAgent?: string, extensions?: UAParserExtensio
133
179
  * and reusing the compiled extensions across multiple `setUA()` calls.
134
180
  */
135
181
  export class UAParser {
136
- constructor(ua?: string, extensions?: UAParserExtensions)
137
- constructor(extensions: UAParserExtensions)
138
- constructor(ua?: string | UAParserExtensions, extensions?: UAParserExtensions) {
139
- if (typeof ua === 'object' && ua !== null) {
140
- extensions = ua
141
- ua = undefined
142
- }
143
-
182
+ constructor(ua?: string, extensions?: UAParserExtensions) {
144
183
  this.nav = typeof globalThis.window !== 'undefined' ? globalThis.navigator : undefined
145
184
  this.rgxMap = extensions ? extend(regexes, extensions) : regexes
146
185
  const initialUa = ua || this.nav?.userAgent || ''
@@ -154,6 +193,11 @@ export class UAParser {
154
193
  private readonly nav: UaNavigator | undefined
155
194
  private readonly rgxMap: UARegexMaps
156
195
  private readonly isSelfNav: boolean
196
+ // Lazily cached results shared by the is* helpers (so multiple checks cost one parse),
197
+ // reset by setUA(). The get* methods deliberately stay uncached and return fresh objects.
198
+ private cachedBrowser?: UABrowser
199
+ private cachedOs?: UAOS
200
+ private cachedDevice?: UADevice
157
201
 
158
202
  getBrowser(): UABrowser {
159
203
  const browser: UABrowser = { name: undefined, version: undefined, major: undefined }
@@ -225,8 +269,76 @@ export class UAParser {
225
269
  setUA(ua: string | undefined): this {
226
270
  ua ||= ''
227
271
  this.ua = ua.length > UA_MAX_LENGTH ? ua.replace(/^\s\s*/, '').slice(0, UA_MAX_LENGTH) : ua
272
+ this.cachedBrowser = this.cachedOs = this.cachedDevice = undefined
228
273
  return this
229
274
  }
275
+
276
+ /**
277
+ * True if the OS is iOS.
278
+ * Note: desktop-mode iPads send a Mac-like UA and are not detected as iOS
279
+ * (except when parsing the browser's own UA, where client-hints refinements apply).
280
+ */
281
+ isIos(): boolean {
282
+ return this.os().name === UAOSName.iOS
283
+ }
284
+
285
+ isAndroid(): boolean {
286
+ return this.os().name === UAOSName.Android
287
+ }
288
+
289
+ isMacOs(): boolean {
290
+ return this.os().name === UAOSName.MacOS
291
+ }
292
+
293
+ isWindows(): boolean {
294
+ return this.os().name === UAOSName.Windows
295
+ }
296
+
297
+ /**
298
+ * True for 'Chrome', 'Chrome WebView' and 'Chrome Headless' (not for Chromium).
299
+ */
300
+ isChrome(): boolean {
301
+ return !!this.browser().name?.startsWith(UABrowserName.Chrome)
302
+ }
303
+
304
+ /**
305
+ * True for 'Safari' and 'Mobile Safari' (not for bare-WebKit iOS in-app webviews).
306
+ */
307
+ isSafari(): boolean {
308
+ const { name } = this.browser()
309
+ return name === UABrowserName.Safari || name === UABrowserName.MobileSafari
310
+ }
311
+
312
+ isFirefox(): boolean {
313
+ return this.browser().name === UABrowserName.Firefox
314
+ }
315
+
316
+ isEdge(): boolean {
317
+ return this.browser().name === UABrowserName.Edge
318
+ }
319
+
320
+ /**
321
+ * True if the device type is 'mobile' (phones; tablets are 'tablet' - see isTablet).
322
+ */
323
+ isMobile(): boolean {
324
+ return this.device().type === MOBILE
325
+ }
326
+
327
+ isTablet(): boolean {
328
+ return this.device().type === TABLET
329
+ }
330
+
331
+ private browser(): UABrowser {
332
+ return (this.cachedBrowser ??= this.getBrowser())
333
+ }
334
+
335
+ private os(): UAOS {
336
+ return (this.cachedOs ??= this.getOS())
337
+ }
338
+
339
+ private device(): UADevice {
340
+ return (this.cachedDevice ??= this.getDevice())
341
+ }
230
342
  }
231
343
 
232
344
  /**
@@ -384,9 +496,9 @@ const ASUS = 'ASUS'
384
496
  const BLACKBERRY = 'BlackBerry'
385
497
  const BROWSER = 'Browser'
386
498
  const SUFFIX_BROWSER = ' Browser'
387
- const CHROME = 'Chrome'
388
- const EDGE = 'Edge'
389
- const FIREFOX = 'Firefox'
499
+ const CHROME = UABrowserName.Chrome
500
+ const EDGE = UABrowserName.Edge
501
+ const FIREFOX = UABrowserName.Firefox
390
502
  const GOOGLE = 'Google'
391
503
  const HONOR = 'Honor'
392
504
  const HUAWEI = 'Huawei'
@@ -396,16 +508,16 @@ const MICROSOFT = 'Microsoft'
396
508
  const MOTOROLA = 'Motorola'
397
509
  const NVIDIA = 'Nvidia'
398
510
  const ONEPLUS = 'OnePlus'
399
- const OPERA = 'Opera'
511
+ const OPERA = UABrowserName.Opera
400
512
  const OPPO = 'OPPO'
401
513
  const SAMSUNG = 'Samsung'
402
514
  const SHARP = 'Sharp'
403
515
  const SONY = 'Sony'
404
516
  const XIAOMI = 'Xiaomi'
405
517
  const ZEBRA = 'Zebra'
406
- const FACEBOOK = 'Facebook'
407
- const CHROMIUM_OS = 'Chromium OS'
408
- const MAC_OS = 'Mac OS'
518
+ const FACEBOOK = UABrowserName.Facebook
519
+ const CHROMIUM_OS = UAOSName.ChromiumOS
520
+ const MAC_OS = UAOSName.MacOS
409
521
 
410
522
  ///////////////
411
523
  // String maps
@@ -449,11 +561,11 @@ const regexes: UARegexMaps = {
449
561
  [
450
562
  /\b(?:crmo|crios)\/([\w\.]+)/i, // Chrome for Android/iOS
451
563
  ],
452
- [VERSION, [NAME, 'Chrome']],
564
+ [VERSION, [NAME, CHROME]],
453
565
  [
454
566
  /edg(?:e|ios|a)?\/([\w\.]+)/i, // Microsoft Edge
455
567
  ],
456
- [VERSION, [NAME, 'Edge']],
568
+ [VERSION, [NAME, EDGE]],
457
569
  [
458
570
  // Presto based
459
571
  /(opera mini)\/([-\w\.]+)/i, // Opera Mini
@@ -576,7 +688,7 @@ const regexes: UARegexMaps = {
576
688
  [
577
689
  /samsungbrowser\/([\w\.]+)/i, // Samsung Internet
578
690
  ],
579
- [VERSION, [NAME, SAMSUNG + ' Internet']],
691
+ [VERSION, [NAME, UABrowserName.SamsungInternet]],
580
692
  [
581
693
  /metasr[\/ ]?([\d\.]+)/i, // Sogou Explorer
582
694
  ],
@@ -629,11 +741,11 @@ const regexes: UARegexMaps = {
629
741
  [
630
742
  /headlesschrome(?:\/([\w\.]+)| )/i, // Chrome Headless
631
743
  ],
632
- [VERSION, [NAME, CHROME + ' Headless']],
744
+ [VERSION, [NAME, UABrowserName.ChromeHeadless]],
633
745
  [
634
746
  / wv\).+(chrome)\/([\w\.]+)/i, // Chrome WebView
635
747
  ],
636
- [[NAME, CHROME + ' WebView'], VERSION],
748
+ [[NAME, UABrowserName.ChromeWebView], VERSION],
637
749
  [
638
750
  /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i, // Android Browser
639
751
  ],
@@ -645,7 +757,7 @@ const regexes: UARegexMaps = {
645
757
  [
646
758
  /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i, // Mobile Safari
647
759
  ],
648
- [VERSION, [NAME, 'Mobile Safari']],
760
+ [VERSION, [NAME, UABrowserName.MobileSafari]],
649
761
  [
650
762
  /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i, // Safari & Safari Mobile
651
763
  ],
@@ -1372,7 +1484,7 @@ const regexes: UARegexMaps = {
1372
1484
  ],
1373
1485
  [
1374
1486
  [VERSION, strMapper, windowsVersionMap],
1375
- [NAME, 'Windows'],
1487
+ [NAME, UAOSName.Windows],
1376
1488
  ],
1377
1489
  [
1378
1490
  // iOS/macOS
@@ -1382,7 +1494,7 @@ const regexes: UARegexMaps = {
1382
1494
  ],
1383
1495
  [
1384
1496
  [VERSION, /_/g, '.'],
1385
- [NAME, 'iOS'],
1497
+ [NAME, UAOSName.iOS],
1386
1498
  ],
1387
1499
  [
1388
1500
  /(mac os x) ?([\w\. ]*)/i,
@@ -1426,7 +1538,7 @@ const regexes: UARegexMaps = {
1426
1538
  [
1427
1539
  /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i, // watchOS
1428
1540
  ],
1429
- [VERSION, [NAME, 'watchOS']],
1541
+ [VERSION, [NAME, UAOSName.WatchOS]],
1430
1542
  [
1431
1543
  // Google Chromecast
1432
1544
  /crkey\/([\d\.]+)/i, // Google Chromecast