import isString from '@tinkoff/utils/is/string' ; import browserslist from 'browserslist' ; import browserslistTinkoffConfig from '@tinkoff/browserslist-config' ; import browserslistFileConfig from '@tramvai/cli/lib/external/browserslist-normalized-file-config' ; import { parse } from './userAgent' ; import type { UserAgent } from './types' ; import { BROWSERS_LIST_MAP , CHROMIUM_BASED_BROWSERS } from './constants' ; const deviceTypes = { mobile : 'mobile' , tablet : 'mobile' , desktop : 'desktop' , } ; type BrowserMap = Record < string , Record < string , number > > ; const normalizedBrowserslist = ( query ) => { const resolved = browserslist ( query , { mobileToDesktop : true , } ) . concat ( [ 'ie 999' ] ) ; const result = { } ; for ( let i = 0 ; i < resolved . length ; i ++ ) { const [ name , version ] = resolved [ i ] . split ( ' ' ) ; if ( BROWSERS_LIST_MAP [ name ] ) { const { type : mapType , name : mapName } = BROWSERS_LIST_MAP [ name ] ; const mapVersion = parseFloat ( version ) ; if ( result [ mapName ] ) { if ( ! result [ mapName ] [ mapType ] || result [ mapName ] [ mapType ] > mapVersion ) { result [ mapName ] [ mapType ] = mapVersion ; } } else { result [ mapName ] = { [ mapType ] : mapVersion , } ; } } } return result ; } ; export const satisfies = ( userAgent , browserslistConfig ? , { env = 'defaults' } = { } ) : boolean | null => { const ua = isString ( userAgent ) ? parse ( userAgent ) : userAgent ; const { engine : { name : engineName = '' , version : engineVersion } , device : { type = '' } = { } , } = ua ; let { browser : { name : browserName = '' , version : browserVersion = '' } = { } } = ua ; if ( engineName . toLowerCase ( ) === 'blink' && CHROMIUM_BASED_BROWSERS . indexOf ( browserName ) !== - 1 ) { browserName = 'chrome' ; browserVersion = engineVersion || '' ; } const checkVersion = parseFloat ( browserVersion ) ; const deviceType = deviceTypes [ type ] || type || deviceTypes . desktop ; if ( ! browserName ) { return null ; } const targets = browserslistConfig ?? browserslistFileConfig [ env ] ?? browserslistTinkoffConfig [ env ] ; const browsers = normalizedBrowserslist ( targets ) ; let hasEntry = false ; if ( browserName in browsers ) { const browserInfo = browsers [ browserName ] ; const browserInfoVersion = browserInfo . any ?? browserInfo [ deviceType ] ; hasEntry = ! ! browserInfoVersion ; if ( checkVersion >= browserInfoVersion ) { return true ; } } return hasEntry ? false : null ; } ;