|                                                                                                                                                                                                                                                                                                                                    |  | /** * @fileoverview Rule to require or disallow line breaks inside braces. * @author Toru Nagashima * @deprecated in ESLint v8.53.0 */
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
// Schema objects.
const OPTION_VALUE = {    oneOf: [        {            enum: ["always", "never"]        },        {            type: "object",            properties: {                multiline: {                    type: "boolean"                },                minProperties: {                    type: "integer",                    minimum: 0                },                consistent: {                    type: "boolean"                }            },            additionalProperties: false,            minProperties: 1        }    ]};
/** * Normalizes a given option value. * @param {string|Object|undefined} value An option value to parse. * @returns {{multiline: boolean, minProperties: number, consistent: boolean}} Normalized option object. */function normalizeOptionValue(value) {    let multiline = false;    let minProperties = Number.POSITIVE_INFINITY;    let consistent = false;
    if (value) {        if (value === "always") {            minProperties = 0;        } else if (value === "never") {            minProperties = Number.POSITIVE_INFINITY;        } else {            multiline = Boolean(value.multiline);            minProperties = value.minProperties || Number.POSITIVE_INFINITY;            consistent = Boolean(value.consistent);        }    } else {        consistent = true;    }
    return { multiline, minProperties, consistent };}
/** * Checks if a value is an object. * @param {any} value The value to check * @returns {boolean} `true` if the value is an object, otherwise `false` */function isObject(value) {    return typeof value === "object" && value !== null;}
/** * Checks if an option is a node-specific option * @param {any} option The option to check * @returns {boolean} `true` if the option is node-specific, otherwise `false` */function isNodeSpecificOption(option) {    return isObject(option) || typeof option === "string";}
/** * Normalizes a given option value. * @param {string|Object|undefined} options An option value to parse. * @returns {{ *   ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean}, *   ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean}, *   ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean}, *   ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean} * }} Normalized option object. */function normalizeOptions(options) {    if (isObject(options) && Object.values(options).some(isNodeSpecificOption)) {        return {            ObjectExpression: normalizeOptionValue(options.ObjectExpression),            ObjectPattern: normalizeOptionValue(options.ObjectPattern),            ImportDeclaration: normalizeOptionValue(options.ImportDeclaration),            ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration)        };    }
    const value = normalizeOptionValue(options);
    return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value };}
/** * Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration * node needs to be checked for missing line breaks * @param {ASTNode} node Node under inspection * @param {Object} options option specific to node type * @param {Token} first First object property * @param {Token} last Last object property * @returns {boolean} `true` if node needs to be checked for missing line breaks */function areLineBreaksRequired(node, options, first, last) {    let objectProperties;
    if (node.type === "ObjectExpression" || node.type === "ObjectPattern") {        objectProperties = node.properties;    } else {
        // is ImportDeclaration or ExportNamedDeclaration
        objectProperties = node.specifiers            .filter(s => s.type === "ImportSpecifier" || s.type === "ExportSpecifier");    }
    return objectProperties.length >= options.minProperties ||        (            options.multiline &&            objectProperties.length > 0 &&            first.loc.start.line !== last.loc.end.line        );}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../shared/types').Rule} */module.exports = {    meta: {        deprecated: true,        replacedBy: [],        type: "layout",
        docs: {            description: "Enforce consistent line breaks after opening and before closing braces",            recommended: false,            url: "https://eslint.org/docs/latest/rules/object-curly-newline"        },
        fixable: "whitespace",
        schema: [            {                oneOf: [                    OPTION_VALUE,                    {                        type: "object",                        properties: {                            ObjectExpression: OPTION_VALUE,                            ObjectPattern: OPTION_VALUE,                            ImportDeclaration: OPTION_VALUE,                            ExportDeclaration: OPTION_VALUE                        },                        additionalProperties: false,                        minProperties: 1                    }                ]            }        ],
        messages: {            unexpectedLinebreakBeforeClosingBrace: "Unexpected line break before this closing brace.",            unexpectedLinebreakAfterOpeningBrace: "Unexpected line break after this opening brace.",            expectedLinebreakBeforeClosingBrace: "Expected a line break before this closing brace.",            expectedLinebreakAfterOpeningBrace: "Expected a line break after this opening brace."        }    },
    create(context) {        const sourceCode = context.sourceCode;        const normalizedOptions = normalizeOptions(context.options[0]);
        /**         * Reports a given node if it violated this rule.         * @param {ASTNode} node A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node.         * @returns {void}         */        function check(node) {            const options = normalizedOptions[node.type];
            if (                (node.type === "ImportDeclaration" &&                    !node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) ||                (node.type === "ExportNamedDeclaration" &&                    !node.specifiers.some(specifier => specifier.type === "ExportSpecifier"))            ) {                return;            }
            const openBrace = sourceCode.getFirstToken(node, token => token.value === "{");
            let closeBrace;
            if (node.typeAnnotation) {                closeBrace = sourceCode.getTokenBefore(node.typeAnnotation);            } else {                closeBrace = sourceCode.getLastToken(node, token => token.value === "}");            }
            let first = sourceCode.getTokenAfter(openBrace, { includeComments: true });            let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
            const needsLineBreaks = areLineBreaksRequired(node, options, first, last);
            const hasCommentsFirstToken = astUtils.isCommentToken(first);            const hasCommentsLastToken = astUtils.isCommentToken(last);
            /*             * Use tokens or comments to check multiline or not.             * But use only tokens to check whether line breaks are needed.             * This allows:             *     var obj = { // eslint-disable-line foo
             *         a: 1             *     }             */            first = sourceCode.getTokenAfter(openBrace);            last = sourceCode.getTokenBefore(closeBrace);
            if (needsLineBreaks) {                if (astUtils.isTokenOnSameLine(openBrace, first)) {                    context.report({                        messageId: "expectedLinebreakAfterOpeningBrace",                        node,                        loc: openBrace.loc,                        fix(fixer) {                            if (hasCommentsFirstToken) {                                return null;                            }
                            return fixer.insertTextAfter(openBrace, "\n");                        }                    });                }                if (astUtils.isTokenOnSameLine(last, closeBrace)) {                    context.report({                        messageId: "expectedLinebreakBeforeClosingBrace",                        node,                        loc: closeBrace.loc,                        fix(fixer) {                            if (hasCommentsLastToken) {                                return null;                            }
                            return fixer.insertTextBefore(closeBrace, "\n");                        }                    });                }            } else {                const consistent = options.consistent;                const hasLineBreakBetweenOpenBraceAndFirst = !astUtils.isTokenOnSameLine(openBrace, first);                const hasLineBreakBetweenCloseBraceAndLast = !astUtils.isTokenOnSameLine(last, closeBrace);
                if (                    (!consistent && hasLineBreakBetweenOpenBraceAndFirst) ||                    (consistent && hasLineBreakBetweenOpenBraceAndFirst && !hasLineBreakBetweenCloseBraceAndLast)                ) {                    context.report({                        messageId: "unexpectedLinebreakAfterOpeningBrace",                        node,                        loc: openBrace.loc,                        fix(fixer) {                            if (hasCommentsFirstToken) {                                return null;                            }
                            return fixer.removeRange([                                openBrace.range[1],                                first.range[0]                            ]);                        }                    });                }                if (                    (!consistent && hasLineBreakBetweenCloseBraceAndLast) ||                    (consistent && !hasLineBreakBetweenOpenBraceAndFirst && hasLineBreakBetweenCloseBraceAndLast)                ) {                    context.report({                        messageId: "unexpectedLinebreakBeforeClosingBrace",                        node,                        loc: closeBrace.loc,                        fix(fixer) {                            if (hasCommentsLastToken) {                                return null;                            }
                            return fixer.removeRange([                                last.range[1],                                closeBrace.range[0]                            ]);                        }                    });                }            }        }
        return {            ObjectExpression: check,            ObjectPattern: check,            ImportDeclaration: check,            ExportNamedDeclaration: check        };    }};
 |