{"_id":"@ekz/lexical-eslint-plugin","_rev":"2-672c66786b52a6c26b3fad5ee0c31f27","name":"@ekz/lexical-eslint-plugin","dist-tags":{"latest":"0.40.1"},"versions":{"0.40.0":{"name":"@ekz/lexical-eslint-plugin","version":"0.40.0","keywords":["eslint","eslint-plugin","eslintplugin","lexical","editor"],"license":"MIT","_id":"@ekz/lexical-eslint-plugin@0.40.0","maintainers":[{"name":"ekz","email":"heitkotter@gmail.com"}],"homepage":"https://lexical.dev/docs/packages/lexical-eslint-plugin","bugs":{"url":"https://github.com/facebook/lexical/issues"},"dist":{"shasum":"927a84d12aa6743d099600dd2de5e130dee5f46d","tarball":"https://registry.npmjs.org/@ekz/lexical-eslint-plugin/-/lexical-eslint-plugin-0.40.0.tgz","fileCount":17,"integrity":"sha512-YOZlqcrQklv1fV7qYffELMf1vFtZ7xcxR2y/1REAcOPGQFfY0r1N6/FYkbZ4K3AcwXx3unpxfQH+STdnw4XpGg==","signatures":[{"sig":"MEUCIQCWTX8avz2KHbI/WGvtBg9KToQ9hH3lGBenbXq30E7K/wIgQ9pCpBFtCu5FOYC6u7A4jt/CrgCgg/JL5IDRNk3Z1Jo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61902},"main":"LexicalEslintPlugin.js","_from":"file:ekz-lexical-eslint-plugin-0.40.0.tgz","types":"index.d.ts","module":"LexicalEslintPlugin.mjs","exports":{".":{"import":{"node":"./LexicalEslintPlugin.node.mjs","types":"./index.d.ts","default":"./LexicalEslintPlugin.mjs","production":"./LexicalEslintPlugin.prod.mjs","development":"./LexicalEslintPlugin.dev.mjs"},"require":{"types":"./index.d.ts","default":"./LexicalEslintPlugin.js","production":"./LexicalEslintPlugin.prod.js","development":"./LexicalEslintPlugin.dev.js"}}},"_npmUser":{"name":"ekz","email":"heitkotter@gmail.com"},"_resolved":"/private/var/folders/qc/q9g_dsy53kn1r210zcx4956w0000gr/T/75d2698a88e8824a1e042f16217ed4b8/ekz-lexical-eslint-plugin-0.40.0.tgz","_integrity":"sha512-YOZlqcrQklv1fV7qYffELMf1vFtZ7xcxR2y/1REAcOPGQFfY0r1N6/FYkbZ4K3AcwXx3unpxfQH+STdnw4XpGg==","repository":{"url":"git+https://github.com/facebook/lexical.git","type":"git","directory":"packages/lexical-eslint-plugin"},"_npmVersion":"10.9.4","description":"Lexical specific linting rules for ESLint","directories":{},"sideEffects":false,"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"devDependencies":{"@types/eslint":"^8.56.9","@types/estree":"^1.0.6"},"peerDependencies":{"eslint":">=7.31.0 || ^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lexical-eslint-plugin_0.40.0_1770732139566_0.9106577807810179","host":"s3://npm-registry-packages-npm-production"}},"0.40.1":{"name":"@ekz/lexical-eslint-plugin","description":"Lexical specific linting rules for ESLint","keywords":["eslint","eslint-plugin","eslintplugin","lexical","editor"],"version":"0.40.1","license":"MIT","repository":{"type":"git","url":"git+https://github.com/facebook/lexical.git","directory":"packages/lexical-eslint-plugin"},"main":"LexicalEslintPlugin.js","types":"index.d.ts","bugs":{"url":"https://github.com/facebook/lexical/issues"},"homepage":"https://lexical.dev/docs/packages/lexical-eslint-plugin","sideEffects":false,"peerDependencies":{"eslint":">=7.31.0 || ^8.0.0"},"exports":{".":{"import":{"types":"./index.d.ts","development":"./LexicalEslintPlugin.dev.mjs","production":"./LexicalEslintPlugin.prod.mjs","node":"./LexicalEslintPlugin.node.mjs","default":"./LexicalEslintPlugin.mjs"},"require":{"types":"./index.d.ts","development":"./LexicalEslintPlugin.dev.js","production":"./LexicalEslintPlugin.prod.js","default":"./LexicalEslintPlugin.js"}}},"devDependencies":{"@types/eslint":"^8.56.9","@types/estree":"^1.0.6"},"module":"LexicalEslintPlugin.mjs","_id":"@ekz/lexical-eslint-plugin@0.40.1","_integrity":"sha512-eplXIjWedsoJ4hg3ltF55zKX1wdcv6zsee836oSN59UqINGqJ4a0duYzB3JoLAHJuxQdZ3AePvQTJn1xOsdldw==","_resolved":"/private/var/folders/qc/q9g_dsy53kn1r210zcx4956w0000gr/T/cd1c0313137d9fa86817b45c1454430f/ekz-lexical-eslint-plugin-0.40.1.tgz","_from":"file:ekz-lexical-eslint-plugin-0.40.1.tgz","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-eplXIjWedsoJ4hg3ltF55zKX1wdcv6zsee836oSN59UqINGqJ4a0duYzB3JoLAHJuxQdZ3AePvQTJn1xOsdldw==","shasum":"6eb9787b6abfaae03fcc608de1aa826a19f83488","tarball":"https://registry.npmjs.org/@ekz/lexical-eslint-plugin/-/lexical-eslint-plugin-0.40.1.tgz","fileCount":17,"unpackedSize":61876,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGdnTiPg7FBEvX+s8osicTBczsOFGtcPxLxowWVXKcY9AiBTV1n1rDeSykI+cjK+Ttt+7dF+AjCyS9jM5HH89RyrsQ=="}]},"_npmUser":{"name":"ekz","email":"heitkotter@gmail.com"},"directories":{},"maintainers":[{"name":"ekz","email":"heitkotter@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lexical-eslint-plugin_0.40.1_1770805095067_0.6817074788127442"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-10T14:02:19.438Z","modified":"2026-02-11T10:18:15.313Z","0.40.0":"2026-02-10T14:02:19.719Z","0.40.1":"2026-02-11T10:18:15.209Z"},"bugs":{"url":"https://github.com/facebook/lexical/issues"},"license":"MIT","homepage":"https://lexical.dev/docs/packages/lexical-eslint-plugin","keywords":["eslint","eslint-plugin","eslintplugin","lexical","editor"],"repository":{"type":"git","url":"git+https://github.com/facebook/lexical.git","directory":"packages/lexical-eslint-plugin"},"description":"Lexical specific linting rules for ESLint","maintainers":[{"name":"ekz","email":"heitkotter@gmail.com"}],"readme":"# `@lexical/eslint-plugin`\n\nThis ESLint plugin enforces the [Lexical $function convention](https://lexical.dev/docs/intro#reading-and-updating-editor-state).\n\n## Installation\n\nAssuming you already have ESLint installed, run:\n\n```sh\nnpm install @lexical/eslint-plugin --save-dev\n```\n\nThen extend the recommended eslint config:\n\n```js\n{\n  \"extends\": [\n    // ...\n    \"plugin:@lexical/recommended\"\n  ]\n}\n```\n\n### Custom Configuration\n\nIf you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:\n\n```js\n{\n  \"plugins\": [\n    // ...\n    \"@lexical\"\n  ],\n  \"rules\": {\n    // ...\n    \"@ekz/lexical-rules-of-lexical\": \"error\"\n  }\n}\n```\n\n### Advanced configuration\n\nMost of the heuristics in `@lexical/rules-of-lexical` can be extended with\nadditional terms or patterns.\n\nThe code example below is shown using the default implementations for each\noption. When you configure these they are combined with the default\nimplementations using \"OR\", the default implementations can not be overridden.\nThese terms and patterns are only shown for reference and pasting this example\ninto your project is not useful.\n\nIf the string begins with a `\"^\"` or `\"(\"` then it is treated as a RegExp,\notherwise it will be an exact match. A string may also be used instead\nof an array of strings.\n\n```js\n{\n  \"plugins\": [\n    // ...\n    \"@lexical\"\n  ],\n  \"rules\": {\n    // ...\n    \"@ekz/lexical-rules-of-lexical\": [\n      \"error\",\n      {\n        \"isDollarFunction\": [\"^\\\\$[a-z_]\"],\n        \"isIgnoredFunction\": [],\n        \"isLexicalProvider\": [\n          \"parseEditorState\",\n          \"read\",\n          \"registerCommand\",\n          \"registerNodeTransform\",\n          \"update\"\n        ],\n        \"isSafeDollarFunction\": [\"^\\\\$is\"]\n      }\n    ]\n  }\n}\n```\n\n#### `isDollarFunction`\n\n*Base case*: `/^\\$[a-z_]/`\n\nThis defines the \\$function convention, which by default is any function that\nstarts with a dollar sign followed by a lowercase latin letter. You may have a\nsecondary convention in your codebase, such as non-latin letters, or an\ninternal prefix that you want to consider (e.g. `\"^INTERNAL_\\\\$\"`).\n\n#### `isIgnoredFunction`\n\n*Base case*: None\n\nFunctions that match these patterns are ignored from analysis, they may call\nLexical \\$functions but are not considered to be a dollar function themselves.\n\n#### `isLexicalProvider`\n\n*Base case*: `/^(parseEditorState|read|registerCommand|registerNodeTransform|update)$/`\n\nThese are functions that allow their function argument to use Lexical\n\\$functions.\n\n#### `isSafeDollarFunction`\n\n*Base case*: `/^\\$is/`\n\nThese \\$functions are considered safe to call from anywhere, generally\nthese functions are runtime type checks that do not depend on any other\nstate.\n\n## Valid and Invalid Examples\n\n### Valid Examples\n\n\\$functions may be called by other \\$functions\n\n```js\nfunction $namedCorrectly() {\n  return $getRoot();\n}\n```\n\n\\$functions may be called in functions defined when calling the following\nmethods (the heuristic only considers the method name):\n\n* `editor.update`\n* `editorState.read`\n* `editor.registerCommand`\n* `editor.registerNodeTransform`\n\n```js\nfunction validUsesEditorOrState(editor) {\n  editor.update(() => $getRoot());\n  editor.getLatestState().read(() => $getRoot());\n}\n```\n\n\\$functions may be called from class methods\n\n```js\nclass CustomNode extends ElementNode {\n  appendText(string) {\n    this.appendChild($createTextNode(string));\n  }\n}\n```\n\n### Invalid Examples\n\n#### Rename autofix\n\n```js\nfunction invalidFunction() {\n  return $getRoot();\n}\nfunction $callsInvalidFunction() {\n  return invalidFunction();\n}\n```\n\n*Autofix:* The function is renamed with a $ prefix. Any references to this\nname in this module are also always renamed.\n\n```js\nfunction $invalidFunction() {\n  return $getRoot();\n}\nfunction $callsInvalidFunction() {\n  return $invalidFunction();\n}\n```\n\n#### Rename & deprecate autofix\n\n```js\nexport function exportedInvalidFunction() {\n  return $getRoot();\n}\n```\n\n*Autofix:* The exported function is renamed with a $ prefix. The previous name\nis also exported and marked deprecated, because automatic renaming of\nreferences to that name is limited to the module's scope.\n\n```js\nexport function $exportedInvalidFunction() {\n  return $getRoot();\n}\n/** @deprecated renamed to {@link $exportedInvalidFunction} by @lexical/eslint-plugin rules-of-lexical */\nexport const exportedInvalidFunction = $exportedInvalidFunction;\n```\n\n#### Rename scope conflict\n\n```js\nimport {$getRoot} from '@ekz/lexical';\nfunction InvalidComponent() {\n  const [editor] = useLexicalComposerContext();\n  const getRoot = useCallback(() => $getRoot(), []);\n  return (<button onClick={() => editor.update(() => getRoot())} />);\n}\n```\n\n*Autofix:* The function is renamed with a $ prefix and _ suffix since the suggested name was already in scope.\n\n```js\nimport {$getRoot} from '@ekz/lexical';\nfunction InvalidComponent() {\n  const [editor] = useLexicalComposerContext();\n  const $getRoot_ = useCallback(() => $getRoot(), []);\n  return (<button onClick={() => editor.update(() => $getRoot_())} />);\n}\n```\n","readmeFilename":"README.md"}