core/quality/eslint/no-regex.eslint.rule.ts

core/quality/eslint/no-regex.eslint.rule.ts is a file in GovLab Quality. 57 lines of code and 6 definitions.

import type { Rule } from "eslint";

const MESSAGE =
    "Use string methods (indexOf, includes, startsWith, endsWith, split, replaceAll, charCodeAt) or " +
    "AST-based analysis instead of RegExp. Zero regex policy. [no_regex]";

const reportRegexpCall = function reportRegexpCall(context: Rule.RuleContext, node: Rule.Node): void {
    if (node.type !== "CallExpression") {
        return;
    }
    if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && node.parent.type !== "NewExpression") {
        context.report({ messageId: "noRegExpFactory", node });
    }
};

const reportRegexLiteral = function reportRegexLiteral(context: Rule.RuleContext, node: Rule.Node): void {
    if (node.type === "Literal" && "regex" in node) {
        context.report({ messageId: "noRegexLiteral", node });
    }
};

const reportRegexpNew = function reportRegexpNew(context: Rule.RuleContext, node: Rule.Node): void {
    if (node.type === "NewExpression" && node.callee.type === "Identifier" && node.callee.name === "RegExp") {
        context.report({ messageId: "noRegExpConstructor", node });
    }
};

export default {
    create(context): Rule.RuleListener {
        const handlers: [string, (node: Rule.Node) => void][] = [
            [
                "CallExpression",
                (node): void => {
                    reportRegexpCall(context, node);
                },
            ],
            [
                "Literal",
                (node): void => {
                    reportRegexLiteral(context, node);
                },
            ],
            [
                "NewExpression",
                (node): void => {
                    reportRegexpNew(context, node);
                },
            ],
        ];
        return Object.fromEntries(handlers);
    },
    meta: {
        docs: { description: "Disallow all RegExp usage — enforce AST + token-based string processing" },
        messages: {
            noRegExpConstructor: `new RegExp() detected. ${MESSAGE}`,
            noRegExpFactory: `RegExp() factory detected. ${MESSAGE}`,
            noRegexLiteral: `Regex literal detected. ${MESSAGE}`,
        },
        schema: [],
        type: "problem",
    },
} satisfies Rule.RuleModule;