/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { isTextLabelChild, isStringWithoutExpressions, createRule, } from '../util'; import type {TSESTree} from '@typescript-eslint/types/dist/ts-estree'; type Options = []; type MessageIds = 'translateChildren' | 'translateArg'; export default createRule({ name: 'string-literal-i18n-messages', meta: { type: 'problem', docs: { description: 'enforce translate APIs to be called on plain text labels', recommended: 'error', }, schema: [], messages: { translateChildren: ' children must be hardcoded strings. You can have in-string dynamic placeholders using the values prop.', translateArg: 'translation message must be a hardcoded string. You can have in-string dynamic placeholders using the values argument.', }, }, defaultOptions: [], create(context) { return { JSXElement(node) { if ( (node.openingElement.name as TSESTree.JSXIdentifier).name !== 'Translate' ) { return; } if (node.children.some((child) => !isTextLabelChild(child))) { context.report({node, messageId: 'translateChildren'}); } }, CallExpression(node) { if ( node.callee.type !== 'Identifier' || node.callee.name !== 'translate' ) { return; } const param = node.arguments[0]; if (!param || param.type !== 'ObjectExpression') { context.report({node, messageId: 'translateArg'}); return; } const messageProperty = param.properties.find( (property): property is TSESTree.Property => property.type === 'Property' && (property.key as TSESTree.Identifier).name === 'message', ); if (!messageProperty) { return; } if (!isStringWithoutExpressions(messageProperty.value)) { context.report({node, messageId: 'translateArg'}); } }, }; }, });