import is from '@sindresorhus/is' ; import { CONFIG_VALIDATION } from '../constants/error-messages' ; import { re2 } from '../expose.cjs' ; import { logger } from '../logger' ; let RegEx ; const cache = new Map < string , RegExp > ( ) ; try { const RE2 = re2 ( ) ; new RE2 ( '.*' ) . exec ( 'test' ) ; logger . debug ( 'Using RE2 as regex engine' ) ; RegEx = RE2 ; } catch ( err ) { logger . warn ( { err } , 'RE2 not usable, falling back to RegExp' ) ; RegEx = RegExp ; } export function regEx ( pattern , flags ? , useCache = true ) { const key = flags ? `${ pattern . toString ( ) }:${ flags }` : pattern . toString ( ) ; if ( useCache ) { const cachedResult = cache . get ( key ) ; if ( cachedResult ) { return cachedResult ; } } try { const instance = new RegEx ( pattern , flags ) ; if ( useCache ) { cache . set ( key , instance ) ; } return instance ; } catch ( err ) { const error = new Error ( CONFIG_VALIDATION ) ; error . validationSource = pattern . toString ( ) ; error . validationError = `Invalid regular expression: ${ pattern . toString ( ) }` ; throw error ; } } export function escapeRegExp ( input ) { return input . replace ( regEx ( /[.*+\-?^${}()|[\]\\]/g ) , '\\$&' ) ; } const configValStart = regEx ( /^!?\// ) ; const configValEnd = regEx ( /\/$/ ) ; export function isConfigRegex ( input ) { return ( is . string ( input ) && configValStart . test ( input ) && configValEnd . test ( input ) ) ; } function parseConfigRegex ( input ) { try { const regexString = input . replace ( configValStart , '' ) . replace ( configValEnd , '' ) ; return regEx ( regexString ) ; } catch ( err ) { } return null ; } type ConfigRegexPredicate = ( s : string ) => boolean ; export function configRegexPredicate ( input ) { if ( isConfigRegex ( input ) ) { const configRegex = parseConfigRegex ( input ) ; if ( configRegex ) { const isPositive = ! input . startsWith ( '!' ) ; return ( x ) : boolean => { const res = configRegex . test ( x ) ; return isPositive ? res : ! res ; } ; } } return null ; }