Skip to content
Snippets Groups Projects
Select Git revision
  • f0cc3bfad1bdecf383a3485377e3e89f321a8b4b
  • main default protected
  • renovate/main-zod-3.x
  • renovate/main-ghcr.io-renovatebot-base-image-10.x
  • renovate/main-ghcr.io-containerbase-devcontainer-13.x
  • next
  • revert-31645-feat/rename-gradle-wrapper-validation-action
  • renovate/main-redis-5.x
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • fix/36615-branch-reuse-bug
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • 41.28.2
  • 41.28.1
  • 41.28.0
  • 41.27.1
  • 41.27.0
  • 41.26.2
  • 41.26.1
  • 41.26.0
  • 41.25.1
  • 41.25.0
  • 41.24.0
  • 41.23.5
  • 41.23.4
  • 41.23.3
  • 41.23.2
  • 41.23.1
  • 41.23.0
  • 41.22.0
  • 41.21.4
  • 41.21.3
41 results

regex.ts

Blame
  • regex.ts 1.73 KiB
    import is from '@sindresorhus/is';
    import { CONFIG_VALIDATION } from '../constants/error-messages';
    import { logger } from '../logger';
    
    let RegEx: RegExpConstructor;
    
    try {
      // eslint-disable-next-line
      const RE2 = require('re2');
      // Test if native is working
      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: string, flags?: string): RegExp {
      try {
        return new RegEx(pattern, flags);
      } catch (err) {
        const error = new Error(CONFIG_VALIDATION);
        error.configFile = pattern;
        error.validationError = `Invalid regular expression: ${pattern}`;
        throw error;
      }
    }
    
    export function escapeRegExp(input: string): string {
      return input.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
    }
    
    const configValStart = /^!?\//;
    const configValEnd = /\/$/;
    
    export function isConfigRegex(input: unknown): input is string {
      return (
        is.string(input) && configValStart.test(input) && configValEnd.test(input)
      );
    }
    
    function parseConfigRegex(input: string): RegExp | null {
      try {
        const regexString = input
          .replace(configValStart, '')
          .replace(configValEnd, '');
        return regEx(regexString);
      } catch (err) {
        // no-op
      }
      return null;
    }
    
    type ConfigRegexPredicate = (string) => boolean;
    
    export function configRegexPredicate(input: string): ConfigRegexPredicate {
      const configRegex = parseConfigRegex(input);
      if (configRegex) {
        const isPositive = !input.startsWith('!');
        return (x: string): boolean => {
          const res = configRegex.test(x);
          return isPositive ? res : !res;
        };
      }
      return null;
    }