const DEFAULT_MAX_PATTERN_CHARS = 512;
const DEFAULT_MAX_INPUT_CHARS = 50_000;
const ALLOWED_FLAGS = /^[dgimsuvy]*$/;
const RISKY_PATTERN_CHECKS = [
    { pattern: /(^|[^\\])\\[1-9]/, reason: 'backreferences are not allowed in operator-supplied regular expressions' },
    { pattern: /\((?:[^()\\]|\\.)*[+*{][^)]*\)\s*[+*{]/, reason: 'nested quantified groups are not allowed' },
    { pattern: /\.\*(?:[^|)]{0,64})\.\*/, reason: 'multiple wildcard repeats in one expression are not allowed' },
];
export function compileSafeRegExp(source, flags, options) {
    const maxPatternChars = options.maxPatternChars ?? DEFAULT_MAX_PATTERN_CHARS;
    if (source.length > maxPatternChars) {
        throw new Error(`${options.operation} regex exceeds ${maxPatternChars} characters`);
    }
    if (!ALLOWED_FLAGS.test(flags) || new Set(flags).size !== flags.length) {
        throw new Error(`${options.operation} regex flags are invalid`);
    }
    for (const check of RISKY_PATTERN_CHECKS) {
        if (check.pattern.test(source)) {
            throw new Error(`${options.operation} regex rejected: ${check.reason}`);
        }
    }
    return new RegExp(source, flags);
}
export function assertSafeRegexInput(input, options) {
    const maxInputChars = options.maxInputChars ?? DEFAULT_MAX_INPUT_CHARS;
    if (input.length > maxInputChars) {
        throw new Error(`${options.operation} regex input exceeds ${maxInputChars} characters`);
    }
}
export function safeRegExpTest(regex, input, options) {
    assertSafeRegexInput(input, options);
    regex.lastIndex = 0;
    return regex.test(input);
}
export function safeRegExpExec(regex, input, options) {
    assertSafeRegexInput(input, options);
    return regex.exec(input);
}
