UNPKG

eslint-plugin-solid

Version:
97 lines (91 loc) 3.6 kB
/** * FIXME: remove this comments and import when below issue is fixed. * This import is necessary for type generation due to a bug in the TypeScript compiler. * See: https://github.com/microsoft/TypeScript/issues/42873 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars import type { TSESLint } from "@typescript-eslint/utils"; import { TSESTree as T, ESLintUtils } from "@typescript-eslint/utils"; import { isFunctionNode, trackImports, isPropsByName, trace } from "../utils"; const createRule = ESLintUtils.RuleCreator.withoutDocs; export default createRule({ meta: { type: "problem", docs: { description: "Disallow usage of APIs that use ES6 Proxies, only to target environments that don't support them.", url: "https://github.com/solidjs-community/eslint-plugin-solid/blob/main/packages/eslint-plugin-solid/docs/no-proxy-apis.md", }, schema: [], messages: { noStore: "Solid Store APIs use Proxies, which are incompatible with your target environment.", spreadCall: "Using a function call in JSX spread makes Solid use Proxies, which are incompatible with your target environment.", spreadMember: "Using a property access in JSX spread makes Solid use Proxies, which are incompatible with your target environment.", proxyLiteral: "Proxies are incompatible with your target environment.", mergeProps: "If you pass a function to `mergeProps`, it will create a Proxy, which are incompatible with your target environment.", }, }, defaultOptions: [], create(context) { const { matchImport, handleImportDeclaration } = trackImports(); return { ImportDeclaration(node) { handleImportDeclaration(node); // track import aliases const source = node.source.value; if (source === "solid-js/store") { context.report({ node, messageId: "noStore", }); } }, "JSXSpreadAttribute MemberExpression"(node: T.MemberExpression) { context.report({ node, messageId: "spreadMember" }); }, "JSXSpreadAttribute CallExpression"(node: T.CallExpression) { context.report({ node, messageId: "spreadCall" }); }, CallExpression(node) { if (node.callee.type === "Identifier") { if (matchImport("mergeProps", node.callee.name)) { node.arguments .filter((arg) => { if (arg.type === "SpreadElement") return true; const traced = trace(arg, context); return ( (traced.type === "Identifier" && !isPropsByName(traced.name)) || isFunctionNode(traced) ); }) .forEach((badArg) => { context.report({ node: badArg, messageId: "mergeProps", }); }); } } else if (node.callee.type === "MemberExpression") { if ( node.callee.object.type === "Identifier" && node.callee.object.name === "Proxy" && node.callee.property.type === "Identifier" && node.callee.property.name === "revocable" ) { context.report({ node, messageId: "proxyLiteral", }); } } }, NewExpression(node) { if (node.callee.type === "Identifier" && node.callee.name === "Proxy") { context.report({ node, messageId: "proxyLiteral" }); } }, }; }, });