@lexical/eslint-plugin 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ /**
10
+ * LexicalEslintPlugin
11
+ */
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import * as modDev from './LexicalEslintPlugin.dev.mjs';
10
+ import * as modProd from './LexicalEslintPlugin.prod.mjs';
11
+ const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
12
+ export default mod.default;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ const mod = await (process.env.NODE_ENV === 'development' ? import('./LexicalEslintPlugin.dev.mjs') : import('./LexicalEslintPlugin.prod.mjs'));
10
+ export default mod.default;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ 'use strict';var l={},n={},p={getParentAssignmentName:function(a){let c=a.parent;if("VariableDeclarator"===c.type&&c.init===a)return c.id;if("AssignmentExpression"===c.type&&c.right===a&&"="===c.operator)return c.left}};let {getParentAssignmentName:r}=p;n.getFunctionName=function(a){if("FunctionDeclaration"===a.type||"FunctionExpression"===a.type&&a.id)return a.id;if("FunctionExpression"===a.type||"ArrowFunctionExpression"===a.type)return r(a)};
10
+ let {getFunctionName:t}=n,{getParentAssignmentName:z}=p,{buildMatcher:A}={buildMatcher:function(...a){let c=[],e=[];for(let b of a.flat(1))b&&("string"===typeof b?e.push(/^[(^]/.test(b)?b:`^${b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}$`):b&&b instanceof RegExp?b.flags?c.push(h=>b.test(h)):e.push(b.source):"function"===typeof b&&c.push(b));if(a=e.map(b=>`(?:${b})`).join("|")){let b=new RegExp(a);c.push(h=>b.test(h))}return b=>{if(b){if("Identifier"!==b.type)throw Error(`Expecting Identifier, not ${b.type}`);
11
+ for(let h of c)if(h(b.name,b))return!0}return!1}}};function B(a,c){a=a.scopeManager;for(let b=c;b;b=b.parent){var e=a.getDeclaredVariables(b).find(h=>h.identifiers.includes(c));if(e)return e;if(e=a.acquire(b))return e.set.get(c.name)||(e.upper?e.upper.set.get(c.name):void 0)}}let C={isDollarFunction:[/^\$[a-z_]/],isIgnoredFunction:[],isLexicalProvider:["parseEditorState","read","registerCommand","registerNodeTransform","update"],isSafeDollarFunction:[/^\$is[A-Z_]/]};
12
+ function D(a){let c={};for(let u in C){var e=u,b=e,h=C[e],g=a;g=Array.isArray(g.options)?g.options[0]:void 0;c[b]=A(h,g&&e in g?g[e]:void 0)}return c}function E(a){if(a){if("Identifier"===a.type)return a;if("MemberExpression"===a.type&&!a.computed)return E(a.property)}}function L(a,c){a=a.name;a=/^[a-z]/.test(a)?"$"+a:/^[A-Z][a-z]/.test(a)?"$"+a.slice(0,1).toLowerCase()+a.slice(1):`$_${a}`;if(c)for(c=c.scope;c;c=c.upper)if(c.set.has(a))return a+"_";return a}
13
+ function M(a){if(a&&1===a.defs.length){[{node:a}]=a.defs;if("ExportNamedDeclaration"===a.parent.type)return a.parent;if("VariableDeclaration"===a.parent.type&&"ExportNamedDeclaration"===a.parent.parent.type)return a.parent.parent}}function N({caller:a,suggestName:c}){return`\n/** @deprecated renamed to {@link ${c}} by @lexical/eslint-plugin rules-of-lexical */\nexport const ${a} = ${c};`}let O={oneOf:[{type:"string"},{contains:{type:"string"},type:"array"}]};
14
+ l.rulesOfLexical={create(a){let c=a.getSourceCode(),e=D(a),b=new Set,h=new Set,g=[],u=()=>{if(0<b.size)return!0;const d=g[g.length-1];return d&&"Property"===d.node.parent.type},F=d=>b.delete(d),v=d=>{a:{var f=t(d);if(!f){f=d.parent;if("CallExpression"===f.type&&f.arguments[0]===d){let k=E(f.callee);if(k&&"Identifier"===k.type&&/^use([A-Z]|$)/.test(k.name)){f=z(f);break a}}f=void 0}}f=E(f);g.push({name:f,node:d});(e.isDollarFunction(f)||e.isIgnoredFunction(f)||e.isLexicalProvider(f))&&b.add(d)},w=
15
+ d=>{g.pop();b.delete(d)},W=()=>{const d=g[g.length-1];return d?d.name:void 0};return{ArrowFunctionExpression:v,"ArrowFunctionExpression:exit":w,CallExpression:d=>{if(!u()){var f=E(d.callee);if(e.isLexicalProvider(f)||e.isSafeDollarFunction(f))b.add(d);else if(e.isDollarFunction(f)){var k=W();if(k&&!h.has(k)){h.add(k);var q=B(c,k),G=L(k,q),H=M(q),x={callee:c.getText(d.callee),caller:c.getText(k),suggestName:G};d=I=>{const J=new Set,y=[],K=m=>{J.has(m)||(J.add(m),y.push(I.replaceText(m,G)))};K(k);H&&
16
+ y.push(I.insertTextAfter(H,N(x)));if(q)for(const m of q.references)K(m.identifier);return y};a.report({data:x,fix:d,messageId:"rulesOfLexicalReport",node:k,suggest:[{data:x,fix:d,messageId:"rulesOfLexicalSuggestion"}]})}}}},"CallExpression:exit":F,ClassBody:d=>b.add(d),"ClassBody:exit":F,FunctionDeclaration:v,"FunctionDeclaration:exit":w,FunctionExpression:v,"FunctionExpression:exit":w}},meta:{docs:{description:"enforces the Rules of Lexical",recommended:!0,url:"https://lexical.dev/docs/packages/lexical-eslint-plugin"},
17
+ fixable:"code",hasSuggestions:!0,messages:{rulesOfLexicalReport:"{{ callee }} called from {{ caller }}, without $ prefix or read/update context",rulesOfLexicalSuggestion:"Rename {{ caller }} to {{ suggestName }}"},schema:[{additionalProperties:!1,properties:{isDollarFunction:O,isIgnoredFunction:O,isLexicalProvider:O,isSafeDollarFunction:O},type:"object"}],type:"suggestion"}};
18
+ let {name:P,version:Q}={name:"@lexical/eslint-plugin",description:"Lexical specific linting rules for ESLint",keywords:["eslint","eslint-plugin","eslintplugin","lexical","editor"],version:"0.15.0",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:!1,
19
+ 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"},module:"LexicalEslintPlugin.mjs"},{rulesOfLexical:R}=
20
+ l,S={plugins:["@lexical"],rules:{"@lexical/rules-of-lexical":"warn"}};for(var T={configs:{all:S,recommended:S},meta:{name:P,version:Q},rules:{"rules-of-lexical":R}},U={__proto__:null,default:T&&T.__esModule&&Object.prototype.hasOwnProperty.call(T,"default")?T["default"]:T},V=[T],X=0;X<V.length;X++){var Y=V[X];if("string"!==typeof Y&&!Array.isArray(Y))for(var Z in Y)"default"===Z||Z in U||(U[Z]=Y[Z])}module.exports=U
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];if("string"!=typeof i&&!Array.isArray(i))for(var r in i)"default"===r||r in e||(e[r]=i[r])}return e}function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var n={name:"@lexical/eslint-plugin",description:"Lexical specific linting rules for ESLint",keywords:["eslint","eslint-plugin","eslintplugin","lexical","editor"],version:"0.15.0",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:!1,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"},module:"LexicalEslintPlugin.mjs"},i={},r={},s={getParentAssignmentName:function(e){const t=e.parent;return"VariableDeclarator"===t.type&&t.init===e?t.id:"AssignmentExpression"===t.type&&t.right===e&&"="===t.operator?t.left:void 0}};const{getParentAssignmentName:o}=s;r.getFunctionName=function(e){return"FunctionDeclaration"===e.type||"FunctionExpression"===e.type&&e.id?e.id:"FunctionExpression"===e.type||"ArrowFunctionExpression"===e.type?o(e):void 0};var a={};a.buildMatcher=function(...e){const t=[],n=[];for(const r of e.flat(1))r&&("string"==typeof r?n.push(/^[(^]/.test(r)?r:`^${i=r,i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}$`):r&&r instanceof RegExp?r.flags?t.push((e=>r.test(e))):n.push(r.source):"function"==typeof r&&t.push(r));var i;const r=n.map((e=>`(?:${e})`)).join("|");if(r){const e=new RegExp(r);t.push((t=>e.test(t)))}return e=>{if(e){if("Identifier"!==e.type)throw new Error(`Expecting Identifier, not ${e.type}`);for(const n of t)if(n(e.name,e))return!0}return!1}};const{getFunctionName:l}=r,{getParentAssignmentName:c}=s,{buildMatcher:u}=a;const p={isDollarFunction:[/^\$[a-z_]/],isIgnoredFunction:[],isLexicalProvider:["parseEditorState","read","registerCommand","registerNodeTransform","update"],isSafeDollarFunction:[/^\$is[A-Z_]/]};function d(e){if(e)return"Identifier"===e.type?e:"MemberExpression"!==e.type||e.computed?void 0:d(e.property)}function f(e,t){const n=Array.isArray(e.options)?e.options[0]:void 0;return n&&t in n?n[t]:void 0}const g={oneOf:[{type:"string"},{contains:{type:"string"},type:"array"}]};i.rulesOfLexical={create(e){const t=function(e){return e.getSourceCode()}(e),n=function(e){const t={};for(const n in p){const i=n;t[i]=u(p[i],f(e,i))}return t}(e),i=new Set,r=new Set,s=[],o=e=>i.add(e),a=e=>i.delete(e),g=e=>{const t=d(function(e){const t=l(e);if(t)return t;const n=e.parent;if("CallExpression"===n.type&&n.arguments[0]===e&&function(e){return e&&"Identifier"===e.type&&/^use([A-Z]|$)/.test(e.name)}(d(n.callee)))return c(n)}(e));s.push({name:t,node:e}),(n.isDollarFunction(t)||n.isIgnoredFunction(t)||n.isLexicalProvider(t))&&o(e)},x=e=>{s.pop(),a(e)};return{ArrowFunctionExpression:g,"ArrowFunctionExpression:exit":x,CallExpression:a=>{if((()=>{if(i.size>0)return!0;const e=s[s.length-1];return e&&"Property"===e.node.parent.type})())return;const l=d(a.callee);if(n.isLexicalProvider(l)||n.isSafeDollarFunction(l))return void o(a);if(!n.isDollarFunction(l))return;const c=(e=>{const t=s[s.length-1];return t?t.name:void 0})();if(!c||r.has(c))return;r.add(c);const u=function(e,t){const n=e.scopeManager;for(let e=t;e;e=e.parent){const i=n.getDeclaredVariables(e).find((e=>e.identifiers.includes(t)));if(i)return i;const r=n.acquire(e);if(r)return r.set.get(t.name)||(r.upper?r.upper.set.get(t.name):void 0)}}(t,c),p=function(e,t){const n=function(e){return/^[a-z]/.test(e)?"$"+e:/^[A-Z][a-z]/.test(e)?"$"+e.slice(0,1).toLowerCase()+e.slice(1):`$_${e}`}(e.name);if(t)for(let e=t.scope;e;e=e.upper)if(e.set.has(n))return n+"_";return n}(c,u),f=function(e){if(e&&1===e.defs.length){const[{node:t}]=e.defs;if("ExportNamedDeclaration"===t.parent.type)return t.parent;if("VariableDeclaration"===t.parent.type&&"ExportNamedDeclaration"===t.parent.parent.type)return t.parent.parent}}(u),g={callee:t.getText(a.callee),caller:t.getText(c),suggestName:p},x=e=>{const t=new Set,n=[],i=i=>{t.has(i)||(t.add(i),n.push(e.replaceText(i,p)))};if(i(c),f&&n.push(e.insertTextAfter(f,function({caller:e,suggestName:t}){return`\n/** @deprecated renamed to {@link ${t}} by @lexical/eslint-plugin rules-of-lexical */\nexport const ${e} = ${t};`}(g))),u)for(const e of u.references)i(e.identifier);return n};e.report({data:g,fix:x,messageId:"rulesOfLexicalReport",node:c,suggest:[{data:g,fix:x,messageId:"rulesOfLexicalSuggestion"}]})},"CallExpression:exit":a,ClassBody:o,"ClassBody:exit":a,FunctionDeclaration:g,"FunctionDeclaration:exit":x,FunctionExpression:g,"FunctionExpression:exit":x}},meta:{docs:{description:"enforces the Rules of Lexical",recommended:!0,url:"https://lexical.dev/docs/packages/lexical-eslint-plugin"},fixable:"code",hasSuggestions:!0,messages:{rulesOfLexicalReport:"{{ callee }} called from {{ caller }}, without $ prefix or read/update context",rulesOfLexicalSuggestion:"Rename {{ caller }} to {{ suggestName }}"},schema:[{additionalProperties:!1,properties:{isDollarFunction:g,isIgnoredFunction:g,isLexicalProvider:g,isSafeDollarFunction:g},type:"object"}],type:"suggestion"}};const{name:x,version:m}=n,{rulesOfLexical:y}=i,h={plugins:["@lexical"],rules:{"@lexical/rules-of-lexical":"warn"}};var E={configs:{all:h,recommended:h},meta:{name:x,version:m},rules:{"rules-of-lexical":y}},v=e({__proto__:null,default:t(E)},[E]);export{v as default};
package/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # `@lexical/eslint-plugin`
2
+
3
+ This ESLint plugin enforces the [Lexical $function convention](https://lexical.dev/docs/intro#reading-and-updating-editor-state).
4
+
5
+ ## Installation
6
+
7
+ Assuming you already have ESLint installed, run:
8
+
9
+ ```sh
10
+ npm install @lexical/eslint-plugin --save-dev
11
+ ```
12
+
13
+ Then extend the recommended eslint config:
14
+
15
+ ```js
16
+ {
17
+ "extends": [
18
+ // ...
19
+ "plugin:@lexical/recommended"
20
+ ]
21
+ }
22
+ ```
23
+
24
+ ### Custom Configuration
25
+
26
+ If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:
27
+
28
+ ```js
29
+ {
30
+ "plugins": [
31
+ // ...
32
+ "@lexical"
33
+ ],
34
+ "rules": {
35
+ // ...
36
+ "@lexical/rules-of-lexical": "error"
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### Advanced configuration
42
+
43
+ Most of the heuristics in `@lexical/rules-of-lexical` can be extended with
44
+ additional terms or patterns.
45
+
46
+ The code example below is shown using the default implementations for each
47
+ option. When you configure these they are combined with the default
48
+ implementations using "OR", the default implementations can not be overridden.
49
+ These terms and patterns are only shown for reference and pasting this example
50
+ into your project is not useful.
51
+
52
+ If the string begins with a `"^"` or `"("` then it is treated as a RegExp,
53
+ otherwise it will be an exact match. A string may also be used instead
54
+ of an array of strings.
55
+
56
+ ```js
57
+ {
58
+ "plugins": [
59
+ // ...
60
+ "@lexical"
61
+ ],
62
+ "rules": {
63
+ // ...
64
+ "@lexical/rules-of-lexical": [
65
+ "error",
66
+ {
67
+ "isDollarFunction": ["^\\$[a-z_]"],
68
+ "isIgnoredFunction": [],
69
+ "isLexicalProvider": [
70
+ "parseEditorState",
71
+ "read",
72
+ "registerCommand",
73
+ "registerNodeTransform",
74
+ "update"
75
+ ],
76
+ "isSafeDollarFunction": ["^\\$is"]
77
+ }
78
+ ]
79
+ }
80
+ }
81
+ ```
82
+
83
+ #### `isDollarFunction`
84
+
85
+ *Base case*: `/^\$[a-z_]/`
86
+
87
+ This defines the \$function convention, which by default is any function that
88
+ starts with a dollar sign followed by a lowercase latin letter. You may have a
89
+ secondary convention in your codebase, such as non-latin letters, or an
90
+ internal prefix that you want to consider (e.g. `"^INTERNAL_\\$"`).
91
+
92
+ #### `isIgnoredFunction`
93
+
94
+ *Base case*: None
95
+
96
+ Functions that match these patterns are ignored from analysis, they may call
97
+ Lexical \$functions but are not considered to be a dollar function themselves.
98
+
99
+ #### `isLexicalProvider`
100
+
101
+ *Base case*: `/^(parseEditorState|read|registerCommand|registerNodeTransform|update)$/`
102
+
103
+ These are functions that allow their function argument to use Lexical
104
+ \$functions.
105
+
106
+ #### `isSafeDollarFunction`
107
+
108
+ *Base case*: `/^\$is/`
109
+
110
+ These \$functions are considered safe to call from anywhere, generally
111
+ these functions are runtime type checks that do not depend on any other
112
+ state.
113
+
114
+ ## Valid and Invalid Examples
115
+
116
+ ### Valid Examples
117
+
118
+ \$functions may be called by other \$functions
119
+
120
+ ```js
121
+ function $namedCorrectly() {
122
+ return $getRoot();
123
+ }
124
+ ```
125
+
126
+ \$functions may be called in functions defined when calling the following
127
+ methods (the heuristic only considers the method name):
128
+
129
+ * `editor.update`
130
+ * `editorState.read`
131
+ * `editor.registerCommand`
132
+ * `editor.registerNodeTransform`
133
+
134
+ ```js
135
+ function validUsesEditorOrState(editor) {
136
+ editor.update(() => $getRoot());
137
+ editor.getLatestState().read(() => $getRoot());
138
+ }
139
+ ```
140
+
141
+ \$functions may be called from class methods
142
+
143
+ ```js
144
+ class CustomNode extends ElementNode {
145
+ appendText(string) {
146
+ this.appendChild($createTextNode(string));
147
+ }
148
+ }
149
+ ```
150
+
151
+ ### Invalid Examples
152
+
153
+ #### Rename autofix
154
+
155
+ ```js
156
+ function invalidFunction() {
157
+ return $getRoot();
158
+ }
159
+ function $callsInvalidFunction() {
160
+ return invalidFunction();
161
+ }
162
+ ```
163
+
164
+ *Autofix:* The function is renamed with a $ prefix. Any references to this
165
+ name in this module are also always renamed.
166
+
167
+ ```js
168
+ function $invalidFunction() {
169
+ return $getRoot();
170
+ }
171
+ function $callsInvalidFunction() {
172
+ return $invalidFunction();
173
+ }
174
+ ```
175
+
176
+ #### Rename & deprecate autofix
177
+
178
+ ```js
179
+ export function exportedInvalidFunction() {
180
+ return $getRoot();
181
+ }
182
+ ```
183
+
184
+ *Autofix:* The exported function is renamed with a $ prefix. The previous name
185
+ is also exported and marked deprecated, because automatic renaming of
186
+ references to that name is limited to the module's scope.
187
+
188
+ ```js
189
+ export function $exportedInvalidFunction() {
190
+ return $getRoot();
191
+ }
192
+ /** @deprecated renamed to {@link $exportedInvalidFunction} by @lexical/eslint-plugin rules-of-lexical */
193
+ export const exportedInvalidFunction = $exportedInvalidFunction;
194
+ ```
195
+
196
+ #### Rename scope conflict
197
+
198
+ ```js
199
+ import {$getRoot} from 'lexical';
200
+ function InvalidComponent() {
201
+ const [editor] = useLexicalComposerContext();
202
+ const getRoot = useCallback(() => $getRoot(), []);
203
+ return (<button onClick={() => editor.update(() => getRoot())} />);
204
+ }
205
+ ```
206
+
207
+ *Autofix:* The function is renamed with a $ prefix and _ suffix since the suggested name was already in scope.
208
+
209
+ ```js
210
+ import {$getRoot} from 'lexical';
211
+ function InvalidComponent() {
212
+ const [editor] = useLexicalComposerContext();
213
+ const $getRoot_ = useCallback(() => $getRoot(), []);
214
+ return (<button onClick={() => editor.update(() => $getRoot_())} />);
215
+ }
216
+ ```
package/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ /**
9
+ * For bootstrapping reasons, this module is written in CJS JavaScript so no
10
+ * compilation is necessary
11
+ */
12
+ import * as plugin from './LexicalEslintPlugin.js';
13
+ export type { RulesOfLexicalOptions } from './rules/rules-of-lexical.js';
14
+ export default plugin;
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@lexical/eslint-plugin",
3
+ "description": "Lexical specific linting rules for ESLint",
4
+ "keywords": [
5
+ "eslint",
6
+ "eslint-plugin",
7
+ "eslintplugin",
8
+ "lexical",
9
+ "editor"
10
+ ],
11
+ "version": "0.15.0",
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/facebook/lexical.git",
16
+ "directory": "packages/lexical-eslint-plugin"
17
+ },
18
+ "main": "LexicalEslintPlugin.js",
19
+ "types": "index.d.ts",
20
+ "bugs": {
21
+ "url": "https://github.com/facebook/lexical/issues"
22
+ },
23
+ "homepage": "https://lexical.dev/docs/packages/lexical-eslint-plugin",
24
+ "sideEffects": false,
25
+ "peerDependencies": {
26
+ "eslint": ">=7.31.0 || ^8.0.0"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "import": {
31
+ "types": "./index.d.ts",
32
+ "development": "./LexicalEslintPlugin.dev.mjs",
33
+ "production": "./LexicalEslintPlugin.prod.mjs",
34
+ "node": "./LexicalEslintPlugin.node.mjs",
35
+ "default": "./LexicalEslintPlugin.mjs"
36
+ },
37
+ "require": {
38
+ "types": "./index.d.ts",
39
+ "development": "./LexicalEslintPlugin.dev.js",
40
+ "production": "./LexicalEslintPlugin.prod.js",
41
+ "default": "./LexicalEslintPlugin.js"
42
+ }
43
+ }
44
+ },
45
+ "devDependencies": {
46
+ "@types/eslint": "^8.56.9"
47
+ },
48
+ "module": "LexicalEslintPlugin.mjs"
49
+ }
@@ -0,0 +1,52 @@
1
+ export const rulesOfLexical: RuleModule;
2
+ export type NodeParentExtension = import('eslint').Rule.NodeParentExtension;
3
+ export type CallExpression = import('estree').CallExpression & NodeParentExtension;
4
+ export type Identifier = import('estree').Identifier & NodeParentExtension;
5
+ export type RuleContext = import('eslint').Rule.RuleContext;
6
+ export type Fix = import('eslint').Rule.Fix;
7
+ export type Node = import('eslint').Rule.Node;
8
+ export type RuleModule = import('eslint').Rule.RuleModule;
9
+ export type ReportFixer = import('eslint').Rule.ReportFixer;
10
+ export type SourceCode = import('eslint').SourceCode;
11
+ export type Variable = import('eslint').Scope.Variable;
12
+ export type Scope = import('eslint').Scope.Scope;
13
+ export type RulesOfLexicalOptions = Partial<BaseMatchers<ToMatcher | ToMatcher[]>>;
14
+ export type Matchers = BaseMatchers<IdentifierMatcher>;
15
+ export type ToMatcher = import('../util/buildMatcher.js').ToMatcher;
16
+ export type IdentifierMatcher = import('../util/buildMatcher.js').IdentifierMatcher;
17
+ /**
18
+ * <T>
19
+ */
20
+ export type BaseMatchers<T> = {
21
+ /**
22
+ * Catch all identifiers that begin with '$' or 'INTERNAL_$' followed by a lowercase Latin character or underscore
23
+ */
24
+ isDollarFunction: T;
25
+ /**
26
+ * These functions may call any $functions even though they do not have the isDollarFunction naming convention
27
+ */
28
+ isIgnoredFunction: T;
29
+ /**
30
+ * Certain calls through the editor or editorState allow for implicit access to call $functions: read, registerCommand, registerNodeTransform, update.
31
+ */
32
+ isLexicalProvider: T;
33
+ /**
34
+ * It's usually safe to call $isNode functions, so any '$is' or 'INTERNAL_$is' function may be called in any context.
35
+ */
36
+ isSafeDollarFunction: T;
37
+ };
38
+ /**
39
+ * @typedef {import('../util/buildMatcher.js').ToMatcher} ToMatcher
40
+ * @typedef {import('../util/buildMatcher.js').IdentifierMatcher} IdentifierMatcher
41
+ */
42
+ /**
43
+ * @template T
44
+ * @typedef {Object} BaseMatchers<T>
45
+ * @property {T} isDollarFunction Catch all identifiers that begin with '$' or 'INTERNAL_$' followed by a lowercase Latin character or underscore
46
+ * @property {T} isIgnoredFunction These functions may call any $functions even though they do not have the isDollarFunction naming convention
47
+ * @property {T} isLexicalProvider Certain calls through the editor or editorState allow for implicit access to call $functions: read, registerCommand, registerNodeTransform, update.
48
+ * @property {T} isSafeDollarFunction It's usually safe to call $isNode functions, so any '$is' or 'INTERNAL_$is' function may be called in any context.
49
+ */
50
+ /** @type {BaseMatchers<Exclude<ToMatcher, undefined>[]>} */
51
+ declare const BaseMatchers: BaseMatchers<Exclude<ToMatcher, undefined>[]>;
52
+ export {};
@@ -0,0 +1,6 @@
1
+ export function buildMatcher(...toMatchers: any[]): IdentifierMatcher;
2
+ export type Node = import('estree').Node;
3
+ export type Identifier = import('estree').Identifier;
4
+ export type NameIdentifierMatcher = (name: string, node: Identifier) => boolean;
5
+ export type ToMatcher = NameIdentifierMatcher | string | RegExp | undefined;
6
+ export type IdentifierMatcher = (node: Identifier | undefined) => boolean;
@@ -0,0 +1 @@
1
+ export function getFunctionName(node: import('eslint').Rule.Node): any;
@@ -0,0 +1 @@
1
+ export function getParentAssignmentName(node: import('eslint').Rule.Node): import("estree").Pattern | undefined;