code:
/**
 * @fileoverview Rule to enforce line breaks after each array element
 * @author Jan Peer Stöcklmair <https://github.com/JPeer264>
 * @deprecated in ESLint v8.53.0
 */

"use strict";

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce line breaks after each array element",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/array-element-newline"
        },

        fixable: "whitespace",

        schema: {
            definitions: {
                basicConfig: {
                    oneOf: [
                        {
                            enum: ["always", "never", "consistent"]
                        },
                        {
                            type: "object",
                            properties: {
                                multiline: {
                                    type: "boolean"
                                },
                                minItems: {
                                    type: ["integer", "null"],
                                    minimum: 0
                                }
                            },
                            additionalProperties: false
                        }
                    ]
                }
            },
            type: "array",
            items: [
                {
                    oneOf: [
                        {
                            $ref: "#/definitions/basicConfig"
                        },
                        {
                            type: "object",
                            properties: {
                                ArrayExpression: {
                                    $ref: "#/definitions/basicConfig"
                                },
                                ArrayPattern: {
                                    $ref: "#/definitions/basicConfig"
                                }
                            },
                            additionalProperties: false,
                            minProperties: 1
                        }
                    ]
                }
            ]
        },

        messages: {
            unexpectedLineBreak: "There should be no linebreak here.",
            missingLineBreak: "There should be a linebreak after this element."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;

        //----------------------------------------------------------------------
        // Helpers
        //----------------------------------------------------------------------

        /**
         * Normalizes a given option value.
         * @param {string|Object|undefined} providedOption An option value to parse.
         * @returns {{multiline: boolean, minItems: number}} Normalized option object.
         */
        function normalizeOptionValue(providedOption) {
            let consistent = false;
            let multiline = false;
            let minItems;

            const option = providedOption || "always";

            if (!option || option === "always" || option.minItems === 0) {
                minItems = 0;
            } else if (option === "never") {
                minItems = Number.POSITIVE_INFINITY;
            } else if (option === "consistent") {
                consistent = true;
                minItems = Number.POSITIVE_INFINITY;
            } else {
                multiline = Boolean(option.multiline);
                minItems = option.minItems || Number.POSITIVE_INFINITY;
            }

            return { consistent, multiline, minItems };
        }

        /**
         * Normalizes a given option value.
         * @param {string|Object|undefined} options An option value to parse.
         * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object.
         */
        function normalizeOptions(options) {
            if (options && (options.ArrayExpression || options.ArrayPattern)) {
                let expressionOptions, patternOptions;

                if (options.ArrayExpression) {
                    expressionOptions = normalizeOptionValue(options.ArrayExpression);
                }

                if (options.ArrayPattern) {
                    patternOptions = normalizeOptionValue(options.ArrayPattern);
                }

                return { ArrayExpression: expressionOptions, ArrayPattern: patternOptions };
            }

            const value = normalizeOptionValue(options);

            return { ArrayExpression: value, ArrayPattern: value };
        }

        /**
         * Reports that there shouldn't be a line break after the first token
         * @param {Token} token The token to use for the report.
         * @returns {void}
         */
        function reportNoLineBreak(token) {
            const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true });

            context.report({
                loc: {
                    start: tokenBefore.loc.end,
                    end: token.loc.start
                },
                messageId: "unexpectedLineBreak",
                fix(fixer) {
                    if (astUtils.isCommentToken(tokenBefore)) {
                        return null;
                    }

                    if (!astUtils.isTokenOnSameLine(tokenBefore, token)) {
                        return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ");
                    }

                    /*
                     * This will check if the comma is on the same line as the next element
                     * Following array:
                     * [
                     *     1
                     *     , 2
                     *     , 3
                     * ]
                     *
                     * will be fixed to:
                     * [
                     *     1, 2, 3
                     * ]
                     */
                    const twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true });

                    if (astUtils.isCommentToken(twoTokensBefore)) {
                        return null;
                    }

                    return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], "");

                }
            });
        }

        /**
         * Reports that there should be a line break after the first token
         * @param {Token} token The token to use for the report.
         * @returns {void}
         */
        function reportRequiredLineBreak(token) {
            const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true });

            context.report({
                loc: {
                    start: tokenBefore.loc.end,
                    end: token.loc.start
                },
                messageId: "missingLineBreak",
                fix(fixer) {
                    return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n");
                }
            });
        }

        /**
         * Reports a given node if it violated this rule.
         * @param {ASTNode} node A node to check. This is an ObjectExpression node or an ObjectPattern node.
         * @returns {void}
         */
        function check(node) {
            const elements = node.elements;
            const normalizedOptions = normalizeOptions(context.options[0]);
            const options = normalizedOptions[node.type];

            if (!options) {
                return;
            }

            let elementBreak = false;

            /*
             * MULTILINE: true
             * loop through every element and check
             * if at least one element has linebreaks inside
             * this ensures that following is not valid (due to elements are on the same line):
             *
             * [
             *      1,
             *      2,
             *      3
             * ]
             */
            if (options.multiline) {
                elementBreak = elements
                    .filter(element => element !== null)
                    .some(element => element.loc.start.line !== element.loc.end.line);
            }

            let linebreaksCount = 0;

            for (let i = 0; i < node.elements.length; i++) {
                const element = node.elements[i];

                const previousElement = elements[i - 1];

                if (i === 0 || element === null || previousElement === null) {
                    continue;
                }

                const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
                const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
                const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);

                if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
                    linebreaksCount++;
                }
            }

            const needsLinebreaks = (
                elements.length >= options.minItems ||
                (
                    options.multiline &&
                    elementBreak
                ) ||
                (
                    options.consistent &&
                    linebreaksCount > 0 &&
                    linebreaksCount < node.elements.length
                )
            );

            elements.forEach((element, i) => {
                const previousElement = elements[i - 1];

                if (i === 0 || element === null || previousElement === null) {
                    return;
                }

                const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
                const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
                const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);

                if (needsLinebreaks) {
                    if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
                        reportRequiredLineBreak(firstTokenOfCurrentElement);
                    }
                } else {
                    if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
                        reportNoLineBreak(firstTokenOfCurrentElement);
                    }
                }
            });
        }

        //----------------------------------------------------------------------
        // Public
        //----------------------------------------------------------------------

        return {
            ArrayPattern: check,
            ArrayExpression: check
        };
    }
};


code:
/**
 * @fileoverview Rule to require braces in arrow function body.
 * @author Alberto Rodríguez
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Require braces around arrow function bodies",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/arrow-body-style"
        },

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "never"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 1
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["as-needed"]
                        },
                        {
                            type: "object",
                            properties: {
                                requireReturnForObjectLiteral: { type: "boolean" }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        },

        fixable: "code",

        messages: {
            unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.",
            unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.",
            unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.",
            unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.",
            expectedBlock: "Expected block statement surrounding arrow body."
        }
    },

    create(context) {
        const options = context.options;
        const always = options[0] === "always";
        const asNeeded = !options[0] || options[0] === "as-needed";
        const never = options[0] === "never";
        const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral;
        const sourceCode = context.sourceCode;
        let funcInfo = null;

        /**
         * Checks whether the given node has ASI problem or not.
         * @param {Token} token The token to check.
         * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed.
         */
        function hasASIProblem(token) {
            return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value);
        }

        /**
         * Gets the closing parenthesis by the given node.
         * @param {ASTNode} node first node after an opening parenthesis.
         * @returns {Token} The found closing parenthesis token.
         */
        function findClosingParen(node) {
            let nodeToCheck = node;

            while (!astUtils.isParenthesised(sourceCode, nodeToCheck)) {
                nodeToCheck = nodeToCheck.parent;
            }
            return sourceCode.getTokenAfter(nodeToCheck);
        }

        /**
         * Check whether the node is inside of a for loop's init
         * @param {ASTNode} node node is inside for loop
         * @returns {boolean} `true` if the node is inside of a for loop, else `false`
         */
        function isInsideForLoopInitializer(node) {
            if (node && node.parent) {
                if (node.parent.type === "ForStatement" && node.parent.init === node) {
                    return true;
                }
                return isInsideForLoopInitializer(node.parent);
            }
            return false;
        }

        /**
         * Determines whether a arrow function body needs braces
         * @param {ASTNode} node The arrow function node.
         * @returns {void}
         */
        function validate(node) {
            const arrowBody = node.body;

            if (arrowBody.type === "BlockStatement") {
                const blockBody = arrowBody.body;

                if (blockBody.length !== 1 && !never) {
                    return;
                }

                if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" &&
                    blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") {
                    return;
                }

                if (never || asNeeded && blockBody[0].type === "ReturnStatement") {
                    let messageId;

                    if (blockBody.length === 0) {
                        messageId = "unexpectedEmptyBlock";
                    } else if (blockBody.length > 1) {
                        messageId = "unexpectedOtherBlock";
                    } else if (blockBody[0].argument === null) {
                        messageId = "unexpectedSingleBlock";
                    } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) {
                        messageId = "unexpectedObjectBlock";
                    } else {
                        messageId = "unexpectedSingleBlock";
                    }

                    context.report({
                        node,
                        loc: arrowBody.loc,
                        messageId,
                        fix(fixer) {
                            const fixes = [];

                            if (blockBody.length !== 1 ||
                                blockBody[0].type !== "ReturnStatement" ||
                                !blockBody[0].argument ||
                                hasASIProblem(sourceCode.getTokenAfter(arrowBody))
                            ) {
                                return fixes;
                            }

                            const openingBrace = sourceCode.getFirstToken(arrowBody);
                            const closingBrace = sourceCode.getLastToken(arrowBody);
                            const firstValueToken = sourceCode.getFirstToken(blockBody[0], 1);
                            const lastValueToken = sourceCode.getLastToken(blockBody[0]);
                            const commentsExist =
                                sourceCode.commentsExistBetween(openingBrace, firstValueToken) ||
                                sourceCode.commentsExistBetween(lastValueToken, closingBrace);

                            /*
                             * Remove tokens around the return value.
                             * If comments don't exist, remove extra spaces as well.
                             */
                            if (commentsExist) {
                                fixes.push(
                                    fixer.remove(openingBrace),
                                    fixer.remove(closingBrace),
                                    fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword
                                );
                            } else {
                                fixes.push(
                                    fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]),
                                    fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]])
                                );
                            }

                            /*
                             * If the first token of the return value is `{` or the return value is a sequence expression,
                             * enclose the return value by parentheses to avoid syntax error.
                             */
                            if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) {
                                if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) {
                                    fixes.push(
                                        fixer.insertTextBefore(firstValueToken, "("),
                                        fixer.insertTextAfter(lastValueToken, ")")
                                    );
                                }
                            }

                            /*
                             * If the last token of the return statement is semicolon, remove it.
                             * Non-block arrow body is an expression, not a statement.
                             */
                            if (astUtils.isSemicolonToken(lastValueToken)) {
                                fixes.push(fixer.remove(lastValueToken));
                            }

                            return fixes;
                        }
                    });
                }
            } else {
                if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) {
                    context.report({
                        node,
                        loc: arrowBody.loc,
                        messageId: "expectedBlock",
                        fix(fixer) {
                            const fixes = [];
                            const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken);
                            const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 });
                            const lastToken = sourceCode.getLastToken(node);

                            let parenthesisedObjectLiteral = null;

                            if (
                                astUtils.isOpeningParenToken(firstTokenAfterArrow) &&
                                astUtils.isOpeningBraceToken(secondTokenAfterArrow)
                            ) {
                                const braceNode = sourceCode.getNodeByRangeIndex(secondTokenAfterArrow.range[0]);

                                if (braceNode.type === "ObjectExpression") {
                                    parenthesisedObjectLiteral = braceNode;
                                }
                            }

                            // If the value is object literal, remove parentheses which were forced by syntax.
                            if (parenthesisedObjectLiteral) {
                                const openingParenToken = firstTokenAfterArrow;
                                const openingBraceToken = secondTokenAfterArrow;

                                if (astUtils.isTokenOnSameLine(openingParenToken, openingBraceToken)) {
                                    fixes.push(fixer.replaceText(openingParenToken, "{return "));
                                } else {

                                    // Avoid ASI
                                    fixes.push(
                                        fixer.replaceText(openingParenToken, "{"),
                                        fixer.insertTextBefore(openingBraceToken, "return ")
                                    );
                                }

                                // Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo()
                                fixes.push(fixer.remove(findClosingParen(parenthesisedObjectLiteral)));
                                fixes.push(fixer.insertTextAfter(lastToken, "}"));

                            } else {
                                fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return "));
                                fixes.push(fixer.insertTextAfter(lastToken, "}"));
                            }

                            return fixes;
                        }
                    });
                }
            }
        }

        return {
            "BinaryExpression[operator='in']"() {
                let info = funcInfo;

                while (info) {
                    info.hasInOperator = true;
                    info = info.upper;
                }
            },
            ArrowFunctionExpression() {
                funcInfo = {
                    upper: funcInfo,
                    hasInOperator: false
                };
            },
            "ArrowFunctionExpression:exit"(node) {
                validate(node);
                funcInfo = funcInfo.upper;
            }
        };
    }
};

license: mit


code:
/**
 * @fileoverview Rule to require parens in arrow function arguments.
 * @author Jxck
 * @deprecated in ESLint v8.53.0
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Determines if the given arrow function has block body.
 * @param {ASTNode} node `ArrowFunctionExpression` node.
 * @returns {boolean} `true` if the function has block body.
 */
function hasBlockBody(node) {
    return node.body.type === "BlockStatement";
}

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Require parentheses around arrow function arguments",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/arrow-parens"
        },

        fixable: "code",

        schema: [
            {
                enum: ["always", "as-needed"]
            },
            {
                type: "object",
                properties: {
                    requireForBlockBody: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            unexpectedParens: "Unexpected parentheses around single function argument.",
            expectedParens: "Expected parentheses around arrow function argument.",

            unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
            expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
        }
    },

    create(context) {
        const asNeeded = context.options[0] === "as-needed";
        const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;

        const sourceCode = context.sourceCode;

        /**
         * Finds opening paren of parameters for the given arrow function, if it exists.
         * It is assumed that the given arrow function has exactly one parameter.
         * @param {ASTNode} node `ArrowFunctionExpression` node.
         * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters.
         */
        function findOpeningParenOfParams(node) {
            const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]);

            if (
                tokenBeforeParams &&
                astUtils.isOpeningParenToken(tokenBeforeParams) &&
                node.range[0] <= tokenBeforeParams.range[0]
            ) {
                return tokenBeforeParams;
            }

            return null;
        }

        /**
         * Finds closing paren of parameters for the given arrow function.
         * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter.
         * @param {ASTNode} node `ArrowFunctionExpression` node.
         * @returns {Token} the closing paren of parameters.
         */
        function getClosingParenOfParams(node) {
            return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
        }

        /**
         * Determines whether the given arrow function has comments inside parens of parameters.
         * It is assumed that the given arrow function has parens of parameters.
         * @param {ASTNode} node `ArrowFunctionExpression` node.
         * @param {Token} openingParen Opening paren of parameters.
         * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters.
         */
        function hasCommentsInParensOfParams(node, openingParen) {
            return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node));
        }

        /**
         * Determines whether the given arrow function has unexpected tokens before opening paren of parameters,
         * in which case it will be assumed that the existing parens of parameters are necessary.
         * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account.
         * Example: <T>(a) => b
         * @param {ASTNode} node `ArrowFunctionExpression` node.
         * @param {Token} openingParen Opening paren of parameters.
         * @returns {boolean} `true` if the function has at least one unexpected token.
         */
        function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) {
            const expectedCount = node.async ? 1 : 0;

            return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen;
        }

        return {
            "ArrowFunctionExpression[params.length=1]"(node) {
                const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node);
                const openingParen = findOpeningParenOfParams(node);
                const hasParens = openingParen !== null;
                const [param] = node.params;

                if (shouldHaveParens && !hasParens) {
                    context.report({
                        node,
                        messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens",
                        loc: param.loc,
                        *fix(fixer) {
                            yield fixer.insertTextBefore(param, "(");
                            yield fixer.insertTextAfter(param, ")");
                        }
                    });
                }

                if (
                    !shouldHaveParens &&
                    hasParens &&
                    param.type === "Identifier" &&
                    !param.typeAnnotation &&
                    !node.returnType &&
                    !hasCommentsInParensOfParams(node, openingParen) &&
                    !hasUnexpectedTokensBeforeOpeningParen(node, openingParen)
                ) {
                    context.report({
                        node,
                        messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens",
                        loc: param.loc,
                        *fix(fixer) {
                            const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen);
                            const closingParen = getClosingParenOfParams(node);

                            if (
                                tokenBeforeOpeningParen &&
                                tokenBeforeOpeningParen.range[1] === openingParen.range[0] &&
                                !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param))
                            ) {
                                yield fixer.insertTextBefore(openingParen, " ");
                            }

                            // remove parens, whitespace inside parens, and possible trailing comma
                            yield fixer.removeRange([openingParen.range[0], param.range[0]]);
                            yield fixer.removeRange([param.range[1], closingParen.range[1]]);
                        }
                    });
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to define spacing before/after arrow function's arrow.
 * @author Jxck
 * @deprecated in ESLint v8.53.0
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce consistent spacing before and after the arrow in arrow functions",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/arrow-spacing"
        },

        fixable: "whitespace",

        schema: [
            {
                type: "object",
                properties: {
                    before: {
                        type: "boolean",
                        default: true
                    },
                    after: {
                        type: "boolean",
                        default: true
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            expectedBefore: "Missing space before =>.",
            unexpectedBefore: "Unexpected space before =>.",

            expectedAfter: "Missing space after =>.",
            unexpectedAfter: "Unexpected space after =>."
        }
    },

    create(context) {

        // merge rules with default
        const rule = Object.assign({}, context.options[0]);

        rule.before = rule.before !== false;
        rule.after = rule.after !== false;

        const sourceCode = context.sourceCode;

        /**
         * Get tokens of arrow(`=>`) and before/after arrow.
         * @param {ASTNode} node The arrow function node.
         * @returns {Object} Tokens of arrow and before/after arrow.
         */
        function getTokens(node) {
            const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);

            return {
                before: sourceCode.getTokenBefore(arrow),
                arrow,
                after: sourceCode.getTokenAfter(arrow)
            };
        }

        /**
         * Count spaces before/after arrow(`=>`) token.
         * @param {Object} tokens Tokens before/after arrow.
         * @returns {Object} count of space before/after arrow.
         */
        function countSpaces(tokens) {
            const before = tokens.arrow.range[0] - tokens.before.range[1];
            const after = tokens.after.range[0] - tokens.arrow.range[1];

            return { before, after };
        }

        /**
         * Determines whether space(s) before after arrow(`=>`) is satisfy rule.
         * if before/after value is `true`, there should be space(s).
         * if before/after value is `false`, there should be no space.
         * @param {ASTNode} node The arrow function node.
         * @returns {void}
         */
        function spaces(node) {
            const tokens = getTokens(node);
            const countSpace = countSpaces(tokens);

            if (rule.before) {

                // should be space(s) before arrow
                if (countSpace.before === 0) {
                    context.report({
                        node: tokens.before,
                        messageId: "expectedBefore",
                        fix(fixer) {
                            return fixer.insertTextBefore(tokens.arrow, " ");
                        }
                    });
                }
            } else {

                // should be no space before arrow
                if (countSpace.before > 0) {
                    context.report({
                        node: tokens.before,
                        messageId: "unexpectedBefore",
                        fix(fixer) {
                            return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
                        }
                    });
                }
            }

            if (rule.after) {

                // should be space(s) after arrow
                if (countSpace.after === 0) {
                    context.report({
                        node: tokens.after,
                        messageId: "expectedAfter",
                        fix(fixer) {
                            return fixer.insertTextAfter(tokens.arrow, " ");
                        }
                    });
                }
            } else {

                // should be no space after arrow
                if (countSpace.after > 0) {
                    context.report({
                        node: tokens.after,
                        messageId: "unexpectedAfter",
                        fix(fixer) {
                            return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
                        }
                    });
                }
            }
        }

        return {
            ArrowFunctionExpression: spaces
        };
    }
};


code:
/**
 * @fileoverview Rule to check for "block scoped" variables by binding context
 * @author Matt DuVall <http://www.mattduvall.com>
 */
"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce the use of variables within the scope they are defined",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/block-scoped-var"
        },

        schema: [],

        messages: {
            outOfScope: "'{{name}}' declared on line {{definitionLine}} column {{definitionColumn}} is used outside of binding context."
        }
    },

    create(context) {
        let stack = [];
        const sourceCode = context.sourceCode;

        /**
         * Makes a block scope.
         * @param {ASTNode} node A node of a scope.
         * @returns {void}
         */
        function enterScope(node) {
            stack.push(node.range);
        }

        /**
         * Pops the last block scope.
         * @returns {void}
         */
        function exitScope() {
            stack.pop();
        }

        /**
         * Reports a given reference.
         * @param {eslint-scope.Reference} reference A reference to report.
         * @param {eslint-scope.Definition} definition A definition for which to report reference.
         * @returns {void}
         */
        function report(reference, definition) {
            const identifier = reference.identifier;
            const definitionPosition = definition.name.loc.start;

            context.report({
                node: identifier,
                messageId: "outOfScope",
                data: {
                    name: identifier.name,
                    definitionLine: definitionPosition.line,
                    definitionColumn: definitionPosition.column + 1
                }
            });
        }

        /**
         * Finds and reports references which are outside of valid scopes.
         * @param {ASTNode} node A node to get variables.
         * @returns {void}
         */
        function checkForVariables(node) {
            if (node.kind !== "var") {
                return;
            }

            // Defines a predicate to check whether or not a given reference is outside of valid scope.
            const scopeRange = stack[stack.length - 1];

            /**
             * Check if a reference is out of scope
             * @param {ASTNode} reference node to examine
             * @returns {boolean} True is its outside the scope
             * @private
             */
            function isOutsideOfScope(reference) {
                const idRange = reference.identifier.range;

                return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
            }

            // Gets declared variables, and checks its references.
            const variables = sourceCode.getDeclaredVariables(node);

            for (let i = 0; i < variables.length; ++i) {

                // Reports.
                variables[i]
                    .references
                    .filter(isOutsideOfScope)
                    .forEach(ref => report(ref, variables[i].defs.find(def => def.parent === node)));
            }
        }

        return {
            Program(node) {
                stack = [node.range];
            },

            // Manages scopes.
            BlockStatement: enterScope,
            "BlockStatement:exit": exitScope,
            ForStatement: enterScope,
            "ForStatement:exit": exitScope,
            ForInStatement: enterScope,
            "ForInStatement:exit": exitScope,
            ForOfStatement: enterScope,
            "ForOfStatement:exit": exitScope,
            SwitchStatement: enterScope,
            "SwitchStatement:exit": exitScope,
            CatchClause: enterScope,
            "CatchClause:exit": exitScope,
            StaticBlock: enterScope,
            "StaticBlock:exit": exitScope,

            // Finds and reports references which are outside of valid scope.
            VariableDeclaration: checkForVariables
        };

    }
};


code:
/**
 * @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
 * @author Toru Nagashima
 * @deprecated in ESLint v8.53.0
 */

"use strict";

const util = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Disallow or enforce spaces inside of blocks after opening block and before closing block",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/block-spacing"
        },

        fixable: "whitespace",

        schema: [
            { enum: ["always", "never"] }
        ],

        messages: {
            missing: "Requires a space {{location}} '{{token}}'.",
            extra: "Unexpected space(s) {{location}} '{{token}}'."
        }
    },

    create(context) {
        const always = (context.options[0] !== "never"),
            messageId = always ? "missing" : "extra",
            sourceCode = context.sourceCode;

        /**
         * Gets the open brace token from a given node.
         * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to get.
         * @returns {Token} The token of the open brace.
         */
        function getOpenBrace(node) {
            if (node.type === "SwitchStatement") {
                if (node.cases.length > 0) {
                    return sourceCode.getTokenBefore(node.cases[0]);
                }
                return sourceCode.getLastToken(node, 1);
            }

            if (node.type === "StaticBlock") {
                return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
            }

            // "BlockStatement"
            return sourceCode.getFirstToken(node);
        }

        /**
         * Checks whether or not:
         *   - given tokens are on same line.
         *   - there is/isn't a space between given tokens.
         * @param {Token} left A token to check.
         * @param {Token} right The token which is next to `left`.
         * @returns {boolean}
         *    When the option is `"always"`, `true` if there are one or more spaces between given tokens.
         *    When the option is `"never"`, `true` if there are not any spaces between given tokens.
         *    If given tokens are not on same line, it's always `true`.
         */
        function isValid(left, right) {
            return (
                !util.isTokenOnSameLine(left, right) ||
                sourceCode.isSpaceBetweenTokens(left, right) === always
            );
        }

        /**
         * Checks and reports invalid spacing style inside braces.
         * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check.
         * @returns {void}
         */
        function checkSpacingInsideBraces(node) {

            // Gets braces and the first/last token of content.
            const openBrace = getOpenBrace(node);
            const closeBrace = sourceCode.getLastToken(node);
            const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true });
            const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true });

            // Skip if the node is invalid or empty.
            if (openBrace.type !== "Punctuator" ||
                openBrace.value !== "{" ||
                closeBrace.type !== "Punctuator" ||
                closeBrace.value !== "}" ||
                firstToken === closeBrace
            ) {
                return;
            }

            // Skip line comments for option never
            if (!always && firstToken.type === "Line") {
                return;
            }

            // Check.
            if (!isValid(openBrace, firstToken)) {
                let loc = openBrace.loc;

                if (messageId === "extra") {
                    loc = {
                        start: openBrace.loc.end,
                        end: firstToken.loc.start
                    };
                }

                context.report({
                    node,
                    loc,
                    messageId,
                    data: {
                        location: "after",
                        token: openBrace.value
                    },
                    fix(fixer) {
                        if (always) {
                            return fixer.insertTextBefore(firstToken, " ");
                        }

                        return fixer.removeRange([openBrace.range[1], firstToken.range[0]]);
                    }
                });
            }
            if (!isValid(lastToken, closeBrace)) {
                let loc = closeBrace.loc;

                if (messageId === "extra") {
                    loc = {
                        start: lastToken.loc.end,
                        end: closeBrace.loc.start
                    };
                }
                context.report({
                    node,
                    loc,
                    messageId,
                    data: {
                        location: "before",
                        token: closeBrace.value
                    },
                    fix(fixer) {
                        if (always) {
                            return fixer.insertTextAfter(lastToken, " ");
                        }

                        return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]);
                    }
                });
            }
        }

        return {
            BlockStatement: checkSpacingInsideBraces,
            StaticBlock: checkSpacingInsideBraces,
            SwitchStatement: checkSpacingInsideBraces
        };
    }
};


code:
/**
 * @fileoverview Rule to flag block statements that do not use the one true brace style
 * @author Ian Christian Myers
 * @deprecated in ESLint v8.53.0
 */

"use strict";

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce consistent brace style for blocks",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/brace-style"
        },

        schema: [
            {
                enum: ["1tbs", "stroustrup", "allman"]
            },
            {
                type: "object",
                properties: {
                    allowSingleLine: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],

        fixable: "whitespace",

        messages: {
            nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.",
            sameLineOpen: "Opening curly brace appears on the same line as controlling statement.",
            blockSameLine: "Statement inside of curly braces should be on next line.",
            nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.",
            singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
            sameLineClose: "Closing curly brace appears on the same line as the subsequent block."
        }
    },

    create(context) {
        const style = context.options[0] || "1tbs",
            params = context.options[1] || {},
            sourceCode = context.sourceCode;

        //--------------------------------------------------------------------------
        // Helpers
        //--------------------------------------------------------------------------

        /**
         * Fixes a place where a newline unexpectedly appears
         * @param {Token} firstToken The token before the unexpected newline
         * @param {Token} secondToken The token after the unexpected newline
         * @returns {Function} A fixer function to remove the newlines between the tokens
         */
        function removeNewlineBetween(firstToken, secondToken) {
            const textRange = [firstToken.range[1], secondToken.range[0]];
            const textBetween = sourceCode.text.slice(textRange[0], textRange[1]);

            // Don't do a fix if there is a comment between the tokens
            if (textBetween.trim()) {
                return null;
            }
            return fixer => fixer.replaceTextRange(textRange, " ");
        }

        /**
         * Validates a pair of curly brackets based on the user's config
         * @param {Token} openingCurly The opening curly bracket
         * @param {Token} closingCurly The closing curly bracket
         * @returns {void}
         */
        function validateCurlyPair(openingCurly, closingCurly) {
            const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly);
            const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly);
            const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly);
            const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly);

            if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) {
                context.report({
                    node: openingCurly,
                    messageId: "nextLineOpen",
                    fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly)
                });
            }

            if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) {
                context.report({
                    node: openingCurly,
                    messageId: "sameLineOpen",
                    fix: fixer => fixer.insertTextBefore(openingCurly, "\n")
                });
            }

            if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) {
                context.report({
                    node: openingCurly,
                    messageId: "blockSameLine",
                    fix: fixer => fixer.insertTextAfter(openingCurly, "\n")
                });
            }

            if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) {
                context.report({
                    node: closingCurly,
                    messageId: "singleLineClose",
                    fix: fixer => fixer.insertTextBefore(closingCurly, "\n")
                });
            }
        }

        /**
         * Validates the location of a token that appears before a keyword (e.g. a newline before `else`)
         * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`).
         * @returns {void}
         */
        function validateCurlyBeforeKeyword(curlyToken) {
            const keywordToken = sourceCode.getTokenAfter(curlyToken);

            if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
                context.report({
                    node: curlyToken,
                    messageId: "nextLineClose",
                    fix: removeNewlineBetween(curlyToken, keywordToken)
                });
            }

            if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
                context.report({
                    node: curlyToken,
                    messageId: "sameLineClose",
                    fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
                });
            }
        }

        //--------------------------------------------------------------------------
        // Public API
        //--------------------------------------------------------------------------

        return {
            BlockStatement(node) {
                if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
                    validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
                }
            },
            StaticBlock(node) {
                validateCurlyPair(
                    sourceCode.getFirstToken(node, { skip: 1 }), // skip the `static` token
                    sourceCode.getLastToken(node)
                );
            },
            ClassBody(node) {
                validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
            },
            SwitchStatement(node) {
                const closingCurly = sourceCode.getLastToken(node);
                const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly);

                validateCurlyPair(openingCurly, closingCurly);
            },
            IfStatement(node) {
                if (node.consequent.type === "BlockStatement" && node.alternate) {

                    // Handle the keyword after the `if` block (before `else`)
                    validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent));
                }
            },
            TryStatement(node) {

                // Handle the keyword after the `try` block (before `catch` or `finally`)
                validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block));

                if (node.handler && node.finalizer) {

                    // Handle the keyword after the `catch` block (before `finally`)
                    validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body));
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Enforce return after a callback.
 * @author Jamund Ferguson
 * @deprecated in ESLint v7.0.0
 */
"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,

        replacedBy: [],

        type: "suggestion",

        docs: {
            description: "Require `return` statements after callbacks",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/callback-return"
        },

        schema: [{
            type: "array",
            items: { type: "string" }
        }],

        messages: {
            missingReturn: "Expected return with your callback function."
        }
    },

    create(context) {

        const callbacks = context.options[0] || ["callback", "cb", "next"],
            sourceCode = context.sourceCode;

        //--------------------------------------------------------------------------
        // Helpers
        //--------------------------------------------------------------------------

        /**
         * Find the closest parent matching a list of types.
         * @param {ASTNode} node The node whose parents we are searching
         * @param {Array} types The node types to match
         * @returns {ASTNode} The matched node or undefined.
         */
        function findClosestParentOfType(node, types) {
            if (!node.parent) {
                return null;
            }
            if (!types.includes(node.parent.type)) {
                return findClosestParentOfType(node.parent, types);
            }
            return node.parent;
        }

        /**
         * Check to see if a node contains only identifiers
         * @param {ASTNode} node The node to check
         * @returns {boolean} Whether or not the node contains only identifiers
         */
        function containsOnlyIdentifiers(node) {
            if (node.type === "Identifier") {
                return true;
            }

            if (node.type === "MemberExpression") {
                if (node.object.type === "Identifier") {
                    return true;
                }
                if (node.object.type === "MemberExpression") {
                    return containsOnlyIdentifiers(node.object);
                }
            }

            return false;
        }

        /**
         * Check to see if a CallExpression is in our callback list.
         * @param {ASTNode} node The node to check against our callback names list.
         * @returns {boolean} Whether or not this function matches our callback name.
         */
        function isCallback(node) {
            return containsOnlyIdentifiers(node.callee) && callbacks.includes(sourceCode.getText(node.callee));
        }

        /**
         * Determines whether or not the callback is part of a callback expression.
         * @param {ASTNode} node The callback node
         * @param {ASTNode} parentNode The expression node
         * @returns {boolean} Whether or not this is part of a callback expression
         */
        function isCallbackExpression(node, parentNode) {

            // ensure the parent node exists and is an expression
            if (!parentNode || parentNode.type !== "ExpressionStatement") {
                return false;
            }

            // cb()
            if (parentNode.expression === node) {
                return true;
            }

            // special case for cb && cb() and similar
            if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") {
                if (parentNode.expression.right === node) {
                    return true;
                }
            }

            return false;
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            CallExpression(node) {

                // if we're not a callback we can return
                if (!isCallback(node)) {
                    return;
                }

                // find the closest block, return or loop
                const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {};

                // if our parent is a return we know we're ok
                if (closestBlock.type === "ReturnStatement") {
                    return;
                }

                // arrow functions don't always have blocks and implicitly return
                if (closestBlock.type === "ArrowFunctionExpression") {
                    return;
                }

                // block statements are part of functions and most if statements
                if (closestBlock.type === "BlockStatement") {

                    // find the last item in the block
                    const lastItem = closestBlock.body[closestBlock.body.length - 1];

                    // if the callback is the last thing in a block that might be ok
                    if (isCallbackExpression(node, lastItem)) {

                        const parentType = closestBlock.parent.type;

                        // but only if the block is part of a function
                        if (parentType === "FunctionExpression" ||
                            parentType === "FunctionDeclaration" ||
                            parentType === "ArrowFunctionExpression"
                        ) {
                            return;
                        }

                    }

                    // ending a block with a return is also ok
                    if (lastItem.type === "ReturnStatement") {

                        // but only if the callback is immediately before
                        if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) {
                            return;
                        }
                    }

                }

                // as long as you're the child of a function at this point you should be asked to return
                if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) {
                    context.report({ node, messageId: "missingReturn" });
                }

            }

        };
    }
};


code:
/**
 * @fileoverview Rule to flag non-camelcased identifiers
 * @author Nicholas C. Zakas
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce camelcase naming convention",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/camelcase"
        },

        schema: [
            {
                type: "object",
                properties: {
                    ignoreDestructuring: {
                        type: "boolean",
                        default: false
                    },
                    ignoreImports: {
                        type: "boolean",
                        default: false
                    },
                    ignoreGlobals: {
                        type: "boolean",
                        default: false
                    },
                    properties: {
                        enum: ["always", "never"]
                    },
                    allow: {
                        type: "array",
                        items: [
                            {
                                type: "string"
                            }
                        ],
                        minItems: 0,
                        uniqueItems: true
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            notCamelCase: "Identifier '{{name}}' is not in camel case.",
            notCamelCasePrivate: "#{{name}} is not in camel case."
        }
    },

    create(context) {
        const options = context.options[0] || {};
        const properties = options.properties === "never" ? "never" : "always";
        const ignoreDestructuring = options.ignoreDestructuring;
        const ignoreImports = options.ignoreImports;
        const ignoreGlobals = options.ignoreGlobals;
        const allow = options.allow || [];
        const sourceCode = context.sourceCode;

        //--------------------------------------------------------------------------
        // Helpers
        //--------------------------------------------------------------------------

        // contains reported nodes to avoid reporting twice on destructuring with shorthand notation
        const reported = new Set();

        /**
         * Checks if a string contains an underscore and isn't all upper-case
         * @param {string} name The string to check.
         * @returns {boolean} if the string is underscored
         * @private
         */
        function isUnderscored(name) {
            const nameBody = name.replace(/^_+|_+$/gu, "");

            // if there's an underscore, it might be A_CONSTANT, which is okay
            return nameBody.includes("_") && nameBody !== nameBody.toUpperCase();
        }

        /**
         * Checks if a string match the ignore list
         * @param {string} name The string to check.
         * @returns {boolean} if the string is ignored
         * @private
         */
        function isAllowed(name) {
            return allow.some(
                entry => name === entry || name.match(new RegExp(entry, "u"))
            );
        }

        /**
         * Checks if a given name is good or not.
         * @param {string} name The name to check.
         * @returns {boolean} `true` if the name is good.
         * @private
         */
        function isGoodName(name) {
            return !isUnderscored(name) || isAllowed(name);
        }

        /**
         * Checks if a given identifier reference or member expression is an assignment
         * target.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} `true` if the node is an assignment target.
         */
        function isAssignmentTarget(node) {
            const parent = node.parent;

            switch (parent.type) {
                case "AssignmentExpression":
                case "AssignmentPattern":
                    return parent.left === node;

                case "Property":
                    return (
                        parent.parent.type === "ObjectPattern" &&
                        parent.value === node
                    );
                case "ArrayPattern":
                case "RestElement":
                    return true;

                default:
                    return false;
            }
        }

        /**
         * Checks if a given binding identifier uses the original name as-is.
         * - If it's in object destructuring or object expression, the original name is its property name.
         * - If it's in import declaration, the original name is its exported name.
         * @param {ASTNode} node The `Identifier` node to check.
         * @returns {boolean} `true` if the identifier uses the original name as-is.
         */
        function equalsToOriginalName(node) {
            const localName = node.name;
            const valueNode = node.parent.type === "AssignmentPattern"
                ? node.parent
                : node;
            const parent = valueNode.parent;

            switch (parent.type) {
                case "Property":
                    return (
                        (parent.parent.type === "ObjectPattern" || parent.parent.type === "ObjectExpression") &&
                        parent.value === valueNode &&
                        !parent.computed &&
                        parent.key.type === "Identifier" &&
                        parent.key.name === localName
                    );

                case "ImportSpecifier":
                    return (
                        parent.local === node &&
                        astUtils.getModuleExportName(parent.imported) === localName
                    );

                default:
                    return false;
            }
        }

        /**
         * Reports an AST node as a rule violation.
         * @param {ASTNode} node The node to report.
         * @returns {void}
         * @private
         */
        function report(node) {
            if (reported.has(node.range[0])) {
                return;
            }
            reported.add(node.range[0]);

            // Report it.
            context.report({
                node,
                messageId: node.type === "PrivateIdentifier"
                    ? "notCamelCasePrivate"
                    : "notCamelCase",
                data: { name: node.name }
            });
        }

        /**
         * Reports an identifier reference or a binding identifier.
         * @param {ASTNode} node The `Identifier` node to report.
         * @returns {void}
         */
        function reportReferenceId(node) {

            /*
             * For backward compatibility, if it's in callings then ignore it.
             * Not sure why it is.
             */
            if (
                node.parent.type === "CallExpression" ||
                node.parent.type === "NewExpression"
            ) {
                return;
            }

            /*
             * For backward compatibility, if it's a default value of
             * destructuring/parameters then ignore it.
             * Not sure why it is.
             */
            if (
                node.parent.type === "AssignmentPattern" &&
                node.parent.right === node
            ) {
                return;
            }

            /*
             * The `ignoreDestructuring` flag skips the identifiers that uses
             * the property name as-is.
             */
            if (ignoreDestructuring && equalsToOriginalName(node)) {
                return;
            }

            report(node);
        }

        return {

            // Report camelcase of global variable references ------------------
            Program(node) {
                const scope = sourceCode.getScope(node);

                if (!ignoreGlobals) {

                    // Defined globals in config files or directive comments.
                    for (const variable of scope.variables) {
                        if (
                            variable.identifiers.length > 0 ||
                            isGoodName(variable.name)
                        ) {
                            continue;
                        }
                        for (const reference of variable.references) {

                            /*
                             * For backward compatibility, this rule reports read-only
                             * references as well.
                             */
                            reportReferenceId(reference.identifier);
                        }
                    }
                }

                // Undefined globals.
                for (const reference of scope.through) {
                    const id = reference.identifier;

                    if (isGoodName(id.name)) {
                        continue;
                    }

                    /*
                     * For backward compatibility, this rule reports read-only
                     * references as well.
                     */
                    reportReferenceId(id);
                }
            },

            // Report camelcase of declared variables --------------------------
            [[
                "VariableDeclaration",
                "FunctionDeclaration",
                "FunctionExpression",
                "ArrowFunctionExpression",
                "ClassDeclaration",
                "ClassExpression",
                "CatchClause"
            ]](node) {
                for (const variable of sourceCode.getDeclaredVariables(node)) {
                    if (isGoodName(variable.name)) {
                        continue;
                    }
                    const id = variable.identifiers[0];

                    // Report declaration.
                    if (!(ignoreDestructuring && equalsToOriginalName(id))) {
                        report(id);
                    }

                    /*
                     * For backward compatibility, report references as well.
                     * It looks unnecessary because declarations are reported.
                     */
                    for (const reference of variable.references) {
                        if (reference.init) {
                            continue; // Skip the write references of initializers.
                        }
                        reportReferenceId(reference.identifier);
                    }
                }
            },

            // Report camelcase in properties ----------------------------------
            [[
                "ObjectExpression > Property[computed!=true] > Identifier.key",
                "MethodDefinition[computed!=true] > Identifier.key",
                "PropertyDefinition[computed!=true] > Identifier.key",
                "MethodDefinition > PrivateIdentifier.key",
                "PropertyDefinition > PrivateIdentifier.key"
            ]](node) {
                if (properties === "never" || isGoodName(node.name)) {
                    return;
                }
                report(node);
            },
            "MemberExpression[computed!=true] > Identifier.property"(node) {
                if (
                    properties === "never" ||
                    !isAssignmentTarget(node.parent) || // ← ignore read-only references.
                    isGoodName(node.name)
                ) {
                    return;
                }
                report(node);
            },

            // Report camelcase in import --------------------------------------
            ImportDeclaration(node) {
                for (const variable of sourceCode.getDeclaredVariables(node)) {
                    if (isGoodName(variable.name)) {
                        continue;
                    }
                    const id = variable.identifiers[0];

                    // Report declaration.
                    if (!(ignoreImports && equalsToOriginalName(id))) {
                        report(id);
                    }

                    /*
                     * For backward compatibility, report references as well.
                     * It looks unnecessary because declarations are reported.
                     */
                    for (const reference of variable.references) {
                        reportReferenceId(reference.identifier);
                    }
                }
            },

            // Report camelcase in re-export -----------------------------------
            [[
                "ExportAllDeclaration > Identifier.exported",
                "ExportSpecifier > Identifier.exported"
            ]](node) {
                if (isGoodName(node.name)) {
                    return;
                }
                report(node);
            },

            // Report camelcase in labels --------------------------------------
            [[
                "LabeledStatement > Identifier.label",

                /*
                 * For backward compatibility, report references as well.
                 * It looks unnecessary because declarations are reported.
                 */
                "BreakStatement > Identifier.label",
                "ContinueStatement > Identifier.label"
            ]](node) {
                if (isGoodName(node.name)) {
                    return;
                }
                report(node);
            }
        };
    }
};


code:
/**
 * @fileoverview enforce or disallow capitalization of the first letter of a comment
 * @author Kevin Partington
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const LETTER_PATTERN = require("./utils/patterns/letters");
const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN,
    WHITESPACE = /\s/gu,
    MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern?

/*
 * Base schema body for defining the basic capitalization rule, ignorePattern,
 * and ignoreInlineComments values.
 * This can be used in a few different ways in the actual schema.
 */
const SCHEMA_BODY = {
    type: "object",
    properties: {
        ignorePattern: {
            type: "string"
        },
        ignoreInlineComments: {
            type: "boolean"
        },
        ignoreConsecutiveComments: {
            type: "boolean"
        }
    },
    additionalProperties: false
};
const DEFAULTS = {
    ignorePattern: "",
    ignoreInlineComments: false,
    ignoreConsecutiveComments: false
};

/**
 * Get normalized options for either block or line comments from the given
 * user-provided options.
 * - If the user-provided options is just a string, returns a normalized
 *   set of options using default values for all other options.
 * - If the user-provided options is an object, then a normalized option
 *   set is returned. Options specified in overrides will take priority
 *   over options specified in the main options object, which will in
 *   turn take priority over the rule's defaults.
 * @param {Object|string} rawOptions The user-provided options.
 * @param {string} which Either "line" or "block".
 * @returns {Object} The normalized options.
 */
function getNormalizedOptions(rawOptions, which) {
    return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions);
}

/**
 * Get normalized options for block and line comments.
 * @param {Object|string} rawOptions The user-provided options.
 * @returns {Object} An object with "Line" and "Block" keys and corresponding
 * normalized options objects.
 */
function getAllNormalizedOptions(rawOptions = {}) {
    return {
        Line: getNormalizedOptions(rawOptions, "line"),
        Block: getNormalizedOptions(rawOptions, "block")
    };
}

/**
 * Creates a regular expression for each ignorePattern defined in the rule
 * options.
 *
 * This is done in order to avoid invoking the RegExp constructor repeatedly.
 * @param {Object} normalizedOptions The normalized rule options.
 * @returns {void}
 */
function createRegExpForIgnorePatterns(normalizedOptions) {
    Object.keys(normalizedOptions).forEach(key => {
        const ignorePatternStr = normalizedOptions[key].ignorePattern;

        if (ignorePatternStr) {
            const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u");

            normalizedOptions[key].ignorePatternRegExp = regExp;
        }
    });
}

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce or disallow capitalization of the first letter of a comment",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/capitalized-comments"
        },

        fixable: "code",

        schema: [
            { enum: ["always", "never"] },
            {
                oneOf: [
                    SCHEMA_BODY,
                    {
                        type: "object",
                        properties: {
                            line: SCHEMA_BODY,
                            block: SCHEMA_BODY
                        },
                        additionalProperties: false
                    }
                ]
            }
        ],

        messages: {
            unexpectedLowercaseComment: "Comments should not begin with a lowercase character.",
            unexpectedUppercaseComment: "Comments should not begin with an uppercase character."
        }
    },

    create(context) {

        const capitalize = context.options[0] || "always",
            normalizedOptions = getAllNormalizedOptions(context.options[1]),
            sourceCode = context.sourceCode;

        createRegExpForIgnorePatterns(normalizedOptions);

        //----------------------------------------------------------------------
        // Helpers
        //----------------------------------------------------------------------

        /**
         * Checks whether a comment is an inline comment.
         *
         * For the purpose of this rule, a comment is inline if:
         * 1. The comment is preceded by a token on the same line; and
         * 2. The command is followed by a token on the same line.
         *
         * Note that the comment itself need not be single-line!
         *
         * Also, it follows from this definition that only block comments can
         * be considered as possibly inline. This is because line comments
         * would consume any following tokens on the same line as the comment.
         * @param {ASTNode} comment The comment node to check.
         * @returns {boolean} True if the comment is an inline comment, false
         * otherwise.
         */
        function isInlineComment(comment) {
            const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }),
                nextToken = sourceCode.getTokenAfter(comment, { includeComments: true });

            return Boolean(
                previousToken &&
                nextToken &&
                comment.loc.start.line === previousToken.loc.end.line &&
                comment.loc.end.line === nextToken.loc.start.line
            );
        }

        /**
         * Determine if a comment follows another comment.
         * @param {ASTNode} comment The comment to check.
         * @returns {boolean} True if the comment follows a valid comment.
         */
        function isConsecutiveComment(comment) {
            const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true });

            return Boolean(
                previousTokenOrComment &&
                ["Block", "Line"].includes(previousTokenOrComment.type)
            );
        }

        /**
         * Check a comment to determine if it is valid for this rule.
         * @param {ASTNode} comment The comment node to process.
         * @param {Object} options The options for checking this comment.
         * @returns {boolean} True if the comment is valid, false otherwise.
         */
        function isCommentValid(comment, options) {

            // 1. Check for default ignore pattern.
            if (DEFAULT_IGNORE_PATTERN.test(comment.value)) {
                return true;
            }

            // 2. Check for custom ignore pattern.
            const commentWithoutAsterisks = comment.value
                .replace(/\*/gu, "");

            if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) {
                return true;
            }

            // 3. Check for inline comments.
            if (options.ignoreInlineComments && isInlineComment(comment)) {
                return true;
            }

            // 4. Is this a consecutive comment (and are we tolerating those)?
            if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) {
                return true;
            }

            // 5. Does the comment start with a possible URL?
            if (MAYBE_URL.test(commentWithoutAsterisks)) {
                return true;
            }

            // 6. Is the initial word character a letter?
            const commentWordCharsOnly = commentWithoutAsterisks
                .replace(WHITESPACE, "");

            if (commentWordCharsOnly.length === 0) {
                return true;
            }

            const firstWordChar = commentWordCharsOnly[0];

            if (!LETTER_PATTERN.test(firstWordChar)) {
                return true;
            }

            // 7. Check the case of the initial word character.
            const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(),
                isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase();

            if (capitalize === "always" && isLowercase) {
                return false;
            }
            if (capitalize === "never" && isUppercase) {
                return false;
            }

            return true;
        }

        /**
         * Process a comment to determine if it needs to be reported.
         * @param {ASTNode} comment The comment node to process.
         * @returns {void}
         */
        function processComment(comment) {
            const options = normalizedOptions[comment.type],
                commentValid = isCommentValid(comment, options);

            if (!commentValid) {
                const messageId = capitalize === "always"
                    ? "unexpectedLowercaseComment"
                    : "unexpectedUppercaseComment";

                context.report({
                    node: null, // Intentionally using loc instead
                    loc: comment.loc,
                    messageId,
                    fix(fixer) {
                        const match = comment.value.match(LETTER_PATTERN);

                        return fixer.replaceTextRange(

                            // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*)
                            [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3],
                            capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase()
                        );
                    }
                });
            }
        }

        //----------------------------------------------------------------------
        // Public
        //----------------------------------------------------------------------

        return {
            Program() {
                const comments = sourceCode.getAllComments();

                comments.filter(token => token.type !== "Shebang").forEach(processComment);
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce that all class methods use 'this'.
 * @author Patrick Williams
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce that class methods utilize `this`",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/class-methods-use-this"
        },

        schema: [{
            type: "object",
            properties: {
                exceptMethods: {
                    type: "array",
                    items: {
                        type: "string"
                    }
                },
                enforceForClassFields: {
                    type: "boolean",
                    default: true
                }
            },
            additionalProperties: false
        }],

        messages: {
            missingThis: "Expected 'this' to be used by class {{name}}."
        }
    },
    create(context) {
        const config = Object.assign({}, context.options[0]);
        const enforceForClassFields = config.enforceForClassFields !== false;
        const exceptMethods = new Set(config.exceptMethods || []);

        const stack = [];

        /**
         * Push `this` used flag initialized with `false` onto the stack.
         * @returns {void}
         */
        function pushContext() {
            stack.push(false);
        }

        /**
         * Pop `this` used flag from the stack.
         * @returns {boolean | undefined} `this` used flag
         */
        function popContext() {
            return stack.pop();
        }

        /**
         * Initializes the current context to false and pushes it onto the stack.
         * These booleans represent whether 'this' has been used in the context.
         * @returns {void}
         * @private
         */
        function enterFunction() {
            pushContext();
        }

        /**
         * Check if the node is an instance method
         * @param {ASTNode} node node to check
         * @returns {boolean} True if its an instance method
         * @private
         */
        function isInstanceMethod(node) {
            switch (node.type) {
                case "MethodDefinition":
                    return !node.static && node.kind !== "constructor";
                case "PropertyDefinition":
                    return !node.static && enforceForClassFields;
                default:
                    return false;
            }
        }

        /**
         * Check if the node is an instance method not excluded by config
         * @param {ASTNode} node node to check
         * @returns {boolean} True if it is an instance method, and not excluded by config
         * @private
         */
        function isIncludedInstanceMethod(node) {
            if (isInstanceMethod(node)) {
                if (node.computed) {
                    return true;
                }

                const hashIfNeeded = node.key.type === "PrivateIdentifier" ? "#" : "";
                const name = node.key.type === "Literal"
                    ? astUtils.getStaticStringValue(node.key)
                    : (node.key.name || "");

                return !exceptMethods.has(hashIfNeeded + name);
            }
            return false;
        }

        /**
         * Checks if we are leaving a function that is a method, and reports if 'this' has not been used.
         * Static methods and the constructor are exempt.
         * Then pops the context off the stack.
         * @param {ASTNode} node A function node that was entered.
         * @returns {void}
         * @private
         */
        function exitFunction(node) {
            const methodUsesThis = popContext();

            if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) {
                context.report({
                    node,
                    loc: astUtils.getFunctionHeadLoc(node, context.sourceCode),
                    messageId: "missingThis",
                    data: {
                        name: astUtils.getFunctionNameWithKind(node)
                    }
                });
            }
        }

        /**
         * Mark the current context as having used 'this'.
         * @returns {void}
         * @private
         */
        function markThisUsed() {
            if (stack.length) {
                stack[stack.length - 1] = true;
            }
        }

        return {
            FunctionDeclaration: enterFunction,
            "FunctionDeclaration:exit": exitFunction,
            FunctionExpression: enterFunction,
            "FunctionExpression:exit": exitFunction,

            /*
             * Class field value are implicit functions.
             */
            "PropertyDefinition > *.key:exit": pushContext,
            "PropertyDefinition:exit": popContext,

            /*
             * Class static blocks are implicit functions. They aren't required to use `this`,
             * but we have to push context so that it captures any use of `this` in the static block
             * separately from enclosing contexts, because static blocks have their own `this` and it
             * shouldn't count as used `this` in enclosing contexts.
             */
            StaticBlock: pushContext,
            "StaticBlock:exit": popContext,

            ThisExpression: markThisUsed,
            Super: markThisUsed,
            ...(
                enforceForClassFields && {
                    "PropertyDefinition > ArrowFunctionExpression.value": enterFunction,
                    "PropertyDefinition > ArrowFunctionExpression.value:exit": exitFunction
                }
            )
        };
    }
};