mirror of https://github.com/renovatebot/renovate
75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import is from '@sindresorhus/is';
|
|
import { CONFIG_VALIDATION } from '../constants/error-messages';
|
|
import { re2 } from '../expose.cjs';
|
|
|
|
const cache = new Map<string, RegExp>();
|
|
|
|
type RegExpEngineStatus =
|
|
| { type: 'available' }
|
|
| {
|
|
type: 'unavailable';
|
|
err: Error;
|
|
}
|
|
| { type: 'ignored' };
|
|
|
|
let status: RegExpEngineStatus;
|
|
let RegEx: RegExpConstructor = RegExp;
|
|
// istanbul ignore next
|
|
if (process.env.RENOVATE_X_IGNORE_RE2) {
|
|
status = { type: 'ignored' };
|
|
} else {
|
|
try {
|
|
const RE2 = re2();
|
|
// Test if native is working
|
|
new RE2('.*').exec('test');
|
|
RegEx = RE2;
|
|
status = { type: 'available' };
|
|
} catch (err) {
|
|
status = { type: 'unavailable', err };
|
|
}
|
|
}
|
|
|
|
export const regexEngineStatus = status;
|
|
|
|
export function regEx(
|
|
pattern: string | RegExp,
|
|
flags?: string,
|
|
useCache = true,
|
|
): RegExp {
|
|
let canBeCached = useCache;
|
|
if (canBeCached && flags?.includes('g')) {
|
|
canBeCached = false;
|
|
}
|
|
if (canBeCached && is.regExp(pattern) && pattern.flags.includes('g')) {
|
|
canBeCached = false;
|
|
}
|
|
|
|
const key = flags ? `${pattern.toString()}:${flags}` : pattern.toString();
|
|
if (canBeCached) {
|
|
const cachedResult = cache.get(key);
|
|
if (cachedResult) {
|
|
return cachedResult;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const instance = flags ? new RegEx(pattern, flags) : new RegEx(pattern);
|
|
if (canBeCached) {
|
|
cache.set(key, instance);
|
|
}
|
|
return instance;
|
|
} catch (err) {
|
|
const error = new Error(CONFIG_VALIDATION);
|
|
error.validationMessage = err.message;
|
|
error.validationSource = pattern.toString();
|
|
error.validationError = `Invalid regular expression (re2): ${pattern.toString()}`;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export function escapeRegExp(input: string): string {
|
|
return input.replace(regEx(/[.*+\-?^${}()|[\]\\]/g), '\\$&'); // $& means the whole matched string
|
|
}
|
|
|
|
export const newlineRegex = regEx(/\r?\n/);
|