1111/// <reference types="user-agent-data-types" />
1212
1313declare interface OSFlags {
14- iOS : number [ ] ;
15- macOS : number [ ] ;
16- iPadOS : number [ ] ;
17- WindowsPhone : number [ ] ;
18- ChromeOS : number [ ] ;
19- Windows : number [ ] ;
20- Android : number [ ] ;
21- Linux : number [ ] ;
22- Firefox : boolean ;
14+ iOS : number [ ] ;
15+ macOS : number [ ] ;
16+ iPadOS : number [ ] ;
17+ WindowsPhone : number [ ] ;
18+ ChromeOS : number [ ] ;
19+ Windows : number [ ] ;
20+ Android : number [ ] ;
21+ Linux : number [ ] ;
22+ Firefox : boolean ;
2323}
2424
2525declare interface UAFlags {
26- Gecko : number [ ] ;
27- Firefox : number [ ] ;
28- Waterfox : number [ ] ;
29- Opera : number [ ] ;
30- Silk : number [ ] ;
31- Blink : number [ ] ;
32- EdgeHTML : number [ ] ;
33- Chrome : number [ ] ;
34- Chromium : number [ ] ;
35- Phoebe : number [ ] ;
36- UCBrowser : number [ ] ;
37- Vivaldi : number [ ] ;
38- Safari : number [ ] ;
39- Edge : number [ ] ;
40- WebKit : number [ ] ;
41- Trident : number [ ] ;
42- InternetExplorer : number [ ] ;
43- Flash : number [ ] ;
44- Facebook : number [ ] ;
45- LINE : number [ ] ;
26+ Gecko : number [ ] ;
27+ Firefox : number [ ] ;
28+ Waterfox : number [ ] ;
29+ Opera : number [ ] ;
30+ Silk : number [ ] ;
31+ Blink : number [ ] ;
32+ EdgeHTML : number [ ] ;
33+ Chrome : number [ ] ;
34+ Chromium : number [ ] ;
35+ Phoebe : number [ ] ;
36+ UCBrowser : number [ ] ;
37+ Vivaldi : number [ ] ;
38+ Safari : number [ ] ;
39+ Edge : number [ ] ;
40+ WebKit : number [ ] ;
41+ Trident : number [ ] ;
42+ InternetExplorer : number [ ] ;
43+ Flash : number [ ] ;
44+ Facebook : number [ ] ;
45+ LINE : number [ ] ;
4646}
4747
4848declare type iOSRequest = "mobile" | "desktop" | undefined ;
4949
5050// Fallback when global 'navigator' is not available, such as in SSR environments.
51- const userAgent = ( ) => typeof navigator === "undefined" ? "" : ( navigator . userAgent || "" ) ;
52- const userAgentData = ( ) => typeof navigator === "undefined" ? undefined : ( navigator . userAgentData || undefined ) ;
51+ const userAgent = ( ) =>
52+ typeof navigator === "undefined" ? "" : navigator . userAgent || "" ;
53+ const userAgentData = ( ) =>
54+ typeof navigator === "undefined"
55+ ? undefined
56+ : navigator . userAgentData || undefined ;
5357
5458class sMLFactory {
55- OS : OSFlags ;
56- UA : UAFlags ;
57- Env ! : string [ ] ;
59+ OS : OSFlags ;
60+ UA : UAFlags ;
61+ Env ! : string [ ] ;
5862
59- constructor ( ) {
60- const NUAD = userAgentData ( ) , NUA = userAgent ( ) ;
63+ constructor ( ) {
64+ const NUAD = userAgentData ( ) ,
65+ NUA = userAgent ( ) ;
6166
62- const _sV = ( V ?: string | number ) => ( typeof V === "string" || typeof V === "number" ) && V ? String ( V ) . replace ( / _ / g, "." ) . split ( "." ) . map ( I => parseInt ( I ) || 0 ) : [ ] ;
63- const _dV = ( Pre = "" ) => {
64- if ( ! Pre ) return [ ] ;
65- const RE = new RegExp ( "^.*" + Pre + "[ :\\/]?(\\d+([\\._]\\d+)*).*$" ) ;
66- if ( ! RE . test ( NUA ) ) return [ ] ;
67- return _sV ( NUA . replace ( RE , "$1" ) ) ;
68- } ;
67+ const _sV = ( V ?: string | number ) =>
68+ ( typeof V === "string" || typeof V === "number" ) && V
69+ ? String ( V )
70+ . replace ( / _ / g, "." )
71+ . split ( "." )
72+ . map ( ( I ) => parseInt ( I ) || 0 )
73+ : [ ] ;
74+ const _dV = ( Pre = "" ) => {
75+ if ( ! Pre ) return [ ] ;
76+ const RE = new RegExp ( "^.*" + Pre + "[ :\\/]?(\\d+([\\._]\\d+)*).*$" ) ;
77+ if ( ! RE . test ( NUA ) ) return [ ] ;
78+ return _sV ( NUA . replace ( RE , "$1" ) ) ;
79+ } ;
6980
70- this . OS = ( ( OS : OSFlags ) => {
71- if ( / ( m a c O S | M a c O S X ) / . test ( NUA ) ) {
72- if ( / \( i P ( h o n e | o d t o u c h ) ; / . test ( NUA ) ) OS . iOS = _dV ( "CPU (?:iPhone )?OS " ) ;
73- if ( / \( i P a d ; / . test ( NUA ) ) OS . iOS = OS . iPadOS = _dV ( "CPU (?:iPhone )?OS " ) ;
74- else if ( / ( m a c O S | M a c O S X ) \d / . test ( NUA ) ) document . ontouchend !== undefined ? OS . iOS = OS . iPadOS = _dV ( ) : OS . macOS = _dV ( "(?:macOS|Mac OS X) " ) ;
75- } else if ( / W i n d o w s ( N T ) ? \d / . test ( NUA ) ) OS . Windows = ( V => V [ 0 ] !== 6 || ! V [ 1 ] ? V : V [ 1 ] === 1 ? [ 7 ] : V [ 1 ] === 2 ? [ 8 ] : [ 8 , 1 ] ) ( _dV ( "Windows(?: NT)?" ) ) ;
76- else if ( / A n d r o i d \d / . test ( NUA ) ) OS . Android = _dV ( "Android" ) ;
77- else if ( / C r O S / . test ( NUA ) ) OS . ChromeOS = _dV ( ) ;
78- else if ( / X 1 1 ; / . test ( NUA ) ) OS . Linux = _dV ( ) ;
79- return OS ;
80- } ) ( { } as OSFlags ) ; if ( NUAD ) NUAD . getHighEntropyValues ( [ "architecture" , "model" , "platform" , "platformVersion" , "uaFullVersion" ] ) . then ( ( HEUAD : any ) => ( OS => { const Pf = HEUAD . platform , PfV = HEUAD . platformVersion ; if ( ! Pf || ! PfV ) return ;
81- if ( / ^ i ( O S | P ( h o n e | o d t o u c h ) ) $ / . test ( Pf ) ) OS . iOS = _sV ( PfV ) ;
82- else if ( / ^ i P a d ( O S ) ? $ / . test ( Pf ) ) OS . iOS = OS . iPadOS = _sV ( PfV ) ;
83- else if ( / ^ ( m a c O S | ( M a c ) ? O S X | M a c ( I n t e l ) ? ) $ / . test ( Pf ) ) document . ontouchend !== undefined ? OS . iOS = OS . iPadOS = _sV ( ) : OS . macOS = _sV ( PfV ) ;
84- else if ( / ^ ( M i c r o s o f t ) ? W i n d o w s $ / . test ( Pf ) ) OS . Windows = _sV ( PfV ) ;
85- else if ( / ^ ( G o o g l e ) ? A n d r o i d $ / . test ( Pf ) ) OS . Android = _sV ( PfV ) ;
86- else if ( / ^ ( ( G o o g l e ) ? C h r o m e O S | C r O S ) $ / . test ( Pf ) ) OS . ChromeOS = _sV ( PfV ) ;
87- else if ( / ^ ( L i n u x | U b u n t u | X 1 1 ) $ / . test ( Pf ) ) OS . Linux = _sV ( PfV ) ;
88- else return ; /**/ Object . keys ( this . OS ) . forEach ( Key => delete ( this . OS as any ) [ Key ] ) , Object . assign ( this . OS , OS ) ;
89- } ) ( { } as OSFlags ) ) ;
81+ this . OS = ( ( OS : OSFlags ) => {
82+ if ( / ( m a c O S | M a c O S X ) / . test ( NUA ) ) {
83+ if ( / \( i P ( h o n e | o d t o u c h ) ; / . test ( NUA ) )
84+ OS . iOS = _dV ( "CPU (?:iPhone )?OS " ) ;
85+ if ( / \( i P a d ; / . test ( NUA ) )
86+ OS . iOS = OS . iPadOS = _dV ( "CPU (?:iPhone )?OS " ) ;
87+ else if ( / ( m a c O S | M a c O S X ) \d / . test ( NUA ) )
88+ document . ontouchend !== undefined
89+ ? ( OS . iOS = OS . iPadOS = _dV ( ) )
90+ : ( OS . macOS = _dV ( "(?:macOS|Mac OS X) " ) ) ;
91+ } else if ( / W i n d o w s ( N T ) ? \d / . test ( NUA ) )
92+ OS . Windows = ( ( V ) =>
93+ V [ 0 ] !== 6 || ! V [ 1 ]
94+ ? V
95+ : V [ 1 ] === 1
96+ ? [ 7 ]
97+ : V [ 1 ] === 2
98+ ? [ 8 ]
99+ : [ 8 , 1 ] ) ( _dV ( "Windows(?: NT)?" ) ) ;
100+ else if ( / A n d r o i d \d / . test ( NUA ) ) OS . Android = _dV ( "Android" ) ;
101+ else if ( / C r O S / . test ( NUA ) ) OS . ChromeOS = _dV ( ) ;
102+ else if ( / X 1 1 ; / . test ( NUA ) ) OS . Linux = _dV ( ) ;
103+ return OS ;
104+ } ) ( { } as OSFlags ) ;
105+ if ( NUAD )
106+ NUAD . getHighEntropyValues ( [
107+ "architecture" ,
108+ "model" ,
109+ "platform" ,
110+ "platformVersion" ,
111+ "uaFullVersion" ,
112+ ] ) . then ( ( HEUAD : any ) =>
113+ ( ( OS ) => {
114+ const Pf = HEUAD . platform ,
115+ PfV = HEUAD . platformVersion ;
116+ if ( ! Pf || ! PfV ) return ;
117+ if ( / ^ i ( O S | P ( h o n e | o d t o u c h ) ) $ / . test ( Pf ) ) OS . iOS = _sV ( PfV ) ;
118+ else if ( / ^ i P a d ( O S ) ? $ / . test ( Pf ) ) OS . iOS = OS . iPadOS = _sV ( PfV ) ;
119+ else if ( / ^ ( m a c O S | ( M a c ) ? O S X | M a c ( I n t e l ) ? ) $ / . test ( Pf ) )
120+ document . ontouchend !== undefined
121+ ? ( OS . iOS = OS . iPadOS = _sV ( ) )
122+ : ( OS . macOS = _sV ( PfV ) ) ;
123+ else if ( / ^ ( M i c r o s o f t ) ? W i n d o w s $ / . test ( Pf ) ) OS . Windows = _sV ( PfV ) ;
124+ else if ( / ^ ( G o o g l e ) ? A n d r o i d $ / . test ( Pf ) ) OS . Android = _sV ( PfV ) ;
125+ else if ( / ^ ( ( G o o g l e ) ? C h r o m e O S | C r O S ) $ / . test ( Pf ) )
126+ OS . ChromeOS = _sV ( PfV ) ;
127+ else if ( / ^ ( L i n u x | U b u n t u | X 1 1 ) $ / . test ( Pf ) ) OS . Linux = _sV ( PfV ) ;
128+ else return ;
129+ /**/ Object . keys ( this . OS ) . forEach (
130+ ( Key ) => delete ( this . OS as any ) [ Key ]
131+ ) ,
132+ Object . assign ( this . OS , OS ) ;
133+ } ) ( { } as OSFlags )
134+ ) ;
90135
91- this . UA = ( ( UA : UAFlags ) => { let _OK = false ;
92- if ( NUAD && Array . isArray ( NUAD . brands ) ) { const BnV = NUAD . brands . reduce ( ( BnV : Record < string , number [ ] > , _ : NavigatorUABrandVersion ) => { BnV [ _ . brand ] = [ ( _ . version as any ) * 1 ] ; return BnV ; } , { } ) ;
93- if ( BnV [ "Google Chrome" ] ) _OK = true , UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] , UA . Chrome = BnV [ "Google Chrome" ] ;
94- else if ( BnV [ "Microsoft Edge" ] ) _OK = true , UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] , UA . Edge = BnV [ "Microsoft Edge" ] ;
95- else if ( BnV [ "Opera" ] ) _OK = true , UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] , UA . Opera = BnV [ "Opera" ] ;
96- } if ( ! _OK ) {
97- if ( / G e c k o \/ \d / . test ( NUA ) ) { UA . Gecko = _dV ( "rv" ) ;
98- if ( / W a t e r f o x \/ \d / . test ( NUA ) ) UA . Waterfox = _dV ( "Waterfox" ) ;
99- else if ( / F i r e f o x \/ \d / . test ( NUA ) ) UA . Firefox = _dV ( "Firefox" ) ;
100- } else if ( / E d g e \/ \d / . test ( NUA ) ) { UA . EdgeHTML = _dV ( "Edge" ) ;
101- UA . Edge = UA . EdgeHTML ;
102- } else if ( / C h r o m ( i u m | e ) \/ \d / . test ( NUA ) ) { UA . Blink = UA . Chromium = ( V => V [ 0 ] ? V : _dV ( "Chrome" ) ) ( _dV ( "Chromium" ) ) ;
103- if ( / E d g A ? \/ \d / . test ( NUA ) ) UA . Edge = ( V => V [ 0 ] ? V : _dV ( "Edg" ) ) ( _dV ( "EdgA" ) ) ;
104- else if ( / O P R \/ \d / . test ( NUA ) ) UA . Opera = _dV ( "OPR" ) ;
105- else if ( / V i v a l d i \/ \d / . test ( NUA ) ) UA . Vivaldi = _dV ( "Vivaldi" ) ;
106- else if ( / S i l k \/ \d / . test ( NUA ) ) UA . Silk = _dV ( "Silk" ) ;
107- else if ( / U C B r o w s e r \/ \d / . test ( NUA ) ) UA . UCBrowser = _dV ( "UCBrowser" ) ;
108- else if ( / P h o e b e \/ \d / . test ( NUA ) ) UA . Phoebe = _dV ( "Phoebe" ) ;
109- else UA . Chrome = ( V => V [ 0 ] ? V : UA . Chromium ) ( _dV ( "Chrome" ) ) ;
110- } else if ( / A p p l e W e b K i t \/ \d / . test ( NUA ) ) { UA . WebKit = _dV ( "AppleWebKit" ) ;
111- if ( / C r i O S \d / . test ( NUA ) ) UA . Chrome = _dV ( "CriOS" ) ;
112- else if ( / F x i O S \d / . test ( NUA ) ) UA . Firefox = _dV ( "FxiOS" ) ;
113- else if ( / E d g i O S \/ \d / . test ( NUA ) ) UA . Edge = _dV ( "EdgiOS" ) ;
114- else if ( / V e r s i o n \/ \d / . test ( NUA ) ) UA . Safari = _dV ( "Version" ) ;
115- } else if ( / T r i d e n t \/ \d / . test ( NUA ) ) { UA . Trident = _dV ( "Trident" ) ;
116- UA . InternetExplorer = ( V => V [ 0 ] ? V : _dV ( "MSIE" ) ) ( _dV ( "rv" ) ) ;
117- }
118- } /*+*/ if ( / [ \[ ; ] F B ( A N | _ I A B ) \/ / . test ( NUA ) ) UA . Facebook = _dV ( "FBAV" ) ;
119- /*+*/ if ( / L i n e \/ \d / . test ( NUA ) ) UA . LINE = _dV ( "Line" ) ;
120- return UA ;
121- } ) ( { } as UAFlags ) ;
136+ this . UA = ( ( UA : UAFlags ) => {
137+ let _OK = false ;
138+ if ( NUAD && Array . isArray ( NUAD . brands ) ) {
139+ const BnV = NUAD . brands . reduce (
140+ ( BnV : Record < string , number [ ] > , _ : NavigatorUABrandVersion ) => {
141+ BnV [ _ . brand ] = [ ( _ . version as any ) * 1 ] ;
142+ return BnV ;
143+ } ,
144+ { }
145+ ) ;
146+ if ( BnV [ "Google Chrome" ] )
147+ ( _OK = true ) ,
148+ ( UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] ) ,
149+ ( UA . Chrome = BnV [ "Google Chrome" ] ) ;
150+ else if ( BnV [ "Microsoft Edge" ] )
151+ ( _OK = true ) ,
152+ ( UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] ) ,
153+ ( UA . Edge = BnV [ "Microsoft Edge" ] ) ;
154+ else if ( BnV [ "Opera" ] )
155+ ( _OK = true ) ,
156+ ( UA . Blink = UA . Chromium = BnV [ "Chromium" ] || [ ] ) ,
157+ ( UA . Opera = BnV [ "Opera" ] ) ;
158+ }
159+ if ( ! _OK ) {
160+ if ( / G e c k o \/ \d / . test ( NUA ) ) {
161+ UA . Gecko = _dV ( "rv" ) ;
162+ if ( / W a t e r f o x \/ \d / . test ( NUA ) ) UA . Waterfox = _dV ( "Waterfox" ) ;
163+ else if ( / F i r e f o x \/ \d / . test ( NUA ) ) UA . Firefox = _dV ( "Firefox" ) ;
164+ } else if ( / E d g e \/ \d / . test ( NUA ) ) {
165+ UA . EdgeHTML = _dV ( "Edge" ) ;
166+ UA . Edge = UA . EdgeHTML ;
167+ } else if ( / C h r o m ( i u m | e ) \/ \d / . test ( NUA ) ) {
168+ UA . Blink = UA . Chromium = ( ( V ) => ( V [ 0 ] ? V : _dV ( "Chrome" ) ) ) (
169+ _dV ( "Chromium" )
170+ ) ;
171+ if ( / E d g A ? \/ \d / . test ( NUA ) )
172+ UA . Edge = ( ( V ) => ( V [ 0 ] ? V : _dV ( "Edg" ) ) ) ( _dV ( "EdgA" ) ) ;
173+ else if ( / O P R \/ \d / . test ( NUA ) ) UA . Opera = _dV ( "OPR" ) ;
174+ else if ( / V i v a l d i \/ \d / . test ( NUA ) ) UA . Vivaldi = _dV ( "Vivaldi" ) ;
175+ else if ( / S i l k \/ \d / . test ( NUA ) ) UA . Silk = _dV ( "Silk" ) ;
176+ else if ( / U C B r o w s e r \/ \d / . test ( NUA ) ) UA . UCBrowser = _dV ( "UCBrowser" ) ;
177+ else if ( / P h o e b e \/ \d / . test ( NUA ) ) UA . Phoebe = _dV ( "Phoebe" ) ;
178+ else UA . Chrome = ( ( V ) => ( V [ 0 ] ? V : UA . Chromium ) ) ( _dV ( "Chrome" ) ) ;
179+ } else if ( / A p p l e W e b K i t \/ \d / . test ( NUA ) ) {
180+ UA . WebKit = _dV ( "AppleWebKit" ) ;
181+ if ( / C r i O S \d / . test ( NUA ) ) UA . Chrome = _dV ( "CriOS" ) ;
182+ else if ( / F x i O S \d / . test ( NUA ) ) UA . Firefox = _dV ( "FxiOS" ) ;
183+ else if ( / E d g i O S \/ \d / . test ( NUA ) ) UA . Edge = _dV ( "EdgiOS" ) ;
184+ else if ( / V e r s i o n \/ \d / . test ( NUA ) ) UA . Safari = _dV ( "Version" ) ;
185+ } else if ( / T r i d e n t \/ \d / . test ( NUA ) ) {
186+ UA . Trident = _dV ( "Trident" ) ;
187+ UA . InternetExplorer = ( ( V ) => ( V [ 0 ] ? V : _dV ( "MSIE" ) ) ) ( _dV ( "rv" ) ) ;
188+ }
189+ }
190+ /*+*/ if ( / [ \[ ; ] F B ( A N | _ I A B ) \/ / . test ( NUA ) ) UA . Facebook = _dV ( "FBAV" ) ;
191+ /*+*/ if ( / L i n e \/ \d / . test ( NUA ) ) UA . LINE = _dV ( "Line" ) ;
192+ return UA ;
193+ } ) ( { } as UAFlags ) ;
122194
123- ( this . Env as any ) = { get : ( ) => [ this . OS , this . UA ] . reduce ( ( Env : string [ ] , OS_UA ) => { for ( const Par in OS_UA ) if ( ( OS_UA as any ) [ Par ] ) Env . push ( Par ) ; return Env ; } , [ ] ) } ;
124- }
195+ ( this . Env as any ) = {
196+ get : ( ) =>
197+ [ this . OS , this . UA ] . reduce ( ( Env : string [ ] , OS_UA ) => {
198+ for ( const Par in OS_UA ) if ( ( OS_UA as any ) [ Par ] ) Env . push ( Par ) ;
199+ return Env ;
200+ } , [ ] ) ,
201+ } ;
202+ }
125203}
126204
127205class sMLFactoryWithRequest extends sMLFactory {
128- get iOSRequest ( ) : iOSRequest {
129- const NUAD = userAgentData ( ) , NUA = userAgent ( ) ;
206+ get iOSRequest ( ) : iOSRequest {
207+ const NUAD = userAgentData ( ) ,
208+ NUA = userAgent ( ) ;
130209
131- if ( this . OS . iOS && ! this . OS . iPadOS ) {
132- return "mobile" ;
133- } else if ( this . OS . iPadOS ) {
134- return ( / \( i P a d ; / . test ( NUA ) || ( NUAD && / ^ i P a d ( O S ) ? $ / . test ( NUAD . platform ) ) ) ? "mobile" : "desktop"
135- }
136-
137- return undefined ;
210+ if ( this . OS . iOS && ! this . OS . iPadOS ) {
211+ return "mobile" ;
212+ } else if ( this . OS . iPadOS ) {
213+ return / \( i P a d ; / . test ( NUA ) || ( NUAD && / ^ i P a d ( O S ) ? $ / . test ( NUAD . platform ) )
214+ ? "mobile"
215+ : "desktop" ;
138216 }
217+
218+ return undefined ;
219+ }
139220}
140221
141222const sML = new sMLFactory ( ) ;
142223const sMLWithRequest = new sMLFactoryWithRequest ( ) ;
143- export { sML , sMLWithRequest } ;
224+ export { sML , sMLWithRequest } ;
0 commit comments