@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,699 @@
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';
10
+
11
+ function _mergeNamespaces(n, m) {
12
+ for (var i = 0; i < m.length; i++) {
13
+ var e = m[i];
14
+ if (typeof e !== 'string' && !Array.isArray(e)) { for (var k in e) {
15
+ if (k !== 'default' && !(k in n)) {
16
+ n[k] = e[k];
17
+ }
18
+ } }
19
+ }
20
+ return n;
21
+ }
22
+
23
+ function getDefaultExportFromCjs (x) {
24
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
25
+ }
26
+
27
+ var name$1 = "@lexical/eslint-plugin";
28
+ var description = "Lexical specific linting rules for ESLint";
29
+ var keywords = [
30
+ "eslint",
31
+ "eslint-plugin",
32
+ "eslintplugin",
33
+ "lexical",
34
+ "editor"
35
+ ];
36
+ var version$1 = "0.15.0";
37
+ var license = "MIT";
38
+ var repository = {
39
+ type: "git",
40
+ url: "git+https://github.com/facebook/lexical.git",
41
+ directory: "packages/lexical-eslint-plugin"
42
+ };
43
+ var main = "LexicalEslintPlugin.js";
44
+ var types = "index.d.ts";
45
+ var bugs = {
46
+ url: "https://github.com/facebook/lexical/issues"
47
+ };
48
+ var homepage = "https://lexical.dev/docs/packages/lexical-eslint-plugin";
49
+ var sideEffects = false;
50
+ var peerDependencies = {
51
+ eslint: ">=7.31.0 || ^8.0.0"
52
+ };
53
+ var exports$1 = {
54
+ ".": {
55
+ "import": {
56
+ types: "./index.d.ts",
57
+ development: "./LexicalEslintPlugin.dev.mjs",
58
+ production: "./LexicalEslintPlugin.prod.mjs",
59
+ node: "./LexicalEslintPlugin.node.mjs",
60
+ "default": "./LexicalEslintPlugin.mjs"
61
+ },
62
+ require: {
63
+ types: "./index.d.ts",
64
+ development: "./LexicalEslintPlugin.dev.js",
65
+ production: "./LexicalEslintPlugin.prod.js",
66
+ "default": "./LexicalEslintPlugin.js"
67
+ }
68
+ }
69
+ };
70
+ var devDependencies = {
71
+ "@types/eslint": "^8.56.9"
72
+ };
73
+ var module$1 = "LexicalEslintPlugin.mjs";
74
+ var require$$0 = {
75
+ name: name$1,
76
+ description: description,
77
+ keywords: keywords,
78
+ version: version$1,
79
+ license: license,
80
+ repository: repository,
81
+ main: main,
82
+ types: types,
83
+ bugs: bugs,
84
+ homepage: homepage,
85
+ sideEffects: sideEffects,
86
+ peerDependencies: peerDependencies,
87
+ exports: exports$1,
88
+ devDependencies: devDependencies,
89
+ module: module$1
90
+ };
91
+
92
+ var rulesOfLexical$1 = {};
93
+
94
+ var getFunctionName$1 = {};
95
+
96
+ var getParentAssignmentName$2 = {};
97
+
98
+ /**
99
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
100
+ *
101
+ * This source code is licensed under the MIT license found in the
102
+ * LICENSE file in the root directory of this source tree.
103
+ *
104
+ */
105
+
106
+ /**
107
+ * Gets the static name of an AST node's parent, used to determine the name of an
108
+ * anonymous function declaration, possibly through a higher order function call.
109
+ * This was extracted from the body of getFunctionName so it could also be used
110
+ * in the context of `useCallback` or `useMemo`, e.g.
111
+ * `const $fun = useCallback(() => {}, [])` where the name is not the direct
112
+ * parent of the anonymous function.
113
+ *
114
+ * @param {import('eslint').Rule.Node} node
115
+ */
116
+ getParentAssignmentName$2.getParentAssignmentName = function getParentAssignmentName(node) {
117
+ // Unlike React's rules of hooks, this does not check property assignment.
118
+ // The rules of lexical $function convention only applies to functions,
119
+ // not methods or properties.
120
+ const parentNode = node.parent;
121
+ if (parentNode.type === 'VariableDeclarator' && parentNode.init === node) {
122
+ // const $function = () => {};
123
+ return parentNode.id;
124
+ } else if (parentNode.type === 'AssignmentExpression' && parentNode.right === node && parentNode.operator === '=') {
125
+ // $function = () => {};
126
+ return parentNode.left;
127
+ } else {
128
+ return undefined;
129
+ }
130
+ };
131
+
132
+ /**
133
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
134
+ *
135
+ * This source code is licensed under the MIT license found in the
136
+ * LICENSE file in the root directory of this source tree.
137
+ *
138
+ */
139
+
140
+ // @ts-check
141
+
142
+ const {
143
+ getParentAssignmentName: getParentAssignmentName$1
144
+ } = getParentAssignmentName$2;
145
+
146
+ /**
147
+ * Gets the static name of a function AST node. For function declarations it is
148
+ * easy. For anonymous function expressions it is much harder. If you search for
149
+ * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
150
+ * where JS gives anonymous function expressions names. We roughly detect the
151
+ * same AST nodes with some exceptions to better fit our use case.
152
+ *
153
+ * @param {import('eslint').Rule.Node} node
154
+ */
155
+ getFunctionName$1.getFunctionName = function getFunctionName(node) {
156
+ if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' && node.id) {
157
+ // function $function() {}
158
+ // const whatever = function $function() {};
159
+ //
160
+ // Function declaration or function expression names win over any
161
+ // assignment statements or other renames.
162
+ return node.id;
163
+ } else if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
164
+ // This checks for assignments such as
165
+ // const $function = function () {};
166
+ // const $function = () => {};
167
+ return getParentAssignmentName$1(node);
168
+ } else {
169
+ return undefined;
170
+ }
171
+ };
172
+
173
+ var buildMatcher$1 = {};
174
+
175
+ /**
176
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
177
+ *
178
+ * This source code is licensed under the MIT license found in the
179
+ * LICENSE file in the root directory of this source tree.
180
+ *
181
+ */
182
+
183
+ /**
184
+ * @typedef {import('estree').Node} Node
185
+ * @typedef {import('estree').Identifier} Identifier
186
+ * @typedef {(name: string, node: Identifier) => boolean} NameIdentifierMatcher
187
+ * @typedef {NameIdentifierMatcher | string | RegExp | undefined} ToMatcher
188
+ * @typedef {(node: Identifier | undefined) => boolean} IdentifierMatcher
189
+ */
190
+
191
+ /**
192
+ * Escape a string for exact match in a RegExp
193
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions#escaping
194
+ *
195
+ * @param {string} string
196
+ * @returns {string}
197
+ */
198
+ function escapeRegExp(string) {
199
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
200
+ }
201
+
202
+ /**
203
+ * Build an Identifier Node Matcher from the given ToMatcher arguments.
204
+ * The Matcher is roughly equivalent to building RegExp from all of the
205
+ * sources and or-ing them together. String arguments are treated as
206
+ * RegExp sources and will be escaped with an implicit '^...$' wrapper
207
+ * unless it starts with a '(' or '^'
208
+ *
209
+ * @param {(ToMatcher | ToMatcher[])[]} args
210
+ * @returns {IdentifierMatcher}
211
+ */
212
+ buildMatcher$1.buildMatcher = function buildMatcher(...toMatchers) {
213
+ /** @type {Matcher[]} */
214
+ const matchFuns = [];
215
+ /** @type {string[]} */
216
+ const regExpSources = [];
217
+ for (const arg of toMatchers.flat(1)) {
218
+ if (!arg) {
219
+ continue;
220
+ } else if (typeof arg === 'string') {
221
+ regExpSources.push(/^[(^]/.test(arg) ? arg : `^${escapeRegExp(arg)}$`);
222
+ } else if (arg && arg instanceof RegExp) {
223
+ if (arg.flags) {
224
+ matchFuns.push(s => arg.test(s));
225
+ } else {
226
+ regExpSources.push(arg.source);
227
+ }
228
+ } else if (typeof arg === 'function') {
229
+ matchFuns.push(arg);
230
+ }
231
+ }
232
+ const pattern = regExpSources.map(s => `(?:${s})`).join('|');
233
+ if (pattern) {
234
+ const re = new RegExp(pattern);
235
+ matchFuns.push(s => re.test(s));
236
+ }
237
+ return node => {
238
+ if (node) {
239
+ if (node.type !== 'Identifier') {
240
+ // Runtime type invariant check
241
+ throw new Error(`Expecting Identifier, not ${node.type}`);
242
+ }
243
+ for (const matcher of matchFuns) {
244
+ if (matcher(node.name, node)) {
245
+ return true;
246
+ }
247
+ }
248
+ }
249
+ return false;
250
+ };
251
+ };
252
+
253
+ /**
254
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
255
+ *
256
+ * This source code is licensed under the MIT license found in the
257
+ * LICENSE file in the root directory of this source tree.
258
+ *
259
+ */
260
+
261
+ // @ts-check
262
+
263
+ const {
264
+ getFunctionName
265
+ } = getFunctionName$1;
266
+ const {
267
+ getParentAssignmentName
268
+ } = getParentAssignmentName$2;
269
+ const {
270
+ buildMatcher
271
+ } = buildMatcher$1;
272
+
273
+ /**
274
+ * @typedef {import('eslint').Rule.NodeParentExtension} NodeParentExtension
275
+ * @typedef {import('estree').CallExpression & NodeParentExtension} CallExpression
276
+ * @typedef {import('estree').Identifier & NodeParentExtension} Identifier
277
+ * @typedef {import('eslint').Rule.RuleContext} RuleContext
278
+ * @typedef {import('eslint').Rule.Fix} Fix
279
+ * @typedef {import('eslint').Rule.Node} Node
280
+ * @typedef {import('eslint').Rule.RuleModule} RuleModule
281
+ * @typedef {import('eslint').Rule.ReportFixer} ReportFixer
282
+ * @typedef {import('eslint').SourceCode} SourceCode
283
+ * @typedef {import('eslint').Scope.Variable} Variable
284
+ * @typedef {import('eslint').Scope.Scope} Scope
285
+ */
286
+
287
+ /**
288
+ * Find the variable associated with the given Identifier
289
+ *
290
+ * @param {SourceCode} sourceCode
291
+ * @param {Identifier} identifier
292
+ */
293
+ function getIdentifierVariable(sourceCode, identifier) {
294
+ const scopeManager = sourceCode.scopeManager;
295
+ for (let node = /** @type {Node | null} */identifier; node; node = /** @type {Node | null}*/node.parent) {
296
+ const variable = scopeManager.getDeclaredVariables(node).find(v => v.identifiers.includes(identifier));
297
+ if (variable) {
298
+ return variable;
299
+ }
300
+ const scope = scopeManager.acquire(node);
301
+ if (scope) {
302
+ return scope.set.get(identifier.name) || (scope.upper ? scope.upper.set.get(identifier.name) : undefined);
303
+ }
304
+ }
305
+ return undefined;
306
+ }
307
+
308
+ /**
309
+ * @typedef {import('../util/buildMatcher.js').ToMatcher} ToMatcher
310
+ * @typedef {import('../util/buildMatcher.js').IdentifierMatcher} IdentifierMatcher
311
+ */
312
+
313
+ /**
314
+ * @template T
315
+ * @typedef {Object} BaseMatchers<T>
316
+ * @property {T} isDollarFunction Catch all identifiers that begin with '$' or 'INTERNAL_$' followed by a lowercase Latin character or underscore
317
+ * @property {T} isIgnoredFunction These functions may call any $functions even though they do not have the isDollarFunction naming convention
318
+ * @property {T} isLexicalProvider Certain calls through the editor or editorState allow for implicit access to call $functions: read, registerCommand, registerNodeTransform, update.
319
+ * @property {T} isSafeDollarFunction It's usually safe to call $isNode functions, so any '$is' or 'INTERNAL_$is' function may be called in any context.
320
+ */
321
+
322
+ /** @type {BaseMatchers<Exclude<ToMatcher, undefined>[]>} */
323
+ const BaseMatchers = {
324
+ isDollarFunction: [/^\$[a-z_]/],
325
+ isIgnoredFunction: [],
326
+ isLexicalProvider: ['parseEditorState', 'read', 'registerCommand', 'registerNodeTransform', 'update'],
327
+ isSafeDollarFunction: [/^\$is[A-Z_]/]
328
+ };
329
+
330
+ /**
331
+ * @typedef {Partial<BaseMatchers<ToMatcher | ToMatcher[]>>} RulesOfLexicalOptions
332
+ * @typedef {BaseMatchers<IdentifierMatcher>} Matchers
333
+ */
334
+
335
+ /**
336
+ * @param {RuleContext} context
337
+ * @returns {Matchers}
338
+ */
339
+ function compileMatchers(context) {
340
+ const rval = /** @type {Matchers} */{};
341
+ for (const k_ in BaseMatchers) {
342
+ const k = /** @type {keyof Matchers} */k_;
343
+ rval[k] = buildMatcher(BaseMatchers[k], parseMatcherOption(context, k));
344
+ }
345
+ return rval;
346
+ }
347
+
348
+ /**
349
+ * Hook functions start with use followed by a capital latin letter.
350
+ *
351
+ * @param {Node | undefined} node
352
+ */
353
+ function isHookFunctionIdentifier(node) {
354
+ return node && node.type === 'Identifier' && /^use([A-Z]|$)/.test(node.name);
355
+ }
356
+
357
+ /**
358
+ * Return this node if is an Identifier, otherwise if it is a MemberExpression such as
359
+ * `editor.read` return the Identifier of its property ('read' in this case).
360
+ *
361
+ * @param {Node | undefined} node
362
+ * @returns {Identifier | undefined}
363
+ */
364
+ function getFunctionNameIdentifier(node) {
365
+ if (!node) {
366
+ return;
367
+ } else if (node.type === 'Identifier') {
368
+ return node;
369
+ } else if (node.type === 'MemberExpression' && !node.computed) {
370
+ return getFunctionNameIdentifier( /** @type {Node} */node.property);
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Get the function's name, or if it is defined with a hook
376
+ * (e.g. useMemo, useCallback), then get the name of the variable the result
377
+ * is assigned to.
378
+ *
379
+ * @param {Node} node
380
+ */
381
+ function getLexicalFunctionName(node) {
382
+ const name = getFunctionName(node);
383
+ if (name) {
384
+ return name;
385
+ }
386
+ const nodeParent = node.parent;
387
+ if (nodeParent.type === 'CallExpression' && nodeParent.arguments[0] === node) {
388
+ const parentName = getFunctionNameIdentifier( /** @type {Node} */nodeParent.callee);
389
+ if (isHookFunctionIdentifier(parentName)) {
390
+ return getParentAssignmentName(nodeParent);
391
+ }
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Return a name suitable for a suggestion.
397
+ * isDollarFunction(getFirstSuggestion(name)) should
398
+ * be true for any given name.
399
+ *
400
+ * @param {string} name
401
+ * @returns {string}
402
+ */
403
+ function getFirstSuggestion(name) {
404
+ if (/^[a-z]/.test(name)) {
405
+ return '$' + name;
406
+ } else if (/^[A-Z][a-z]/.test(name)) {
407
+ return '$' + name.slice(0, 1).toLowerCase() + name.slice(1);
408
+ } else {
409
+ return `$_${name}`;
410
+ }
411
+ }
412
+
413
+ /**
414
+ * Get the suggested name for a variable and add an underscore if it shadows
415
+ * or conflicts with an existing variable.
416
+ *
417
+ * @param {Identifier} nameIdentifier
418
+ * @param {Variable | undefined} variable
419
+ */
420
+ function getSuggestName(nameIdentifier, variable) {
421
+ const suggestName = getFirstSuggestion(nameIdentifier.name);
422
+ // Add an underscore if this would shadow an existing name
423
+ if (variable) {
424
+ for (let scope = /** @type {Scope | null} */variable.scope; scope; scope = scope.upper) {
425
+ if (scope.set.has(suggestName)) {
426
+ return suggestName + '_';
427
+ }
428
+ }
429
+ }
430
+ return suggestName;
431
+ }
432
+
433
+ /**
434
+ * Get the export declaration for a variable, if it has one.
435
+ *
436
+ * @param {Variable | undefined} variable
437
+ */
438
+ function getExportDeclaration(variable) {
439
+ if (variable && variable.defs.length === 1) {
440
+ const [{
441
+ node
442
+ }] = variable.defs;
443
+ if (node.parent.type === 'ExportNamedDeclaration') {
444
+ // export function foo();
445
+ return node.parent;
446
+ } else if (node.parent.type === 'VariableDeclaration' && node.parent.parent.type === 'ExportNamedDeclaration') {
447
+ // export const foo = () => {};
448
+ return node.parent.parent;
449
+ }
450
+ }
451
+ }
452
+
453
+ /**
454
+ * The comment we insert when an export is renamed.
455
+ *
456
+ * @param {Record<'caller'|'suggestName', string>} data
457
+ */
458
+ function renameExportText({
459
+ caller,
460
+ suggestName
461
+ }) {
462
+ return `\n/** @deprecated renamed to {@link ${suggestName}} by @lexical/eslint-plugin rules-of-lexical */\nexport const ${caller} = ${suggestName};`;
463
+ }
464
+
465
+ /**
466
+ * @param {RuleContext} context
467
+ * @param {string} optionName
468
+ * @returns {ToMatcher}
469
+ */
470
+ function parseMatcherOption(context, optionName) {
471
+ const options = Array.isArray(context.options) ? context.options[0] : undefined;
472
+ return options && optionName in options ? options[optionName] : undefined;
473
+ }
474
+
475
+ /** @param {RuleContext} context */
476
+ function getSourceCode(context) {
477
+ // Deprecated in 8.x but we are still on 7.x
478
+ return context.getSourceCode();
479
+ }
480
+ const matcherSchema = {
481
+ oneOf: [{
482
+ type: 'string'
483
+ }, {
484
+ contains: {
485
+ type: 'string'
486
+ },
487
+ type: 'array'
488
+ }]
489
+ };
490
+
491
+ /** @type {RuleModule} */
492
+ rulesOfLexical$1.rulesOfLexical = {
493
+ create(context) {
494
+ const sourceCode = getSourceCode(context);
495
+ const matchers = compileMatchers(context);
496
+
497
+ /**
498
+ * When this set is non-empty it means that we are visiting a node
499
+ * that should not be analyzed.
500
+ *
501
+ * @type {Set<Node>}
502
+ */
503
+ const ignoreSet = new Set();
504
+ /**
505
+ * The set of Identifier nodes that have been reported, we do not
506
+ * want to report the same node more than once (a function making several
507
+ * calls to $functions only needs to be renamed once!)
508
+ *
509
+ * @type {Set<Identifier>}
510
+ */
511
+ const reportedSet = new Set();
512
+ /**
513
+ * The current stack of functions
514
+ *
515
+ * @type {{ name?: Identifier, node: Node }[]} funStack
516
+ */
517
+ const funStack = [];
518
+ const shouldIgnore = () => {
519
+ if (ignoreSet.size > 0) {
520
+ return true;
521
+ }
522
+ // Ignore property assignments
523
+ const lastFunction = funStack[funStack.length - 1];
524
+ return lastFunction && lastFunction.node.parent.type === 'Property';
525
+ };
526
+ const pushIgnoredNode = ( /** @type {Node} */node) => ignoreSet.add(node);
527
+ const popIgnoredNode = ( /** @type {Node} */node) => ignoreSet.delete(node);
528
+ const pushFunction = ( /** @type {Node} */node) => {
529
+ const name = getFunctionNameIdentifier(getLexicalFunctionName(node));
530
+ funStack.push({
531
+ name,
532
+ node
533
+ });
534
+ if (matchers.isDollarFunction(name) || matchers.isIgnoredFunction(name) || matchers.isLexicalProvider(name)) {
535
+ pushIgnoredNode(node);
536
+ }
537
+ };
538
+ const popFunction = ( /** @type {Node} */node) => {
539
+ funStack.pop();
540
+ popIgnoredNode(node);
541
+ };
542
+ const getParentLexicalFunctionNameIdentifier = ( /** @type {Node} */_node) => {
543
+ const pair = funStack[funStack.length - 1];
544
+ return pair ? pair.name : undefined;
545
+ };
546
+ // Find all $function calls that are not inside a class or inside a $function
547
+ // by visiting all function definitions and calls
548
+ return {
549
+ ArrowFunctionExpression: pushFunction,
550
+ 'ArrowFunctionExpression:exit': popFunction,
551
+ CallExpression: node => {
552
+ if (shouldIgnore()) {
553
+ return;
554
+ }
555
+ const calleeName = getFunctionNameIdentifier( /** @type {Node} */node.callee);
556
+ if (matchers.isLexicalProvider(calleeName) || matchers.isSafeDollarFunction(calleeName)) {
557
+ pushIgnoredNode(node);
558
+ return;
559
+ }
560
+ if (!matchers.isDollarFunction(calleeName)) {
561
+ return;
562
+ }
563
+ const nameIdentifier = getParentLexicalFunctionNameIdentifier();
564
+ if (!nameIdentifier || reportedSet.has(nameIdentifier)) {
565
+ return;
566
+ }
567
+ reportedSet.add(nameIdentifier);
568
+ const variable = getIdentifierVariable(sourceCode, nameIdentifier);
569
+ const suggestName = getSuggestName(nameIdentifier, variable);
570
+ const exportDeclaration = getExportDeclaration(variable);
571
+ const data = {
572
+ callee: sourceCode.getText(node.callee),
573
+ caller: sourceCode.getText(nameIdentifier),
574
+ suggestName
575
+ };
576
+ /** @type {ReportFixer} */
577
+ const fix = fixer => {
578
+ /** @type {Set<Identifier>} */
579
+ const replaced = new Set();
580
+ /** @type {Fix[]} */
581
+ const fixes = [];
582
+ const renameIdentifier = ( /** @type {Identifier} */identifier) => {
583
+ if (!replaced.has(identifier)) {
584
+ replaced.add(identifier);
585
+ fixes.push(fixer.replaceText(identifier, suggestName));
586
+ }
587
+ };
588
+ renameIdentifier(nameIdentifier);
589
+ if (exportDeclaration) {
590
+ fixes.push(fixer.insertTextAfter(exportDeclaration, renameExportText(data)));
591
+ }
592
+ if (variable) {
593
+ for (const ref of variable.references) {
594
+ renameIdentifier( /** @type {Identifier} */ref.identifier);
595
+ }
596
+ }
597
+ return fixes;
598
+ };
599
+ context.report({
600
+ data,
601
+ fix,
602
+ messageId: 'rulesOfLexicalReport',
603
+ node: nameIdentifier,
604
+ suggest: [{
605
+ data,
606
+ fix,
607
+ messageId: 'rulesOfLexicalSuggestion'
608
+ }]
609
+ });
610
+ },
611
+ 'CallExpression:exit': popIgnoredNode,
612
+ ClassBody: pushIgnoredNode,
613
+ 'ClassBody:exit': popIgnoredNode,
614
+ FunctionDeclaration: pushFunction,
615
+ 'FunctionDeclaration:exit': popFunction,
616
+ FunctionExpression: pushFunction,
617
+ 'FunctionExpression:exit': popFunction
618
+ };
619
+ },
620
+ meta: {
621
+ docs: {
622
+ description: 'enforces the Rules of Lexical',
623
+ recommended: true,
624
+ url: 'https://lexical.dev/docs/packages/lexical-eslint-plugin'
625
+ },
626
+ fixable: 'code',
627
+ hasSuggestions: true,
628
+ messages: {
629
+ rulesOfLexicalReport: '{{ callee }} called from {{ caller }}, without $ prefix or read/update context',
630
+ rulesOfLexicalSuggestion: 'Rename {{ caller }} to {{ suggestName }}'
631
+ },
632
+ schema: [{
633
+ additionalProperties: false,
634
+ properties: {
635
+ isDollarFunction: matcherSchema,
636
+ isIgnoredFunction: matcherSchema,
637
+ isLexicalProvider: matcherSchema,
638
+ isSafeDollarFunction: matcherSchema
639
+ },
640
+ type: 'object'
641
+ }],
642
+ type: 'suggestion'
643
+ }
644
+ };
645
+
646
+ /**
647
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
648
+ *
649
+ * This source code is licensed under the MIT license found in the
650
+ * LICENSE file in the root directory of this source tree.
651
+ *
652
+ */
653
+
654
+ // @ts-check
655
+
656
+ const {
657
+ name,
658
+ version
659
+ } = require$$0;
660
+ const {
661
+ rulesOfLexical
662
+ } = rulesOfLexical$1;
663
+ const all = {
664
+ plugins: ['@lexical'],
665
+ rules: {
666
+ '@lexical/rules-of-lexical': 'warn'
667
+ }
668
+ };
669
+ const plugin = {
670
+ configs: {
671
+ all,
672
+ recommended: all
673
+ },
674
+ meta: {
675
+ name,
676
+ version
677
+ },
678
+ rules: {
679
+ 'rules-of-lexical': rulesOfLexical
680
+ }
681
+ };
682
+ var LexicalEslintPlugin = plugin;
683
+
684
+ var LexicalEslintPlugin$1 = /*@__PURE__*/getDefaultExportFromCjs(LexicalEslintPlugin);
685
+
686
+ var plugin$1 = /*#__PURE__*/_mergeNamespaces({
687
+ __proto__: null,
688
+ default: LexicalEslintPlugin$1
689
+ }, [LexicalEslintPlugin]);
690
+
691
+ /**
692
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
693
+ *
694
+ * This source code is licensed under the MIT license found in the
695
+ * LICENSE file in the root directory of this source tree.
696
+ *
697
+ */
698
+
699
+ module.exports = plugin$1;