eslint-plugin-sitecore-jss
Version:
An ESLint plugin to enforce correct usage of Sitecore JSS components
79 lines • 3.72 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const type_checking_1 = __importDefault(require("./utils/type-checking"));
const { getType, isLinkField } = type_checking_1.default;
exports.default = {
defaultOptions: [],
meta: {
type: "problem",
docs: {
description: "Ensure `<Link>` is used instead of raw `<a>` for `LinkField`.",
recommended: "recommended",
},
messages: {
useLinkComponent: "Use `<Link field={{{fieldName}}} />` instead of `<a>`. Make sure you are using `LinkField`.",
},
fixable: "code",
schema: [],
},
create(context) {
const parserServices = utils_1.ESLintUtils.getParserServices(context);
if (!parserServices || !parserServices.program)
return {};
const checker = parserServices.program.getTypeChecker();
return {
JSXOpeningElement(node) {
if (node.name.type !== utils_1.AST_NODE_TYPES.JSXIdentifier ||
node.name.name !== "a")
return;
const hrefAttr = node.attributes.find((attr) => attr.type === utils_1.AST_NODE_TYPES.JSXAttribute &&
attr.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
attr.name.name === "href");
if (!(hrefAttr === null || hrefAttr === void 0 ? void 0 : hrefAttr.value) ||
hrefAttr.value.type !== utils_1.AST_NODE_TYPES.JSXExpressionContainer) {
console.warn("⚠️ `href` does not contain an expression, skipping.");
return;
}
const expression = hrefAttr.value.expression;
if (expression.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
console.warn("⚠️ `href` is not a MemberExpression, skipping:", context.getSourceCode().getText(expression));
return;
}
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(expression.object);
if (!tsNode) {
console.warn("⚠️ TypeScript Node not found.");
return;
}
const type = getType(tsNode, checker);
if (isLinkField(type)) {
let fieldName = expression;
while (fieldName.type === utils_1.AST_NODE_TYPES.MemberExpression) {
if (fieldName.property.type === utils_1.AST_NODE_TYPES.Identifier &&
(fieldName.property.name === "value" ||
fieldName.property.name === "href")) {
fieldName = fieldName.object;
}
else {
break;
}
}
const fieldNameText = context.getSourceCode().getText(fieldName);
const parentElement = node.parent;
context.report({
node,
messageId: "useLinkComponent",
data: { fieldName: fieldNameText },
fix(fixer) {
return fixer.replaceText(parentElement, `<Link field={${fieldNameText}} />`);
},
});
}
},
};
},
};
//# sourceMappingURL=enforce-link-component.js.map