74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
import type { Rule } from "eslint";
|
|
|
|
export const noReactNamespaceImport: Rule.RuleModule = {
|
|
meta: {
|
|
type: "suggestion",
|
|
docs: {
|
|
description: "Require named imports from React",
|
|
},
|
|
messages: {
|
|
namespaceImport:
|
|
"Import only the React exports used by this module instead of using a namespace import.",
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
ImportDeclaration(node) {
|
|
if (
|
|
node.source.value === "react" &&
|
|
node.specifiers.some(
|
|
(specifier) => specifier.type === "ImportNamespaceSpecifier",
|
|
)
|
|
) {
|
|
context.report({ node, messageId: "namespaceImport" });
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
function isPropertyNamed(
|
|
member: {
|
|
computed: boolean;
|
|
property: { type: string; name?: string; value?: unknown };
|
|
},
|
|
name: string,
|
|
): boolean {
|
|
return member.computed
|
|
? member.property.type === "Literal" && member.property.value === name
|
|
: member.property.type === "Identifier" && member.property.name === name;
|
|
}
|
|
|
|
export const noWindowLocationReload: Rule.RuleModule = {
|
|
meta: {
|
|
type: "problem",
|
|
docs: {
|
|
description: "Disallow reloads that bypass TanStack Router",
|
|
},
|
|
messages: {
|
|
reload:
|
|
"Do not use window.location.reload(); use TanStack Router navigation instead.",
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
CallExpression(node) {
|
|
const callee = node.callee;
|
|
if (
|
|
callee.type !== "MemberExpression" ||
|
|
!isPropertyNamed(callee, "reload") ||
|
|
callee.object.type !== "MemberExpression" ||
|
|
!isPropertyNamed(callee.object, "location") ||
|
|
callee.object.object.type !== "Identifier" ||
|
|
callee.object.object.name !== "window"
|
|
) {
|
|
return;
|
|
}
|
|
|
|
context.report({ node, messageId: "reload" });
|
|
},
|
|
};
|
|
},
|
|
};
|