eslint-plugin-absolute 0.1.6 → 0.2.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.
Files changed (40) hide show
  1. package/.claude/settings.local.json +5 -0
  2. package/dist/index.js +1226 -798
  3. package/package.json +12 -11
  4. package/src/index.ts +45 -0
  5. package/src/rules/explicit-object-types.ts +73 -0
  6. package/src/rules/{inline-style-limit.js → inline-style-limit.ts} +16 -7
  7. package/src/rules/localize-react-props.ts +459 -0
  8. package/src/rules/max-depth-extended.ts +164 -0
  9. package/src/rules/{max-jsx-nesting.js → max-jsx-nesting.ts} +15 -8
  10. package/src/rules/{min-var-length.js → min-var-length.ts} +75 -45
  11. package/src/rules/no-button-navigation.ts +312 -0
  12. package/src/rules/no-explicit-return-types.ts +87 -0
  13. package/src/rules/{no-inline-prop-types.js → no-inline-prop-types.ts} +22 -9
  14. package/src/rules/no-multi-style-objects.ts +87 -0
  15. package/src/rules/no-nested-jsx-return.ts +210 -0
  16. package/src/rules/no-or-none-component.ts +65 -0
  17. package/src/rules/{no-transition-cssproperties.js → no-transition-cssproperties.ts} +50 -27
  18. package/src/rules/no-unnecessary-div.ts +73 -0
  19. package/src/rules/{no-unnecessary-key.js → no-unnecessary-key.ts} +43 -26
  20. package/src/rules/no-useless-function.ts +58 -0
  21. package/src/rules/seperate-style-files.ts +81 -0
  22. package/src/rules/sort-exports.ts +420 -0
  23. package/src/rules/sort-keys-fixable.ts +621 -0
  24. package/src/rules/spring-naming-convention.ts +145 -0
  25. package/tsconfig.json +2 -1
  26. package/src/index.js +0 -45
  27. package/src/rules/explicit-object-types.js +0 -54
  28. package/src/rules/localize-react-props.js +0 -418
  29. package/src/rules/max-depth-extended.js +0 -124
  30. package/src/rules/no-button-navigation.js +0 -232
  31. package/src/rules/no-explicit-return-types.js +0 -64
  32. package/src/rules/no-multi-style-objects.js +0 -70
  33. package/src/rules/no-nested-jsx-return.js +0 -154
  34. package/src/rules/no-or-none-component.js +0 -50
  35. package/src/rules/no-unnecessary-div.js +0 -40
  36. package/src/rules/no-useless-function.js +0 -43
  37. package/src/rules/seperate-style-files.js +0 -62
  38. package/src/rules/sort-exports.js +0 -397
  39. package/src/rules/sort-keys-fixable.js +0 -459
  40. package/src/rules/spring-naming-convention.js +0 -111
package/dist/index.js CHANGED
@@ -1,62 +1,76 @@
1
1
  // @bun
2
- // src/rules/no-nested-jsx-return.js
3
- var no_nested_jsx_return_default = {
2
+ // src/rules/no-nested-jsx-return.ts
3
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
4
+ var noNestedJSXReturn = {
4
5
  meta: {
5
6
  type: "problem",
6
7
  docs: {
7
- description: "Disallow nested functions that return non-component, non-singular JSX to enforce one component per file",
8
- recommended: false
8
+ description: "Disallow nested functions that return non-component, non-singular JSX to enforce one component per file"
9
9
  },
10
- schema: []
10
+ schema: [],
11
+ messages: {
12
+ nestedFunctionJSX: "Nested function returning non-component, non-singular JSX detected. Extract it into its own component.",
13
+ nestedArrowJSX: "Nested arrow function returning non-component, non-singular JSX detected. Extract it into its own component.",
14
+ nestedArrowFragment: "Nested arrow function returning a non-singular JSX fragment detected. Extract it into its own component."
15
+ }
11
16
  },
17
+ defaultOptions: [],
12
18
  create(context) {
13
19
  function isJSX(node) {
14
- return node && (node.type === "JSXElement" || node.type === "JSXFragment");
20
+ return !!node && (node.type === AST_NODE_TYPES.JSXElement || node.type === AST_NODE_TYPES.JSXFragment);
21
+ }
22
+ function getLeftmostJSXIdentifier(name) {
23
+ let current = name;
24
+ while (current.type === AST_NODE_TYPES.JSXMemberExpression) {
25
+ current = current.object;
26
+ }
27
+ if (current.type === AST_NODE_TYPES.JSXIdentifier) {
28
+ return current;
29
+ }
30
+ return null;
15
31
  }
16
32
  function isJSXComponentElement(node) {
17
- if (node && node.type === "JSXElement") {
18
- const opening = node.openingElement;
19
- if (opening && opening.name) {
20
- if (opening.name.type === "JSXIdentifier") {
21
- return /^[A-Z]/.test(opening.name.name);
22
- }
23
- if (opening.name.type === "JSXMemberExpression") {
24
- let current = opening.name;
25
- while (current && current.type === "JSXMemberExpression") {
26
- current = current.object;
27
- }
28
- return current && current.type === "JSXIdentifier" && /^[A-Z]/.test(current.name);
29
- }
30
- }
33
+ if (!node || node.type !== AST_NODE_TYPES.JSXElement) {
31
34
  return false;
32
35
  }
33
- return false;
36
+ const opening = node.openingElement;
37
+ const nameNode = opening.name;
38
+ if (nameNode.type === AST_NODE_TYPES.JSXIdentifier) {
39
+ return /^[A-Z]/.test(nameNode.name);
40
+ }
41
+ const leftmost = getLeftmostJSXIdentifier(nameNode);
42
+ if (!leftmost) {
43
+ return false;
44
+ }
45
+ return /^[A-Z]/.test(leftmost.name);
34
46
  }
35
47
  function isSingularJSXReturn(node) {
36
48
  if (!isJSX(node))
37
49
  return false;
38
- let children = [];
39
- if (node.type === "JSXElement" || node.type === "JSXFragment") {
40
- children = node.children.filter((child) => {
41
- if (child.type === "JSXText") {
42
- return child.value.trim() !== "";
43
- }
44
- return true;
45
- });
46
- if (children.length === 1) {
47
- const child = children[0];
48
- if (child.type === "JSXElement" || child.type === "JSXFragment") {
49
- const innerChildren = child.children.filter((innerChild) => {
50
- if (innerChild.type === "JSXText") {
51
- return innerChild.value.trim() !== "";
52
- }
53
- return true;
54
- });
55
- return innerChildren.length === 0;
56
- }
57
- return true;
50
+ const children = node.children.filter((child) => {
51
+ if (child.type === AST_NODE_TYPES.JSXText) {
52
+ return child.value.trim() !== "";
53
+ }
54
+ return true;
55
+ });
56
+ if (children.length === 0) {
57
+ return true;
58
+ }
59
+ if (children.length === 1) {
60
+ const child = children[0];
61
+ if (!child) {
62
+ return false;
63
+ }
64
+ if (child.type === AST_NODE_TYPES.JSXElement || child.type === AST_NODE_TYPES.JSXFragment) {
65
+ const innerChildren = child.children.filter((innerChild) => {
66
+ if (innerChild.type === AST_NODE_TYPES.JSXText) {
67
+ return innerChild.value.trim() !== "";
68
+ }
69
+ return true;
70
+ });
71
+ return innerChildren.length === 0;
58
72
  }
59
- return children.length === 0;
73
+ return true;
60
74
  }
61
75
  return false;
62
76
  }
@@ -71,36 +85,49 @@ var no_nested_jsx_return_default = {
71
85
  "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression"(node) {
72
86
  pushFunction(node);
73
87
  },
74
- "FunctionDeclaration:exit"(node) {
88
+ "FunctionDeclaration:exit"(_node) {
75
89
  popFunction();
76
90
  },
77
- "FunctionExpression:exit"(node) {
91
+ "FunctionExpression:exit"(_node) {
78
92
  popFunction();
79
93
  },
80
- "ArrowFunctionExpression:exit"(node) {
94
+ "ArrowFunctionExpression:exit"(_node) {
81
95
  popFunction();
82
96
  },
83
97
  ReturnStatement(node) {
84
- if (functionStack.length > 1 && isJSX(node.argument) && !isJSXComponentElement(node.argument) && !isSingularJSXReturn(node.argument)) {
98
+ if (functionStack.length <= 1) {
99
+ return;
100
+ }
101
+ const argument = node.argument;
102
+ if (!isJSX(argument)) {
103
+ return;
104
+ }
105
+ if (!isJSXComponentElement(argument) && !isSingularJSXReturn(argument)) {
85
106
  context.report({
86
107
  node,
87
- message: "Nested function returning non-component, non-singular JSX detected. Extract it into its own component."
108
+ messageId: "nestedFunctionJSX"
88
109
  });
89
110
  }
90
111
  },
91
112
  "ArrowFunctionExpression > JSXElement"(node) {
92
- if (functionStack.length > 1 && !isJSXComponentElement(node) && !isSingularJSXReturn(node)) {
113
+ if (functionStack.length <= 1) {
114
+ return;
115
+ }
116
+ if (!isJSXComponentElement(node) && !isSingularJSXReturn(node)) {
93
117
  context.report({
94
118
  node,
95
- message: "Nested arrow function returning non-component, non-singular JSX detected. Extract it into its own component."
119
+ messageId: "nestedArrowJSX"
96
120
  });
97
121
  }
98
122
  },
99
123
  "ArrowFunctionExpression > JSXFragment"(node) {
100
- if (functionStack.length > 1 && !isSingularJSXReturn(node)) {
124
+ if (functionStack.length <= 1) {
125
+ return;
126
+ }
127
+ if (!isSingularJSXReturn(node)) {
101
128
  context.report({
102
129
  node,
103
- message: "Nested arrow function returning a non-singular JSX fragment detected. Extract it into its own component."
130
+ messageId: "nestedArrowFragment"
104
131
  });
105
132
  }
106
133
  }
@@ -108,39 +135,49 @@ var no_nested_jsx_return_default = {
108
135
  }
109
136
  };
110
137
 
111
- // src/rules/explicit-object-types.js
112
- var explicit_object_types_default = {
138
+ // src/rules/explicit-object-types.ts
139
+ var explicitObjectTypes = {
113
140
  meta: {
114
141
  type: "problem",
115
142
  docs: {
116
- description: "Require explicit type annotations for object literals and arrays of object literals",
117
- recommended: false
143
+ description: "Require explicit type annotations for object literals and arrays of object literals"
118
144
  },
119
- schema: []
145
+ schema: [],
146
+ messages: {
147
+ objectLiteralNeedsType: "Object literal must have an explicit type annotation.",
148
+ arrayOfObjectLiteralsNeedsType: "Array of object literals must have an explicit type annotation."
149
+ }
120
150
  },
151
+ defaultOptions: [],
121
152
  create(context) {
122
153
  function isObjectLiteral(node) {
123
- return node && node.type === "ObjectExpression";
154
+ return !!node && node.type === "ObjectExpression";
124
155
  }
125
156
  return {
126
157
  VariableDeclarator(node) {
127
158
  if (!node.init)
128
159
  return;
129
- if (node.id && node.id.typeAnnotation)
160
+ if (node.id.type === "Identifier" && node.id.typeAnnotation)
130
161
  return;
131
162
  if (isObjectLiteral(node.init)) {
132
- context.report({
133
- node: node.id,
134
- message: "Object literal must have an explicit type annotation."
135
- });
163
+ if (node.id.type === "Identifier") {
164
+ context.report({
165
+ node: node.id,
166
+ messageId: "objectLiteralNeedsType"
167
+ });
168
+ }
136
169
  return;
137
170
  }
138
171
  if (node.init.type === "ArrayExpression") {
139
- const hasObjectLiteral = node.init.elements.some((element) => element && isObjectLiteral(element));
140
- if (hasObjectLiteral) {
172
+ const hasObjectLiteral = node.init.elements.some((element) => {
173
+ if (!element || element.type === "SpreadElement")
174
+ return false;
175
+ return isObjectLiteral(element);
176
+ });
177
+ if (hasObjectLiteral && node.id.type === "Identifier") {
141
178
  context.report({
142
179
  node: node.id,
143
- message: "Array of object literals must have an explicit type annotation."
180
+ messageId: "arrayOfObjectLiteralsNeedsType"
144
181
  });
145
182
  }
146
183
  }
@@ -149,13 +186,12 @@ var explicit_object_types_default = {
149
186
  }
150
187
  };
151
188
 
152
- // src/rules/sort-keys-fixable.js
153
- var sort_keys_fixable_default = {
189
+ // src/rules/sort-keys-fixable.ts
190
+ var sortKeysFixable = {
154
191
  meta: {
155
192
  type: "suggestion",
156
193
  docs: {
157
- description: "enforce sorted keys in object literals with auto-fix (limited to simple cases, preserving comments)",
158
- recommended: false
194
+ description: "enforce sorted keys in object literals with auto-fix (limited to simple cases, preserving comments)"
159
195
  },
160
196
  fixable: "code",
161
197
  schema: [
@@ -163,6 +199,7 @@ var sort_keys_fixable_default = {
163
199
  type: "object",
164
200
  properties: {
165
201
  order: {
202
+ type: "string",
166
203
  enum: ["asc", "desc"]
167
204
  },
168
205
  caseSensitive: {
@@ -186,14 +223,15 @@ var sort_keys_fixable_default = {
186
223
  unsorted: "Object keys are not sorted."
187
224
  }
188
225
  },
226
+ defaultOptions: [{}],
189
227
  create(context) {
190
- const sourceCode = context.getSourceCode();
191
- const options = context.options[0] || {};
192
- const order = options.order || "asc";
193
- const caseSensitive = options.caseSensitive !== undefined ? options.caseSensitive : false;
194
- const natural = options.natural !== undefined ? options.natural : false;
195
- const minKeys = options.minKeys !== undefined ? options.minKeys : 2;
196
- const variablesBeforeFunctions = options.variablesBeforeFunctions !== undefined ? options.variablesBeforeFunctions : false;
228
+ const sourceCode = context.sourceCode;
229
+ const option = context.options[0];
230
+ const order = option && option.order ? option.order : "asc";
231
+ const caseSensitive = option && typeof option.caseSensitive === "boolean" ? option.caseSensitive : false;
232
+ const natural = option && typeof option.natural === "boolean" ? option.natural : false;
233
+ const minKeys = option && typeof option.minKeys === "number" ? option.minKeys : 2;
234
+ const variablesBeforeFunctions = option && typeof option.variablesBeforeFunctions === "boolean" ? option.variablesBeforeFunctions : false;
197
235
  function compareKeys(a, b) {
198
236
  let keyA = a;
199
237
  let keyB = b;
@@ -202,41 +240,116 @@ var sort_keys_fixable_default = {
202
240
  keyB = keyB.toLowerCase();
203
241
  }
204
242
  if (natural) {
205
- return keyA.localeCompare(keyB, undefined, { numeric: true });
243
+ return keyA.localeCompare(keyB, undefined, {
244
+ numeric: true
245
+ });
206
246
  }
207
247
  return keyA.localeCompare(keyB);
208
248
  }
209
249
  function isFunctionProperty(prop) {
210
- return prop.value && (prop.value.type === "FunctionExpression" || prop.value.type === "ArrowFunctionExpression" || prop.method === true);
250
+ const value = prop.value;
251
+ return !!value && (value.type === "FunctionExpression" || value.type === "ArrowFunctionExpression" || prop.method === true);
252
+ }
253
+ function getPropertyKeyName(prop) {
254
+ const key = prop.key;
255
+ if (key.type === "Identifier") {
256
+ return key.name;
257
+ }
258
+ if (key.type === "Literal") {
259
+ const value = key.value;
260
+ if (typeof value === "string") {
261
+ return value;
262
+ }
263
+ return String(value);
264
+ }
265
+ return "";
266
+ }
267
+ function getLeadingComments(prop, prevProp) {
268
+ const comments = sourceCode.getCommentsBefore(prop);
269
+ if (!prevProp || comments.length === 0) {
270
+ return comments;
271
+ }
272
+ return comments.filter((c) => c.loc.start.line !== prevProp.loc.end.line);
211
273
  }
212
- function buildSortedText(fixableProps) {
213
- const sorted = fixableProps.slice().sort((a, b) => {
274
+ function getTrailingComments(prop, nextProp) {
275
+ const after = sourceCode.getCommentsAfter(prop).filter((c) => c.loc.start.line === prop.loc.end.line);
276
+ if (nextProp) {
277
+ const beforeNext = sourceCode.getCommentsBefore(nextProp);
278
+ const trailingOfPrev = beforeNext.filter((c) => c.loc.start.line === prop.loc.end.line);
279
+ for (const c of trailingOfPrev) {
280
+ if (!after.some((a) => a.range[0] === c.range[0])) {
281
+ after.push(c);
282
+ }
283
+ }
284
+ }
285
+ return after;
286
+ }
287
+ function buildSortedText(fixableProps, rangeStart) {
288
+ const chunks = [];
289
+ for (let i = 0;i < fixableProps.length; i++) {
290
+ const prop = fixableProps[i];
291
+ const prevProp = i > 0 ? fixableProps[i - 1] : null;
292
+ const nextProp = i < fixableProps.length - 1 ? fixableProps[i + 1] : null;
293
+ const leading = getLeadingComments(prop, prevProp);
294
+ const trailing = getTrailingComments(prop, nextProp);
295
+ const fullStart = leading.length > 0 ? leading[0].range[0] : prop.range[0];
296
+ const fullEnd = trailing.length > 0 ? trailing[trailing.length - 1].range[1] : prop.range[1];
297
+ let chunkStart;
298
+ if (i === 0) {
299
+ chunkStart = rangeStart;
300
+ } else {
301
+ const prevTrailing = getTrailingComments(prevProp, prop);
302
+ const prevEnd = prevTrailing.length > 0 ? prevTrailing[prevTrailing.length - 1].range[1] : prevProp.range[1];
303
+ const tokenAfterPrev = sourceCode.getTokenAfter({
304
+ range: [prevEnd, prevEnd]
305
+ }, { includeComments: false });
306
+ if (tokenAfterPrev && tokenAfterPrev.value === "," && tokenAfterPrev.range[1] <= fullStart) {
307
+ chunkStart = tokenAfterPrev.range[1];
308
+ } else {
309
+ chunkStart = prevEnd;
310
+ }
311
+ }
312
+ const text = sourceCode.text.slice(chunkStart, fullEnd);
313
+ chunks.push({ prop, text });
314
+ }
315
+ const sorted = chunks.slice().sort((a, b) => {
214
316
  if (variablesBeforeFunctions) {
215
- const aIsFunc = isFunctionProperty(a);
216
- const bIsFunc = isFunctionProperty(b);
317
+ const aIsFunc = isFunctionProperty(a.prop);
318
+ const bIsFunc = isFunctionProperty(b.prop);
217
319
  if (aIsFunc !== bIsFunc) {
218
320
  return aIsFunc ? 1 : -1;
219
321
  }
220
322
  }
221
- const keyA = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
222
- const keyB = b.key.type === "Identifier" ? b.key.name : String(b.key.value);
223
- let res = compareKeys(keyA, keyB);
323
+ const aKey = getPropertyKeyName(a.prop);
324
+ const bKey = getPropertyKeyName(b.prop);
325
+ let res = compareKeys(aKey, bKey);
224
326
  if (order === "desc") {
225
327
  res = -res;
226
328
  }
227
329
  return res;
228
330
  });
229
- return sorted.map((prop) => {
230
- const leadingComments = sourceCode.getCommentsBefore(prop) || [];
231
- const trailingComments = sourceCode.getCommentsAfter(prop) || [];
232
- const leadingText = leadingComments.length > 0 ? leadingComments.map((comment) => sourceCode.getText(comment)).join(`
233
- `) + `
234
- ` : "";
235
- const trailingText = trailingComments.length > 0 ? `
236
- ` + trailingComments.map((comment) => sourceCode.getText(comment)).join(`
237
- `) : "";
238
- return leadingText + sourceCode.getText(prop) + trailingText;
239
- }).join(", ");
331
+ const firstPropLine = fixableProps[0].loc.start.line;
332
+ const lastPropLine = fixableProps[fixableProps.length - 1].loc.start.line;
333
+ const isMultiline = firstPropLine !== lastPropLine;
334
+ let separator;
335
+ if (isMultiline) {
336
+ const col = fixableProps[0].loc.start.column;
337
+ const indent = sourceCode.text.slice(fixableProps[0].range[0] - col, fixableProps[0].range[0]);
338
+ separator = `,
339
+ ` + indent;
340
+ } else {
341
+ separator = ", ";
342
+ }
343
+ return sorted.map((chunk, i) => {
344
+ if (i === 0) {
345
+ const originalFirstChunk = chunks[0];
346
+ const originalLeadingWs = originalFirstChunk.text.match(/^(\s*)/)?.[1] ?? "";
347
+ const stripped2 = chunk.text.replace(/^\s*/, "");
348
+ return originalLeadingWs + stripped2;
349
+ }
350
+ const stripped = chunk.text.replace(/^\s*/, "");
351
+ return separator + stripped;
352
+ }).join("");
240
353
  }
241
354
  function checkObjectExpression(node) {
242
355
  if (node.properties.length < minKeys) {
@@ -253,140 +366,171 @@ var sort_keys_fixable_default = {
253
366
  if (prop.key.type === "Identifier") {
254
367
  keyName = prop.key.name;
255
368
  } else if (prop.key.type === "Literal") {
256
- keyName = String(prop.key.value);
369
+ const value = prop.key.value;
370
+ keyName = typeof value === "string" ? value : String(value);
257
371
  } else {
258
372
  autoFixable = false;
259
373
  }
260
- if (prop.value) {
261
- if (prop.value.type === "FunctionExpression" || prop.value.type === "ArrowFunctionExpression" || prop.method === true) {
262
- isFunc = true;
263
- }
374
+ if (isFunctionProperty(prop)) {
375
+ isFunc = true;
264
376
  }
265
377
  } else {
266
378
  autoFixable = false;
267
379
  }
268
- return { keyName, node: prop, isFunction: isFunc };
380
+ return {
381
+ keyName,
382
+ node: prop,
383
+ isFunction: isFunc
384
+ };
269
385
  });
386
+ const getFixableProps = () => {
387
+ const props = [];
388
+ for (const prop of node.properties) {
389
+ if (prop.type !== "Property") {
390
+ continue;
391
+ }
392
+ if (prop.computed) {
393
+ continue;
394
+ }
395
+ if (prop.key.type !== "Identifier" && prop.key.type !== "Literal") {
396
+ continue;
397
+ }
398
+ props.push(prop);
399
+ }
400
+ return props;
401
+ };
270
402
  let fixProvided = false;
271
403
  for (let i = 1;i < keys.length; i++) {
272
404
  const prev = keys[i - 1];
273
405
  const curr = keys[i];
406
+ if (!prev || !curr) {
407
+ continue;
408
+ }
274
409
  if (prev.keyName === null || curr.keyName === null) {
275
410
  continue;
276
411
  }
412
+ const shouldFix = !fixProvided && autoFixable;
413
+ const reportWithFix = () => {
414
+ context.report({
415
+ node: curr.node.type === "Property" ? curr.node.key : curr.node,
416
+ messageId: "unsorted",
417
+ fix: shouldFix ? (fixer) => {
418
+ const fixableProps = getFixableProps();
419
+ if (fixableProps.length < minKeys) {
420
+ return null;
421
+ }
422
+ const firstProp = fixableProps[0];
423
+ const lastProp = fixableProps[fixableProps.length - 1];
424
+ if (!firstProp || !lastProp) {
425
+ return null;
426
+ }
427
+ const firstLeading = getLeadingComments(firstProp, null);
428
+ const rangeStart = firstLeading.length > 0 ? firstLeading[0].range[0] : firstProp.range[0];
429
+ const lastTrailing = getTrailingComments(lastProp, null);
430
+ const rangeEnd = lastTrailing.length > 0 ? lastTrailing[lastTrailing.length - 1].range[1] : lastProp.range[1];
431
+ const sortedText = buildSortedText(fixableProps, rangeStart);
432
+ return fixer.replaceTextRange([rangeStart, rangeEnd], sortedText);
433
+ } : null
434
+ });
435
+ fixProvided = true;
436
+ };
277
437
  if (variablesBeforeFunctions) {
278
438
  if (prev.isFunction && !curr.isFunction) {
279
- context.report({
280
- node: curr.node.key,
281
- messageId: "unsorted",
282
- fix: !fixProvided && autoFixable ? (fixer) => {
283
- const fixableProps = node.properties.filter((prop) => prop.type === "Property" && !prop.computed && (prop.key.type === "Identifier" || prop.key.type === "Literal") || false);
284
- if (fixableProps.length < minKeys) {
285
- return null;
286
- }
287
- const sortedText = buildSortedText(fixableProps);
288
- const firstProp = fixableProps[0];
289
- const lastProp = fixableProps[fixableProps.length - 1];
290
- return fixer.replaceTextRange([
291
- firstProp.range[0],
292
- lastProp.range[1]
293
- ], sortedText);
294
- } : null
295
- });
296
- fixProvided = true;
439
+ reportWithFix();
297
440
  continue;
298
- } else if (prev.isFunction === curr.isFunction) {
299
- if (compareKeys(prev.keyName, curr.keyName) > 0) {
300
- context.report({
301
- node: curr.node.key,
302
- messageId: "unsorted",
303
- fix: !fixProvided && autoFixable ? (fixer) => {
304
- const fixableProps = node.properties.filter((prop) => prop.type === "Property" && !prop.computed && (prop.key.type === "Identifier" || prop.key.type === "Literal") || false);
305
- if (fixableProps.length < minKeys) {
306
- return null;
307
- }
308
- const sortedText = buildSortedText(fixableProps);
309
- const firstProp = fixableProps[0];
310
- const lastProp = fixableProps[fixableProps.length - 1];
311
- return fixer.replaceTextRange([
312
- firstProp.range[0],
313
- lastProp.range[1]
314
- ], sortedText);
315
- } : null
316
- });
317
- fixProvided = true;
318
- }
441
+ }
442
+ if (prev.isFunction === curr.isFunction && compareKeys(prev.keyName, curr.keyName) > 0) {
443
+ reportWithFix();
319
444
  }
320
445
  } else {
321
446
  if (compareKeys(prev.keyName, curr.keyName) > 0) {
322
- context.report({
323
- node: curr.node.key,
324
- messageId: "unsorted",
325
- fix: !fixProvided && autoFixable ? (fixer) => {
326
- const fixableProps = node.properties.filter((prop) => prop.type === "Property" && !prop.computed && (prop.key.type === "Identifier" || prop.key.type === "Literal") || false);
327
- if (fixableProps.length < minKeys) {
328
- return null;
329
- }
330
- const sortedText = buildSortedText(fixableProps);
331
- const firstProp = fixableProps[0];
332
- const lastProp = fixableProps[fixableProps.length - 1];
333
- return fixer.replaceTextRange([
334
- firstProp.range[0],
335
- lastProp.range[1]
336
- ], sortedText);
337
- } : null
338
- });
339
- fixProvided = true;
447
+ reportWithFix();
340
448
  }
341
449
  }
342
450
  }
343
451
  }
344
452
  function checkJSXAttributeObject(attr) {
345
- if (attr.value && attr.value.type === "JSXExpressionContainer" && attr.value.expression && attr.value.expression.type === "ObjectExpression") {
346
- checkObjectExpression(attr.value.expression);
453
+ const value = attr.value;
454
+ if (value && value.type === "JSXExpressionContainer") {
455
+ const expr = value.expression;
456
+ if (expr && expr.type === "ObjectExpression") {
457
+ checkObjectExpression(expr);
458
+ }
347
459
  }
348
460
  }
349
461
  function checkJSXOpeningElement(node) {
350
462
  const attrs = node.attributes;
351
- if (attrs.length < minKeys)
463
+ if (attrs.length < minKeys) {
352
464
  return;
353
- if (attrs.some((a) => a.type !== "JSXAttribute"))
465
+ }
466
+ if (attrs.some((a) => a.type !== "JSXAttribute")) {
354
467
  return;
355
- if (attrs.some((a) => a.name.type !== "JSXIdentifier"))
468
+ }
469
+ if (attrs.some((a) => a.type === "JSXAttribute" && a.name.type !== "JSXIdentifier")) {
356
470
  return;
357
- const names = attrs.map((a) => a.name.name);
471
+ }
472
+ const names = attrs.map((a) => {
473
+ if (a.type !== "JSXAttribute") {
474
+ return "";
475
+ }
476
+ if (a.name.type !== "JSXIdentifier") {
477
+ return "";
478
+ }
479
+ return a.name.name;
480
+ });
358
481
  const cmp = (a, b) => {
359
482
  let res = compareKeys(a, b);
360
- return order === "desc" ? -res : res;
483
+ if (order === "desc") {
484
+ res = -res;
485
+ }
486
+ return res;
361
487
  };
362
488
  let outOfOrder = false;
363
489
  for (let i = 1;i < names.length; i++) {
364
- if (cmp(names[i - 1], names[i]) > 0) {
490
+ const prevName = names[i - 1];
491
+ const currName = names[i];
492
+ if (!prevName || !currName) {
493
+ continue;
494
+ }
495
+ if (cmp(prevName, currName) > 0) {
365
496
  outOfOrder = true;
366
497
  break;
367
498
  }
368
499
  }
369
- if (!outOfOrder)
500
+ if (!outOfOrder) {
370
501
  return;
502
+ }
371
503
  for (let i = 1;i < attrs.length; i++) {
372
- const between = sourceCode.text.slice(attrs[i - 1].range[1], attrs[i].range[0]);
504
+ const prevAttr = attrs[i - 1];
505
+ const currAttr = attrs[i];
506
+ if (!prevAttr || !currAttr) {
507
+ continue;
508
+ }
509
+ const between = sourceCode.text.slice(prevAttr.range[1], currAttr.range[0]);
373
510
  if (between.includes("{")) {
374
511
  context.report({
375
- node: attrs[i].name,
512
+ node: currAttr.type === "JSXAttribute" ? currAttr.name : currAttr,
376
513
  messageId: "unsorted"
377
514
  });
378
515
  return;
379
516
  }
380
517
  }
381
- const sorted = attrs.slice().sort((a, b) => cmp(a.name.name, b.name.name));
382
- const first = attrs[0];
383
- const last = attrs[attrs.length - 1];
384
- const replacement = sorted.map((a) => sourceCode.getText(a)).join(" ");
518
+ const sortedAttrs = attrs.slice().sort((a, b) => {
519
+ const aName = a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" ? a.name.name : "";
520
+ const bName = b.type === "JSXAttribute" && b.name.type === "JSXIdentifier" ? b.name.name : "";
521
+ return cmp(aName, bName);
522
+ });
523
+ const firstAttr = attrs[0];
524
+ const lastAttr = attrs[attrs.length - 1];
525
+ if (!firstAttr || !lastAttr) {
526
+ return;
527
+ }
528
+ const replacement = sortedAttrs.map((a) => sourceCode.getText(a)).join(" ");
385
529
  context.report({
386
- node: first.name,
530
+ node: firstAttr.type === "JSXAttribute" ? firstAttr.name : firstAttr,
387
531
  messageId: "unsorted",
388
532
  fix(fixer) {
389
- return fixer.replaceTextRange([first.range[0], last.range[1]], replacement);
533
+ return fixer.replaceTextRange([firstAttr.range[0], lastAttr.range[1]], replacement);
390
534
  }
391
535
  });
392
536
  }
@@ -400,21 +544,21 @@ var sort_keys_fixable_default = {
400
544
  }
401
545
  };
402
546
 
403
- // src/rules/no-transition-cssproperties.js
404
- var no_transition_cssproperties_default = {
547
+ // src/rules/no-transition-cssproperties.ts
548
+ var noTransitionCSSProperties = {
405
549
  meta: {
406
550
  type: "problem",
407
551
  docs: {
408
- description: "Objects typed as CSSProperties must not include a 'transition' property as it conflicts with react-spring.",
409
- recommended: false
552
+ description: "Objects typed as CSSProperties must not include a 'transition' property as it conflicts with react-spring."
410
553
  },
411
554
  schema: [],
412
555
  messages: {
413
556
  forbiddenTransition: "Objects typed as CSSProperties must not include a 'transition' property as it conflicts with react-spring."
414
557
  }
415
558
  },
559
+ defaultOptions: [],
416
560
  create(context) {
417
- const sourceCode = context.getSourceCode();
561
+ const sourceCode = context.sourceCode;
418
562
  return {
419
563
  VariableDeclarator(node) {
420
564
  if (!node.id || node.id.type !== "Identifier" || !node.id.typeAnnotation) {
@@ -423,10 +567,10 @@ var no_transition_cssproperties_default = {
423
567
  let isStyleType = false;
424
568
  const typeAnnotation = node.id.typeAnnotation.typeAnnotation;
425
569
  if (typeAnnotation && typeAnnotation.type === "TSTypeReference") {
426
- const { typeName } = typeAnnotation;
570
+ const typeName = typeAnnotation.typeName;
427
571
  if (typeName.type === "Identifier" && typeName.name === "CSSProperties") {
428
572
  isStyleType = true;
429
- } else if (typeName.type === "TSQualifiedName" && typeName.right && typeName.right.name === "CSSProperties") {
573
+ } else if (typeName.type === "TSQualifiedName" && typeName.right && typeName.right.type === "Identifier" && typeName.right.name === "CSSProperties") {
430
574
  isStyleType = true;
431
575
  }
432
576
  }
@@ -439,80 +583,100 @@ var no_transition_cssproperties_default = {
439
583
  if (!isStyleType) {
440
584
  return;
441
585
  }
442
- if (node.init && node.init.type === "ObjectExpression") {
443
- node.init.properties.forEach((prop) => {
444
- if (prop.type !== "Property") {
445
- return;
446
- }
447
- if (prop.computed) {
448
- return;
449
- }
450
- let keyName = null;
451
- if (prop.key.type === "Identifier") {
452
- keyName = prop.key.name;
453
- } else if (prop.key.type === "Literal") {
586
+ const init = node.init;
587
+ if (!init || init.type !== "ObjectExpression") {
588
+ return;
589
+ }
590
+ for (const prop of init.properties) {
591
+ if (prop.type !== "Property") {
592
+ continue;
593
+ }
594
+ if (prop.computed) {
595
+ continue;
596
+ }
597
+ let keyName = null;
598
+ if (prop.key.type === "Identifier") {
599
+ keyName = prop.key.name;
600
+ } else if (prop.key.type === "Literal") {
601
+ if (typeof prop.key.value === "string") {
602
+ keyName = prop.key.value;
603
+ } else {
454
604
  keyName = String(prop.key.value);
455
605
  }
456
- if (keyName === "transition") {
457
- context.report({
458
- node: prop,
459
- messageId: "forbiddenTransition"
460
- });
461
- }
462
- });
606
+ }
607
+ if (keyName === "transition") {
608
+ context.report({
609
+ node: prop,
610
+ messageId: "forbiddenTransition"
611
+ });
612
+ }
463
613
  }
464
614
  }
465
615
  };
466
616
  }
467
617
  };
468
618
 
469
- // src/rules/no-explicit-return-types.js
470
- var no_explicit_return_types_default = {
619
+ // src/rules/no-explicit-return-types.ts
620
+ var noExplicitReturnTypes = {
471
621
  meta: {
472
622
  type: "suggestion",
473
623
  docs: {
474
- description: "Disallow explicit return type annotations on functions, except when using type predicates for type guards or inline object literal returns (e.g., style objects).",
475
- recommended: false
624
+ description: "Disallow explicit return type annotations on functions, except when using type predicates for type guards or inline object literal returns (e.g., style objects)."
476
625
  },
477
626
  schema: [],
478
627
  messages: {
479
628
  noExplicitReturnType: "Explicit return types are disallowed; rely on TypeScript's inference instead."
480
629
  }
481
630
  },
631
+ defaultOptions: [],
482
632
  create(context) {
633
+ function hasSingleObjectReturn(body) {
634
+ let returnCount = 0;
635
+ let returnedObject = null;
636
+ for (const stmt of body.body) {
637
+ if (stmt.type === "ReturnStatement") {
638
+ returnCount++;
639
+ const arg = stmt.argument;
640
+ if (arg && arg.type === "ObjectExpression") {
641
+ returnedObject = arg;
642
+ }
643
+ }
644
+ }
645
+ return returnCount === 1 && returnedObject !== null;
646
+ }
483
647
  return {
484
648
  "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression"(node) {
485
- if (node.returnType) {
486
- const typeAnnotation = node.returnType.typeAnnotation;
487
- if (typeAnnotation && typeAnnotation.type === "TSTypePredicate") {
488
- return;
489
- }
490
- if (node.type === "ArrowFunctionExpression" && node.expression && node.body && node.body.type === "ObjectExpression") {
649
+ const returnType = node.returnType;
650
+ if (!returnType) {
651
+ return;
652
+ }
653
+ const typeAnnotation = returnType.typeAnnotation;
654
+ if (typeAnnotation && typeAnnotation.type === "TSTypePredicate") {
655
+ return;
656
+ }
657
+ if (node.type === "ArrowFunctionExpression" && node.expression === true && node.body.type === "ObjectExpression") {
658
+ return;
659
+ }
660
+ if (node.body && node.body.type === "BlockStatement") {
661
+ if (hasSingleObjectReturn(node.body)) {
491
662
  return;
492
663
  }
493
- if (node.body && node.body.type === "BlockStatement") {
494
- const returns = node.body.body.filter((stmt) => stmt.type === "ReturnStatement");
495
- if (returns.length === 1 && returns[0].argument && returns[0].argument.type === "ObjectExpression") {
496
- return;
497
- }
498
- }
499
- context.report({
500
- node: node.returnType,
501
- messageId: "noExplicitReturnType"
502
- });
503
664
  }
665
+ context.report({
666
+ node: returnType,
667
+ messageId: "noExplicitReturnType"
668
+ });
504
669
  }
505
670
  };
506
671
  }
507
672
  };
508
673
 
509
- // src/rules/max-jsx-nesting.js
510
- var max_jsx_nesting_default = {
674
+ // src/rules/max-jsx-nesting.ts
675
+ var maxJSXNesting = {
511
676
  meta: {
512
677
  type: "suggestion",
513
678
  docs: {
514
- description: "Warn when JSX elements are nested too deeply, suggesting refactoring into a separate component.",
515
- recommended: false
679
+ description: "Warn when JSX elements are nested too deeply, suggesting refactoring into a separate component."
516
680
  },
517
681
  schema: [
518
682
  {
@@ -524,8 +688,10 @@ var max_jsx_nesting_default = {
524
688
  tooDeeplyNested: "JSX element is nested too deeply ({{level}} levels, allowed is {{maxAllowed}} levels). Consider refactoring into a separate component."
525
689
  }
526
690
  },
691
+ defaultOptions: [1],
527
692
  create(context) {
528
- const maxAllowed = context.options[0];
693
+ const option = context.options[0];
694
+ const maxAllowed = typeof option === "number" ? option : 1;
529
695
  function getJSXNestingLevel(node) {
530
696
  let level = 1;
531
697
  let current = node.parent;
@@ -552,68 +718,74 @@ var max_jsx_nesting_default = {
552
718
  }
553
719
  };
554
720
 
555
- // src/rules/seperate-style-files.js
556
- var seperate_style_files_default = {
721
+ // src/rules/seperate-style-files.ts
722
+ var seperateStyleFiles = {
557
723
  meta: {
558
724
  type: "suggestion",
559
725
  docs: {
560
- description: "Warn when a component file (.jsx or .tsx) contains a style object typed as CSSProperties. " + "Style objects should be moved to their own file under the style folder.",
561
- recommended: false
726
+ description: "Warn when a component file (.jsx or .tsx) contains a style object typed as CSSProperties. " + "Style objects should be moved to their own file under the style folder."
562
727
  },
563
728
  schema: [],
564
729
  messages: {
565
730
  moveToFile: 'Style object "{{name}}" is typed as {{typeName}}. Move it to its own file under the style folder.'
566
731
  }
567
732
  },
733
+ defaultOptions: [],
568
734
  create(context) {
569
- const filename = context.getFilename();
735
+ const filename = context.filename;
570
736
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) {
571
737
  return {};
572
738
  }
573
739
  return {
574
740
  VariableDeclarator(node) {
575
- if (!node.id || node.id.type !== "Identifier")
741
+ if (!node.id || node.id.type !== "Identifier") {
576
742
  return;
743
+ }
577
744
  const identifier = node.id;
578
- if (!identifier.typeAnnotation)
745
+ const idTypeAnnotation = identifier.typeAnnotation;
746
+ if (!idTypeAnnotation || idTypeAnnotation.type !== "TSTypeAnnotation") {
579
747
  return;
580
- const typeNode = identifier.typeAnnotation.typeAnnotation;
581
- if (typeNode.type === "TSTypeReference" && typeNode.typeName) {
582
- let typeName = null;
583
- if (typeNode.typeName.type === "Identifier") {
584
- typeName = typeNode.typeName.name;
585
- } else if (typeNode.typeName.type === "TSQualifiedName") {
586
- typeName = typeNode.typeName.right.name;
587
- }
588
- if (typeName === "CSSProperties") {
589
- context.report({
590
- node,
591
- messageId: "moveToFile",
592
- data: {
593
- name: identifier.name,
594
- typeName
595
- }
596
- });
597
- }
748
+ }
749
+ const typeNode = idTypeAnnotation.typeAnnotation;
750
+ if (!typeNode || typeNode.type !== "TSTypeReference") {
751
+ return;
752
+ }
753
+ const typeNameNode = typeNode.typeName;
754
+ let typeName = null;
755
+ if (typeNameNode.type === "Identifier") {
756
+ typeName = typeNameNode.name;
757
+ } else if (typeNameNode.type === "TSQualifiedName") {
758
+ const right = typeNameNode.right;
759
+ typeName = right.name;
760
+ }
761
+ if (typeName === "CSSProperties") {
762
+ context.report({
763
+ node,
764
+ messageId: "moveToFile",
765
+ data: {
766
+ name: identifier.name,
767
+ typeName
768
+ }
769
+ });
598
770
  }
599
771
  }
600
772
  };
601
773
  }
602
774
  };
603
775
 
604
- // src/rules/no-unnecessary-key.js
605
- var no_unnecessary_key_default = {
776
+ // src/rules/no-unnecessary-key.ts
777
+ var noUnnecessaryKey = {
606
778
  meta: {
607
779
  type: "problem",
608
780
  docs: {
609
- description: "enforce that the key prop is only used on components rendered as part of a mapping",
610
- recommended: false
781
+ description: "enforce that the key prop is only used on components rendered as part of a mapping"
611
782
  },
612
783
  schema: [],
613
784
  messages: {
614
785
  unnecessaryKey: "The key prop should only be used on elements that are directly rendered as part of an array mapping."
615
786
  }
616
787
  },
788
+ defaultOptions: [],
617
789
  create(context) {
618
790
  function getAncestors(node) {
619
791
  const ancestors = [];
@@ -625,23 +797,38 @@ var no_unnecessary_key_default = {
625
797
  return ancestors;
626
798
  }
627
799
  function isInsideMapCall(ancestors) {
628
- return ancestors.some((node) => {
629
- if (node.type === "CallExpression" && node.callee && node.callee.type === "MemberExpression") {
800
+ for (const node of ancestors) {
801
+ if (node.type === "CallExpression" && node.callee.type === "MemberExpression") {
630
802
  const property = node.callee.property;
631
- return property.type === "Identifier" && property.name === "map" || property.type === "Literal" && property.value === "map";
803
+ if (property.type === "Identifier" && property.name === "map") {
804
+ return true;
805
+ }
806
+ if (property.type === "Literal" && property.value === "map") {
807
+ return true;
808
+ }
632
809
  }
633
- return false;
634
- });
810
+ }
811
+ return false;
635
812
  }
636
813
  function isReturnedFromFunction(ancestors) {
637
- return ancestors.some((node) => node.type === "ReturnStatement");
814
+ for (const node of ancestors) {
815
+ if (node.type === "ReturnStatement") {
816
+ return true;
817
+ }
818
+ }
819
+ return false;
638
820
  }
639
821
  function checkJSXOpeningElement(node) {
640
- const keyAttribute = node.attributes.find((attr) => attr.type === "JSXAttribute" && attr.name && attr.name.name === "key");
822
+ const keyAttribute = node.attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.type === "JSXIdentifier" && attr.name.name === "key");
641
823
  if (!keyAttribute) {
642
824
  return;
643
825
  }
644
- const ancestors = typeof context.getAncestors === "function" ? context.getAncestors() : getAncestors(node);
826
+ let ancestors;
827
+ if (typeof context.getAncestors === "function") {
828
+ ancestors = context.getAncestors();
829
+ } else {
830
+ ancestors = getAncestors(node);
831
+ }
645
832
  if (isInsideMapCall(ancestors)) {
646
833
  return;
647
834
  }
@@ -659,14 +846,12 @@ var no_unnecessary_key_default = {
659
846
  }
660
847
  };
661
848
 
662
- // src/rules/sort-exports.js
663
- var sort_exports_default = {
849
+ // src/rules/sort-exports.ts
850
+ var sortExports = {
664
851
  meta: {
665
852
  type: "suggestion",
666
853
  docs: {
667
- description: "Enforce that top-level export declarations are sorted by exported name and, optionally, that variable exports come before function exports",
668
- category: "Stylistic Issues",
669
- recommended: false
854
+ description: "Enforce that top-level export declarations are sorted by exported name and, optionally, that variable exports come before function exports"
670
855
  },
671
856
  fixable: "code",
672
857
  schema: [
@@ -674,6 +859,7 @@ var sort_exports_default = {
674
859
  type: "object",
675
860
  properties: {
676
861
  order: {
862
+ type: "string",
677
863
  enum: ["asc", "desc"]
678
864
  },
679
865
  caseSensitive: {
@@ -698,14 +884,15 @@ var sort_exports_default = {
698
884
  variablesBeforeFunctions: "Non-function exports should come before function exports."
699
885
  }
700
886
  },
887
+ defaultOptions: [{}],
701
888
  create(context) {
702
- const sourceCode = context.getSourceCode();
703
- const options = context.options[0] || {};
704
- const order = options.order || "asc";
705
- const caseSensitive = options.caseSensitive !== undefined ? options.caseSensitive : false;
706
- const natural = options.natural !== undefined ? options.natural : false;
707
- const minKeys = options.minKeys !== undefined ? options.minKeys : 2;
708
- const variablesBeforeFunctions = options.variablesBeforeFunctions !== undefined ? options.variablesBeforeFunctions : false;
889
+ const sourceCode = context.sourceCode;
890
+ const option = context.options[0];
891
+ const order = option && option.order ? option.order : "asc";
892
+ const caseSensitive = option && typeof option.caseSensitive === "boolean" ? option.caseSensitive : false;
893
+ const natural = option && typeof option.natural === "boolean" ? option.natural : false;
894
+ const minKeys = option && typeof option.minKeys === "number" ? option.minKeys : 2;
895
+ const variablesBeforeFunctions = option && typeof option.variablesBeforeFunctions === "boolean" ? option.variablesBeforeFunctions : false;
709
896
  function generateExportText(node) {
710
897
  return sourceCode.getText(node).trim().replace(/\s*;?\s*$/, ";");
711
898
  }
@@ -716,48 +903,66 @@ var sort_exports_default = {
716
903
  strA = strA.toLowerCase();
717
904
  strB = strB.toLowerCase();
718
905
  }
719
- let cmp = natural ? strA.localeCompare(strB, undefined, { numeric: true }) : strA.localeCompare(strB);
906
+ const cmp = natural ? strA.localeCompare(strB, undefined, { numeric: true }) : strA.localeCompare(strB);
720
907
  return order === "asc" ? cmp : -cmp;
721
908
  }
722
909
  function getExportName(node) {
723
- if (node.declaration) {
724
- const decl = node.declaration;
725
- if (decl.type === "VariableDeclaration") {
726
- if (decl.declarations.length === 1) {
727
- const id = decl.declarations[0].id;
728
- if (id.type === "Identifier") {
729
- return id.name;
910
+ const declaration = node.declaration;
911
+ if (declaration) {
912
+ if (declaration.type === "VariableDeclaration") {
913
+ if (declaration.declarations.length === 1) {
914
+ const firstDeclarator = declaration.declarations[0];
915
+ if (firstDeclarator && firstDeclarator.id.type === "Identifier") {
916
+ return firstDeclarator.id.name;
730
917
  }
731
918
  }
732
- } else if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") {
733
- if (decl.id && decl.id.type === "Identifier") {
734
- return decl.id.name;
919
+ } else if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
920
+ const id = declaration.id;
921
+ if (id && id.type === "Identifier") {
922
+ return id.name;
735
923
  }
736
924
  }
737
- } else if (node.specifiers && node.specifiers.length === 1) {
925
+ } else if (node.specifiers.length === 1) {
738
926
  const spec = node.specifiers[0];
739
- return spec.exported.name || spec.exported.value;
927
+ if (!spec) {
928
+ return null;
929
+ }
930
+ if (spec.exported.type === "Identifier") {
931
+ return spec.exported.name;
932
+ }
933
+ if (spec.exported.type === "Literal" && typeof spec.exported.value === "string") {
934
+ return spec.exported.value;
935
+ }
740
936
  }
741
937
  return null;
742
938
  }
743
939
  function isFunctionExport(node) {
744
- if (node.declaration) {
745
- const decl = node.declaration;
746
- if (decl.type === "VariableDeclaration") {
747
- if (decl.declarations.length === 1) {
748
- const init = decl.declarations[0].init;
749
- return init && (init.type === "FunctionExpression" || init.type === "ArrowFunctionExpression");
750
- }
751
- } else if (decl.type === "FunctionDeclaration") {
752
- return true;
940
+ const declaration = node.declaration;
941
+ if (!declaration) {
942
+ return false;
943
+ }
944
+ if (declaration.type === "VariableDeclaration") {
945
+ if (declaration.declarations.length === 1) {
946
+ const firstDeclarator = declaration.declarations[0];
947
+ if (!firstDeclarator) {
948
+ return false;
949
+ }
950
+ const init = firstDeclarator.init;
951
+ if (!init) {
952
+ return false;
953
+ }
954
+ return init.type === "FunctionExpression" || init.type === "ArrowFunctionExpression";
753
955
  }
754
956
  return false;
755
957
  }
958
+ if (declaration.type === "FunctionDeclaration") {
959
+ return true;
960
+ }
756
961
  return false;
757
962
  }
758
963
  function sortComparator(a, b) {
759
- const kindA = a.node.exportKind || "value";
760
- const kindB = b.node.exportKind || "value";
964
+ const kindA = a.node.exportKind ?? "value";
965
+ const kindB = b.node.exportKind ?? "value";
761
966
  if (kindA !== kindB) {
762
967
  return kindA === "type" ? -1 : 1;
763
968
  }
@@ -768,33 +973,11 @@ var sort_exports_default = {
768
973
  }
769
974
  return compareStrings(a.name, b.name);
770
975
  }
771
- function hasForwardDependency(node, laterNames, visited = new WeakSet) {
772
- if (!node || typeof node !== "object") {
773
- return false;
774
- }
775
- if (visited.has(node)) {
776
- return false;
777
- }
778
- visited.add(node);
779
- if (node.type === "Identifier" && laterNames.has(node.name)) {
780
- return true;
781
- }
782
- for (const key in node) {
783
- if (Object.prototype.hasOwnProperty.call(node, key)) {
784
- const value = node[key];
785
- if (Array.isArray(value)) {
786
- for (const element of value) {
787
- if (element && typeof element === "object") {
788
- if (hasForwardDependency(element, laterNames, visited)) {
789
- return true;
790
- }
791
- }
792
- }
793
- } else if (value && typeof value === "object") {
794
- if (hasForwardDependency(value, laterNames, visited)) {
795
- return true;
796
- }
797
- }
976
+ function hasForwardDependency(node, laterNames) {
977
+ const text = sourceCode.getText(node);
978
+ for (const name of laterNames) {
979
+ if (text.includes(name)) {
980
+ return true;
798
981
  }
799
982
  }
800
983
  return false;
@@ -803,18 +986,19 @@ var sort_exports_default = {
803
986
  if (block.length < minKeys) {
804
987
  return;
805
988
  }
806
- const items = block.map((node) => {
989
+ const items = [];
990
+ for (const node of block) {
807
991
  const name = getExportName(node);
808
- if (name === null) {
809
- return null;
992
+ if (!name) {
993
+ continue;
810
994
  }
811
- return {
995
+ items.push({
812
996
  name,
813
997
  node,
814
998
  isFunction: isFunctionExport(node),
815
999
  text: sourceCode.getText(node)
816
- };
817
- }).filter(Boolean);
1000
+ });
1001
+ }
818
1002
  if (items.length < minKeys) {
819
1003
  return;
820
1004
  }
@@ -822,9 +1006,14 @@ var sort_exports_default = {
822
1006
  let reportNeeded = false;
823
1007
  let messageId = "alphabetical";
824
1008
  for (let i = 1;i < items.length; i++) {
825
- if (sortComparator(items[i - 1], items[i]) > 0) {
1009
+ const prev = items[i - 1];
1010
+ const current = items[i];
1011
+ if (!prev || !current) {
1012
+ continue;
1013
+ }
1014
+ if (sortComparator(prev, current) > 0) {
826
1015
  reportNeeded = true;
827
- if (variablesBeforeFunctions && items[i - 1].isFunction && !items[i].isFunction) {
1016
+ if (variablesBeforeFunctions && prev.isFunction && !current.isFunction) {
828
1017
  messageId = "variablesBeforeFunctions";
829
1018
  }
830
1019
  break;
@@ -835,66 +1024,85 @@ var sort_exports_default = {
835
1024
  }
836
1025
  const exportNames = items.map((item) => item.name);
837
1026
  for (let i = 0;i < items.length; i++) {
1027
+ const item = items[i];
1028
+ if (!item) {
1029
+ continue;
1030
+ }
838
1031
  const laterNames = new Set(exportNames.slice(i + 1));
839
- const nodeToCheck = items[i].node.declaration || items[i].node;
1032
+ const nodeToCheck = item.node.declaration ?? item.node;
840
1033
  if (hasForwardDependency(nodeToCheck, laterNames)) {
841
1034
  return;
842
1035
  }
843
1036
  }
844
1037
  const expectedOrder = sortedItems.map((item) => item.name).join(", ");
1038
+ const firstNode = block[0];
1039
+ const lastNode = block[block.length - 1];
1040
+ if (!firstNode || !lastNode) {
1041
+ return;
1042
+ }
845
1043
  context.report({
846
- node: items[0].node,
1044
+ node: firstNode,
847
1045
  messageId,
848
1046
  data: {
849
1047
  expectedOrder
850
1048
  },
851
1049
  fix(fixer) {
852
- const fixableNodes = block.filter((n) => {
853
- if (n.declaration) {
854
- if (n.declaration.type === "VariableDeclaration" && n.declaration.declarations.length === 1 && n.declaration.declarations[0].id.type === "Identifier") {
855
- return true;
1050
+ const fixableNodes = [];
1051
+ for (const n of block) {
1052
+ const declaration = n.declaration;
1053
+ if (declaration) {
1054
+ if (declaration.type === "VariableDeclaration" && declaration.declarations.length === 1) {
1055
+ const firstDecl = declaration.declarations[0];
1056
+ if (firstDecl && firstDecl.id.type === "Identifier") {
1057
+ fixableNodes.push(n);
1058
+ continue;
1059
+ }
856
1060
  }
857
- if ((n.declaration.type === "FunctionDeclaration" || n.declaration.type === "ClassDeclaration") && n.declaration.id && n.declaration.id.type === "Identifier") {
858
- return true;
1061
+ if ((declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") && declaration.id && declaration.id.type === "Identifier") {
1062
+ fixableNodes.push(n);
1063
+ continue;
859
1064
  }
860
- return false;
1065
+ continue;
861
1066
  }
862
- if (n.specifiers && n.specifiers.length === 1) {
863
- return true;
1067
+ if (n.specifiers.length === 1) {
1068
+ fixableNodes.push(n);
864
1069
  }
865
- return false;
866
- });
1070
+ }
867
1071
  if (fixableNodes.length < minKeys) {
868
1072
  return null;
869
1073
  }
870
1074
  const sortedText = sortedItems.map((item) => generateExportText(item.node)).join(`
871
1075
  `);
872
- const first = block[0].range[0];
873
- const last = block[block.length - 1].range[1];
874
- const originalText = sourceCode.getText().slice(first, last);
1076
+ const rangeStart = firstNode.range[0];
1077
+ const rangeEnd = lastNode.range[1];
1078
+ const fullText = sourceCode.getText();
1079
+ const originalText = fullText.slice(rangeStart, rangeEnd);
875
1080
  if (originalText === sortedText) {
876
1081
  return null;
877
1082
  }
878
- return fixer.replaceTextRange([first, last], sortedText);
1083
+ return fixer.replaceTextRange([rangeStart, rangeEnd], sortedText);
879
1084
  }
880
1085
  });
881
1086
  }
882
1087
  return {
883
1088
  "Program:exit"(node) {
884
1089
  const body = node.body;
885
- let block = [];
1090
+ const block = [];
886
1091
  for (let i = 0;i < body.length; i++) {
887
- const n = body[i];
888
- if (n.type === "ExportNamedDeclaration" && !n.source && getExportName(n) !== null) {
889
- block.push(n);
1092
+ const stmt = body[i];
1093
+ if (!stmt) {
1094
+ continue;
1095
+ }
1096
+ if (stmt.type === "ExportNamedDeclaration" && !stmt.source && getExportName(stmt) !== null) {
1097
+ block.push(stmt);
890
1098
  } else {
891
- if (block.length) {
1099
+ if (block.length > 0) {
892
1100
  processExportBlock(block);
893
- block = [];
1101
+ block.length = 0;
894
1102
  }
895
1103
  }
896
1104
  }
897
- if (block.length) {
1105
+ if (block.length > 0) {
898
1106
  processExportBlock(block);
899
1107
  }
900
1108
  }
@@ -902,47 +1110,73 @@ var sort_exports_default = {
902
1110
  }
903
1111
  };
904
1112
 
905
- // src/rules/localize-react-props.js
906
- var localize_react_props_default = {
1113
+ // src/rules/localize-react-props.ts
1114
+ import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/utils";
1115
+ var localizeReactProps = {
907
1116
  meta: {
908
1117
  type: "suggestion",
909
1118
  docs: {
910
- description: "Disallow variables that are only passed to a single custom child component. For useState, only report if both the state and its setter are exclusively passed to a single custom child. For general variables, only report if a given child receives exactly one such candidate \u2013 if two or more are passed to the same component type, they\u2019re assumed to be settings that belong on the parent.",
911
- category: "Best Practices",
912
- recommended: false
1119
+ description: "Disallow variables that are only passed to a single custom child component. For useState, only report if both the state and its setter are exclusively passed to a single custom child. For general variables, only report if a given child receives exactly one such candidate \u2013 if two or more are passed to the same component type, they\u2019re assumed to be settings that belong on the parent."
1120
+ },
1121
+ schema: [],
1122
+ messages: {
1123
+ stateAndSetterToChild: "State variable '{{stateVarName}}' and its setter '{{setterVarName}}' are only passed to a single custom child component. Consider moving the state into that component.",
1124
+ variableToChild: "Variable '{{varName}}' is only passed to a single custom child component. Consider moving it to that component."
913
1125
  }
914
1126
  },
1127
+ defaultOptions: [],
915
1128
  create(context) {
916
1129
  const candidateVariables = [];
917
- function getJSXElementName(jsxElement) {
918
- if (!jsxElement || !jsxElement.openingElement || !jsxElement.openingElement.name) {
919
- return "";
1130
+ function getSingleSetElement(set) {
1131
+ for (const value of set) {
1132
+ return value;
920
1133
  }
921
- const nameNode = jsxElement.openingElement.name;
922
- if (nameNode.type === "JSXIdentifier") {
923
- return nameNode.name;
1134
+ return null;
1135
+ }
1136
+ function getRightmostJSXIdentifier(name) {
1137
+ let current = name;
1138
+ while (current.type === AST_NODE_TYPES2.JSXMemberExpression) {
1139
+ current = current.property;
924
1140
  }
925
- if (nameNode.type === "JSXMemberExpression") {
926
- let current = nameNode;
927
- while (current.property) {
928
- current = current.property;
929
- }
930
- if (current && current.type === "JSXIdentifier") {
931
- return current.name;
932
- }
1141
+ if (current.type === AST_NODE_TYPES2.JSXIdentifier) {
1142
+ return current;
933
1143
  }
934
- return "";
1144
+ return null;
1145
+ }
1146
+ function getLeftmostJSXIdentifier(name) {
1147
+ let current = name;
1148
+ while (current.type === AST_NODE_TYPES2.JSXMemberExpression) {
1149
+ current = current.object;
1150
+ }
1151
+ if (current.type === AST_NODE_TYPES2.JSXIdentifier) {
1152
+ return current;
1153
+ }
1154
+ return null;
1155
+ }
1156
+ function getJSXElementName(jsxElement) {
1157
+ if (!jsxElement || !jsxElement.openingElement || !jsxElement.openingElement.name) {
1158
+ return "";
1159
+ }
1160
+ const nameNode = jsxElement.openingElement.name;
1161
+ if (nameNode.type === AST_NODE_TYPES2.JSXIdentifier) {
1162
+ return nameNode.name;
1163
+ }
1164
+ const rightmost = getRightmostJSXIdentifier(nameNode);
1165
+ if (rightmost) {
1166
+ return rightmost.name;
1167
+ }
1168
+ return "";
935
1169
  }
936
1170
  function isUseStateCall(node) {
937
- return node && node.type === "CallExpression" && node.callee && (node.callee.type === "Identifier" && node.callee.name === "useState" || node.callee.type === "MemberExpression" && node.callee.property && node.callee.property.name === "useState");
1171
+ return node !== null && node.type === AST_NODE_TYPES2.CallExpression && node.callee !== null && (node.callee.type === AST_NODE_TYPES2.Identifier && node.callee.name === "useState" || node.callee.type === AST_NODE_TYPES2.MemberExpression && node.callee.property !== null && node.callee.property.type === AST_NODE_TYPES2.Identifier && node.callee.property.name === "useState");
938
1172
  }
939
1173
  function isHookCall(node) {
940
- return node && node.type === "CallExpression" && node.callee && node.callee.type === "Identifier" && /^use[A-Z]/.test(node.callee.name) && node.callee.name !== "useState";
1174
+ return node !== null && node.type === AST_NODE_TYPES2.CallExpression && node.callee !== null && node.callee.type === AST_NODE_TYPES2.Identifier && /^use[A-Z]/.test(node.callee.name) && node.callee.name !== "useState";
941
1175
  }
942
1176
  function getJSXAncestor(node) {
943
1177
  let current = node.parent;
944
1178
  while (current) {
945
- if (current.type === "JSXElement") {
1179
+ if (current.type === AST_NODE_TYPES2.JSXElement) {
946
1180
  return current;
947
1181
  }
948
1182
  current = current.parent;
@@ -952,21 +1186,18 @@ var localize_react_props_default = {
952
1186
  function isContextProviderValueProp(node) {
953
1187
  let current = node.parent;
954
1188
  while (current) {
955
- if (current.type === "JSXAttribute" && current.name && current.name.name === "value") {
956
- if (current.parent && current.parent.type === "JSXOpeningElement") {
1189
+ if (current.type === AST_NODE_TYPES2.JSXAttribute && current.name && current.name.type === AST_NODE_TYPES2.JSXIdentifier && current.name.name === "value") {
1190
+ if (current.parent && current.parent.type === AST_NODE_TYPES2.JSXOpeningElement) {
957
1191
  const nameNode = current.parent.name;
958
- if (nameNode.type === "JSXIdentifier") {
1192
+ if (nameNode.type === AST_NODE_TYPES2.JSXIdentifier) {
959
1193
  const tagName = nameNode.name;
960
1194
  if (tagName.endsWith("Provider") || tagName.endsWith("Context")) {
961
1195
  return true;
962
1196
  }
963
- } else if (nameNode.type === "JSXMemberExpression") {
964
- let currentMember = nameNode;
965
- while (currentMember.type === "JSXMemberExpression") {
966
- currentMember = currentMember.property;
967
- }
968
- if (currentMember && currentMember.type === "JSXIdentifier") {
969
- if (currentMember.name.endsWith("Provider") || currentMember.name.endsWith("Context")) {
1197
+ } else {
1198
+ const rightmost = getRightmostJSXIdentifier(nameNode);
1199
+ if (rightmost) {
1200
+ if (rightmost.name.endsWith("Provider") || rightmost.name.endsWith("Context")) {
970
1201
  return true;
971
1202
  }
972
1203
  }
@@ -982,120 +1213,105 @@ var localize_react_props_default = {
982
1213
  return false;
983
1214
  }
984
1215
  const nameNode = jsxElement.openingElement.name;
985
- if (nameNode.type === "JSXIdentifier") {
1216
+ if (nameNode.type === AST_NODE_TYPES2.JSXIdentifier) {
986
1217
  return /^[A-Z]/.test(nameNode.name);
987
1218
  }
988
- if (nameNode.type === "JSXMemberExpression") {
989
- let current = nameNode;
990
- while (current.object) {
991
- current = current.object;
992
- }
993
- return current.type === "JSXIdentifier" && /^[A-Z]/.test(current.name);
1219
+ const leftmost = getLeftmostJSXIdentifier(nameNode);
1220
+ if (leftmost && /^[A-Z]/.test(leftmost.name)) {
1221
+ return true;
994
1222
  }
995
1223
  return false;
996
1224
  }
997
1225
  function getComponentFunction(node) {
998
1226
  let current = node;
999
1227
  while (current) {
1000
- if (current.type === "FunctionDeclaration" || current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression") {
1228
+ if (current.type === AST_NODE_TYPES2.FunctionDeclaration || current.type === AST_NODE_TYPES2.FunctionExpression || current.type === AST_NODE_TYPES2.ArrowFunctionExpression) {
1001
1229
  return current;
1002
1230
  }
1003
1231
  current = current.parent;
1004
1232
  }
1005
1233
  return null;
1006
1234
  }
1007
- function analyzeVariableUsage(declarationNode, varName, componentFunction) {
1008
- const usage = { jsxUsageSet: new Set, hasOutsideUsage: false };
1009
- const sourceCode = context.getSourceCode();
1010
- const visitorKeys = sourceCode.visitorKeys || {};
1011
- const stack = [];
1012
- if (componentFunction.body.type === "BlockStatement") {
1013
- for (let i = 0;i < componentFunction.body.body.length; i++) {
1014
- stack.push(componentFunction.body.body[i]);
1235
+ function findVariableForIdentifier(id) {
1236
+ let scope = context.sourceCode.getScope(id);
1237
+ while (scope) {
1238
+ for (const variable of scope.variables) {
1239
+ for (const def of variable.defs) {
1240
+ if (def.name === id) {
1241
+ return variable;
1242
+ }
1243
+ }
1015
1244
  }
1016
- } else {
1017
- stack.push(componentFunction.body);
1245
+ scope = scope.upper ?? null;
1018
1246
  }
1019
- while (stack.length) {
1020
- const currentNode = stack.pop();
1021
- if (!currentNode)
1247
+ return null;
1248
+ }
1249
+ function analyzeVariableUsage(declarationId) {
1250
+ const variable = findVariableForIdentifier(declarationId);
1251
+ if (!variable) {
1252
+ return {
1253
+ jsxUsageSet: new Set,
1254
+ hasOutsideUsage: false
1255
+ };
1256
+ }
1257
+ const jsxUsageSet = new Set;
1258
+ let hasOutsideUsage = false;
1259
+ for (const reference of variable.references) {
1260
+ const identifier = reference.identifier;
1261
+ if (identifier === declarationId) {
1022
1262
  continue;
1023
- if (currentNode.type === "Identifier" && currentNode.name === varName && currentNode !== declarationNode) {
1024
- if (isContextProviderValueProp(currentNode)) {} else {
1025
- const jsxAncestor = getJSXAncestor(currentNode);
1026
- if (jsxAncestor && isCustomJSXElement(jsxAncestor)) {
1027
- usage.jsxUsageSet.add(jsxAncestor);
1028
- } else {
1029
- usage.hasOutsideUsage = true;
1030
- }
1031
- }
1032
1263
  }
1033
- const isFunction = currentNode.type === "FunctionDeclaration" || currentNode.type === "FunctionExpression" || currentNode.type === "ArrowFunctionExpression";
1034
- if (isFunction && currentNode !== componentFunction) {
1035
- let shadows = false;
1036
- if (currentNode.params && currentNode.params.length > 0) {
1037
- for (let i = 0;i < currentNode.params.length; i++) {
1038
- const param = currentNode.params[i];
1039
- if (param.type === "Identifier" && param.name === varName) {
1040
- shadows = true;
1041
- break;
1042
- }
1043
- }
1044
- }
1045
- if (shadows)
1046
- continue;
1264
+ if (isContextProviderValueProp(identifier)) {
1265
+ continue;
1047
1266
  }
1048
- const keys = visitorKeys[currentNode.type] || [];
1049
- for (let i = 0;i < keys.length; i++) {
1050
- const key = keys[i];
1051
- const child = currentNode[key];
1052
- if (Array.isArray(child)) {
1053
- for (let j = 0;j < child.length; j++) {
1054
- if (child[j] && typeof child[j].type === "string") {
1055
- stack.push(child[j]);
1056
- }
1057
- }
1058
- } else if (child && typeof child.type === "string") {
1059
- stack.push(child);
1060
- }
1267
+ const jsxAncestor = getJSXAncestor(identifier);
1268
+ if (jsxAncestor && isCustomJSXElement(jsxAncestor)) {
1269
+ jsxUsageSet.add(jsxAncestor);
1270
+ } else {
1271
+ hasOutsideUsage = true;
1061
1272
  }
1062
1273
  }
1063
- return usage;
1274
+ return {
1275
+ jsxUsageSet,
1276
+ hasOutsideUsage
1277
+ };
1064
1278
  }
1065
1279
  const componentHookVars = new WeakMap;
1066
1280
  function getHookSet(componentFunction) {
1067
- if (!componentHookVars.has(componentFunction)) {
1068
- componentHookVars.set(componentFunction, new Set);
1281
+ let hookSet = componentHookVars.get(componentFunction);
1282
+ if (!hookSet) {
1283
+ hookSet = new Set;
1284
+ componentHookVars.set(componentFunction, hookSet);
1069
1285
  }
1070
- return componentHookVars.get(componentFunction);
1286
+ return hookSet;
1071
1287
  }
1072
1288
  function hasHookDependency(node, hookSet) {
1073
- const sourceCode = context.getSourceCode();
1074
- const visitorKeys = sourceCode.visitorKeys || {};
1075
- const stack = [node];
1076
- while (stack.length) {
1077
- const currentNode = stack.pop();
1078
- if (!currentNode)
1079
- continue;
1080
- if (currentNode.type === "Identifier") {
1081
- if (hookSet.has(currentNode.name)) {
1082
- return true;
1289
+ if (!node.range) {
1290
+ return false;
1291
+ }
1292
+ const nodeRange = node.range;
1293
+ const nodeStart = nodeRange[0];
1294
+ const nodeEnd = nodeRange[1];
1295
+ let scope = context.sourceCode.getScope(node);
1296
+ while (scope) {
1297
+ for (const variable of scope.variables) {
1298
+ if (!hookSet.has(variable.name)) {
1299
+ continue;
1083
1300
  }
1084
- }
1085
- const keys = visitorKeys[currentNode.type] || [];
1086
- for (let i = 0;i < keys.length; i++) {
1087
- const key = keys[i];
1088
- const child = currentNode[key];
1089
- if (Array.isArray(child)) {
1090
- for (let j = 0;j < child.length; j++) {
1091
- if (child[j] && typeof child[j].type === "string") {
1092
- stack.push(child[j]);
1093
- }
1301
+ for (const reference of variable.references) {
1302
+ const identifier = reference.identifier;
1303
+ if (!identifier.range) {
1304
+ continue;
1305
+ }
1306
+ const refRange = identifier.range;
1307
+ const refStart = refRange[0];
1308
+ const refEnd = refRange[1];
1309
+ if (refStart >= nodeStart && refEnd <= nodeEnd) {
1310
+ return true;
1094
1311
  }
1095
- } else if (child && typeof child.type === "string") {
1096
- stack.push(child);
1097
1312
  }
1098
1313
  }
1314
+ scope = scope.upper ?? null;
1099
1315
  }
1100
1316
  return false;
1101
1317
  }
@@ -1104,30 +1320,34 @@ var localize_react_props_default = {
1104
1320
  const componentFunction = getComponentFunction(node);
1105
1321
  if (!componentFunction || !componentFunction.body)
1106
1322
  return;
1107
- if (node.init && node.id && node.id.type === "Identifier" && node.init.type === "CallExpression" && isHookCall(node.init)) {
1323
+ if (node.init && node.id && node.id.type === AST_NODE_TYPES2.Identifier && node.init.type === AST_NODE_TYPES2.CallExpression && isHookCall(node.init)) {
1108
1324
  const hookSet = getHookSet(componentFunction);
1109
1325
  hookSet.add(node.id.name);
1110
1326
  }
1111
- if (node.init && isUseStateCall(node.init) && node.id.type === "ArrayPattern" && node.id.elements.length >= 2) {
1327
+ if (node.init && isUseStateCall(node.init) && node.id.type === AST_NODE_TYPES2.ArrayPattern && node.id.elements.length >= 2) {
1112
1328
  const stateElem = node.id.elements[0];
1113
1329
  const setterElem = node.id.elements[1];
1114
- if (!stateElem || stateElem.type !== "Identifier" || !setterElem || setterElem.type !== "Identifier") {
1330
+ if (!stateElem || stateElem.type !== AST_NODE_TYPES2.Identifier || !setterElem || setterElem.type !== AST_NODE_TYPES2.Identifier) {
1115
1331
  return;
1116
1332
  }
1117
1333
  const stateVarName = stateElem.name;
1118
1334
  const setterVarName = setterElem.name;
1119
- const stateUsage = analyzeVariableUsage(stateElem, stateVarName, componentFunction);
1120
- const setterUsage = analyzeVariableUsage(setterElem, setterVarName, componentFunction);
1335
+ const stateUsage = analyzeVariableUsage(stateElem);
1336
+ const setterUsage = analyzeVariableUsage(setterElem);
1121
1337
  const stateExclusivelySingleJSX = !stateUsage.hasOutsideUsage && stateUsage.jsxUsageSet.size === 1;
1122
1338
  const setterExclusivelySingleJSX = !setterUsage.hasOutsideUsage && setterUsage.jsxUsageSet.size === 1;
1123
- if (stateExclusivelySingleJSX && setterExclusivelySingleJSX && [...stateUsage.jsxUsageSet][0] === [...setterUsage.jsxUsageSet][0]) {
1124
- context.report({
1125
- node,
1126
- message: "State variable '{{stateVarName}}' and its setter '{{setterVarName}}' are only passed to a single custom child component. Consider moving the state into that component.",
1127
- data: { stateVarName, setterVarName }
1128
- });
1339
+ if (stateExclusivelySingleJSX && setterExclusivelySingleJSX) {
1340
+ const stateTarget = getSingleSetElement(stateUsage.jsxUsageSet);
1341
+ const setterTarget = getSingleSetElement(setterUsage.jsxUsageSet);
1342
+ if (stateTarget && stateTarget === setterTarget) {
1343
+ context.report({
1344
+ node,
1345
+ messageId: "stateAndSetterToChild",
1346
+ data: { stateVarName, setterVarName }
1347
+ });
1348
+ }
1129
1349
  }
1130
- } else if (node.id && node.id.type === "Identifier") {
1350
+ } else if (node.id && node.id.type === AST_NODE_TYPES2.Identifier) {
1131
1351
  const varName = node.id.name;
1132
1352
  if (node.init) {
1133
1353
  const hookSet = getHookSet(componentFunction);
@@ -1135,9 +1355,9 @@ var localize_react_props_default = {
1135
1355
  return;
1136
1356
  }
1137
1357
  }
1138
- const usage = analyzeVariableUsage(node.id, varName, componentFunction);
1358
+ const usage = analyzeVariableUsage(node.id);
1139
1359
  if (!usage.hasOutsideUsage && usage.jsxUsageSet.size === 1) {
1140
- const target = [...usage.jsxUsageSet][0];
1360
+ const target = getSingleSetElement(usage.jsxUsageSet);
1141
1361
  const componentName = getJSXElementName(target);
1142
1362
  candidateVariables.push({
1143
1363
  node,
@@ -1149,244 +1369,367 @@ var localize_react_props_default = {
1149
1369
  },
1150
1370
  "Program:exit"() {
1151
1371
  const groups = new Map;
1152
- candidateVariables.forEach((candidate) => {
1372
+ for (const candidate of candidateVariables) {
1153
1373
  const key = candidate.componentName;
1154
- if (!groups.has(key)) {
1155
- groups.set(key, []);
1374
+ const existing = groups.get(key);
1375
+ if (existing) {
1376
+ existing.push(candidate);
1377
+ } else {
1378
+ groups.set(key, [candidate]);
1156
1379
  }
1157
- groups.get(key).push(candidate);
1158
- });
1159
- groups.forEach((candidates) => {
1380
+ }
1381
+ for (const candidates of groups.values()) {
1160
1382
  if (candidates.length === 1) {
1161
1383
  const candidate = candidates[0];
1384
+ if (!candidate) {
1385
+ continue;
1386
+ }
1162
1387
  context.report({
1163
1388
  node: candidate.node,
1164
- message: "Variable '{{varName}}' is only passed to a single custom child component. Consider moving it to that component.",
1389
+ messageId: "variableToChild",
1165
1390
  data: { varName: candidate.varName }
1166
1391
  });
1167
1392
  }
1168
- });
1393
+ }
1169
1394
  }
1170
1395
  };
1171
1396
  }
1172
1397
  };
1173
1398
 
1174
- // src/rules/no-or-none-component.js
1175
- var no_or_none_component_default = {
1399
+ // src/rules/no-or-none-component.ts
1400
+ var noOrNoneComponent = {
1176
1401
  meta: {
1177
1402
  type: "suggestion",
1178
1403
  docs: {
1179
- description: "Prefer using logical && operator over ternary with null/undefined for conditional JSX rendering.",
1180
- recommended: false
1404
+ description: "Prefer using logical && operator over ternary with null/undefined for conditional JSX rendering."
1181
1405
  },
1406
+ schema: [],
1182
1407
  messages: {
1183
1408
  useLogicalAnd: "Prefer using the logical '&&' operator instead of a ternary with null/undefined for conditional rendering."
1184
1409
  }
1185
1410
  },
1411
+ defaultOptions: [],
1186
1412
  create(context) {
1187
1413
  return {
1188
1414
  ConditionalExpression(node) {
1189
1415
  const alternate = node.alternate;
1190
- if (alternate && (alternate.type === "Literal" && alternate.value === null || alternate.type === "Identifier" && alternate.name === "undefined")) {
1191
- if (node.parent && node.parent.type === "JSXExpressionContainer") {
1192
- const containerParent = node.parent.parent;
1193
- if (containerParent && containerParent.type !== "JSXAttribute") {
1194
- context.report({
1195
- node,
1196
- messageId: "useLogicalAnd"
1197
- });
1198
- }
1199
- }
1416
+ const isNullAlternate = alternate && alternate.type === "Literal" && alternate.value === null;
1417
+ const isUndefinedAlternate = alternate && alternate.type === "Identifier" && alternate.name === "undefined";
1418
+ if (!isNullAlternate && !isUndefinedAlternate) {
1419
+ return;
1420
+ }
1421
+ const parent = node.parent;
1422
+ if (!parent || parent.type !== "JSXExpressionContainer") {
1423
+ return;
1424
+ }
1425
+ const containerParent = parent.parent;
1426
+ if (containerParent && containerParent.type !== "JSXAttribute") {
1427
+ context.report({
1428
+ node,
1429
+ messageId: "useLogicalAnd"
1430
+ });
1200
1431
  }
1201
1432
  }
1202
1433
  };
1203
1434
  }
1204
1435
  };
1205
1436
 
1206
- // src/rules/no-button-navigation.js
1207
- var no_button_navigation_default = {
1437
+ // src/rules/no-button-navigation.ts
1438
+ var noButtonNavigation = {
1208
1439
  meta: {
1209
1440
  type: "suggestion",
1210
1441
  docs: {
1211
- description: "Enforce using anchor tags for navigation instead of buttons whose onClick handlers change the path. Allow only query/hash updates via window.location.search or history.replaceState(window.location.pathname + \u2026).",
1212
- category: "Best Practices",
1213
- recommended: false
1442
+ description: "Enforce using anchor tags for navigation instead of buttons whose onClick handlers change the path. Allow only query/hash updates via window.location.search or history.replaceState(window.location.pathname + \u2026)."
1214
1443
  },
1215
- schema: []
1444
+ schema: [],
1445
+ messages: {
1446
+ noButtonNavigation: "Use an anchor tag for navigation instead of a button whose onClick handler changes the path. Detected: {{reason}}. Only query/hash updates (reading window.location.search, .pathname, or .hash) are allowed."
1447
+ }
1216
1448
  },
1449
+ defaultOptions: [],
1217
1450
  create(context) {
1218
- function urlUsesAllowedLocation(argNode) {
1219
- let allowed = false;
1220
- const visited = new WeakSet;
1221
- function check(n) {
1222
- if (allowed || !n || typeof n !== "object" || visited.has(n))
1451
+ const handlerStack = [];
1452
+ function getCurrentHandler() {
1453
+ const state = handlerStack[handlerStack.length - 1];
1454
+ if (!state) {
1455
+ return null;
1456
+ }
1457
+ return state;
1458
+ }
1459
+ function isOnClickButtonHandler(node) {
1460
+ const parent = node.parent;
1461
+ if (!parent || parent.type !== "JSXExpressionContainer") {
1462
+ return null;
1463
+ }
1464
+ const attributeCandidate = parent.parent;
1465
+ if (!attributeCandidate || attributeCandidate.type !== "JSXAttribute") {
1466
+ return null;
1467
+ }
1468
+ const attr = attributeCandidate;
1469
+ if (!attr.name || attr.name.type !== "JSXIdentifier" || attr.name.name !== "onClick") {
1470
+ return null;
1471
+ }
1472
+ const openingElementCandidate = attr.parent;
1473
+ if (!openingElementCandidate || openingElementCandidate.type !== "JSXOpeningElement") {
1474
+ return null;
1475
+ }
1476
+ const openingElement = openingElementCandidate;
1477
+ const tagNameNode = openingElement.name;
1478
+ if (tagNameNode.type !== "JSXIdentifier" || tagNameNode.name !== "button") {
1479
+ return null;
1480
+ }
1481
+ return attr;
1482
+ }
1483
+ function isWindowLocationMember(member) {
1484
+ const object = member.object;
1485
+ if (object.type !== "MemberExpression") {
1486
+ return false;
1487
+ }
1488
+ const outerObject = object.object;
1489
+ const outerProperty = object.property;
1490
+ if (outerObject.type === "Identifier" && outerObject.name === "window" && outerProperty.type === "Identifier" && outerProperty.name === "location") {
1491
+ return true;
1492
+ }
1493
+ return false;
1494
+ }
1495
+ function isWindowHistoryMember(member) {
1496
+ const object = member.object;
1497
+ if (object.type !== "MemberExpression") {
1498
+ return false;
1499
+ }
1500
+ const outerObject = object.object;
1501
+ const outerProperty = object.property;
1502
+ if (outerObject.type === "Identifier" && outerObject.name === "window" && outerProperty.type === "Identifier" && outerProperty.name === "history") {
1503
+ return true;
1504
+ }
1505
+ return false;
1506
+ }
1507
+ return {
1508
+ ArrowFunctionExpression(node) {
1509
+ const attr = isOnClickButtonHandler(node);
1510
+ if (!attr) {
1223
1511
  return;
1224
- visited.add(n);
1225
- if (n.type === "MemberExpression" && n.object.type === "MemberExpression" && n.object.object.type === "Identifier" && n.object.object.name === "window" && n.object.property.type === "Identifier" && n.object.property.name === "location" && n.property.type === "Identifier" && (n.property.name === "pathname" || n.property.name === "search" || n.property.name === "hash")) {
1226
- allowed = true;
1512
+ }
1513
+ handlerStack.push({
1514
+ attribute: attr,
1515
+ reason: null,
1516
+ sawReplaceCall: false,
1517
+ sawAllowedLocationRead: false
1518
+ });
1519
+ },
1520
+ "ArrowFunctionExpression:exit"(node) {
1521
+ const attr = isOnClickButtonHandler(node);
1522
+ if (!attr) {
1227
1523
  return;
1228
1524
  }
1229
- for (const key of Object.keys(n)) {
1230
- if (key === "parent")
1231
- continue;
1232
- const child = n[key];
1233
- if (Array.isArray(child)) {
1234
- child.forEach((c) => check(c));
1235
- } else {
1236
- check(child);
1237
- }
1525
+ const state = handlerStack.pop();
1526
+ if (!state) {
1527
+ return;
1238
1528
  }
1239
- }
1240
- check(argNode);
1241
- return allowed;
1242
- }
1243
- function containsWindowNavigation(node) {
1244
- let reason = null;
1245
- const visited = new WeakSet;
1246
- let sawReplaceCall = false;
1247
- let sawAllowedLocationRead = false;
1248
- function inspect(n, parent) {
1249
- if (reason || !n || typeof n !== "object" || visited.has(n))
1529
+ const reason = state.reason;
1530
+ const sawReplaceCall = state.sawReplaceCall;
1531
+ const sawAllowedLocationRead = state.sawAllowedLocationRead;
1532
+ if (reason) {
1533
+ context.report({
1534
+ node: state.attribute,
1535
+ messageId: "noButtonNavigation",
1536
+ data: { reason }
1537
+ });
1250
1538
  return;
1251
- visited.add(n);
1252
- if (n.type === "MemberExpression" && n.object.type === "Identifier" && n.object.name === "window" && n.property.type === "Identifier" && n.property.name === "open") {
1253
- reason = "window.open";
1539
+ }
1540
+ if (sawReplaceCall && !sawAllowedLocationRead) {
1541
+ context.report({
1542
+ node: state.attribute,
1543
+ messageId: "noButtonNavigation",
1544
+ data: {
1545
+ reason: "history.replaceState/pushState without reading window.location"
1546
+ }
1547
+ });
1548
+ }
1549
+ },
1550
+ FunctionExpression(node) {
1551
+ const attr = isOnClickButtonHandler(node);
1552
+ if (!attr) {
1254
1553
  return;
1255
1554
  }
1256
- if (n.type === "AssignmentExpression" && n.left.type === "MemberExpression") {
1257
- const left = n.left;
1258
- if (left.object.type === "Identifier" && left.object.name === "window" && left.property.type === "Identifier" && left.property.name === "location") {
1259
- reason = "assignment to window.location";
1260
- return;
1555
+ handlerStack.push({
1556
+ attribute: attr,
1557
+ reason: null,
1558
+ sawReplaceCall: false,
1559
+ sawAllowedLocationRead: false
1560
+ });
1561
+ },
1562
+ "FunctionExpression:exit"(node) {
1563
+ const attr = isOnClickButtonHandler(node);
1564
+ if (!attr) {
1565
+ return;
1566
+ }
1567
+ const state = handlerStack.pop();
1568
+ if (!state) {
1569
+ return;
1570
+ }
1571
+ const reason = state.reason;
1572
+ const sawReplaceCall = state.sawReplaceCall;
1573
+ const sawAllowedLocationRead = state.sawAllowedLocationRead;
1574
+ if (reason) {
1575
+ context.report({
1576
+ node: state.attribute,
1577
+ messageId: "noButtonNavigation",
1578
+ data: { reason }
1579
+ });
1580
+ return;
1581
+ }
1582
+ if (sawReplaceCall && !sawAllowedLocationRead) {
1583
+ context.report({
1584
+ node: state.attribute,
1585
+ messageId: "noButtonNavigation",
1586
+ data: {
1587
+ reason: "history.replaceState/pushState without reading window.location"
1588
+ }
1589
+ });
1590
+ }
1591
+ },
1592
+ MemberExpression(node) {
1593
+ const state = getCurrentHandler();
1594
+ if (!state) {
1595
+ return;
1596
+ }
1597
+ if (node.object.type === "Identifier" && node.object.name === "window" && node.property.type === "Identifier" && node.property.name === "open") {
1598
+ if (!state.reason) {
1599
+ state.reason = "window.open";
1261
1600
  }
1262
- if (left.object.type === "MemberExpression" && left.object.object.type === "Identifier" && left.object.object.name === "window" && left.object.property.type === "Identifier" && left.object.property.name === "location") {
1263
- reason = "assignment to window.location sub-property";
1264
- return;
1601
+ }
1602
+ if (isWindowLocationMember(node) && node.property.type === "Identifier" && (node.property.name === "search" || node.property.name === "pathname" || node.property.name === "hash")) {
1603
+ state.sawAllowedLocationRead = true;
1604
+ }
1605
+ },
1606
+ AssignmentExpression(node) {
1607
+ const state = getCurrentHandler();
1608
+ if (!state) {
1609
+ return;
1610
+ }
1611
+ if (node.left.type !== "MemberExpression") {
1612
+ return;
1613
+ }
1614
+ const left = node.left;
1615
+ if (left.object.type === "Identifier" && left.object.name === "window" && left.property.type === "Identifier" && left.property.name === "location") {
1616
+ if (!state.reason) {
1617
+ state.reason = "assignment to window.location";
1265
1618
  }
1619
+ return;
1266
1620
  }
1267
- if (n.type === "MemberExpression" && n.object.type === "MemberExpression" && n.object.object.type === "Identifier" && n.object.object.name === "window" && n.object.property.type === "Identifier" && n.object.property.name === "location" && n.property.type === "Identifier" && n.property.name === "replace") {
1268
- if (parent && parent.type === "CallExpression") {
1269
- reason = "window.location.replace";
1270
- return;
1621
+ if (isWindowLocationMember(left)) {
1622
+ if (!state.reason) {
1623
+ state.reason = "assignment to window.location sub-property";
1271
1624
  }
1272
1625
  }
1273
- if (n.type === "MemberExpression" && n.object.type === "MemberExpression" && n.object.object.type === "Identifier" && n.object.object.name === "window" && n.object.property.type === "Identifier" && n.object.property.name === "history" && n.property.type === "Identifier" && (n.property.name === "pushState" || n.property.name === "replaceState")) {
1274
- sawReplaceCall = true;
1626
+ },
1627
+ CallExpression(node) {
1628
+ const state = getCurrentHandler();
1629
+ if (!state) {
1630
+ return;
1275
1631
  }
1276
- if (n.type === "MemberExpression" && n.object.type === "MemberExpression" && n.object.object.type === "Identifier" && n.object.object.name === "window" && n.object.property.type === "Identifier" && n.object.property.name === "location" && n.property.type === "Identifier" && (n.property.name === "search" || n.property.name === "pathname" || n.property.name === "hash")) {
1277
- sawAllowedLocationRead = true;
1632
+ const callee = node.callee;
1633
+ if (callee.type !== "MemberExpression") {
1634
+ return;
1278
1635
  }
1279
- for (const key of Object.keys(n)) {
1280
- if (key === "parent" || reason)
1281
- continue;
1282
- const child = n[key];
1283
- if (Array.isArray(child)) {
1284
- child.forEach((c) => inspect(c, n));
1285
- } else {
1286
- inspect(child, n);
1636
+ if (isWindowLocationMember(callee) && callee.property.type === "Identifier" && callee.property.name === "replace") {
1637
+ if (!state.reason) {
1638
+ state.reason = "window.location.replace";
1287
1639
  }
1288
- if (reason)
1289
- return;
1640
+ return;
1290
1641
  }
1291
- }
1292
- inspect(node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" ? node.body : node, null);
1293
- if (reason) {
1294
- return { shouldReport: true, reason };
1295
- }
1296
- if (sawReplaceCall && !sawAllowedLocationRead) {
1297
- return {
1298
- shouldReport: true,
1299
- reason: "history.replace/pushState without reading window.location"
1300
- };
1301
- }
1302
- return { shouldReport: false, reason: null };
1303
- }
1304
- return {
1305
- JSXElement(node) {
1306
- const { openingElement } = node;
1307
- if (openingElement.name.type === "JSXIdentifier" && openingElement.name.name === "button") {
1308
- for (const attr of openingElement.attributes) {
1309
- if (attr.type === "JSXAttribute" && attr.name.name === "onClick" && attr.value?.type === "JSXExpressionContainer") {
1310
- const expr = attr.value.expression;
1311
- if (expr.type === "ArrowFunctionExpression" || expr.type === "FunctionExpression") {
1312
- const { shouldReport, reason } = containsWindowNavigation(expr);
1313
- if (shouldReport) {
1314
- context.report({
1315
- node: attr,
1316
- message: `Use an anchor tag for navigation instead of a button whose onClick handler changes the path. ` + `Detected: ${reason}. Only query/hash updates (reading window.location.search, .pathname, or .hash) are allowed.`
1317
- });
1318
- }
1319
- }
1320
- }
1321
- }
1642
+ if (isWindowHistoryMember(callee) && callee.property.type === "Identifier" && (callee.property.name === "pushState" || callee.property.name === "replaceState")) {
1643
+ state.sawReplaceCall = true;
1322
1644
  }
1323
1645
  }
1324
1646
  };
1325
1647
  }
1326
1648
  };
1327
1649
 
1328
- // src/rules/no-multi-style-objects.js
1329
- var no_multi_style_objects_default = {
1650
+ // src/rules/no-multi-style-objects.ts
1651
+ var noMultiStyleObjects = {
1330
1652
  meta: {
1331
1653
  type: "problem",
1332
1654
  docs: {
1333
- description: "Disallow grouping CSS style objects in a single export; export each style separately.",
1334
- category: "Best Practices",
1335
- recommended: false
1655
+ description: "Disallow grouping CSS style objects in a single export; export each style separately."
1336
1656
  },
1337
- schema: []
1657
+ schema: [],
1658
+ messages: {
1659
+ noMultiStyleObjects: "Do not group CSS style objects in a single export; export each style separately."
1660
+ }
1338
1661
  },
1662
+ defaultOptions: [],
1339
1663
  create(context) {
1340
1664
  function checkObjectExpression(node) {
1341
- if (node.properties && node.properties.length > 0) {
1342
- const cssStyleProperties = node.properties.filter((prop) => {
1343
- if (prop.key) {
1344
- if (prop.key.type === "Identifier") {
1345
- return prop.key.name.endsWith("Style");
1346
- }
1347
- if (prop.key.type === "Literal" && typeof prop.key.value === "string") {
1348
- return prop.key.value.endsWith("Style");
1349
- }
1350
- }
1351
- return false;
1352
- });
1353
- if (cssStyleProperties.length > 1) {
1354
- context.report({
1355
- node,
1356
- message: "Do not group CSS style objects in a single export; export each style separately."
1357
- });
1665
+ if (!node.properties.length) {
1666
+ return;
1667
+ }
1668
+ const cssStyleProperties = [];
1669
+ for (const prop of node.properties) {
1670
+ if (prop.type !== "Property") {
1671
+ continue;
1672
+ }
1673
+ const key = prop.key;
1674
+ let name = null;
1675
+ if (key.type === "Identifier") {
1676
+ name = key.name;
1677
+ } else if (key.type === "Literal" && typeof key.value === "string") {
1678
+ name = key.value;
1679
+ }
1680
+ if (name && name.endsWith("Style")) {
1681
+ cssStyleProperties.push(prop);
1358
1682
  }
1359
1683
  }
1684
+ if (cssStyleProperties.length > 1) {
1685
+ context.report({
1686
+ node,
1687
+ messageId: "noMultiStyleObjects"
1688
+ });
1689
+ }
1360
1690
  }
1361
1691
  return {
1362
1692
  ExportDefaultDeclaration(node) {
1363
- if (node.declaration && node.declaration.type === "ObjectExpression") {
1364
- checkObjectExpression(node.declaration);
1693
+ const declaration = node.declaration;
1694
+ if (declaration && declaration.type === "ObjectExpression") {
1695
+ checkObjectExpression(declaration);
1365
1696
  }
1366
1697
  },
1367
1698
  ReturnStatement(node) {
1368
- if (node.argument && node.argument.type === "ObjectExpression") {
1369
- checkObjectExpression(node.argument);
1699
+ const argument = node.argument;
1700
+ if (argument && argument.type === "ObjectExpression") {
1701
+ checkObjectExpression(argument);
1370
1702
  }
1371
1703
  }
1372
1704
  };
1373
1705
  }
1374
1706
  };
1375
1707
 
1376
- // src/rules/no-useless-function.js
1377
- var no_useless_function_default = {
1708
+ // src/rules/no-useless-function.ts
1709
+ var noUselessFunction = {
1378
1710
  meta: {
1379
1711
  type: "suggestion",
1380
1712
  docs: {
1381
- description: "Disallow functions that have no parameters and just return an object literal; consider exporting the object directly, unless the function is used as a callback (e.g., in react-spring).",
1382
- category: "Best Practices",
1383
- recommended: false
1713
+ description: "Disallow functions that have no parameters and just return an object literal; consider exporting the object directly, unless the function is used as a callback (e.g., in react-spring)."
1384
1714
  },
1385
- fixable: null
1715
+ schema: [],
1716
+ messages: {
1717
+ uselessFunction: "This function has no parameters and simply returns an object. Consider exporting the object directly instead of wrapping it in a function."
1718
+ }
1386
1719
  },
1720
+ defaultOptions: [],
1387
1721
  create(context) {
1388
1722
  function isCallbackFunction(node) {
1389
- return node.parent && node.parent.type === "CallExpression" && node.parent.arguments.includes(node);
1723
+ const parent = node.parent;
1724
+ if (!parent || parent.type !== "CallExpression") {
1725
+ return false;
1726
+ }
1727
+ for (const arg of parent.arguments) {
1728
+ if (arg === node) {
1729
+ return true;
1730
+ }
1731
+ }
1732
+ return false;
1390
1733
  }
1391
1734
  return {
1392
1735
  ArrowFunctionExpression(node) {
@@ -1396,7 +1739,7 @@ var no_useless_function_default = {
1396
1739
  }
1397
1740
  context.report({
1398
1741
  node,
1399
- message: "This function has no parameters and simply returns an object. Consider exporting the object directly instead of wrapping it in a function."
1742
+ messageId: "uselessFunction"
1400
1743
  });
1401
1744
  }
1402
1745
  }
@@ -1404,13 +1747,12 @@ var no_useless_function_default = {
1404
1747
  }
1405
1748
  };
1406
1749
 
1407
- // src/rules/min-var-length.js
1408
- var min_var_length_default = {
1750
+ // src/rules/min-var-length.ts
1751
+ var minVarLength = {
1409
1752
  meta: {
1410
1753
  type: "problem",
1411
1754
  docs: {
1412
- description: "Disallow variable names shorter than the configured minimum length unless an outer variable with a longer name starting with the same characters exists. You can exempt specific variable names using the allowedVars option.",
1413
- recommended: false
1755
+ description: "Disallow variable names shorter than the configured minimum length unless an outer variable with a longer name starting with the same characters exists. You can exempt specific variable names using the allowedVars option."
1414
1756
  },
1415
1757
  schema: [
1416
1758
  {
@@ -1436,11 +1778,14 @@ var min_var_length_default = {
1436
1778
  variableNameTooShort: "Variable '{{name}}' is too short. Minimum allowed length is {{minLength}} characters unless an outer variable with a longer name starting with '{{name}}' exists."
1437
1779
  }
1438
1780
  },
1781
+ defaultOptions: [{}],
1439
1782
  create(context) {
1440
- const sourceCode = context.getSourceCode();
1441
- const options = context.options[0] || {};
1442
- const minLength = typeof options.minLength === "number" ? options.minLength : 1;
1443
- const allowedVars = options.allowedVars || [];
1783
+ const sourceCode = context.sourceCode;
1784
+ const options = context.options[0];
1785
+ const configuredMinLength = options && typeof options.minLength === "number" ? options.minLength : 1;
1786
+ const configuredAllowedVars = options && Array.isArray(options.allowedVars) ? options.allowedVars : [];
1787
+ const minLength = configuredMinLength;
1788
+ const allowedVars = configuredAllowedVars;
1444
1789
  function getAncestors(node) {
1445
1790
  const ancestors = [];
1446
1791
  let current = node.parent;
@@ -1451,7 +1796,15 @@ var min_var_length_default = {
1451
1796
  return ancestors;
1452
1797
  }
1453
1798
  function getScope(node) {
1454
- return sourceCode.scopeManager.acquire(node) || sourceCode.scopeManager.globalScope;
1799
+ const scopeManager = sourceCode.scopeManager;
1800
+ if (!scopeManager) {
1801
+ return null;
1802
+ }
1803
+ const acquired = scopeManager.acquire(node);
1804
+ if (acquired) {
1805
+ return acquired;
1806
+ }
1807
+ return scopeManager.globalScope ?? null;
1455
1808
  }
1456
1809
  function getVariablesInNearestBlock(node) {
1457
1810
  let current = node.parent;
@@ -1459,7 +1812,7 @@ var min_var_length_default = {
1459
1812
  current = current.parent;
1460
1813
  }
1461
1814
  const names = [];
1462
- if (current && Array.isArray(current.body)) {
1815
+ if (current && current.type === "BlockStatement" && Array.isArray(current.body)) {
1463
1816
  for (const stmt of current.body) {
1464
1817
  if (stmt.type === "VariableDeclaration") {
1465
1818
  for (const decl of stmt.declarations) {
@@ -1490,8 +1843,9 @@ var min_var_length_default = {
1490
1843
  break;
1491
1844
  case "ArrayPattern":
1492
1845
  for (const element of pattern.elements) {
1493
- if (element)
1846
+ if (element) {
1494
1847
  extractIdentifiersFromPattern(element, identifiers);
1848
+ }
1495
1849
  }
1496
1850
  break;
1497
1851
  case "AssignmentPattern":
@@ -1503,8 +1857,8 @@ var min_var_length_default = {
1503
1857
  return identifiers;
1504
1858
  }
1505
1859
  function hasOuterCorrespondingIdentifier(shortName, node) {
1506
- let currentScope = getScope(node);
1507
- let outer = currentScope.upper;
1860
+ const startingScope = getScope(node);
1861
+ let outer = startingScope && startingScope.upper ? startingScope.upper : null;
1508
1862
  while (outer) {
1509
1863
  for (const variable of outer.variables) {
1510
1864
  if (variable.name.length >= minLength && variable.name.length > shortName.length && variable.name.startsWith(shortName)) {
@@ -1550,7 +1904,7 @@ var min_var_length_default = {
1550
1904
  }
1551
1905
  function checkIdentifier(node) {
1552
1906
  const name = node.name;
1553
- if (typeof name === "string" && name.length < minLength) {
1907
+ if (name.length < minLength) {
1554
1908
  if (allowedVars.includes(name)) {
1555
1909
  return;
1556
1910
  }
@@ -1581,8 +1935,9 @@ var min_var_length_default = {
1581
1935
  break;
1582
1936
  case "ArrayPattern":
1583
1937
  for (const element of pattern.elements) {
1584
- if (element)
1938
+ if (element) {
1585
1939
  checkPattern(element);
1940
+ }
1586
1941
  }
1587
1942
  break;
1588
1943
  case "AssignmentPattern":
@@ -1612,23 +1967,26 @@ var min_var_length_default = {
1612
1967
  }
1613
1968
  };
1614
1969
 
1615
- // src/rules/max-depth-extended.js
1616
- var max_depth_extended_default = {
1970
+ // src/rules/max-depth-extended.ts
1971
+ var maxDepthExtended = {
1617
1972
  meta: {
1618
1973
  type: "suggestion",
1619
1974
  docs: {
1620
- description: "disallow too many nested blocks except when the block only contains an early exit (return or throw)",
1621
- category: "Best Practices",
1622
- recommended: false
1975
+ description: "disallow too many nested blocks except when the block only contains an early exit (return or throw)"
1623
1976
  },
1624
1977
  schema: [
1625
1978
  {
1626
1979
  type: "number"
1627
1980
  }
1628
- ]
1981
+ ],
1982
+ messages: {
1983
+ tooDeep: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}} or an early exit."
1984
+ }
1629
1985
  },
1986
+ defaultOptions: [1],
1630
1987
  create(context) {
1631
- const maxDepth = typeof context.options[0] === "number" ? context.options[0] : 1;
1988
+ const option = context.options[0];
1989
+ const maxDepth = typeof option === "number" ? option : 1;
1632
1990
  const functionStack = [];
1633
1991
  function getAncestors(node) {
1634
1992
  const ancestors = [];
@@ -1640,13 +1998,44 @@ var max_depth_extended_default = {
1640
1998
  return ancestors;
1641
1999
  }
1642
2000
  function isEarlyExitBlock(node) {
1643
- return node.body.length === 1 && (node.body[0].type === "ReturnStatement" || node.body[0].type === "ThrowStatement");
2001
+ if (node.body.length !== 1) {
2002
+ return false;
2003
+ }
2004
+ const first = node.body[0];
2005
+ if (!first) {
2006
+ return false;
2007
+ }
2008
+ return first.type === "ReturnStatement" || first.type === "ThrowStatement";
2009
+ }
2010
+ function incrementCurrentDepth() {
2011
+ if (functionStack.length === 0) {
2012
+ return null;
2013
+ }
2014
+ const index = functionStack.length - 1;
2015
+ const currentDepth = functionStack[index];
2016
+ if (typeof currentDepth !== "number") {
2017
+ return null;
2018
+ }
2019
+ const nextDepth = currentDepth + 1;
2020
+ functionStack[index] = nextDepth;
2021
+ return nextDepth;
2022
+ }
2023
+ function decrementCurrentDepth() {
2024
+ if (functionStack.length === 0) {
2025
+ return;
2026
+ }
2027
+ const index = functionStack.length - 1;
2028
+ const currentDepth = functionStack[index];
2029
+ if (typeof currentDepth !== "number") {
2030
+ return;
2031
+ }
2032
+ functionStack[index] = currentDepth - 1;
1644
2033
  }
1645
2034
  function checkDepth(node, depth) {
1646
2035
  if (depth > maxDepth) {
1647
2036
  context.report({
1648
2037
  node,
1649
- message: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}} or an early exit.",
2038
+ messageId: "tooDeep",
1650
2039
  data: { depth, maxDepth }
1651
2040
  });
1652
2041
  }
@@ -1663,30 +2052,28 @@ var max_depth_extended_default = {
1663
2052
  },
1664
2053
  BlockStatement(node) {
1665
2054
  const ancestors = getAncestors(node);
1666
- const parent = ancestors[0];
2055
+ const parent = ancestors.length > 0 ? ancestors[0] : undefined;
1667
2056
  if (parent && (parent.type === "FunctionDeclaration" || parent.type === "FunctionExpression" || parent.type === "ArrowFunctionExpression") && node === parent.body) {
1668
2057
  return;
1669
2058
  }
1670
2059
  if (isEarlyExitBlock(node)) {
1671
2060
  return;
1672
2061
  }
1673
- if (functionStack.length > 0) {
1674
- functionStack[functionStack.length - 1]++;
1675
- checkDepth(node, functionStack[functionStack.length - 1]);
2062
+ const depth = incrementCurrentDepth();
2063
+ if (depth !== null) {
2064
+ checkDepth(node, depth);
1676
2065
  }
1677
2066
  },
1678
2067
  "BlockStatement:exit"(node) {
1679
2068
  const ancestors = getAncestors(node);
1680
- const parent = ancestors[0];
2069
+ const parent = ancestors.length > 0 ? ancestors[0] : undefined;
1681
2070
  if (parent && (parent.type === "FunctionDeclaration" || parent.type === "FunctionExpression" || parent.type === "ArrowFunctionExpression") && node === parent.body) {
1682
2071
  return;
1683
2072
  }
1684
2073
  if (isEarlyExitBlock(node)) {
1685
2074
  return;
1686
2075
  }
1687
- if (functionStack.length > 0) {
1688
- functionStack[functionStack.length - 1]--;
1689
- }
2076
+ decrementCurrentDepth();
1690
2077
  },
1691
2078
  "FunctionDeclaration:exit"() {
1692
2079
  functionStack.pop();
@@ -1701,88 +2088,103 @@ var max_depth_extended_default = {
1701
2088
  }
1702
2089
  };
1703
2090
 
1704
- // src/rules/spring-naming-convention.js
1705
- var spring_naming_convention_default = {
2091
+ // src/rules/spring-naming-convention.ts
2092
+ var springNamingConvention = {
1706
2093
  meta: {
1707
2094
  type: "problem",
1708
2095
  docs: {
1709
- description: "Enforce correct naming for useSpring and useSprings hook destructuring",
1710
- category: "Stylistic Issues",
1711
- recommended: false
2096
+ description: "Enforce correct naming for useSpring and useSprings hook destructuring"
1712
2097
  },
1713
- schema: []
2098
+ schema: [],
2099
+ messages: {
2100
+ firstMustEndWithSprings: "The first variable must end with 'Springs'.",
2101
+ firstMustHaveBase: "The first variable must have a non-empty name before 'Springs'.",
2102
+ secondMustMatch: "The second variable must be named '{{expected}}'.",
2103
+ pluralRequired: "The first variable for useSprings should be plural (ending with 's') before 'Springs'."
2104
+ }
1714
2105
  },
2106
+ defaultOptions: [],
1715
2107
  create(context) {
1716
2108
  return {
1717
2109
  VariableDeclarator(node) {
1718
- if (node.init && node.init.type === "CallExpression" && node.init.callee && node.init.callee.type === "Identifier" && (node.init.callee.name === "useSpring" || node.init.callee.name === "useSprings")) {
1719
- const hookName = node.init.callee.name;
1720
- if (node.id && node.id.type === "ArrayPattern") {
1721
- const elements = node.id.elements;
1722
- if (elements.length < 2) {
1723
- return;
1724
- }
1725
- const firstElem = elements[0];
1726
- const secondElem = elements[1];
1727
- if (!firstElem || firstElem.type !== "Identifier" || !secondElem || secondElem.type !== "Identifier") {
1728
- return;
1729
- }
1730
- const firstName = firstElem.name;
1731
- const secondName = secondElem.name;
1732
- if (hookName === "useSpring") {
1733
- if (!firstName.endsWith("Springs")) {
1734
- context.report({
1735
- node: firstElem,
1736
- message: "The first variable from useSpring must end with 'Springs'."
1737
- });
1738
- } else {
1739
- const base = firstName.slice(0, -"Springs".length);
1740
- if (!base) {
1741
- context.report({
1742
- node: firstElem,
1743
- message: "The first variable must have a non-empty name before 'Springs'."
1744
- });
1745
- return;
1746
- }
1747
- const expectedSecond = base + "Api";
1748
- if (secondName !== expectedSecond) {
1749
- context.report({
1750
- node: secondElem,
1751
- message: `The second variable from useSpring must be named '${expectedSecond}'.`
1752
- });
1753
- }
1754
- }
1755
- } else if (hookName === "useSprings") {
1756
- if (!firstName.endsWith("Springs")) {
1757
- context.report({
1758
- node: firstElem,
1759
- message: "The first variable from useSprings must end with 'Springs'."
1760
- });
1761
- } else {
1762
- const basePlural = firstName.slice(0, -"Springs".length);
1763
- if (!basePlural) {
1764
- context.report({
1765
- node: firstElem,
1766
- message: "The first variable must have a non-empty name before 'Springs'."
1767
- });
1768
- return;
1769
- }
1770
- if (!basePlural.endsWith("s")) {
1771
- context.report({
1772
- node: firstElem,
1773
- message: "The first variable for useSprings should be a plural name (ending with an 's') before 'Springs'."
1774
- });
1775
- } else {
1776
- const expectedSecond = basePlural + "Api";
1777
- if (secondName !== expectedSecond) {
1778
- context.report({
1779
- node: secondElem,
1780
- message: `The second variable from useSprings must be named '${expectedSecond}'.`
1781
- });
1782
- }
1783
- }
1784
- }
1785
- }
2110
+ const init = node.init;
2111
+ if (!init || init.type !== "CallExpression" || init.callee.type !== "Identifier") {
2112
+ return;
2113
+ }
2114
+ const hookName = init.callee.name;
2115
+ if (hookName !== "useSpring" && hookName !== "useSprings") {
2116
+ return;
2117
+ }
2118
+ if (node.id.type !== "ArrayPattern") {
2119
+ return;
2120
+ }
2121
+ const elements = node.id.elements;
2122
+ if (elements.length < 2) {
2123
+ return;
2124
+ }
2125
+ const firstElem = elements[0];
2126
+ const secondElem = elements[1];
2127
+ if (!firstElem || firstElem.type !== "Identifier" || !secondElem || secondElem.type !== "Identifier") {
2128
+ return;
2129
+ }
2130
+ const firstName = firstElem.name;
2131
+ const secondName = secondElem.name;
2132
+ if (hookName === "useSpring") {
2133
+ if (!firstName.endsWith("Springs")) {
2134
+ context.report({
2135
+ node: firstElem,
2136
+ messageId: "firstMustEndWithSprings"
2137
+ });
2138
+ return;
2139
+ }
2140
+ const base = firstName.slice(0, -"Springs".length);
2141
+ if (!base) {
2142
+ context.report({
2143
+ node: firstElem,
2144
+ messageId: "firstMustHaveBase"
2145
+ });
2146
+ return;
2147
+ }
2148
+ const expectedSecond = `${base}Api`;
2149
+ if (secondName !== expectedSecond) {
2150
+ context.report({
2151
+ node: secondElem,
2152
+ messageId: "secondMustMatch",
2153
+ data: { expected: expectedSecond }
2154
+ });
2155
+ }
2156
+ return;
2157
+ }
2158
+ if (hookName === "useSprings") {
2159
+ if (!firstName.endsWith("Springs")) {
2160
+ context.report({
2161
+ node: firstElem,
2162
+ messageId: "firstMustEndWithSprings"
2163
+ });
2164
+ return;
2165
+ }
2166
+ const basePlural = firstName.slice(0, -"Springs".length);
2167
+ if (!basePlural) {
2168
+ context.report({
2169
+ node: firstElem,
2170
+ messageId: "firstMustHaveBase"
2171
+ });
2172
+ return;
2173
+ }
2174
+ if (!basePlural.endsWith("s")) {
2175
+ context.report({
2176
+ node: firstElem,
2177
+ messageId: "pluralRequired"
2178
+ });
2179
+ return;
2180
+ }
2181
+ const expectedSecond = `${basePlural}Api`;
2182
+ if (secondName !== expectedSecond) {
2183
+ context.report({
2184
+ node: secondElem,
2185
+ messageId: "secondMustMatch",
2186
+ data: { expected: expectedSecond }
2187
+ });
1786
2188
  }
1787
2189
  }
1788
2190
  }
@@ -1790,14 +2192,12 @@ var spring_naming_convention_default = {
1790
2192
  }
1791
2193
  };
1792
2194
 
1793
- // src/rules/inline-style-limit.js
1794
- var inline_style_limit_default = {
2195
+ // src/rules/inline-style-limit.ts
2196
+ var inlineStyleLimit = {
1795
2197
  meta: {
1796
2198
  type: "suggestion",
1797
2199
  docs: {
1798
- description: "Disallow inline style objects with too many keys and encourage extracting them",
1799
- category: "Best Practices",
1800
- recommended: false
2200
+ description: "Disallow inline style objects with too many keys and encourage extracting them"
1801
2201
  },
1802
2202
  schema: [
1803
2203
  {
@@ -1822,12 +2222,13 @@ var inline_style_limit_default = {
1822
2222
  extractStyle: "Inline style objects should be extracted into a separate object or file when containing more than {{max}} keys."
1823
2223
  }
1824
2224
  },
2225
+ defaultOptions: [3],
1825
2226
  create(context) {
1826
2227
  const option = context.options[0];
1827
2228
  const maxKeys = typeof option === "number" ? option : option && option.maxKeys || 3;
1828
2229
  return {
1829
2230
  JSXAttribute(node) {
1830
- if (node.name.name !== "style") {
2231
+ if (node.name.type !== "JSXIdentifier" || node.name.name !== "style") {
1831
2232
  return;
1832
2233
  }
1833
2234
  if (node.value && node.value.type === "JSXExpressionContainer" && node.value.expression && node.value.expression.type === "ObjectExpression") {
@@ -1846,23 +2247,22 @@ var inline_style_limit_default = {
1846
2247
  }
1847
2248
  };
1848
2249
 
1849
- // src/rules/no-inline-prop-types.js
1850
- var no_inline_prop_types_default = {
2250
+ // src/rules/no-inline-prop-types.ts
2251
+ var noInlinePropTypes = {
1851
2252
  meta: {
1852
2253
  type: "suggestion",
1853
2254
  docs: {
1854
- description: "Enforce that component prop types are not defined inline (using an object literal) but rather use a named type or interface.",
1855
- category: "Best Practices",
1856
- recommended: false
2255
+ description: "Enforce that component prop types are not defined inline (using an object literal) but rather use a named type or interface."
1857
2256
  },
1858
2257
  schema: [],
1859
2258
  messages: {
1860
2259
  noInlinePropTypes: "Inline prop type definitions are not allowed. Use a named type alias or interface instead of an inline object type."
1861
2260
  }
1862
2261
  },
2262
+ defaultOptions: [],
1863
2263
  create(context) {
1864
2264
  function checkParameter(param) {
1865
- if (param && param.type === "ObjectPattern" && param.typeAnnotation && param.typeAnnotation.type === "TSTypeAnnotation") {
2265
+ if (param.type === "ObjectPattern" && param.typeAnnotation && param.typeAnnotation.type === "TSTypeAnnotation") {
1866
2266
  const annotation = param.typeAnnotation.typeAnnotation;
1867
2267
  if (annotation.type === "TSTypeLiteral") {
1868
2268
  context.report({
@@ -1874,70 +2274,98 @@ var no_inline_prop_types_default = {
1874
2274
  }
1875
2275
  return {
1876
2276
  "FunctionDeclaration, ArrowFunctionExpression, FunctionExpression"(node) {
2277
+ if (node.params.length === 0) {
2278
+ return;
2279
+ }
1877
2280
  const firstParam = node.params[0];
1878
- if (firstParam) {
1879
- checkParameter(firstParam);
2281
+ if (!firstParam) {
2282
+ return;
1880
2283
  }
2284
+ checkParameter(firstParam);
1881
2285
  }
1882
2286
  };
1883
2287
  }
1884
2288
  };
1885
2289
 
1886
- // src/rules/no-unnecessary-div.js
1887
- var no_unnecessary_div_default = {
2290
+ // src/rules/no-unnecessary-div.ts
2291
+ import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
2292
+ var noUnnecessaryDiv = {
1888
2293
  meta: {
1889
2294
  type: "suggestion",
1890
2295
  docs: {
1891
- description: "Flag unnecessary <div> wrappers that enclose a single JSX element. Remove the wrapper if it doesn't add semantic or functional value, or replace it with a semantic element if wrapping is needed.",
1892
- category: "Best Practices",
1893
- recommended: false
2296
+ description: "Flag unnecessary <div> wrappers that enclose a single JSX element. Remove the wrapper if it doesn't add semantic or functional value, or replace it with a semantic element if wrapping is needed."
2297
+ },
2298
+ schema: [],
2299
+ messages: {
2300
+ unnecessaryDivWrapper: "Unnecessary <div> wrapper detected. Remove it if not needed, or replace with a semantic element that reflects its purpose."
1894
2301
  }
1895
2302
  },
2303
+ defaultOptions: [],
1896
2304
  create(context) {
2305
+ function isDivElement(node) {
2306
+ const nameNode = node.openingElement.name;
2307
+ return nameNode.type === AST_NODE_TYPES3.JSXIdentifier && nameNode.name === "div";
2308
+ }
2309
+ function getMeaningfulChildren(node) {
2310
+ const result = [];
2311
+ for (const child of node.children) {
2312
+ if (child.type === AST_NODE_TYPES3.JSXText) {
2313
+ if (child.value.trim() !== "") {
2314
+ result.push(child);
2315
+ }
2316
+ } else {
2317
+ result.push(child);
2318
+ }
2319
+ }
2320
+ return result;
2321
+ }
1897
2322
  return {
1898
2323
  JSXElement(node) {
1899
- if (node.openingElement.name && node.openingElement.name.name === "div") {
1900
- const meaningfulChildren = node.children.filter((child) => {
1901
- if (child.type === "JSXText") {
1902
- return child.value.trim() !== "";
1903
- }
1904
- return true;
2324
+ if (!isDivElement(node)) {
2325
+ return;
2326
+ }
2327
+ const meaningfulChildren = getMeaningfulChildren(node);
2328
+ if (meaningfulChildren.length !== 1) {
2329
+ return;
2330
+ }
2331
+ const onlyChild = meaningfulChildren[0];
2332
+ if (!onlyChild) {
2333
+ return;
2334
+ }
2335
+ if (onlyChild.type === AST_NODE_TYPES3.JSXElement) {
2336
+ context.report({
2337
+ node,
2338
+ messageId: "unnecessaryDivWrapper"
1905
2339
  });
1906
- if (meaningfulChildren.length === 1 && meaningfulChildren[0].type === "JSXElement") {
1907
- context.report({
1908
- node,
1909
- message: "Unnecessary <div> wrapper detected. Remove it if not needed, or replace with a semantic element that reflects its purpose."
1910
- });
1911
- }
1912
2340
  }
1913
2341
  }
1914
2342
  };
1915
2343
  }
1916
2344
  };
1917
2345
 
1918
- // src/index.js
2346
+ // src/index.ts
1919
2347
  var src_default = {
1920
2348
  rules: {
1921
- "no-nested-jsx-return": no_nested_jsx_return_default,
1922
- "explicit-object-types": explicit_object_types_default,
1923
- "sort-keys-fixable": sort_keys_fixable_default,
1924
- "no-transition-cssproperties": no_transition_cssproperties_default,
1925
- "no-explicit-return-type": no_explicit_return_types_default,
1926
- "max-jsxnesting": max_jsx_nesting_default,
1927
- "seperate-style-files": seperate_style_files_default,
1928
- "no-unnecessary-key": no_unnecessary_key_default,
1929
- "sort-exports": sort_exports_default,
1930
- "localize-react-props": localize_react_props_default,
1931
- "no-or-none-component": no_or_none_component_default,
1932
- "no-button-navigation": no_button_navigation_default,
1933
- "no-multi-style-objects": no_multi_style_objects_default,
1934
- "no-useless-function": no_useless_function_default,
1935
- "min-var-length": min_var_length_default,
1936
- "max-depth-extended": max_depth_extended_default,
1937
- "spring-naming-convention": spring_naming_convention_default,
1938
- "inline-style-limit": inline_style_limit_default,
1939
- "no-inline-prop-types": no_inline_prop_types_default,
1940
- "no-unnecessary-div": no_unnecessary_div_default
2349
+ "no-nested-jsx-return": noNestedJSXReturn,
2350
+ "explicit-object-types": explicitObjectTypes,
2351
+ "sort-keys-fixable": sortKeysFixable,
2352
+ "no-transition-cssproperties": noTransitionCSSProperties,
2353
+ "no-explicit-return-type": noExplicitReturnTypes,
2354
+ "max-jsxnesting": maxJSXNesting,
2355
+ "seperate-style-files": seperateStyleFiles,
2356
+ "no-unnecessary-key": noUnnecessaryKey,
2357
+ "sort-exports": sortExports,
2358
+ "localize-react-props": localizeReactProps,
2359
+ "no-or-none-component": noOrNoneComponent,
2360
+ "no-button-navigation": noButtonNavigation,
2361
+ "no-multi-style-objects": noMultiStyleObjects,
2362
+ "no-useless-function": noUselessFunction,
2363
+ "min-var-length": minVarLength,
2364
+ "max-depth-extended": maxDepthExtended,
2365
+ "spring-naming-convention": springNamingConvention,
2366
+ "inline-style-limit": inlineStyleLimit,
2367
+ "no-inline-prop-types": noInlinePropTypes,
2368
+ "no-unnecessary-div": noUnnecessaryDiv
1941
2369
  }
1942
2370
  };
1943
2371
  export {