/** * @fileoverview Prevent using string literals in React component definition * @author Caleb Morris * @author David Buchan-Swanson */ 'use strict'; const docsUrl = require('../util/docsUrl'); // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: 'Prevent using string literals in React component definition', category: 'Stylistic Issues', recommended: false, url: docsUrl('jsx-no-literals') }, schema: [{ type: 'object', properties: { noStrings: { type: 'boolean' } }, additionalProperties: false }] }, create(context) { const isNoStrings = context.options[0] ? context.options[0].noStrings : false; const message = isNoStrings ? 'Strings not allowed in JSX files' : 'Missing JSX expression container around literal string'; function reportLiteralNode(node) { context.report({ node, message: `${message}: “${context.getSourceCode().getText(node).trim()}”` }); } function getParentIgnoringBinaryExpressions(node) { let current = node; while (current.parent.type === 'BinaryExpression') { current = current.parent; } return current.parent; } function getValidation(node) { const parent = getParentIgnoringBinaryExpressions(node); const standard = !/^[\s]+$/.test(node.value) && typeof node.value === 'string' && parent.type.indexOf('JSX') !== -1 && parent.type !== 'JSXAttribute'; if (isNoStrings) { return standard; } return standard && parent.type !== 'JSXExpressionContainer'; } // -------------------------------------------------------------------------- // Public // -------------------------------------------------------------------------- return { Literal(node) { if (getValidation(node)) { reportLiteralNode(node); } }, JSXText(node) { if (getValidation(node)) { reportLiteralNode(node); } }, TemplateLiteral(node) { const parent = getParentIgnoringBinaryExpressions(node); if (isNoStrings && parent.type === 'JSXExpressionContainer') { reportLiteralNode(node); } } }; } };