UNPKG

@raycast/eslint-plugin

Version:

ESLint plugin designed to help Raycast's extensions authors follow best practices

113 lines (112 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("@typescript-eslint/utils"); const utils_2 = require("../utils"); const title_case_1 = require("../title-case"); exports.default = (0, utils_2.createRule)({ create: (context) => { return { JSXOpeningElement: (node) => { if ((0, utils_2.isActionComponent)(node.name)) { const titleAttribute = node.attributes.find((attribute) => { return (attribute.type === "JSXAttribute" && attribute.name.name === "title"); }); if (titleAttribute) { const value = titleAttribute.type === "JSXAttribute" && titleAttribute.value; if (value) { if (value.type === utils_1.AST_NODE_TYPES.Literal && typeof value.value === "string") { const originalTitle = value.value; const formattedTitle = (0, title_case_1.titleCase)(originalTitle); if (originalTitle !== formattedTitle) { context.report({ node: value, messageId: "isNotTitleCased", fix: (fixer) => fixer.replaceText(value, `"${formattedTitle}"`), }); } } if (value.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer) { const expression = value.expression; if (expression.type === utils_1.AST_NODE_TYPES.Literal && expression.value && typeof expression.value === "string") { const formattedTitle = (0, title_case_1.titleCase)(expression.value); if (expression.value !== formattedTitle) { context.report({ node: expression, messageId: "isNotTitleCased", fix: (fixer) => fixer.replaceText(expression, `"${formattedTitle}"`), }); } } if (expression.type === utils_1.AST_NODE_TYPES.ConditionalExpression) { const consequent = expression.consequent; const alternate = expression.alternate; if (consequent.type === utils_1.AST_NODE_TYPES.Literal && consequent.value && typeof consequent.value === "string") { const formattedTitle = (0, title_case_1.titleCase)(consequent.value); if (consequent.value !== formattedTitle) { context.report({ node: consequent, messageId: "isNotTitleCased", fix: (fixer) => fixer.replaceText(consequent, `"${formattedTitle}"`), }); } } if (alternate.type === utils_1.AST_NODE_TYPES.Literal && alternate.value && typeof alternate.value === "string") { const formattedTitle = (0, title_case_1.titleCase)(alternate.value); if (alternate.value !== formattedTitle) { context.report({ node: alternate, messageId: "isNotTitleCased", fix: (fixer) => fixer.replaceText(alternate, `"${formattedTitle}"`), }); } } } if (expression.type === utils_1.AST_NODE_TYPES.TemplateLiteral) { const quasis = expression.quasis; var hasQuasiWithoutTitleCase = false; quasis.forEach((quasi) => { if (quasi.type === utils_1.AST_NODE_TYPES.TemplateElement && quasi.value && typeof quasi.value.raw === "string") { const formattedTitle = (0, title_case_1.titleCase)(quasi.value.raw); if (quasi.value.raw !== formattedTitle) { hasQuasiWithoutTitleCase = true; } } }); if (hasQuasiWithoutTitleCase) { return context.report({ node: expression, messageId: "isNotTitleCased", }); } } } } } } }, }; }, name: "prefer-title-case", meta: { fixable: "code", messages: { isNotTitleCased: "Prefer Title Case naming convention for action titles (e.g Copy to Clipboard).", }, type: "suggestion", docs: { description: "Prefer Title Case", }, schema: [], }, defaultOptions: [], });