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