|                                                                                                                            |  | /** * @fileoverview Restrict usage of specified globals. * @author Benoît Zugmeyer */"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../shared/types').Rule} */module.exports = {    meta: {        type: "suggestion",
        docs: {            description: "Disallow specified global variables",            recommended: false,            url: "https://eslint.org/docs/latest/rules/no-restricted-globals"        },
        schema: {            type: "array",            items: {                oneOf: [                    {                        type: "string"                    },                    {                        type: "object",                        properties: {                            name: { type: "string" },                            message: { type: "string" }                        },                        required: ["name"],                        additionalProperties: false                    }                ]            },            uniqueItems: true,            minItems: 0        },
        messages: {            defaultMessage: "Unexpected use of '{{name}}'.",            // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
            customMessage: "Unexpected use of '{{name}}'. {{customMessage}}"        }    },
    create(context) {
        const sourceCode = context.sourceCode;
        // If no globals are restricted, we don't need to do anything
        if (context.options.length === 0) {            return {};        }
        const restrictedGlobalMessages = context.options.reduce((memo, option) => {            if (typeof option === "string") {                memo[option] = null;            } else {                memo[option.name] = option.message;            }
            return memo;        }, {});
        /**         * Report a variable to be used as a restricted global.         * @param {Reference} reference the variable reference         * @returns {void}         * @private         */        function reportReference(reference) {            const name = reference.identifier.name,                customMessage = restrictedGlobalMessages[name],                messageId = customMessage                    ? "customMessage"                    : "defaultMessage";
            context.report({                node: reference.identifier,                messageId,                data: {                    name,                    customMessage                }            });        }
        /**         * Check if the given name is a restricted global name.         * @param {string} name name of a variable         * @returns {boolean} whether the variable is a restricted global or not         * @private         */        function isRestricted(name) {            return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name);        }
        return {            Program(node) {                const scope = sourceCode.getScope(node);
                // Report variables declared elsewhere (ex: variables defined as "global" by eslint)
                scope.variables.forEach(variable => {                    if (!variable.defs.length && isRestricted(variable.name)) {                        variable.references.forEach(reportReference);                    }                });
                // Report variables not declared at all
                scope.through.forEach(reference => {                    if (isRestricted(reference.identifier.name)) {                        reportReference(reference);                    }                });
            }        };    }};
 |