@pobammer-ts/eslint-cease-nonsense-rules 1.6.0 → 1.7.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 (79) hide show
  1. package/README.md +594 -535
  2. package/dist/build-metadata.json +3 -3
  3. package/dist/index.d.ts +7 -3
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +1211 -716
  6. package/dist/index.js.map +33 -28
  7. package/dist/oxfmt-sync.d.ts +4 -0
  8. package/dist/oxfmt-sync.d.ts.map +1 -0
  9. package/dist/oxfmt-worker.d.ts +12 -0
  10. package/dist/oxfmt-worker.d.ts.map +1 -0
  11. package/dist/oxfmt-worker.js +172786 -0
  12. package/dist/oxfmt-worker.js.map +27 -0
  13. package/dist/recognizers/camel-case-detector.d.ts +2 -2
  14. package/dist/recognizers/camel-case-detector.d.ts.map +1 -0
  15. package/dist/recognizers/code-recognizer.d.ts +6 -6
  16. package/dist/recognizers/code-recognizer.d.ts.map +1 -0
  17. package/dist/recognizers/contains-detector.d.ts +2 -2
  18. package/dist/recognizers/contains-detector.d.ts.map +1 -0
  19. package/dist/recognizers/detector.d.ts +3 -4
  20. package/dist/recognizers/detector.d.ts.map +1 -0
  21. package/dist/recognizers/end-with-detector.d.ts +2 -2
  22. package/dist/recognizers/end-with-detector.d.ts.map +1 -0
  23. package/dist/recognizers/javascript-footprint.d.ts +2 -2
  24. package/dist/recognizers/javascript-footprint.d.ts.map +1 -0
  25. package/dist/recognizers/keywords-detector.d.ts +2 -2
  26. package/dist/recognizers/keywords-detector.d.ts.map +1 -0
  27. package/dist/rules/ban-instances.d.ts +1 -0
  28. package/dist/rules/ban-instances.d.ts.map +1 -0
  29. package/dist/rules/ban-react-fc.d.ts +1 -0
  30. package/dist/rules/ban-react-fc.d.ts.map +1 -0
  31. package/dist/rules/enforce-ianitor-check-type.d.ts +2 -1
  32. package/dist/rules/enforce-ianitor-check-type.d.ts.map +1 -0
  33. package/dist/rules/fast-format.d.ts +36 -0
  34. package/dist/rules/fast-format.d.ts.map +1 -0
  35. package/dist/rules/no-async-constructor.d.ts +1 -0
  36. package/dist/rules/no-async-constructor.d.ts.map +1 -0
  37. package/dist/rules/no-color3-constructor.d.ts +1 -0
  38. package/dist/rules/no-color3-constructor.d.ts.map +1 -0
  39. package/dist/rules/no-commented-code.d.ts +1 -0
  40. package/dist/rules/no-commented-code.d.ts.map +1 -0
  41. package/dist/rules/no-god-components.d.ts +1 -0
  42. package/dist/rules/no-god-components.d.ts.map +1 -0
  43. package/dist/rules/no-identity-map.d.ts +9 -0
  44. package/dist/rules/no-identity-map.d.ts.map +1 -0
  45. package/dist/rules/no-instance-methods-without-this.d.ts +1 -0
  46. package/dist/rules/no-instance-methods-without-this.d.ts.map +1 -0
  47. package/dist/rules/no-print.d.ts +1 -0
  48. package/dist/rules/no-print.d.ts.map +1 -0
  49. package/dist/rules/no-shorthand-names.d.ts +1 -0
  50. package/dist/rules/no-shorthand-names.d.ts.map +1 -0
  51. package/dist/rules/no-useless-use-spring.d.ts +1 -0
  52. package/dist/rules/no-useless-use-spring.d.ts.map +1 -0
  53. package/dist/rules/no-warn.d.ts +1 -0
  54. package/dist/rules/no-warn.d.ts.map +1 -0
  55. package/dist/rules/prefer-sequence-overloads.d.ts +1 -0
  56. package/dist/rules/prefer-sequence-overloads.d.ts.map +1 -0
  57. package/dist/rules/prefer-udim2-shorthand.d.ts +1 -0
  58. package/dist/rules/prefer-udim2-shorthand.d.ts.map +1 -0
  59. package/dist/rules/require-named-effect-functions.d.ts +4 -3
  60. package/dist/rules/require-named-effect-functions.d.ts.map +1 -0
  61. package/dist/rules/require-paired-calls.d.ts +1 -0
  62. package/dist/rules/require-paired-calls.d.ts.map +1 -0
  63. package/dist/rules/require-react-component-keys.d.ts +1 -0
  64. package/dist/rules/require-react-component-keys.d.ts.map +1 -0
  65. package/dist/rules/use-exhaustive-dependencies.d.ts +1 -0
  66. package/dist/rules/use-exhaustive-dependencies.d.ts.map +1 -0
  67. package/dist/rules/use-hook-at-top-level.d.ts +1 -0
  68. package/dist/rules/use-hook-at-top-level.d.ts.map +1 -0
  69. package/dist/types/oxfmt.d.ts +88 -0
  70. package/dist/types/oxfmt.d.ts.map +1 -0
  71. package/dist/{configure-utilities.d.ts → utilities/configure-utilities.d.ts} +12 -11
  72. package/dist/utilities/configure-utilities.d.ts.map +1 -0
  73. package/dist/utilities/error-utilities.d.ts +25 -0
  74. package/dist/utilities/error-utilities.d.ts.map +1 -0
  75. package/dist/utilities/format-utilities.d.ts +20 -0
  76. package/dist/utilities/format-utilities.d.ts.map +1 -0
  77. package/dist/utilities/typebox-utilities.d.ts +4 -0
  78. package/dist/utilities/typebox-utilities.d.ts.map +1 -0
  79. package/package.json +23 -10
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ var __export = (target, all) => {
25
25
  set: (newValue) => all[name] = () => newValue
26
26
  });
27
27
  };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
28
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
29
30
 
30
31
  // node_modules/eslint-visitor-keys/dist/eslint-visitor-keys.cjs
@@ -5663,7 +5664,7 @@ var require_ScopeBase = __commonJS((exports) => {
5663
5664
  }
5664
5665
  };
5665
5666
  #staticCloseRef = (ref6) => {
5666
- const resolve2 = () => {
5667
+ const resolve3 = () => {
5667
5668
  const name = ref6.identifier.name;
5668
5669
  const variable = this.set.get(name);
5669
5670
  if (!variable) {
@@ -5681,7 +5682,7 @@ var require_ScopeBase = __commonJS((exports) => {
5681
5682
  ref6.resolved = variable;
5682
5683
  return true;
5683
5684
  };
5684
- if (!resolve2()) {
5685
+ if (!resolve3()) {
5685
5686
  this.delegateToUpperScope(ref6);
5686
5687
  }
5687
5688
  };
@@ -6163,7 +6164,7 @@ var require_VisitorBase = __commonJS((exports) => {
6163
6164
  function isObject(obj) {
6164
6165
  return typeof obj === "object" && obj != null;
6165
6166
  }
6166
- function isNode3(node) {
6167
+ function isNode2(node) {
6167
6168
  return isObject(node) && typeof node.type === "string";
6168
6169
  }
6169
6170
 
@@ -6190,11 +6191,11 @@ var require_VisitorBase = __commonJS((exports) => {
6190
6191
  }
6191
6192
  if (Array.isArray(child)) {
6192
6193
  for (const subChild of child) {
6193
- if (isNode3(subChild)) {
6194
+ if (isNode2(subChild)) {
6194
6195
  this.visit(subChild);
6195
6196
  }
6196
6197
  }
6197
- } else if (isNode3(child)) {
6198
+ } else if (isNode2(child)) {
6198
6199
  this.visit(child);
6199
6200
  }
6200
6201
  }
@@ -7399,7 +7400,7 @@ var require_analyze = __commonJS((exports) => {
7399
7400
  var visitor_keys_1 = require_dist();
7400
7401
  var referencer_1 = require_referencer();
7401
7402
  var ScopeManager_1 = require_ScopeManager();
7402
- var DEFAULT_OPTIONS3 = {
7403
+ var DEFAULT_OPTIONS = {
7403
7404
  childVisitorKeys: visitor_keys_1.visitorKeys,
7404
7405
  emitDecoratorMetadata: false,
7405
7406
  globalReturn: false,
@@ -7411,14 +7412,14 @@ var require_analyze = __commonJS((exports) => {
7411
7412
  };
7412
7413
  function analyze(tree, providedOptions) {
7413
7414
  const options3 = {
7414
- childVisitorKeys: providedOptions?.childVisitorKeys ?? DEFAULT_OPTIONS3.childVisitorKeys,
7415
+ childVisitorKeys: providedOptions?.childVisitorKeys ?? DEFAULT_OPTIONS.childVisitorKeys,
7415
7416
  emitDecoratorMetadata: false,
7416
- globalReturn: providedOptions?.globalReturn ?? DEFAULT_OPTIONS3.globalReturn,
7417
- impliedStrict: providedOptions?.impliedStrict ?? DEFAULT_OPTIONS3.impliedStrict,
7418
- jsxFragmentName: providedOptions?.jsxFragmentName ?? DEFAULT_OPTIONS3.jsxFragmentName,
7419
- jsxPragma: providedOptions?.jsxPragma === undefined ? DEFAULT_OPTIONS3.jsxPragma : providedOptions.jsxPragma,
7417
+ globalReturn: providedOptions?.globalReturn ?? DEFAULT_OPTIONS.globalReturn,
7418
+ impliedStrict: providedOptions?.impliedStrict ?? DEFAULT_OPTIONS.impliedStrict,
7419
+ jsxFragmentName: providedOptions?.jsxFragmentName ?? DEFAULT_OPTIONS.jsxFragmentName,
7420
+ jsxPragma: providedOptions?.jsxPragma === undefined ? DEFAULT_OPTIONS.jsxPragma : providedOptions.jsxPragma,
7420
7421
  lib: providedOptions?.lib ?? ["esnext"],
7421
- sourceType: providedOptions?.sourceType ?? DEFAULT_OPTIONS3.sourceType
7422
+ sourceType: providedOptions?.sourceType ?? DEFAULT_OPTIONS.sourceType
7422
7423
  };
7423
7424
  options3.lib = options3.lib.map((l) => l.toLowerCase());
7424
7425
  const scopeManager = new ScopeManager_1.ScopeManager(options3);
@@ -15425,7 +15426,10 @@ function Compile(...args) {
15425
15426
  var isArrayConfig = Compile(build_default.Array(build_default.String()));
15426
15427
  var isObjectConfig = Compile(build_default.Record(build_default.String(), build_default.String()));
15427
15428
  var isOptionsObject = Compile(build_default.Object({
15428
- bannedInstances: build_default.Union([build_default.Array(build_default.String()), build_default.Record(build_default.String(), build_default.String())])
15429
+ bannedInstances: build_default.Union([
15430
+ build_default.Array(build_default.String()),
15431
+ build_default.Record(build_default.String(), build_default.String())
15432
+ ])
15429
15433
  }));
15430
15434
  function normalizeConfig(options3) {
15431
15435
  if (!isOptionsObject.Check(options3))
@@ -15434,13 +15438,13 @@ function normalizeConfig(options3) {
15434
15438
  if (isArrayConfig.Check(bannedInstances)) {
15435
15439
  const map = new Map;
15436
15440
  for (const className of bannedInstances)
15437
- map.set(className.toLowerCase(), { originalName: className, message: undefined });
15441
+ map.set(className.toLowerCase(), { message: undefined, originalName: className });
15438
15442
  return { bannedClasses: map };
15439
15443
  }
15440
15444
  if (isObjectConfig.Check(bannedInstances)) {
15441
15445
  const map = new Map;
15442
15446
  for (const [className, message] of Object.entries(bannedInstances))
15443
- map.set(className.toLowerCase(), { originalName: className, message });
15447
+ map.set(className.toLowerCase(), { message, originalName: className });
15444
15448
  return { bannedClasses: map };
15445
15449
  }
15446
15450
  return { bannedClasses: new Map };
@@ -15597,9 +15601,9 @@ function hasTypeAnnotationProperty(node) {
15597
15601
  }
15598
15602
  function hasTypeAnnotation(node) {
15599
15603
  if (node.type === TSESTree3.AST_NODE_TYPES.VariableDeclarator && node.id && typeof node.id === "object" && hasTypeAnnotationProperty(node.id))
15600
- return !!node.id.typeAnnotation;
15604
+ return Boolean(node.id.typeAnnotation);
15601
15605
  if (SHOULD_NOT_NOT_RETURN_TYPE.has(node.type))
15602
- return !!node.returnType;
15606
+ return Boolean(node.returnType);
15603
15607
  return false;
15604
15608
  }
15605
15609
  function getTypeName(node) {
@@ -15610,29 +15614,33 @@ function isIanitorValidator(node) {
15610
15614
  }
15611
15615
  function extractIanitorStaticVariable(typeAnnotation) {
15612
15616
  let currentType = typeAnnotation;
15613
- if (currentType.type === TSESTree3.AST_NODE_TYPES.TSTypeReference && currentType.typeName.type === TSESTree3.AST_NODE_TYPES.Identifier && currentType.typeName.name === "Readonly" && currentType.typeArguments?.params[0])
15614
- currentType = currentType.typeArguments.params[0];
15617
+ if (currentType.type === TSESTree3.AST_NODE_TYPES.TSTypeReference && currentType.typeName.type === TSESTree3.AST_NODE_TYPES.Identifier && currentType.typeName.name === "Readonly" && currentType.typeArguments?.params[0]) {
15618
+ [currentType] = currentType.typeArguments.params;
15619
+ }
15615
15620
  if (currentType.type !== TSESTree3.AST_NODE_TYPES.TSTypeReference)
15616
15621
  return;
15617
15622
  const { typeName, typeArguments } = currentType;
15618
15623
  const firstParam = typeArguments?.params[0];
15619
- if (typeName.type === TSESTree3.AST_NODE_TYPES.TSQualifiedName && typeName.left.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.left.name === "Ianitor" && typeName.right.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.right.name === "Static" && firstParam?.type === TSESTree3.AST_NODE_TYPES.TSTypeQuery && firstParam.exprName.type === TSESTree3.AST_NODE_TYPES.Identifier)
15624
+ if (typeName.type === TSESTree3.AST_NODE_TYPES.TSQualifiedName && typeName.left.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.left.name === "Ianitor" && typeName.right.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.right.name === "Static" && firstParam?.type === TSESTree3.AST_NODE_TYPES.TSTypeQuery && firstParam.exprName.type === TSESTree3.AST_NODE_TYPES.Identifier) {
15620
15625
  return firstParam.exprName.name;
15626
+ }
15621
15627
  return;
15622
15628
  }
15623
15629
  function hasIanitorStaticType(typeAnnotation) {
15624
15630
  let currentType = typeAnnotation;
15625
- if (currentType.type === TSESTree3.AST_NODE_TYPES.TSTypeReference && currentType.typeName.type === TSESTree3.AST_NODE_TYPES.Identifier && currentType.typeName.name === "Readonly" && currentType.typeArguments?.params[0])
15626
- currentType = currentType.typeArguments.params[0];
15631
+ if (currentType.type === TSESTree3.AST_NODE_TYPES.TSTypeReference && currentType.typeName.type === TSESTree3.AST_NODE_TYPES.Identifier && currentType.typeName.name === "Readonly" && currentType.typeArguments?.params[0]) {
15632
+ [currentType] = currentType.typeArguments.params;
15633
+ }
15627
15634
  if (currentType.type !== TSESTree3.AST_NODE_TYPES.TSTypeReference)
15628
15635
  return false;
15629
15636
  const { typeName, typeArguments } = currentType;
15630
15637
  return typeName.type === TSESTree3.AST_NODE_TYPES.TSQualifiedName && typeName.left.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.left.name === "Ianitor" && typeName.right.type === TSESTree3.AST_NODE_TYPES.Identifier && typeName.right.name === "Static" && typeArguments?.params[0]?.type === TSESTree3.AST_NODE_TYPES.TSTypeQuery;
15631
15638
  }
15632
15639
  function calculateIanitorComplexity(node) {
15633
- const callee = node.callee;
15634
- if (callee?.type !== TSESTree3.AST_NODE_TYPES.MemberExpression || callee.property?.type !== TSESTree3.AST_NODE_TYPES.Identifier)
15640
+ const { callee } = node;
15641
+ if (callee?.type !== TSESTree3.AST_NODE_TYPES.MemberExpression || callee.property?.type !== TSESTree3.AST_NODE_TYPES.Identifier) {
15635
15642
  return 0;
15643
+ }
15636
15644
  const method = callee.property.name;
15637
15645
  switch (method) {
15638
15646
  case "interface":
@@ -15662,7 +15670,8 @@ function calculateIanitorComplexity(node) {
15662
15670
  var createRule = ESLintUtils.RuleCreator((name) => `https://github.com/howmanysmall/eslint-cease-nonsense-rules/blob/main/docs/rules/${name}.md`);
15663
15671
  var enforceIanitorCheckType = createRule({
15664
15672
  create(context) {
15665
- const config = { ...DEFAULT_CONFIGURATION, ...context.options[0] };
15673
+ const [rawOptions] = context.options;
15674
+ const config = { ...DEFAULT_CONFIGURATION, ...rawOptions };
15666
15675
  const cache = {
15667
15676
  nodeCache: new WeakMap,
15668
15677
  visitedNodes: new WeakSet
@@ -15789,15 +15798,14 @@ var enforceIanitorCheckType = createRule({
15789
15798
  }
15790
15799
  case TSESTree3.AST_NODE_TYPES.TSFunctionType:
15791
15800
  case TSESTree3.AST_NODE_TYPES.TSMethodSignature: {
15792
- const func = node;
15793
15801
  score = 2;
15794
- for (const param of func.params) {
15802
+ for (const param of node.params) {
15795
15803
  const typeAnnotation = "typeAnnotation" in param ? param.typeAnnotation : undefined;
15796
15804
  if (typeAnnotation)
15797
15805
  score = addScore(score, calculateStructuralComplexity(typeAnnotation.typeAnnotation, nextDepth));
15798
15806
  }
15799
- if (func.returnType)
15800
- score = addScore(score, calculateStructuralComplexity(func.returnType.typeAnnotation, nextDepth));
15807
+ if (node.returnType)
15808
+ score = addScore(score, calculateStructuralComplexity(node.returnType.typeAnnotation, nextDepth));
15801
15809
  break;
15802
15810
  }
15803
15811
  default:
@@ -15811,8 +15819,7 @@ var enforceIanitorCheckType = createRule({
15811
15819
  const variableDeclaratorsToCheck = new Map;
15812
15820
  return {
15813
15821
  "Program:exit"() {
15814
- for (const [nodeKey, data] of variableDeclaratorsToCheck.entries()) {
15815
- const node = nodeKey;
15822
+ for (const [node, data] of variableDeclaratorsToCheck.entries()) {
15816
15823
  if (node.id.type === TSESTree3.AST_NODE_TYPES.Identifier && ianitorStaticVariables.has(node.id.name))
15817
15824
  continue;
15818
15825
  context.report({
@@ -15890,6 +15897,283 @@ var enforceIanitorCheckType = createRule({
15890
15897
  });
15891
15898
  var enforce_ianitor_check_type_default = enforceIanitorCheckType;
15892
15899
 
15900
+ // src/utilities/format-utilities.ts
15901
+ import { readFileSync } from "node:fs";
15902
+ import { resolve as resolve2 } from "node:path";
15903
+
15904
+ // node_modules/arkregex/out/regex.js
15905
+ var regex2 = (src, flags) => new RegExp(src, flags);
15906
+ Object.assign(regex2, { as: regex2 });
15907
+ // src/oxfmt-sync.ts
15908
+ import { existsSync } from "node:fs";
15909
+ import { fileURLToPath } from "node:url";
15910
+ import { MessageChannel, receiveMessageOnPort, Worker } from "node:worker_threads";
15911
+ var FORMAT_TIMEOUT = 30000;
15912
+ var workerState;
15913
+ function resolveWorkerPath() {
15914
+ const jsPath = new URL("./oxfmt-worker.js", import.meta.url);
15915
+ const jsFilePath = fileURLToPath(jsPath);
15916
+ if (existsSync(jsFilePath))
15917
+ return jsPath;
15918
+ const tsPath = new URL("./oxfmt-worker.ts", import.meta.url);
15919
+ const tsFilePath = fileURLToPath(tsPath);
15920
+ if (existsSync(tsFilePath))
15921
+ return tsPath;
15922
+ throw new Error(`Oxfmt worker not found at ${jsFilePath} or ${tsFilePath}. Did you run 'bun run build'?`);
15923
+ }
15924
+ function getWorker() {
15925
+ if (workerState !== undefined)
15926
+ return workerState;
15927
+ const controlBuffer = new SharedArrayBuffer(4);
15928
+ const workerPath = resolveWorkerPath();
15929
+ const { port1: responsePort, port2: requestPort } = new MessageChannel;
15930
+ const worker = new Worker(workerPath, {
15931
+ stderr: true,
15932
+ stdout: true,
15933
+ transferList: [requestPort],
15934
+ workerData: { requestPort }
15935
+ });
15936
+ worker.unref();
15937
+ workerState = { controlBuffer, responsePort, worker };
15938
+ return workerState;
15939
+ }
15940
+ function formatSync(fileName, sourceText, options3 = {}) {
15941
+ const { controlBuffer, responsePort } = getWorker();
15942
+ const control = new Int32Array(controlBuffer);
15943
+ Atomics.store(control, 0, 0);
15944
+ const request = {
15945
+ controlBuffer,
15946
+ fileName,
15947
+ options: options3,
15948
+ sourceText
15949
+ };
15950
+ responsePort.postMessage(request);
15951
+ const waitResult = Atomics.wait(control, 0, 0, FORMAT_TIMEOUT);
15952
+ if (waitResult === "timed-out")
15953
+ throw new Error(`Oxfmt timed out after ${FORMAT_TIMEOUT}ms`);
15954
+ const received = receiveMessageOnPort(responsePort);
15955
+ if (received === undefined)
15956
+ throw new Error("No response received from oxfmt worker");
15957
+ const response = received.message;
15958
+ if (response.error !== undefined)
15959
+ throw new Error(response.error);
15960
+ if (response.code === undefined)
15961
+ throw new Error("Oxfmt returned undefined code");
15962
+ return response.code;
15963
+ }
15964
+
15965
+ // src/utilities/format-utilities.ts
15966
+ var cachedConfig;
15967
+ function loadOxfmtConfig() {
15968
+ if (cachedConfig !== undefined)
15969
+ return cachedConfig;
15970
+ try {
15971
+ const configPath = resolve2(process.cwd(), ".oxfmtrc.json");
15972
+ const configText = readFileSync(configPath, "utf8");
15973
+ const parsed = JSON.parse(configText);
15974
+ if (typeof parsed !== "object" || parsed === null) {
15975
+ cachedConfig = {};
15976
+ return cachedConfig;
15977
+ }
15978
+ const config = parsed;
15979
+ const { $schema: _schema, ignorePatterns: _ignore, ...formatOptions } = config;
15980
+ cachedConfig = formatOptions;
15981
+ return cachedConfig;
15982
+ } catch {
15983
+ cachedConfig = {};
15984
+ return cachedConfig;
15985
+ }
15986
+ }
15987
+ function getExtension(filePath) {
15988
+ if (filePath.endsWith(".tsx"))
15989
+ return ".tsx";
15990
+ if (filePath.endsWith(".ts"))
15991
+ return ".ts";
15992
+ if (filePath.endsWith(".jsx"))
15993
+ return ".jsx";
15994
+ if (filePath.endsWith(".js"))
15995
+ return ".js";
15996
+ if (filePath.endsWith(".mts"))
15997
+ return ".mts";
15998
+ if (filePath.endsWith(".mjs"))
15999
+ return ".mjs";
16000
+ if (filePath.endsWith(".cts"))
16001
+ return ".cts";
16002
+ if (filePath.endsWith(".cjs"))
16003
+ return ".cjs";
16004
+ return;
16005
+ }
16006
+ function formatWithOxfmtSync(source, filePath) {
16007
+ const extension = getExtension(filePath);
16008
+ if (extension === undefined)
16009
+ throw new Error(`Unsupported file extension for ${filePath}`);
16010
+ const config = loadOxfmtConfig();
16011
+ return formatSync(filePath, source, config);
16012
+ }
16013
+ function generateDifferences(original, formatted) {
16014
+ if (original === formatted)
16015
+ return [];
16016
+ return [
16017
+ {
16018
+ deleteText: original,
16019
+ insertText: formatted,
16020
+ offset: 0,
16021
+ operation: "REPLACE"
16022
+ }
16023
+ ];
16024
+ }
16025
+ var MAX_LENGTH = 60;
16026
+ var SYMBOLS = {
16027
+ " ": "·",
16028
+ "\n": "␊",
16029
+ "\r": "␍",
16030
+ "\t": "→"
16031
+ };
16032
+ var WHITESPACE_REGEXP = regex2(`[\r
16033
+ ]`, "g");
16034
+ function toSymbol(character) {
16035
+ return SYMBOLS[character] ?? character;
16036
+ }
16037
+ function showInvisibles(text) {
16038
+ let result = text;
16039
+ if (result.length > MAX_LENGTH)
16040
+ result = `${result.slice(0, MAX_LENGTH)}…`;
16041
+ return result.replaceAll(WHITESPACE_REGEXP, toSymbol);
16042
+ }
16043
+
16044
+ // src/rules/fast-format.ts
16045
+ var INSERT = "INSERT";
16046
+ var DELETE = "DELETE";
16047
+ var REPLACE = "REPLACE";
16048
+ var DEFAULT_CACHE_CAPACITY = 32;
16049
+ function getLocFromIndex(sourceCode, index2) {
16050
+ if (typeof sourceCode.getLocFromIndex === "function")
16051
+ return sourceCode.getLocFromIndex(index2);
16052
+ return { column: index2, line: 1 };
16053
+ }
16054
+ function createCacheKey(filename, source) {
16055
+ return `${filename}::${source}`;
16056
+ }
16057
+ function createLruCache(limit) {
16058
+ const entries = new Map;
16059
+ const capacity = Math.max(limit, 1);
16060
+ function clear() {
16061
+ entries.clear();
16062
+ }
16063
+ function get(key) {
16064
+ const value = entries.get(key);
16065
+ if (value === undefined)
16066
+ return;
16067
+ entries.delete(key);
16068
+ entries.set(key, value);
16069
+ return value;
16070
+ }
16071
+ function set(key, value) {
16072
+ entries.set(key, value);
16073
+ if (entries.size > capacity) {
16074
+ const oldestKey = entries.keys().next().value;
16075
+ if (oldestKey !== undefined)
16076
+ entries.delete(oldestKey);
16077
+ }
16078
+ return value;
16079
+ }
16080
+ return { clear, get, set };
16081
+ }
16082
+ function cacheFormattedResult(cache, filename, source, formatted) {
16083
+ const entry = { formatted, kind: "formatted" };
16084
+ const sourceKey = createCacheKey(filename, source);
16085
+ cache.set(sourceKey, entry);
16086
+ if (formatted !== source) {
16087
+ const formattedKey = createCacheKey(filename, formatted);
16088
+ cache.set(formattedKey, entry);
16089
+ }
16090
+ return entry;
16091
+ }
16092
+ function formatWithCaching(cache, filename, source, services) {
16093
+ const cacheKey = createCacheKey(filename, source);
16094
+ const cached = cache.get(cacheKey);
16095
+ if (cached !== undefined)
16096
+ return cached;
16097
+ try {
16098
+ const formatted = services.format(source, filename);
16099
+ return cacheFormattedResult(cache, filename, source, formatted);
16100
+ } catch (error2) {
16101
+ const message = error2 instanceof Error ? error2.message : String(error2);
16102
+ return cache.set(cacheKey, { kind: "error", message: `Oxfmt error: ${message}` });
16103
+ }
16104
+ }
16105
+ function createFormatCache(limit = DEFAULT_CACHE_CAPACITY) {
16106
+ return createLruCache(limit);
16107
+ }
16108
+ var defaultServices = {
16109
+ format: formatWithOxfmtSync,
16110
+ generate: generateDifferences,
16111
+ show: showInvisibles
16112
+ };
16113
+ var defaultCache = createFormatCache();
16114
+ function createFastFormatRule(options3 = {}) {
16115
+ const cache = options3.cache ?? defaultCache;
16116
+ const services = {
16117
+ format: options3.services?.format ?? defaultServices.format,
16118
+ generate: options3.services?.generate ?? defaultServices.generate,
16119
+ show: options3.services?.show ?? defaultServices.show
16120
+ };
16121
+ return {
16122
+ create(context) {
16123
+ const { filename, sourceCode } = context;
16124
+ if (getExtension(filename) === undefined)
16125
+ return {};
16126
+ return {
16127
+ Program() {
16128
+ const source = sourceCode.text;
16129
+ const outcome = formatWithCaching(cache, filename, source, services);
16130
+ if (outcome.kind === "error") {
16131
+ context.report({
16132
+ loc: { column: 0, line: 1 },
16133
+ message: outcome.message
16134
+ });
16135
+ return;
16136
+ }
16137
+ if (source === outcome.formatted)
16138
+ return;
16139
+ const differences = services.generate(source, outcome.formatted);
16140
+ for (const { operation, offset, deleteText, insertText } of differences) {
16141
+ const range = [offset, offset + (deleteText?.length ?? 0)];
16142
+ context.report({
16143
+ data: {
16144
+ deleteText: services.show(deleteText ?? ""),
16145
+ insertText: services.show(insertText ?? "")
16146
+ },
16147
+ fix: (fixer) => fixer.replaceTextRange(range, insertText ?? ""),
16148
+ loc: {
16149
+ end: getLocFromIndex(sourceCode, range[1]),
16150
+ start: getLocFromIndex(sourceCode, range[0])
16151
+ },
16152
+ messageId: operation
16153
+ });
16154
+ }
16155
+ }
16156
+ };
16157
+ },
16158
+ meta: {
16159
+ docs: {
16160
+ description: "Enforce oxfmt code formatting",
16161
+ recommended: true
16162
+ },
16163
+ fixable: "code",
16164
+ messages: {
16165
+ [INSERT]: "Insert `{{ insertText }}`",
16166
+ [DELETE]: "Delete `{{ deleteText }}`",
16167
+ [REPLACE]: "Replace `{{ deleteText }}` with `{{ insertText }}`"
16168
+ },
16169
+ schema: [],
16170
+ type: "layout"
16171
+ }
16172
+ };
16173
+ }
16174
+ var fastFormat = createFastFormatRule();
16175
+ var fast_format_default = fastFormat;
16176
+
15893
16177
  // src/rules/no-async-constructor.ts
15894
16178
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
15895
16179
  var PROMISE_CHAIN_METHODS = new Set(["then", "catch", "finally"]);
@@ -16023,22 +16307,24 @@ function findConstructorViolations(constructorBody, asyncMethods) {
16023
16307
  if (!hasDynamicProperties(current))
16024
16308
  return;
16025
16309
  for (const key in current) {
16026
- const childValue = current[key];
16027
- if (childValue === undefined)
16028
- continue;
16029
- if (Array.isArray(childValue)) {
16030
- for (const item of childValue) {
16031
- if (!isNode(item))
16032
- continue;
16033
- parentMap.set(item, current);
16034
- traverse(item);
16310
+ if (Object.hasOwn(current, key)) {
16311
+ const childValue = current[key];
16312
+ if (childValue === undefined)
16313
+ continue;
16314
+ if (Array.isArray(childValue)) {
16315
+ for (const item of childValue) {
16316
+ if (!isNode(item))
16317
+ continue;
16318
+ parentMap.set(item, current);
16319
+ traverse(item);
16320
+ }
16321
+ continue;
16035
16322
  }
16036
- continue;
16323
+ if (!isNode(childValue))
16324
+ continue;
16325
+ parentMap.set(childValue, current);
16326
+ traverse(childValue);
16037
16327
  }
16038
- if (!isNode(childValue))
16039
- continue;
16040
- parentMap.set(childValue, current);
16041
- traverse(childValue);
16042
16328
  }
16043
16329
  }
16044
16330
  traverse(constructorBody);
@@ -16182,7 +16468,7 @@ import { createRequire as createRequire4 } from "node:module";
16182
16468
  import { createRequire as createRequire2 } from "node:module";
16183
16469
  var require2 = createRequire2(import.meta.url);
16184
16470
  var __dirname2 = new URL(".", import.meta.url).pathname;
16185
- var { readFileSync } = require2("node:fs");
16471
+ var { readFileSync: readFileSync2 } = require2("node:fs");
16186
16472
  var nativeBinding = null;
16187
16473
  var loadErrors = [];
16188
16474
  var isMusl = () => {
@@ -16201,7 +16487,7 @@ var isMusl = () => {
16201
16487
  var isFileMusl = (f) => f.includes("libc.musl-") || f.includes("ld-musl-");
16202
16488
  var isMuslFromFilesystem = () => {
16203
16489
  try {
16204
- return readFileSync("/usr/bin/ldd", "utf-8").includes("musl");
16490
+ return readFileSync2("/usr/bin/ldd", "utf-8").includes("musl");
16205
16491
  } catch {
16206
16492
  return null;
16207
16493
  }
@@ -17106,8 +17392,8 @@ function createCamelCaseDetector(probability) {
17106
17392
  }
17107
17393
 
17108
17394
  // src/recognizers/contains-detector.ts
17109
- var WHITESPACE_GLOBAL_REGEX = /\s+/g;
17110
- var ESCAPE = /[-/\\^$*+?.()|[\]{}]/g;
17395
+ var WHITESPACE_GLOBAL_REGEX = regex2("\\s+", "g");
17396
+ var ESCAPE = regex2("[-/\\^$*+?.()|[\\]{}]", "g");
17111
17397
  function escapeForRegex(value) {
17112
17398
  return value.replaceAll(ESCAPE, String.raw`\$&`);
17113
17399
  }
@@ -17130,17 +17416,17 @@ function createContainsDetector(probability, patterns2) {
17130
17416
  }
17131
17417
 
17132
17418
  // src/recognizers/end-with-detector.ts
17133
- var WHITESPACE_REGEX = /\s/;
17419
+ var WHITESPACE_REGEX = regex2("\\s");
17134
17420
  function createEndWithDetector(probability, endings) {
17135
17421
  const endingsSet = new Set(endings);
17136
17422
  return {
17137
17423
  probability,
17138
17424
  scan(line) {
17139
17425
  for (let index2 = line.length - 1;index2 >= 0; index2 -= 1) {
17140
- const char = line.charAt(index2);
17141
- if (endingsSet.has(char))
17426
+ const character = line.charAt(index2);
17427
+ if (endingsSet.has(character))
17142
17428
  return 1;
17143
- if (!WHITESPACE_REGEX.test(char) && char !== "*" && char !== "/")
17429
+ if (!WHITESPACE_REGEX.test(character) && character !== "*" && character !== "/")
17144
17430
  return 0;
17145
17431
  }
17146
17432
  return 0;
@@ -17258,7 +17544,7 @@ function groupComments(comments, sourceCode) {
17258
17544
  if (size > 0) {
17259
17545
  groups[groupsSize++] = {
17260
17546
  comments: currentLineComments,
17261
- value: currentLineComments.map((c) => c.value).join(`
17547
+ value: currentLineComments.map(({ value }) => value).join(`
17262
17548
  `)
17263
17549
  };
17264
17550
  currentLineComments = [];
@@ -17341,7 +17627,7 @@ function toParsedStatements(body) {
17341
17627
  function isExpressionExclusion(statement, codeText) {
17342
17628
  if (statement.type !== "ExpressionStatement")
17343
17629
  return false;
17344
- const expression = statement.expression;
17630
+ const { expression } = statement;
17345
17631
  if (!expression)
17346
17632
  return false;
17347
17633
  if (expression.type === "Identifier")
@@ -17418,7 +17704,7 @@ var noCommentedCode = {
17418
17704
  if (containsCode(balanced, context.filename)) {
17419
17705
  const firstComment = group.comments.at(0);
17420
17706
  const lastComment = group.comments.at(-1);
17421
- if (!firstComment || !lastComment)
17707
+ if (!(firstComment && lastComment))
17422
17708
  continue;
17423
17709
  context.report({
17424
17710
  loc: {
@@ -17455,95 +17741,633 @@ var noCommentedCode = {
17455
17741
  };
17456
17742
  var no_commented_code_default = noCommentedCode;
17457
17743
 
17458
- // src/rules/no-instance-methods-without-this.ts
17459
- import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/types";
17460
- var DEFAULT_OPTIONS = {
17461
- checkPrivate: true,
17462
- checkProtected: true,
17463
- checkPublic: true
17464
- };
17465
- function normalizeOptions(rawOptions) {
17466
- const mergedOptions = { ...DEFAULT_OPTIONS };
17467
- if (rawOptions?.checkPrivate !== undefined)
17468
- mergedOptions.checkPrivate = rawOptions.checkPrivate;
17469
- if (rawOptions?.checkProtected !== undefined)
17470
- mergedOptions.checkProtected = rawOptions.checkProtected;
17471
- if (rawOptions?.checkPublic !== undefined)
17472
- mergedOptions.checkPublic = rawOptions.checkPublic;
17473
- return mergedOptions;
17474
- }
17475
- function shouldCheckMethod(node, options3) {
17476
- if (node.static)
17477
- return false;
17478
- if (node.kind !== "method")
17479
- return false;
17480
- const accessibility = node.accessibility ?? "public";
17481
- if (accessibility === "private" && !options3.checkPrivate)
17482
- return false;
17483
- if (accessibility === "protected" && !options3.checkProtected)
17484
- return false;
17485
- if (accessibility === "public" && !options3.checkPublic)
17486
- return false;
17487
- return true;
17744
+ // src/rules/no-god-components.ts
17745
+ import { TSESTree as TSESTree5 } from "@typescript-eslint/types";
17746
+ var COMPONENT_NAME_PATTERN = /^[A-Z]/;
17747
+ var FUNCTION_BOUNDARIES = new Set([
17748
+ TSESTree5.AST_NODE_TYPES.FunctionDeclaration,
17749
+ TSESTree5.AST_NODE_TYPES.FunctionExpression,
17750
+ TSESTree5.AST_NODE_TYPES.ArrowFunctionExpression
17751
+ ]);
17752
+ var RUNTIME_TS_WRAPPERS = new Set([
17753
+ "ParenthesizedExpression",
17754
+ "TSAsExpression",
17755
+ "TSSatisfiesExpression",
17756
+ "TSTypeAssertion",
17757
+ "TSNonNullExpression",
17758
+ "TSInstantiationExpression",
17759
+ "ChainExpression"
17760
+ ]);
17761
+ function isComponentName(name) {
17762
+ return COMPONENT_NAME_PATTERN.test(name);
17488
17763
  }
17489
- function isNode2(value) {
17490
- return typeof value === "object" && value !== null && "type" in value;
17764
+ function isReactComponentHOC(callExpr) {
17765
+ const { callee } = callExpr;
17766
+ if (callee.type === TSESTree5.AST_NODE_TYPES.Identifier)
17767
+ return callee.name === "forwardRef" || callee.name === "memo";
17768
+ if (callee.type === TSESTree5.AST_NODE_TYPES.MemberExpression && callee.object.type === TSESTree5.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === TSESTree5.AST_NODE_TYPES.Identifier)
17769
+ return callee.property.name === "forwardRef" || callee.property.name === "memo";
17770
+ return false;
17491
17771
  }
17492
- function hasDynamicProperties2(_node) {
17493
- return true;
17772
+ function getComponentNameFromFunction(node) {
17773
+ if (node.type === TSESTree5.AST_NODE_TYPES.FunctionDeclaration && node.id && isComponentName(node.id.name)) {
17774
+ return node.id.name;
17775
+ }
17776
+ if (node.type === TSESTree5.AST_NODE_TYPES.FunctionExpression || node.type === TSESTree5.AST_NODE_TYPES.ArrowFunctionExpression) {
17777
+ const { parent } = node;
17778
+ if (parent === null || parent === undefined)
17779
+ return;
17780
+ if (parent.type === TSESTree5.AST_NODE_TYPES.VariableDeclarator && parent.id.type === TSESTree5.AST_NODE_TYPES.Identifier && isComponentName(parent.id.name)) {
17781
+ return parent.id.name;
17782
+ }
17783
+ if (parent.type === TSESTree5.AST_NODE_TYPES.Property && parent.key.type === TSESTree5.AST_NODE_TYPES.Identifier && isComponentName(parent.key.name)) {
17784
+ return parent.key.name;
17785
+ }
17786
+ if (parent.type === TSESTree5.AST_NODE_TYPES.MethodDefinition && parent.key.type === TSESTree5.AST_NODE_TYPES.Identifier && isComponentName(parent.key.name)) {
17787
+ return parent.key.name;
17788
+ }
17789
+ }
17790
+ return;
17494
17791
  }
17495
- function traverseForThis(currentNode, visited2) {
17496
- if (visited2.has(currentNode))
17497
- return false;
17498
- visited2.add(currentNode);
17499
- if (currentNode.type === AST_NODE_TYPES2.ThisExpression || currentNode.type === AST_NODE_TYPES2.Super)
17500
- return true;
17501
- if (!hasDynamicProperties2(currentNode))
17502
- return false;
17503
- for (const key in currentNode) {
17504
- const childValue = currentNode[key];
17505
- if (childValue === null || childValue === undefined)
17506
- continue;
17507
- if (Array.isArray(childValue)) {
17508
- for (const item of childValue)
17509
- if (isNode2(item) && traverseForThis(item, visited2))
17510
- return true;
17511
- continue;
17792
+ function getComponentNameFromCallParent(callExpr) {
17793
+ const { parent } = callExpr;
17794
+ if (parent === null || parent === undefined)
17795
+ return;
17796
+ if (parent.type === TSESTree5.AST_NODE_TYPES.VariableDeclarator && parent.id.type === TSESTree5.AST_NODE_TYPES.Identifier && isComponentName(parent.id.name)) {
17797
+ return parent.id.name;
17798
+ }
17799
+ if (parent.type === TSESTree5.AST_NODE_TYPES.AssignmentExpression && parent.left.type === TSESTree5.AST_NODE_TYPES.Identifier && isComponentName(parent.left.name)) {
17800
+ return parent.left.name;
17801
+ }
17802
+ if (parent.type === TSESTree5.AST_NODE_TYPES.ExportDefaultDeclaration && callExpr.arguments.length > 0) {
17803
+ const [firstArg] = callExpr.arguments;
17804
+ if (firstArg && firstArg.type === TSESTree5.AST_NODE_TYPES.FunctionExpression && firstArg.id && isComponentName(firstArg.id.name)) {
17805
+ return firstArg.id.name;
17512
17806
  }
17513
- if (isNode2(childValue) && traverseForThis(childValue, visited2))
17514
- return true;
17515
17807
  }
17516
- return false;
17808
+ return;
17517
17809
  }
17518
- function methodUsesThis(node) {
17519
- const value = node.value;
17520
- if (value === undefined || value.type !== AST_NODE_TYPES2.FunctionExpression)
17810
+ function getHookName(callExpression) {
17811
+ const { callee } = callExpression;
17812
+ if (callee.type === TSESTree5.AST_NODE_TYPES.Identifier)
17813
+ return callee.name;
17814
+ if (callee.type === TSESTree5.AST_NODE_TYPES.MemberExpression && callee.property.type === TSESTree5.AST_NODE_TYPES.Identifier) {
17815
+ return callee.property.name;
17816
+ }
17817
+ return;
17818
+ }
17819
+ function countDestructuredProps(node) {
17820
+ const [firstParam] = node.params;
17821
+ if (!firstParam)
17822
+ return;
17823
+ let pattern4;
17824
+ if (firstParam.type === TSESTree5.AST_NODE_TYPES.ObjectPattern)
17825
+ pattern4 = firstParam;
17826
+ if (firstParam.type === TSESTree5.AST_NODE_TYPES.AssignmentPattern && firstParam.left.type === TSESTree5.AST_NODE_TYPES.ObjectPattern) {
17827
+ pattern4 = firstParam.left;
17828
+ }
17829
+ if (!pattern4)
17830
+ return;
17831
+ let count = 0;
17832
+ for (const { type: type3 } of pattern4.properties)
17833
+ if (type3 === TSESTree5.AST_NODE_TYPES.Property)
17834
+ count += 1;
17835
+ return count;
17836
+ }
17837
+ function isTypeOnlyNullLiteral(node) {
17838
+ const { parent } = node;
17839
+ if (parent === null || parent === undefined)
17521
17840
  return false;
17522
- return traverseForThis(value, new WeakSet);
17841
+ if (typeof parent.type === "string" && parent.type.startsWith("TS") && !RUNTIME_TS_WRAPPERS.has(parent.type))
17842
+ return true;
17843
+ if (parent.type === TSESTree5.AST_NODE_TYPES.TSLiteralType)
17844
+ return true;
17845
+ return false;
17523
17846
  }
17524
- var noInstanceMethodsWithoutThis = {
17525
- create(context) {
17526
- const rawOptions = context.options[0];
17527
- const options3 = normalizeOptions(rawOptions);
17528
- return {
17529
- MethodDefinition(node) {
17530
- if (!shouldCheckMethod(node, options3))
17531
- return;
17532
- if (methodUsesThis(node))
17533
- return;
17534
- const methodName = node.key.type === AST_NODE_TYPES2.Identifier ? node.key.name : "unknown";
17535
- context.report({
17536
- data: { methodName },
17537
- messageId: "noInstanceMethodWithoutThis",
17538
- node
17539
- });
17847
+ function analyzeComponentBody(functionNode, sourceCode, stateHooks) {
17848
+ let maxJsxDepth = 0;
17849
+ let stateHookCount = 0;
17850
+ const nullLiterals = new Array;
17851
+ function visit(current, jsxDepth) {
17852
+ if (FUNCTION_BOUNDARIES.has(current.type) && current !== functionNode)
17853
+ return;
17854
+ let nextDepth = jsxDepth;
17855
+ if (current.type === TSESTree5.AST_NODE_TYPES.JSXElement || current.type === TSESTree5.AST_NODE_TYPES.JSXFragment) {
17856
+ nextDepth = jsxDepth + 1;
17857
+ if (nextDepth > maxJsxDepth)
17858
+ maxJsxDepth = nextDepth;
17859
+ }
17860
+ if (current.type === TSESTree5.AST_NODE_TYPES.CallExpression) {
17861
+ const hookName = getHookName(current);
17862
+ if (typeof hookName === "string" && hookName.length > 0 && stateHooks.has(hookName))
17863
+ stateHookCount += 1;
17864
+ }
17865
+ if (current.type === TSESTree5.AST_NODE_TYPES.Literal && current.value === null) {
17866
+ const literalNode = current;
17867
+ if (!isTypeOnlyNullLiteral(literalNode))
17868
+ nullLiterals.push(literalNode);
17869
+ }
17870
+ function getVisitorKeysForNodeType(nodeType) {
17871
+ const visitorKeysUnknown = sourceCode.visitorKeys;
17872
+ if (visitorKeysUnknown === null || visitorKeysUnknown === undefined || typeof visitorKeysUnknown !== "object")
17873
+ return [];
17874
+ const visitorKeysRecord = visitorKeysUnknown;
17875
+ const keysUnknown = visitorKeysRecord[nodeType];
17876
+ if (!Array.isArray(keysUnknown))
17877
+ return [];
17878
+ const keys3 = new Array;
17879
+ for (const key of keysUnknown)
17880
+ if (typeof key === "string")
17881
+ keys3.push(key);
17882
+ return keys3;
17883
+ }
17884
+ const keys2 = getVisitorKeysForNodeType(current.type);
17885
+ const currentRecord = current;
17886
+ for (const key of keys2) {
17887
+ const value = currentRecord[key];
17888
+ if (Array.isArray(value)) {
17889
+ for (const item of value) {
17890
+ if (typeof item === "object" && item !== null && "type" in item) {
17891
+ visit(item, nextDepth);
17892
+ }
17893
+ }
17894
+ continue;
17540
17895
  }
17541
- };
17542
- },
17543
- defaultOptions: [DEFAULT_OPTIONS],
17544
- meta: {
17545
- docs: {
17546
- description: "Detect instance methods that do not use 'this' and suggest converting them to standalone functions for better performance in roblox-ts.",
17896
+ if (typeof value === "object" && value !== null && "type" in value) {
17897
+ visit(value, nextDepth);
17898
+ }
17899
+ }
17900
+ }
17901
+ visit(functionNode.body, 0);
17902
+ return { maxJsxDepth, nullLiterals, stateHookCount };
17903
+ }
17904
+ function parseOptions(options3) {
17905
+ const defaults = {
17906
+ enforceTargetLines: true,
17907
+ ignoreComponents: [],
17908
+ maxDestructuredProps: 5,
17909
+ maxLines: 200,
17910
+ maxStateHooks: 5,
17911
+ maxTsxNesting: 3,
17912
+ stateHooks: ["useState", "useReducer", "useBinding"],
17913
+ targetLines: 120
17914
+ };
17915
+ if (typeof options3 !== "object" || options3 === null)
17916
+ return defaults;
17917
+ const cast = options3;
17918
+ return {
17919
+ enforceTargetLines: typeof cast.enforceTargetLines === "boolean" ? cast.enforceTargetLines : defaults.enforceTargetLines,
17920
+ ignoreComponents: Array.isArray(cast.ignoreComponents) ? cast.ignoreComponents : defaults.ignoreComponents,
17921
+ maxDestructuredProps: typeof cast.maxDestructuredProps === "number" ? cast.maxDestructuredProps : defaults.maxDestructuredProps,
17922
+ maxLines: typeof cast.maxLines === "number" ? cast.maxLines : defaults.maxLines,
17923
+ maxStateHooks: typeof cast.maxStateHooks === "number" ? cast.maxStateHooks : defaults.maxStateHooks,
17924
+ maxTsxNesting: typeof cast.maxTsxNesting === "number" ? cast.maxTsxNesting : defaults.maxTsxNesting,
17925
+ stateHooks: Array.isArray(cast.stateHooks) ? cast.stateHooks : defaults.stateHooks,
17926
+ targetLines: typeof cast.targetLines === "number" ? cast.targetLines : defaults.targetLines
17927
+ };
17928
+ }
17929
+ var noGodComponents = {
17930
+ create(context) {
17931
+ const configuration = parseOptions(context.options[0]);
17932
+ const ignoreSet = new Set(configuration.ignoreComponents);
17933
+ const stateHooks = new Set(configuration.stateHooks);
17934
+ const checked = new WeakSet;
17935
+ const { sourceCode } = context;
17936
+ function checkComponent(node, name) {
17937
+ if (ignoreSet.has(name))
17938
+ return;
17939
+ if (checked.has(node))
17940
+ return;
17941
+ checked.add(node);
17942
+ const location = node.loc;
17943
+ if (location !== null && location !== undefined) {
17944
+ const lines = location.end.line - location.start.line + 1;
17945
+ if (lines > configuration.maxLines) {
17946
+ context.report({
17947
+ data: { lines, max: configuration.maxLines, name, target: configuration.targetLines },
17948
+ messageId: "exceedsMaxLines",
17949
+ node
17950
+ });
17951
+ } else if (configuration.enforceTargetLines && lines > configuration.targetLines) {
17952
+ context.report({
17953
+ data: { lines, max: configuration.maxLines, name, target: configuration.targetLines },
17954
+ messageId: "exceedsTargetLines",
17955
+ node
17956
+ });
17957
+ }
17958
+ }
17959
+ const propsCount = countDestructuredProps(node);
17960
+ if (typeof propsCount === "number" && propsCount > configuration.maxDestructuredProps) {
17961
+ context.report({
17962
+ data: { count: propsCount, max: configuration.maxDestructuredProps, name },
17963
+ messageId: "tooManyProps",
17964
+ node
17965
+ });
17966
+ }
17967
+ const analysis = analyzeComponentBody(node, sourceCode, stateHooks);
17968
+ if (analysis.maxJsxDepth > configuration.maxTsxNesting) {
17969
+ context.report({
17970
+ data: { depth: analysis.maxJsxDepth, max: configuration.maxTsxNesting, name },
17971
+ messageId: "tsxNestingTooDeep",
17972
+ node
17973
+ });
17974
+ }
17975
+ if (analysis.stateHookCount > configuration.maxStateHooks) {
17976
+ context.report({
17977
+ data: {
17978
+ count: analysis.stateHookCount,
17979
+ hooks: configuration.stateHooks.join(", "),
17980
+ max: configuration.maxStateHooks,
17981
+ name
17982
+ },
17983
+ messageId: "tooManyStateHooks",
17984
+ node
17985
+ });
17986
+ }
17987
+ for (const literal2 of analysis.nullLiterals) {
17988
+ context.report({
17989
+ messageId: "nullLiteral",
17990
+ node: literal2
17991
+ });
17992
+ }
17993
+ }
17994
+ function maybeCheckFunction(node) {
17995
+ const name = getComponentNameFromFunction(node);
17996
+ if (typeof name !== "string" || name.length === 0)
17997
+ return;
17998
+ checkComponent(node, name);
17999
+ }
18000
+ return {
18001
+ ArrowFunctionExpression(node) {
18002
+ maybeCheckFunction(node);
18003
+ },
18004
+ CallExpression(node) {
18005
+ const callExpr = node;
18006
+ if (!isReactComponentHOC(callExpr))
18007
+ return;
18008
+ const [firstArg] = callExpr.arguments;
18009
+ if (!firstArg || firstArg.type !== TSESTree5.AST_NODE_TYPES.FunctionExpression && firstArg.type !== TSESTree5.AST_NODE_TYPES.ArrowFunctionExpression) {
18010
+ return;
18011
+ }
18012
+ const nameFromParent = getComponentNameFromCallParent(callExpr);
18013
+ const nameFromArg = getComponentNameFromFunction(firstArg);
18014
+ const name = nameFromParent ?? nameFromArg;
18015
+ if (typeof name !== "string" || name.length === 0)
18016
+ return;
18017
+ checkComponent(firstArg, name);
18018
+ },
18019
+ FunctionDeclaration(node) {
18020
+ maybeCheckFunction(node);
18021
+ },
18022
+ FunctionExpression(node) {
18023
+ maybeCheckFunction(node);
18024
+ }
18025
+ };
18026
+ },
18027
+ meta: {
18028
+ docs: {
18029
+ description: "Enforce React component size and complexity limits inspired by the 'Refactor God Component' checklist.",
18030
+ recommended: false
18031
+ },
18032
+ messages: {
18033
+ exceedsMaxLines: "Component '{{name}}' is {{lines}} lines; max allowed is {{max}}. Split into smaller components/hooks.",
18034
+ exceedsTargetLines: "Component '{{name}}' is {{lines}} lines; target is {{target}} (max {{max}}). Consider extracting hooks/components.",
18035
+ nullLiteral: "Avoid `null` in components; use `undefined` instead.",
18036
+ tooManyProps: "Component '{{name}}' destructures {{count}} props; max allowed is {{max}}. Group props or split the component.",
18037
+ tooManyStateHooks: "Component '{{name}}' has {{count}} state hooks ({{hooks}}); max allowed is {{max}}. Extract cohesive state into a custom hook.",
18038
+ tsxNestingTooDeep: "Component '{{name}}' has TSX nesting depth {{depth}}; max allowed is {{max}}. Extract child components."
18039
+ },
18040
+ schema: [
18041
+ {
18042
+ additionalProperties: false,
18043
+ properties: {
18044
+ enforceTargetLines: {
18045
+ default: true,
18046
+ description: "Whether to report when exceeding targetLines (soft limit).",
18047
+ type: "boolean"
18048
+ },
18049
+ ignoreComponents: {
18050
+ description: "Component names to ignore.",
18051
+ items: { type: "string" },
18052
+ type: "array"
18053
+ },
18054
+ maxDestructuredProps: {
18055
+ default: 5,
18056
+ description: "Maximum number of destructured props in a component parameter.",
18057
+ type: "number"
18058
+ },
18059
+ maxLines: {
18060
+ default: 200,
18061
+ description: "Hard maximum lines for a component.",
18062
+ type: "number"
18063
+ },
18064
+ maxStateHooks: {
18065
+ default: 5,
18066
+ description: "Maximum number of stateful hook calls in a component.",
18067
+ type: "number"
18068
+ },
18069
+ maxTsxNesting: {
18070
+ default: 3,
18071
+ description: "Maximum JSX/TSX nesting depth in a component.",
18072
+ type: "number"
18073
+ },
18074
+ stateHooks: {
18075
+ default: ["useState", "useReducer", "useBinding"],
18076
+ description: "Hook names to count toward state complexity.",
18077
+ items: { type: "string" },
18078
+ type: "array"
18079
+ },
18080
+ targetLines: {
18081
+ default: 120,
18082
+ description: "Soft target lines for a component.",
18083
+ type: "number"
18084
+ }
18085
+ },
18086
+ type: "object"
18087
+ }
18088
+ ],
18089
+ type: "problem"
18090
+ }
18091
+ };
18092
+ var no_god_components_default = noGodComponents;
18093
+
18094
+ // src/rules/no-identity-map.ts
18095
+ var import_scope_manager = __toESM(require_dist2(), 1);
18096
+ import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/utils";
18097
+ var DEFAULT_BINDING_PATTERNS = ["binding"];
18098
+ function getParameterName(param) {
18099
+ if (param.type === AST_NODE_TYPES2.Identifier)
18100
+ return param.name;
18101
+ if (param.type === AST_NODE_TYPES2.AssignmentPattern && param.left.type === AST_NODE_TYPES2.Identifier) {
18102
+ return param.left.name;
18103
+ }
18104
+ return;
18105
+ }
18106
+ function isBlockReturningIdentity(body, paramName) {
18107
+ if (body.body.length !== 1)
18108
+ return false;
18109
+ const [statement] = body.body;
18110
+ if (statement?.type !== AST_NODE_TYPES2.ReturnStatement)
18111
+ return false;
18112
+ if (!statement.argument)
18113
+ return false;
18114
+ if (statement.argument.type !== AST_NODE_TYPES2.Identifier)
18115
+ return false;
18116
+ return statement.argument.name === paramName;
18117
+ }
18118
+ function isIdentityCallback(callback) {
18119
+ if (callback.type === AST_NODE_TYPES2.ArrowFunctionExpression) {
18120
+ if (callback.params.length !== 1)
18121
+ return false;
18122
+ const [param] = callback.params;
18123
+ if (param === undefined)
18124
+ return false;
18125
+ const paramName = getParameterName(param);
18126
+ if (paramName === undefined || paramName === "")
18127
+ return false;
18128
+ if (callback.body.type === AST_NODE_TYPES2.Identifier) {
18129
+ return callback.body.name === paramName;
18130
+ }
18131
+ if (callback.body.type === AST_NODE_TYPES2.BlockStatement) {
18132
+ return isBlockReturningIdentity(callback.body, paramName);
18133
+ }
18134
+ return false;
18135
+ }
18136
+ if (callback.type === AST_NODE_TYPES2.FunctionExpression) {
18137
+ if (callback.params.length !== 1)
18138
+ return false;
18139
+ const [param] = callback.params;
18140
+ if (param === undefined)
18141
+ return false;
18142
+ const paramName = getParameterName(param);
18143
+ if (paramName === undefined || paramName === "")
18144
+ return false;
18145
+ return isBlockReturningIdentity(callback.body, paramName);
18146
+ }
18147
+ return false;
18148
+ }
18149
+ function findVariable(context, identifier3) {
18150
+ let scope = context.sourceCode.getScope(identifier3);
18151
+ while (scope) {
18152
+ const variable = scope.set.get(identifier3.name);
18153
+ if (variable)
18154
+ return variable;
18155
+ scope = scope.upper ?? undefined;
18156
+ }
18157
+ return;
18158
+ }
18159
+ function getHookName2(node) {
18160
+ const { callee } = node;
18161
+ if (callee.type === AST_NODE_TYPES2.Identifier) {
18162
+ return callee.name;
18163
+ }
18164
+ if (callee.type === AST_NODE_TYPES2.MemberExpression && callee.property.type === AST_NODE_TYPES2.Identifier) {
18165
+ return callee.property.name;
18166
+ }
18167
+ return;
18168
+ }
18169
+ function isJoinBindingsCall(node) {
18170
+ const { callee } = node;
18171
+ if (callee.type === AST_NODE_TYPES2.Identifier) {
18172
+ return callee.name === "joinBindings";
18173
+ }
18174
+ if (callee.type === AST_NODE_TYPES2.MemberExpression && callee.property.type === AST_NODE_TYPES2.Identifier) {
18175
+ return callee.property.name === "joinBindings";
18176
+ }
18177
+ return false;
18178
+ }
18179
+ function isBindingInitialization(variable) {
18180
+ for (const def of variable.defs) {
18181
+ if (def.type !== import_scope_manager.DefinitionType.Variable)
18182
+ continue;
18183
+ const { init } = def.node;
18184
+ if (!init || init.type !== AST_NODE_TYPES2.CallExpression)
18185
+ continue;
18186
+ const hookName = getHookName2(init);
18187
+ if (hookName === "useBinding")
18188
+ return true;
18189
+ if (isJoinBindingsCall(init))
18190
+ return true;
18191
+ if (init.callee.type === AST_NODE_TYPES2.MemberExpression && init.callee.property.type === AST_NODE_TYPES2.Identifier && init.callee.property.name === "map") {
18192
+ return true;
18193
+ }
18194
+ }
18195
+ return false;
18196
+ }
18197
+ function isLikelyBinding(context, callee, patterns2) {
18198
+ const { object: object3 } = callee;
18199
+ if (object3.type === AST_NODE_TYPES2.Identifier) {
18200
+ const lowerName = object3.name.toLowerCase();
18201
+ for (const pattern4 of patterns2) {
18202
+ if (lowerName.includes(pattern4.toLowerCase()))
18203
+ return true;
18204
+ }
18205
+ const variable = findVariable(context, object3);
18206
+ if (variable && isBindingInitialization(variable))
18207
+ return true;
18208
+ }
18209
+ if (object3.type === AST_NODE_TYPES2.CallExpression && object3.callee.type === AST_NODE_TYPES2.MemberExpression && object3.callee.property.type === AST_NODE_TYPES2.Identifier && object3.callee.property.name === "map") {
18210
+ return true;
18211
+ }
18212
+ if (object3.type === AST_NODE_TYPES2.CallExpression && isJoinBindingsCall(object3)) {
18213
+ return true;
18214
+ }
18215
+ return false;
18216
+ }
18217
+ var noIdentityMap = {
18218
+ create(context) {
18219
+ const [rawOptions] = context.options;
18220
+ const patterns2 = rawOptions?.bindingPatterns ?? DEFAULT_BINDING_PATTERNS;
18221
+ return {
18222
+ CallExpression(node) {
18223
+ const { callee } = node;
18224
+ if (callee.type !== AST_NODE_TYPES2.MemberExpression)
18225
+ return;
18226
+ if (callee.computed)
18227
+ return;
18228
+ if (callee.property.type !== AST_NODE_TYPES2.Identifier)
18229
+ return;
18230
+ if (callee.property.name !== "map")
18231
+ return;
18232
+ if (node.arguments.length !== 1)
18233
+ return;
18234
+ const [callback] = node.arguments;
18235
+ if (!callback || callback.type === AST_NODE_TYPES2.SpreadElement)
18236
+ return;
18237
+ if (!isIdentityCallback(callback))
18238
+ return;
18239
+ const isBinding = isLikelyBinding(context, callee, patterns2);
18240
+ context.report({
18241
+ fix(fixer) {
18242
+ const objectText = context.sourceCode.getText(callee.object);
18243
+ return fixer.replaceText(node, objectText);
18244
+ },
18245
+ messageId: isBinding ? "identityBindingMap" : "identityArrayMap",
18246
+ node
18247
+ });
18248
+ }
18249
+ };
18250
+ },
18251
+ defaultOptions: [{}],
18252
+ meta: {
18253
+ docs: {
18254
+ description: "Disallow pointless identity `.map()` calls that return the parameter unchanged"
18255
+ },
18256
+ fixable: "code",
18257
+ messages: {
18258
+ identityArrayMap: "Pointless identity `.map()` call on Array. Use `table.clone(array)` or `[...array]` instead.",
18259
+ identityBindingMap: "Pointless identity `.map()` call on Binding. Use the original binding directly."
18260
+ },
18261
+ schema: [
18262
+ {
18263
+ additionalProperties: false,
18264
+ properties: {
18265
+ bindingPatterns: {
18266
+ default: [...DEFAULT_BINDING_PATTERNS],
18267
+ description: "Variable name patterns to recognize as Bindings (case insensitive)",
18268
+ items: { type: "string" },
18269
+ type: "array"
18270
+ }
18271
+ },
18272
+ type: "object"
18273
+ }
18274
+ ],
18275
+ type: "suggestion"
18276
+ }
18277
+ };
18278
+ var no_identity_map_default = noIdentityMap;
18279
+
18280
+ // src/rules/no-instance-methods-without-this.ts
18281
+ import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/types";
18282
+ var DEFAULT_OPTIONS = {
18283
+ checkPrivate: true,
18284
+ checkProtected: true,
18285
+ checkPublic: true
18286
+ };
18287
+ function normalizeOptions(rawOptions) {
18288
+ const mergedOptions = { ...DEFAULT_OPTIONS };
18289
+ if (rawOptions?.checkPrivate !== undefined)
18290
+ mergedOptions.checkPrivate = rawOptions.checkPrivate;
18291
+ if (rawOptions?.checkProtected !== undefined)
18292
+ mergedOptions.checkProtected = rawOptions.checkProtected;
18293
+ if (rawOptions?.checkPublic !== undefined)
18294
+ mergedOptions.checkPublic = rawOptions.checkPublic;
18295
+ return mergedOptions;
18296
+ }
18297
+ function shouldCheckMethod(node, options3) {
18298
+ if (node.static)
18299
+ return false;
18300
+ if (node.kind !== "method")
18301
+ return false;
18302
+ const accessibility = node.accessibility ?? "public";
18303
+ if (accessibility === "private" && !options3.checkPrivate)
18304
+ return false;
18305
+ if (accessibility === "protected" && !options3.checkProtected)
18306
+ return false;
18307
+ if (accessibility === "public" && !options3.checkPublic)
18308
+ return false;
18309
+ return true;
18310
+ }
18311
+ function isNode2(value) {
18312
+ return typeof value === "object" && value !== null && "type" in value;
18313
+ }
18314
+ function hasDynamicProperties2(_node) {
18315
+ return true;
18316
+ }
18317
+ function traverseForThis(currentNode, visited2) {
18318
+ if (visited2.has(currentNode))
18319
+ return false;
18320
+ visited2.add(currentNode);
18321
+ if (currentNode.type === AST_NODE_TYPES3.ThisExpression || currentNode.type === AST_NODE_TYPES3.Super)
18322
+ return true;
18323
+ if (!hasDynamicProperties2(currentNode))
18324
+ return false;
18325
+ for (const key in currentNode) {
18326
+ if (!Object.hasOwn(currentNode, key))
18327
+ continue;
18328
+ const childValue = currentNode[key];
18329
+ if (childValue === null || childValue === undefined)
18330
+ continue;
18331
+ if (Array.isArray(childValue)) {
18332
+ for (const item of childValue)
18333
+ if (isNode2(item) && traverseForThis(item, visited2))
18334
+ return true;
18335
+ continue;
18336
+ }
18337
+ if (isNode2(childValue) && traverseForThis(childValue, visited2))
18338
+ return true;
18339
+ }
18340
+ return false;
18341
+ }
18342
+ function methodUsesThis(node) {
18343
+ const { value } = node;
18344
+ if (value === undefined || value.type !== AST_NODE_TYPES3.FunctionExpression)
18345
+ return false;
18346
+ return traverseForThis(value, new WeakSet);
18347
+ }
18348
+ var noInstanceMethodsWithoutThis = {
18349
+ create(context) {
18350
+ const [rawOptions] = context.options;
18351
+ const options3 = normalizeOptions(rawOptions);
18352
+ return {
18353
+ MethodDefinition(node) {
18354
+ if (!shouldCheckMethod(node, options3))
18355
+ return;
18356
+ if (methodUsesThis(node))
18357
+ return;
18358
+ const methodName = node.key.type === AST_NODE_TYPES3.Identifier ? node.key.name : "unknown";
18359
+ context.report({
18360
+ data: { methodName },
18361
+ messageId: "noInstanceMethodWithoutThis",
18362
+ node
18363
+ });
18364
+ }
18365
+ };
18366
+ },
18367
+ defaultOptions: [DEFAULT_OPTIONS],
18368
+ meta: {
18369
+ docs: {
18370
+ description: "Detect instance methods that do not use 'this' and suggest converting them to standalone functions for better performance in roblox-ts.",
17547
18371
  recommended: true
17548
18372
  },
17549
18373
  messages: {
@@ -17604,7 +18428,7 @@ var noPrint = {
17604
18428
  var no_print_default = noPrint;
17605
18429
 
17606
18430
  // src/rules/no-shorthand-names.ts
17607
- import { TSESTree as TSESTree5 } from "@typescript-eslint/types";
18431
+ import { TSESTree as TSESTree6 } from "@typescript-eslint/types";
17608
18432
  var isRuleOptions = Compile(build_default.Object({
17609
18433
  allowPropertyAccess: build_default.Optional(build_default.Array(build_default.String())),
17610
18434
  shorthands: build_default.Optional(build_default.Record(build_default.String(), build_default.String()))
@@ -17621,19 +18445,19 @@ var DEFAULT_OPTIONS2 = {
17621
18445
  plr: "player"
17622
18446
  }
17623
18447
  };
17624
- var REGEX_PATTERN_MATCHER = /^\/(.+)\/([gimsuy]*)$/;
18448
+ var REGEX_PATTERN_MATCHER = regex2("^/(?<first>.+)/(?<second>[gimsuy]*)$");
17625
18449
  var WORD_BOUNDARY_REGEX = /(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-zA-Z])(?=\d)|(?<=\d)(?=[a-zA-Z])/;
17626
18450
  function splitIdentifierIntoWords(identifier3) {
17627
18451
  return identifier3.split(WORD_BOUNDARY_REGEX);
17628
18452
  }
17629
18453
  function createMatcher(key, replacement) {
17630
18454
  if (key.startsWith("/")) {
17631
- const match = key.match(REGEX_PATTERN_MATCHER);
18455
+ const match = REGEX_PATTERN_MATCHER.exec(key);
17632
18456
  if (match) {
17633
18457
  return {
17634
18458
  matcher: {
17635
18459
  original: key,
17636
- pattern: new RegExp(`^${match[1]}$`, match[2]),
18460
+ pattern: new RegExp(`^${match.groups.first}$`, match.groups.second),
17637
18461
  replacement
17638
18462
  },
17639
18463
  type: "pattern"
@@ -17671,8 +18495,8 @@ function matchWord(word, matchers, exactMatchers) {
17671
18495
  const match = word.match(matcher.pattern);
17672
18496
  if (match) {
17673
18497
  let replaced = matcher.replacement;
17674
- for (let i = 1;i < match.length; i++) {
17675
- replaced = replaced.replaceAll(new RegExp(`\\$${i}`, "g"), match[i] ?? "");
18498
+ for (let index2 = 1;index2 < match.length; index2 += 1) {
18499
+ replaced = replaced.replaceAll(new RegExp(`\\$${index2}`, "g"), match[index2] ?? "");
17676
18500
  }
17677
18501
  return {
17678
18502
  replacement: replaced,
@@ -17684,7 +18508,7 @@ function matchWord(word, matchers, exactMatchers) {
17684
18508
  }
17685
18509
  function buildReplacementIdentifier(identifier3, options3) {
17686
18510
  const words = splitIdentifierIntoWords(identifier3);
17687
- const matches = [];
18511
+ const matches = new Array;
17688
18512
  let hasMatch = false;
17689
18513
  const newWords = words.map((word) => {
17690
18514
  const match = matchWord(word, options3.matchers, options3.exactMatchers);
@@ -17701,18 +18525,18 @@ function buildReplacementIdentifier(identifier3, options3) {
17701
18525
  }
17702
18526
  function normalizeOptions2(rawOptions) {
17703
18527
  const mergedShorthands = { ...DEFAULT_OPTIONS2.shorthands };
17704
- if (rawOptions?.shorthands)
18528
+ if (rawOptions?.shorthands) {
17705
18529
  for (const [key, value] of Object.entries(rawOptions.shorthands))
17706
18530
  mergedShorthands[key] = value;
17707
- const matchers = [];
18531
+ }
18532
+ const matchers = new Array;
17708
18533
  const exactMatchers = new Map;
17709
18534
  for (const [key, value] of Object.entries(mergedShorthands)) {
17710
18535
  const result = createMatcher(key, value);
17711
- if (result.type === "exact") {
18536
+ if (result.type === "exact")
17712
18537
  exactMatchers.set(result.original, result.replacement);
17713
- } else {
18538
+ else
17714
18539
  matchers.push(result.matcher);
17715
- }
17716
18540
  }
17717
18541
  const allowPropertyAccessSource = rawOptions?.allowPropertyAccess ?? DEFAULT_OPTIONS2.allowPropertyAccess;
17718
18542
  return {
@@ -17736,11 +18560,12 @@ var noShorthandNames = {
17736
18560
  const { replaced, matches } = result;
17737
18561
  const { parent } = node;
17738
18562
  const [match] = matches;
17739
- if (matches.length === 1 && match !== undefined && allowPropertyAccess.has(match.shorthand) && parent !== undefined && isRecord2(parent) && parent.type === TSESTree5.AST_NODE_TYPES.MemberExpression && parent.property === node)
18563
+ if (matches.length === 1 && match !== undefined && allowPropertyAccess.has(match.shorthand) && parent !== undefined && isRecord2(parent) && parent.type === TSESTree6.AST_NODE_TYPES.MemberExpression && parent.property === node) {
17740
18564
  return;
17741
- if (identifierName === "plr" && parent?.type === TSESTree5.AST_NODE_TYPES.VariableDeclarator && parent.id === node) {
18565
+ }
18566
+ if (identifierName === "plr" && parent?.type === TSESTree6.AST_NODE_TYPES.VariableDeclarator && parent.id === node) {
17742
18567
  const { init } = parent;
17743
- if (init && isRecord2(init) && init.type === TSESTree5.AST_NODE_TYPES.MemberExpression && init.object !== undefined && isRecord2(init.object) && init.object.type === TSESTree5.AST_NODE_TYPES.Identifier && init.object.name === "Players" && init.property !== undefined && isRecord2(init.property) && init.property.type === TSESTree5.AST_NODE_TYPES.Identifier && init.property.name === "LocalPlayer") {
18568
+ if (init && isRecord2(init) && init.type === TSESTree6.AST_NODE_TYPES.MemberExpression && init.object !== undefined && isRecord2(init.object) && init.object.type === TSESTree6.AST_NODE_TYPES.Identifier && init.object.name === "Players" && init.property !== undefined && isRecord2(init.property) && init.property.type === TSESTree6.AST_NODE_TYPES.Identifier && init.property.name === "LocalPlayer") {
17744
18569
  context.report({
17745
18570
  data: { replacement: "localPlayer", shorthand: "plr" },
17746
18571
  messageId: "useReplacement",
@@ -17749,7 +18574,7 @@ var noShorthandNames = {
17749
18574
  return;
17750
18575
  }
17751
18576
  }
17752
- const shorthandList = matches.map((m) => m.shorthand).join(", ");
18577
+ const shorthandList = matches.map(({ shorthand }) => shorthand).join(", ");
17753
18578
  context.report({
17754
18579
  data: { replacement: replaced, shorthand: shorthandList },
17755
18580
  messageId: "useReplacement",
@@ -17790,8 +18615,8 @@ var noShorthandNames = {
17790
18615
  var no_shorthand_names_default = noShorthandNames;
17791
18616
 
17792
18617
  // src/rules/no-useless-use-spring.ts
17793
- var import_scope_manager = __toESM(require_dist2(), 1);
17794
- import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
18618
+ var import_scope_manager2 = __toESM(require_dist2(), 1);
18619
+ import { AST_NODE_TYPES as AST_NODE_TYPES4 } from "@typescript-eslint/utils";
17795
18620
  var DEFAULT_STATIC_GLOBAL_FACTORIES = [
17796
18621
  "Axes",
17797
18622
  "BrickColor",
@@ -17827,34 +18652,34 @@ var STATIC_UNARY_OPERATORS = new Set(["-", "+", "!", "~", "typeof", "void", "del
17827
18652
  function unwrapExpression(expression) {
17828
18653
  let current = expression;
17829
18654
  while (true) {
17830
- if (current.type === AST_NODE_TYPES3.TSAsExpression) {
18655
+ if (current.type === AST_NODE_TYPES4.TSAsExpression) {
17831
18656
  current = current.expression;
17832
18657
  continue;
17833
18658
  }
17834
- if (current.type === AST_NODE_TYPES3.TSTypeAssertion) {
18659
+ if (current.type === AST_NODE_TYPES4.TSTypeAssertion) {
17835
18660
  current = current.expression;
17836
18661
  continue;
17837
18662
  }
17838
- if (current.type === AST_NODE_TYPES3.TSNonNullExpression) {
18663
+ if (current.type === AST_NODE_TYPES4.TSNonNullExpression) {
17839
18664
  current = current.expression;
17840
18665
  continue;
17841
18666
  }
17842
- if (current.type === AST_NODE_TYPES3.TSSatisfiesExpression) {
18667
+ if (current.type === AST_NODE_TYPES4.TSSatisfiesExpression) {
17843
18668
  current = current.expression;
17844
18669
  continue;
17845
18670
  }
17846
- if (current.type === AST_NODE_TYPES3.TSInstantiationExpression) {
18671
+ if (current.type === AST_NODE_TYPES4.TSInstantiationExpression) {
17847
18672
  current = current.expression;
17848
18673
  continue;
17849
18674
  }
17850
- if (current.type === AST_NODE_TYPES3.ChainExpression) {
18675
+ if (current.type === AST_NODE_TYPES4.ChainExpression) {
17851
18676
  current = current.expression;
17852
18677
  continue;
17853
18678
  }
17854
18679
  return current;
17855
18680
  }
17856
18681
  }
17857
- function findVariable(context, identifier3) {
18682
+ function findVariable2(context, identifier3) {
17858
18683
  let scope = context.sourceCode.getScope(identifier3);
17859
18684
  while (scope) {
17860
18685
  const variable = scope.set.get(identifier3.name);
@@ -17865,29 +18690,29 @@ function findVariable(context, identifier3) {
17865
18690
  return;
17866
18691
  }
17867
18692
  function isModuleLevelScope(scope) {
17868
- return scope.type === import_scope_manager.ScopeType.module || scope.type === import_scope_manager.ScopeType.global;
18693
+ return scope.type === import_scope_manager2.ScopeType.module || scope.type === import_scope_manager2.ScopeType.global;
17869
18694
  }
17870
18695
  function isImport(variable) {
17871
18696
  for (const definition of variable.defs)
17872
- if (definition.type === import_scope_manager.DefinitionType.ImportBinding)
18697
+ if (definition.type === import_scope_manager2.DefinitionType.ImportBinding)
17873
18698
  return true;
17874
18699
  return false;
17875
18700
  }
17876
18701
  function getConstInitializer(definition) {
17877
- if (definition === undefined || definition.type !== import_scope_manager.DefinitionType.Variable)
18702
+ if (definition === undefined || definition.type !== import_scope_manager2.DefinitionType.Variable)
17878
18703
  return;
17879
18704
  const declarator = definition.node;
17880
- if (declarator.type !== AST_NODE_TYPES3.VariableDeclarator)
18705
+ if (declarator.type !== AST_NODE_TYPES4.VariableDeclarator)
17881
18706
  return;
17882
18707
  const declaration = definition.parent;
17883
- if (declaration?.type !== AST_NODE_TYPES3.VariableDeclaration)
18708
+ if (declaration?.type !== AST_NODE_TYPES4.VariableDeclaration)
17884
18709
  return;
17885
18710
  if (declaration.kind !== "const")
17886
18711
  return;
17887
18712
  return declarator.init ?? undefined;
17888
18713
  }
17889
18714
  function isStaticIdentifier(context, identifier3, seen, options3) {
17890
- const variable = findVariable(context, identifier3);
18715
+ const variable = findVariable2(context, identifier3);
17891
18716
  if (variable === undefined)
17892
18717
  return options3.staticGlobalFactories.has(identifier3.name);
17893
18718
  if (!isModuleLevelScope(variable.scope))
@@ -17904,34 +18729,34 @@ function isStaticIdentifier(context, identifier3, seen, options3) {
17904
18729
  return false;
17905
18730
  }
17906
18731
  function isStaticMemberProperty(property, seen, options3) {
17907
- if (property.type === AST_NODE_TYPES3.PrivateIdentifier)
18732
+ if (property.type === AST_NODE_TYPES4.PrivateIdentifier)
17908
18733
  return false;
17909
- if (property.type === AST_NODE_TYPES3.Identifier)
18734
+ if (property.type === AST_NODE_TYPES4.Identifier)
17910
18735
  return true;
17911
18736
  return isStaticExpressionInner(property, seen, options3);
17912
18737
  }
17913
18738
  function isStaticCallCallee(context, callee, seen, options3) {
17914
18739
  const unwrapped = unwrapExpression(callee);
17915
- if (unwrapped.type === AST_NODE_TYPES3.Identifier)
18740
+ if (unwrapped.type === AST_NODE_TYPES4.Identifier)
17916
18741
  return isStaticIdentifier(context, unwrapped, seen, options3);
17917
- if (unwrapped.type === AST_NODE_TYPES3.MemberExpression) {
18742
+ if (unwrapped.type === AST_NODE_TYPES4.MemberExpression) {
17918
18743
  if (!isStaticExpression(context, unwrapped.object, seen, options3))
17919
18744
  return false;
17920
18745
  if (unwrapped.computed)
17921
18746
  return isStaticMemberProperty(unwrapped.property, seen, options3);
17922
- return unwrapped.property.type === AST_NODE_TYPES3.Identifier;
18747
+ return unwrapped.property.type === AST_NODE_TYPES4.Identifier;
17923
18748
  }
17924
18749
  return false;
17925
18750
  }
17926
18751
  function isStaticObjectExpression(context, objectExpr, seen, options3) {
17927
18752
  for (const property of objectExpr.properties) {
17928
- if (property.type !== AST_NODE_TYPES3.Property)
18753
+ if (property.type !== AST_NODE_TYPES4.Property)
17929
18754
  return false;
17930
18755
  if (property.kind !== "init")
17931
18756
  return false;
17932
18757
  if (property.computed && !isStaticExpressionInner(property.key, seen, options3))
17933
18758
  return false;
17934
- const value = property.value;
18759
+ const { value } = property;
17935
18760
  if (!isNonPatternExpression(value))
17936
18761
  return false;
17937
18762
  if (!isStaticExpression(context, value, seen, options3))
@@ -17940,20 +18765,20 @@ function isStaticObjectExpression(context, objectExpr, seen, options3) {
17940
18765
  return true;
17941
18766
  }
17942
18767
  function isNonPatternExpression(value) {
17943
- return value.type !== AST_NODE_TYPES3.PrivateIdentifier && value.type !== AST_NODE_TYPES3.AssignmentPattern && value.type !== AST_NODE_TYPES3.ArrayPattern && value.type !== AST_NODE_TYPES3.ObjectPattern && value.type !== AST_NODE_TYPES3.RestElement && value.type !== AST_NODE_TYPES3.TSEmptyBodyFunctionExpression;
18768
+ return value.type !== AST_NODE_TYPES4.PrivateIdentifier && value.type !== AST_NODE_TYPES4.AssignmentPattern && value.type !== AST_NODE_TYPES4.ArrayPattern && value.type !== AST_NODE_TYPES4.ObjectPattern && value.type !== AST_NODE_TYPES4.RestElement && value.type !== AST_NODE_TYPES4.TSEmptyBodyFunctionExpression;
17944
18769
  }
17945
18770
  function isNonPrivateExpression(value) {
17946
- return value.type !== AST_NODE_TYPES3.PrivateIdentifier;
18771
+ return value.type !== AST_NODE_TYPES4.PrivateIdentifier;
17947
18772
  }
17948
18773
  function objectHasFromAndTo(objectExpr) {
17949
18774
  let hasFrom = false;
17950
18775
  let hasTo = false;
17951
18776
  for (const property of objectExpr.properties) {
17952
- if (property.type !== AST_NODE_TYPES3.Property)
18777
+ if (property.type !== AST_NODE_TYPES4.Property)
17953
18778
  continue;
17954
18779
  if (property.computed)
17955
18780
  continue;
17956
- if (property.key.type !== AST_NODE_TYPES3.Identifier)
18781
+ if (property.key.type !== AST_NODE_TYPES4.Identifier)
17957
18782
  continue;
17958
18783
  if (property.key.name === "from")
17959
18784
  hasFrom = true;
@@ -17966,10 +18791,10 @@ function objectHasFromAndTo(objectExpr) {
17966
18791
  }
17967
18792
  function hasFromAndToProperties(context, expression) {
17968
18793
  const unwrapped = unwrapExpression(expression);
17969
- if (unwrapped.type === AST_NODE_TYPES3.ObjectExpression)
18794
+ if (unwrapped.type === AST_NODE_TYPES4.ObjectExpression)
17970
18795
  return objectHasFromAndTo(unwrapped);
17971
- if (unwrapped.type === AST_NODE_TYPES3.Identifier) {
17972
- const variable = findVariable(context, unwrapped);
18796
+ if (unwrapped.type === AST_NODE_TYPES4.Identifier) {
18797
+ const variable = findVariable2(context, unwrapped);
17973
18798
  if (variable === undefined)
17974
18799
  return false;
17975
18800
  if (!isModuleLevelScope(variable.scope))
@@ -17981,7 +18806,7 @@ function hasFromAndToProperties(context, expression) {
17981
18806
  if (initializer === undefined)
17982
18807
  continue;
17983
18808
  const normalizedInitializer = unwrapExpression(initializer);
17984
- if (normalizedInitializer.type !== AST_NODE_TYPES3.ObjectExpression)
18809
+ if (normalizedInitializer.type !== AST_NODE_TYPES4.ObjectExpression)
17985
18810
  continue;
17986
18811
  if (objectHasFromAndTo(normalizedInitializer))
17987
18812
  return true;
@@ -17991,10 +18816,10 @@ function hasFromAndToProperties(context, expression) {
17991
18816
  }
17992
18817
  function isStaticObjectLikeConfig(context, expression, seen, options3) {
17993
18818
  const unwrapped = unwrapExpression(expression);
17994
- if (unwrapped.type === AST_NODE_TYPES3.ObjectExpression)
18819
+ if (unwrapped.type === AST_NODE_TYPES4.ObjectExpression)
17995
18820
  return isStaticObjectExpression(context, unwrapped, seen, options3);
17996
- if (unwrapped.type === AST_NODE_TYPES3.Identifier) {
17997
- const variable = findVariable(context, unwrapped);
18821
+ if (unwrapped.type === AST_NODE_TYPES4.Identifier) {
18822
+ const variable = findVariable2(context, unwrapped);
17998
18823
  if (variable === undefined)
17999
18824
  return false;
18000
18825
  if (!isModuleLevelScope(variable.scope))
@@ -18006,7 +18831,7 @@ function isStaticObjectLikeConfig(context, expression, seen, options3) {
18006
18831
  if (initializer === undefined)
18007
18832
  continue;
18008
18833
  const normalizedInitializer = unwrapExpression(initializer);
18009
- if (normalizedInitializer.type !== AST_NODE_TYPES3.ObjectExpression)
18834
+ if (normalizedInitializer.type !== AST_NODE_TYPES4.ObjectExpression)
18010
18835
  continue;
18011
18836
  if (isStaticObjectExpression(context, normalizedInitializer, seen, options3))
18012
18837
  return true;
@@ -18018,7 +18843,7 @@ function isStaticArrayExpression(context, arrayExpr, seen, options3) {
18018
18843
  for (const element of arrayExpr.elements) {
18019
18844
  if (!element)
18020
18845
  continue;
18021
- if (element.type === AST_NODE_TYPES3.SpreadElement)
18846
+ if (element.type === AST_NODE_TYPES4.SpreadElement)
18022
18847
  return false;
18023
18848
  if (!isStaticExpression(context, element, seen, options3))
18024
18849
  return false;
@@ -18034,520 +18859,179 @@ function isStaticExpression(context, expression, seen, options3) {
18034
18859
  return true;
18035
18860
  seen.add(unwrapped);
18036
18861
  switch (unwrapped.type) {
18037
- case AST_NODE_TYPES3.Literal:
18862
+ case AST_NODE_TYPES4.Literal:
18038
18863
  return true;
18039
- case AST_NODE_TYPES3.TemplateLiteral:
18864
+ case AST_NODE_TYPES4.TemplateLiteral:
18040
18865
  return unwrapped.expressions.length === 0;
18041
- case AST_NODE_TYPES3.UnaryExpression:
18866
+ case AST_NODE_TYPES4.UnaryExpression:
18042
18867
  return STATIC_UNARY_OPERATORS.has(unwrapped.operator) && isStaticExpression(context, unwrapped.argument, seen, options3);
18043
- case AST_NODE_TYPES3.BinaryExpression:
18044
- case AST_NODE_TYPES3.LogicalExpression:
18045
- if (!isNonPrivateExpression(unwrapped.left) || !isNonPrivateExpression(unwrapped.right))
18868
+ case AST_NODE_TYPES4.BinaryExpression:
18869
+ case AST_NODE_TYPES4.LogicalExpression:
18870
+ if (!(isNonPrivateExpression(unwrapped.left) && isNonPrivateExpression(unwrapped.right)))
18046
18871
  return false;
18047
18872
  return isStaticExpression(context, unwrapped.left, seen, options3) && isStaticExpression(context, unwrapped.right, seen, options3);
18048
- case AST_NODE_TYPES3.ConditionalExpression:
18873
+ case AST_NODE_TYPES4.ConditionalExpression:
18049
18874
  return isStaticExpression(context, unwrapped.test, seen, options3) && isStaticExpression(context, unwrapped.consequent, seen, options3) && isStaticExpression(context, unwrapped.alternate, seen, options3);
18050
- case AST_NODE_TYPES3.ArrayExpression:
18875
+ case AST_NODE_TYPES4.ArrayExpression:
18051
18876
  return context !== undefined && isStaticArrayExpression(context, unwrapped, seen, options3);
18052
- case AST_NODE_TYPES3.ObjectExpression:
18877
+ case AST_NODE_TYPES4.ObjectExpression:
18053
18878
  return context !== undefined && isStaticObjectExpression(context, unwrapped, seen, options3);
18054
- case AST_NODE_TYPES3.Identifier:
18879
+ case AST_NODE_TYPES4.Identifier:
18055
18880
  return context !== undefined && isStaticIdentifier(context, unwrapped, seen, options3);
18056
- case AST_NODE_TYPES3.MemberExpression:
18881
+ case AST_NODE_TYPES4.MemberExpression:
18057
18882
  return isStaticExpression(context, unwrapped.object, seen, options3) && (!unwrapped.computed || isStaticMemberProperty(unwrapped.property, seen, options3));
18058
- case AST_NODE_TYPES3.ChainExpression:
18883
+ case AST_NODE_TYPES4.ChainExpression:
18059
18884
  return isStaticExpression(context, unwrapped.expression, seen, options3);
18060
- case AST_NODE_TYPES3.CallExpression:
18061
- return context !== undefined && isStaticCallCallee(context, unwrapped.callee, seen, options3) && unwrapped.arguments.every((arg) => arg.type !== AST_NODE_TYPES3.SpreadElement && isStaticExpression(context, arg, seen, options3));
18062
- case AST_NODE_TYPES3.NewExpression:
18063
- return context !== undefined && isStaticCallCallee(context, unwrapped.callee, seen, options3) && (unwrapped.arguments ?? []).every((arg) => arg.type !== AST_NODE_TYPES3.SpreadElement && isStaticExpression(context, arg, seen, options3));
18064
- case AST_NODE_TYPES3.SequenceExpression:
18885
+ case AST_NODE_TYPES4.CallExpression:
18886
+ return context !== undefined && isStaticCallCallee(context, unwrapped.callee, seen, options3) && unwrapped.arguments.every((arg) => arg.type !== AST_NODE_TYPES4.SpreadElement && isStaticExpression(context, arg, seen, options3));
18887
+ case AST_NODE_TYPES4.NewExpression:
18888
+ return context !== undefined && isStaticCallCallee(context, unwrapped.callee, seen, options3) && (unwrapped.arguments ?? []).every((arg) => arg.type !== AST_NODE_TYPES4.SpreadElement && isStaticExpression(context, arg, seen, options3));
18889
+ case AST_NODE_TYPES4.SequenceExpression:
18065
18890
  return unwrapped.expressions.length > 0 && unwrapped.expressions.every((expr) => isStaticExpression(context, expr, seen, options3));
18066
- case AST_NODE_TYPES3.AssignmentExpression:
18891
+ case AST_NODE_TYPES4.AssignmentExpression:
18067
18892
  return isStaticExpression(context, unwrapped.right, seen, options3);
18068
- default:
18069
- return false;
18070
- }
18071
- }
18072
- function classifyDependencies(context, argument, seen, options3) {
18073
- if (argument === undefined)
18074
- return 0 /* MissingOrOmitted */;
18075
- if (argument.type === AST_NODE_TYPES3.SpreadElement)
18076
- return 3 /* DynamicOrUnknown */;
18077
- const expr = unwrapExpression(argument);
18078
- if (expr.type !== AST_NODE_TYPES3.ArrayExpression)
18079
- return 3 /* DynamicOrUnknown */;
18080
- if (expr.elements.length === 0)
18081
- return 1 /* EmptyArray */;
18082
- if (isStaticArrayExpression(context, expr, seen, options3))
18083
- return 2 /* StaticArray */;
18084
- return 3 /* DynamicOrUnknown */;
18085
- }
18086
- function depsAreNonUpdating(kind, options3) {
18087
- if (kind === 0 /* MissingOrOmitted */ || kind === 2 /* StaticArray */)
18088
- return true;
18089
- if (kind === 1 /* EmptyArray */)
18090
- return options3.treatEmptyDepsAsViolation;
18091
- return false;
18092
- }
18093
- function isSpringHookCall(node, options3) {
18094
- const { callee } = node;
18095
- if (callee.type === AST_NODE_TYPES3.Identifier)
18096
- return options3.springHooks.has(callee.name);
18097
- if (callee.type === AST_NODE_TYPES3.MemberExpression && !callee.computed) {
18098
- const { property } = callee;
18099
- if (property.type === AST_NODE_TYPES3.Identifier)
18100
- return options3.springHooks.has(property.name);
18101
- }
18102
- return false;
18103
- }
18104
- var noUselessUseSpring = {
18105
- create(context) {
18106
- const rawOptions = context.options[0];
18107
- const normalized = {
18108
- ...DEFAULT_OPTION_VALUES,
18109
- ...rawOptions,
18110
- springHooks: new Set(rawOptions?.springHooks ?? DEFAULT_OPTION_VALUES.springHooks),
18111
- staticGlobalFactories: new Set(rawOptions?.staticGlobalFactories ?? DEFAULT_OPTION_VALUES.staticGlobalFactories)
18112
- };
18113
- return {
18114
- CallExpression(node) {
18115
- if (!isSpringHookCall(node, normalized))
18116
- return;
18117
- if (node.arguments.length === 0)
18118
- return;
18119
- const configArgument = node.arguments[0];
18120
- if (!configArgument)
18121
- return;
18122
- if (configArgument.type === AST_NODE_TYPES3.SpreadElement)
18123
- return;
18124
- const seen = new Set;
18125
- if (!isStaticObjectLikeConfig(context, configArgument, seen, normalized))
18126
- return;
18127
- if (hasFromAndToProperties(context, configArgument))
18128
- return;
18129
- const depsKind = classifyDependencies(context, node.arguments[1], seen, normalized);
18130
- if (!depsAreNonUpdating(depsKind, normalized))
18131
- return;
18132
- context.report({
18133
- messageId: "uselessSpring",
18134
- node
18135
- });
18136
- }
18137
- };
18138
- },
18139
- defaultOptions: [DEFAULT_OPTION_VALUES],
18140
- meta: {
18141
- docs: {
18142
- description: "Disallow useSpring hooks whose config and dependencies are entirely static"
18143
- },
18144
- messages: {
18145
- uselessSpring: "useSpring call has only static inputs and non-updating dependencies; replace it with a constant or remove the hook."
18146
- },
18147
- schema: [
18148
- {
18149
- additionalProperties: false,
18150
- properties: {
18151
- springHooks: {
18152
- description: "Hook identifiers that should be treated as spring hooks",
18153
- items: { type: "string" },
18154
- type: "array"
18155
- },
18156
- staticGlobalFactories: {
18157
- default: [...DEFAULT_STATIC_GLOBAL_FACTORIES],
18158
- description: "Global factory identifiers that are treated as static constructors",
18159
- items: { type: "string" },
18160
- type: "array"
18161
- },
18162
- treatEmptyDepsAsViolation: {
18163
- default: true,
18164
- description: "Treat static config with an empty dependency array as a violation",
18165
- type: "boolean"
18166
- }
18167
- },
18168
- type: "object"
18169
- }
18170
- ],
18171
- type: "suggestion"
18172
- }
18173
- };
18174
- var no_useless_use_spring_default = noUselessUseSpring;
18175
-
18176
- // src/rules/no-warn.ts
18177
- var noWarn = {
18178
- create(context) {
18179
- return {
18180
- 'CallExpression[callee.type="Identifier"][callee.name="warn"]'(node) {
18181
- context.report({
18182
- messageId: "useLog",
18183
- node
18184
- });
18185
- }
18186
- };
18187
- },
18188
- meta: {
18189
- docs: {
18190
- description: "Ban warn() function calls. Use Log instead.",
18191
- recommended: false
18192
- },
18193
- messages: {
18194
- useLog: "Use Log instead of warn()"
18195
- },
18196
- schema: [],
18197
- type: "problem"
18198
- }
18199
- };
18200
- var no_warn_default = noWarn;
18201
-
18202
- // src/rules/no-god-components.ts
18203
- import { TSESTree as TSESTree6 } from "@typescript-eslint/types";
18204
- var COMPONENT_NAME_PATTERN = /^[A-Z]/;
18205
- var FUNCTION_BOUNDARIES = new Set([
18206
- TSESTree6.AST_NODE_TYPES.FunctionDeclaration,
18207
- TSESTree6.AST_NODE_TYPES.FunctionExpression,
18208
- TSESTree6.AST_NODE_TYPES.ArrowFunctionExpression
18209
- ]);
18210
- var RUNTIME_TS_WRAPPERS = new Set([
18211
- "ParenthesizedExpression",
18212
- "TSAsExpression",
18213
- "TSSatisfiesExpression",
18214
- "TSTypeAssertion",
18215
- "TSNonNullExpression",
18216
- "TSInstantiationExpression",
18217
- "ChainExpression"
18218
- ]);
18219
- function isComponentName(name) {
18220
- return COMPONENT_NAME_PATTERN.test(name);
18221
- }
18222
- function isReactComponentHOC(callExpr) {
18223
- const { callee } = callExpr;
18224
- if (callee.type === TSESTree6.AST_NODE_TYPES.Identifier)
18225
- return callee.name === "forwardRef" || callee.name === "memo";
18226
- if (callee.type === TSESTree6.AST_NODE_TYPES.MemberExpression && callee.object.type === TSESTree6.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === TSESTree6.AST_NODE_TYPES.Identifier)
18227
- return callee.property.name === "forwardRef" || callee.property.name === "memo";
18228
- return false;
18229
- }
18230
- function getComponentNameFromFunction(node) {
18231
- if (node.type === TSESTree6.AST_NODE_TYPES.FunctionDeclaration && node.id && isComponentName(node.id.name))
18232
- return node.id.name;
18233
- if (node.type === TSESTree6.AST_NODE_TYPES.FunctionExpression || node.type === TSESTree6.AST_NODE_TYPES.ArrowFunctionExpression) {
18234
- const { parent } = node;
18235
- if (parent === null || parent === undefined)
18236
- return;
18237
- if (parent.type === TSESTree6.AST_NODE_TYPES.VariableDeclarator && parent.id.type === TSESTree6.AST_NODE_TYPES.Identifier && isComponentName(parent.id.name))
18238
- return parent.id.name;
18239
- if (parent.type === TSESTree6.AST_NODE_TYPES.Property && parent.key.type === TSESTree6.AST_NODE_TYPES.Identifier && isComponentName(parent.key.name))
18240
- return parent.key.name;
18241
- if (parent.type === TSESTree6.AST_NODE_TYPES.MethodDefinition && parent.key.type === TSESTree6.AST_NODE_TYPES.Identifier && isComponentName(parent.key.name))
18242
- return parent.key.name;
18243
- }
18244
- return;
18245
- }
18246
- function getComponentNameFromCallParent(callExpr) {
18247
- const { parent } = callExpr;
18248
- if (parent === null || parent === undefined)
18249
- return;
18250
- if (parent.type === TSESTree6.AST_NODE_TYPES.VariableDeclarator && parent.id.type === TSESTree6.AST_NODE_TYPES.Identifier && isComponentName(parent.id.name))
18251
- return parent.id.name;
18252
- if (parent.type === TSESTree6.AST_NODE_TYPES.AssignmentExpression && parent.left.type === TSESTree6.AST_NODE_TYPES.Identifier && isComponentName(parent.left.name))
18253
- return parent.left.name;
18254
- if (parent.type === TSESTree6.AST_NODE_TYPES.ExportDefaultDeclaration && callExpr.arguments.length > 0) {
18255
- const firstArg = callExpr.arguments[0];
18256
- if (firstArg && firstArg.type === TSESTree6.AST_NODE_TYPES.FunctionExpression && firstArg.id && isComponentName(firstArg.id.name))
18257
- return firstArg.id.name;
18258
- }
18259
- return;
18260
- }
18261
- function getHookName(callExpression) {
18262
- const { callee } = callExpression;
18263
- if (callee.type === TSESTree6.AST_NODE_TYPES.Identifier)
18264
- return callee.name;
18265
- if (callee.type === TSESTree6.AST_NODE_TYPES.MemberExpression && callee.property.type === TSESTree6.AST_NODE_TYPES.Identifier)
18266
- return callee.property.name;
18267
- return;
18268
- }
18269
- function countDestructuredProps(node) {
18270
- const firstParam = node.params[0];
18271
- if (!firstParam)
18272
- return;
18273
- let pattern4;
18274
- if (firstParam.type === TSESTree6.AST_NODE_TYPES.ObjectPattern)
18275
- pattern4 = firstParam;
18276
- if (firstParam.type === TSESTree6.AST_NODE_TYPES.AssignmentPattern && firstParam.left.type === TSESTree6.AST_NODE_TYPES.ObjectPattern)
18277
- pattern4 = firstParam.left;
18278
- if (!pattern4)
18279
- return;
18280
- let count = 0;
18281
- for (const prop of pattern4.properties) {
18282
- if (prop.type === TSESTree6.AST_NODE_TYPES.Property)
18283
- count += 1;
18284
- }
18285
- return count;
18286
- }
18287
- function isTypeOnlyNullLiteral(node) {
18288
- const parent = node.parent;
18289
- if (parent === null || parent === undefined)
18290
- return false;
18291
- if (typeof parent.type === "string" && parent.type.startsWith("TS") && !RUNTIME_TS_WRAPPERS.has(parent.type))
18292
- return true;
18293
- if (parent.type === TSESTree6.AST_NODE_TYPES.TSLiteralType)
18294
- return true;
18295
- return false;
18296
- }
18297
- function analyzeComponentBody(functionNode, sourceCode, stateHooks) {
18298
- let maxJsxDepth = 0;
18299
- let stateHookCount = 0;
18300
- const nullLiterals = new Array;
18301
- function visit(current, jsxDepth) {
18302
- if (FUNCTION_BOUNDARIES.has(current.type) && current !== functionNode)
18303
- return;
18304
- let nextDepth = jsxDepth;
18305
- if (current.type === TSESTree6.AST_NODE_TYPES.JSXElement || current.type === TSESTree6.AST_NODE_TYPES.JSXFragment) {
18306
- nextDepth = jsxDepth + 1;
18307
- if (nextDepth > maxJsxDepth)
18308
- maxJsxDepth = nextDepth;
18309
- }
18310
- if (current.type === TSESTree6.AST_NODE_TYPES.CallExpression) {
18311
- const hookName = getHookName(current);
18312
- if (typeof hookName === "string" && hookName.length > 0 && stateHooks.has(hookName))
18313
- stateHookCount += 1;
18314
- }
18315
- if (current.type === TSESTree6.AST_NODE_TYPES.Literal && current.value === null) {
18316
- const literalNode = current;
18317
- if (!isTypeOnlyNullLiteral(literalNode))
18318
- nullLiterals.push(literalNode);
18319
- }
18320
- function getVisitorKeysForNodeType(nodeType) {
18321
- const visitorKeysUnknown = sourceCode.visitorKeys;
18322
- if (visitorKeysUnknown === null || visitorKeysUnknown === undefined || typeof visitorKeysUnknown !== "object")
18323
- return [];
18324
- const visitorKeysRecord = visitorKeysUnknown;
18325
- const keysUnknown = visitorKeysRecord[nodeType];
18326
- if (!Array.isArray(keysUnknown))
18327
- return [];
18328
- const keys3 = new Array;
18329
- for (const key of keysUnknown)
18330
- if (typeof key === "string")
18331
- keys3.push(key);
18332
- return keys3;
18333
- }
18334
- const keys2 = getVisitorKeysForNodeType(current.type);
18335
- const currentRecord = current;
18336
- for (const key of keys2) {
18337
- const value = currentRecord[key];
18338
- if (Array.isArray(value)) {
18339
- for (const item of value) {
18340
- if (typeof item === "object" && item !== null && "type" in item) {
18341
- visit(item, nextDepth);
18342
- }
18343
- }
18344
- continue;
18345
- }
18346
- if (typeof value === "object" && value !== null && "type" in value) {
18347
- visit(value, nextDepth);
18348
- }
18349
- }
18893
+ default:
18894
+ return false;
18350
18895
  }
18351
- visit(functionNode.body, 0);
18352
- return { maxJsxDepth, nullLiterals, stateHookCount };
18353
18896
  }
18354
- function parseOptions(options3) {
18355
- const defaults = {
18356
- enforceTargetLines: true,
18357
- ignoreComponents: [],
18358
- maxDestructuredProps: 5,
18359
- maxLines: 200,
18360
- maxStateHooks: 5,
18361
- maxTsxNesting: 3,
18362
- stateHooks: ["useState", "useReducer", "useBinding"],
18363
- targetLines: 120
18364
- };
18365
- if (typeof options3 !== "object" || options3 === null)
18366
- return defaults;
18367
- const cast = options3;
18368
- return {
18369
- enforceTargetLines: typeof cast.enforceTargetLines === "boolean" ? cast.enforceTargetLines : defaults.enforceTargetLines,
18370
- ignoreComponents: Array.isArray(cast.ignoreComponents) ? cast.ignoreComponents : defaults.ignoreComponents,
18371
- maxDestructuredProps: typeof cast.maxDestructuredProps === "number" ? cast.maxDestructuredProps : defaults.maxDestructuredProps,
18372
- maxLines: typeof cast.maxLines === "number" ? cast.maxLines : defaults.maxLines,
18373
- maxStateHooks: typeof cast.maxStateHooks === "number" ? cast.maxStateHooks : defaults.maxStateHooks,
18374
- maxTsxNesting: typeof cast.maxTsxNesting === "number" ? cast.maxTsxNesting : defaults.maxTsxNesting,
18375
- stateHooks: Array.isArray(cast.stateHooks) ? cast.stateHooks : defaults.stateHooks,
18376
- targetLines: typeof cast.targetLines === "number" ? cast.targetLines : defaults.targetLines
18377
- };
18897
+ function classifyDependencies(context, argument, seen, options3) {
18898
+ if (argument === undefined)
18899
+ return 0 /* MissingOrOmitted */;
18900
+ if (argument.type === AST_NODE_TYPES4.SpreadElement)
18901
+ return 3 /* DynamicOrUnknown */;
18902
+ const expr = unwrapExpression(argument);
18903
+ if (expr.type !== AST_NODE_TYPES4.ArrayExpression)
18904
+ return 3 /* DynamicOrUnknown */;
18905
+ if (expr.elements.length === 0)
18906
+ return 1 /* EmptyArray */;
18907
+ if (isStaticArrayExpression(context, expr, seen, options3))
18908
+ return 2 /* StaticArray */;
18909
+ return 3 /* DynamicOrUnknown */;
18378
18910
  }
18379
- var noGodComponents = {
18911
+ function depsAreNonUpdating(kind, options3) {
18912
+ if (kind === 0 /* MissingOrOmitted */ || kind === 2 /* StaticArray */)
18913
+ return true;
18914
+ if (kind === 1 /* EmptyArray */)
18915
+ return options3.treatEmptyDepsAsViolation;
18916
+ return false;
18917
+ }
18918
+ function isSpringHookCall(node, options3) {
18919
+ const { callee } = node;
18920
+ if (callee.type === AST_NODE_TYPES4.Identifier)
18921
+ return options3.springHooks.has(callee.name);
18922
+ if (callee.type === AST_NODE_TYPES4.MemberExpression && !callee.computed) {
18923
+ const { property } = callee;
18924
+ if (property.type === AST_NODE_TYPES4.Identifier)
18925
+ return options3.springHooks.has(property.name);
18926
+ }
18927
+ return false;
18928
+ }
18929
+ var noUselessUseSpring = {
18380
18930
  create(context) {
18381
- const configuration = parseOptions(context.options[0]);
18382
- const ignoreSet = new Set(configuration.ignoreComponents);
18383
- const stateHooks = new Set(configuration.stateHooks);
18384
- const checked = new WeakSet;
18385
- const sourceCode = context.sourceCode;
18386
- function checkComponent(node, name) {
18387
- if (ignoreSet.has(name))
18388
- return;
18389
- if (checked.has(node))
18390
- return;
18391
- checked.add(node);
18392
- const location = node.loc;
18393
- if (location !== null && location !== undefined) {
18394
- const lines = location.end.line - location.start.line + 1;
18395
- if (lines > configuration.maxLines) {
18396
- context.report({
18397
- data: { lines, max: configuration.maxLines, name, target: configuration.targetLines },
18398
- messageId: "exceedsMaxLines",
18399
- node
18400
- });
18401
- } else if (configuration.enforceTargetLines && lines > configuration.targetLines) {
18402
- context.report({
18403
- data: { lines, max: configuration.maxLines, name, target: configuration.targetLines },
18404
- messageId: "exceedsTargetLines",
18405
- node
18406
- });
18407
- }
18408
- }
18409
- const propsCount = countDestructuredProps(node);
18410
- if (typeof propsCount === "number" && propsCount > configuration.maxDestructuredProps) {
18411
- context.report({
18412
- data: { count: propsCount, max: configuration.maxDestructuredProps, name },
18413
- messageId: "tooManyProps",
18414
- node
18415
- });
18416
- }
18417
- const analysis = analyzeComponentBody(node, sourceCode, stateHooks);
18418
- if (analysis.maxJsxDepth > configuration.maxTsxNesting) {
18419
- context.report({
18420
- data: { depth: analysis.maxJsxDepth, max: configuration.maxTsxNesting, name },
18421
- messageId: "tsxNestingTooDeep",
18422
- node
18423
- });
18424
- }
18425
- if (analysis.stateHookCount > configuration.maxStateHooks) {
18426
- context.report({
18427
- data: {
18428
- count: analysis.stateHookCount,
18429
- hooks: configuration.stateHooks.join(", "),
18430
- max: configuration.maxStateHooks,
18431
- name
18432
- },
18433
- messageId: "tooManyStateHooks",
18434
- node
18435
- });
18436
- }
18437
- for (const literal2 of analysis.nullLiterals) {
18438
- context.report({
18439
- messageId: "nullLiteral",
18440
- node: literal2
18441
- });
18442
- }
18443
- }
18444
- function maybeCheckFunction(node) {
18445
- const name = getComponentNameFromFunction(node);
18446
- if (typeof name !== "string" || name.length === 0)
18447
- return;
18448
- checkComponent(node, name);
18449
- }
18931
+ const [rawOptions] = context.options;
18932
+ const normalized = {
18933
+ ...DEFAULT_OPTION_VALUES,
18934
+ ...rawOptions,
18935
+ springHooks: new Set(rawOptions?.springHooks ?? DEFAULT_OPTION_VALUES.springHooks),
18936
+ staticGlobalFactories: new Set(rawOptions?.staticGlobalFactories ?? DEFAULT_OPTION_VALUES.staticGlobalFactories)
18937
+ };
18450
18938
  return {
18451
- FunctionDeclaration(node) {
18452
- maybeCheckFunction(node);
18453
- },
18454
- FunctionExpression(node) {
18455
- maybeCheckFunction(node);
18456
- },
18457
- ArrowFunctionExpression(node) {
18458
- maybeCheckFunction(node);
18459
- },
18460
18939
  CallExpression(node) {
18461
- const callExpr = node;
18462
- if (!isReactComponentHOC(callExpr))
18940
+ if (!isSpringHookCall(node, normalized))
18463
18941
  return;
18464
- const firstArg = callExpr.arguments[0];
18465
- if (!firstArg || firstArg.type !== TSESTree6.AST_NODE_TYPES.FunctionExpression && firstArg.type !== TSESTree6.AST_NODE_TYPES.ArrowFunctionExpression)
18942
+ if (node.arguments.length === 0)
18466
18943
  return;
18467
- const nameFromParent = getComponentNameFromCallParent(callExpr);
18468
- const nameFromArg = getComponentNameFromFunction(firstArg);
18469
- const name = nameFromParent ?? nameFromArg;
18470
- if (typeof name !== "string" || name.length === 0)
18944
+ const [configArgument] = node.arguments;
18945
+ if (!configArgument)
18471
18946
  return;
18472
- checkComponent(firstArg, name);
18947
+ if (configArgument.type === AST_NODE_TYPES4.SpreadElement)
18948
+ return;
18949
+ const seen = new Set;
18950
+ if (!isStaticObjectLikeConfig(context, configArgument, seen, normalized))
18951
+ return;
18952
+ if (hasFromAndToProperties(context, configArgument))
18953
+ return;
18954
+ const depsKind = classifyDependencies(context, node.arguments[1], seen, normalized);
18955
+ if (!depsAreNonUpdating(depsKind, normalized))
18956
+ return;
18957
+ context.report({
18958
+ messageId: "uselessSpring",
18959
+ node
18960
+ });
18473
18961
  }
18474
18962
  };
18475
18963
  },
18964
+ defaultOptions: [DEFAULT_OPTION_VALUES],
18476
18965
  meta: {
18477
18966
  docs: {
18478
- description: "Enforce React component size and complexity limits inspired by the 'Refactor God Component' checklist.",
18479
- recommended: false
18967
+ description: "Disallow useSpring hooks whose config and dependencies are entirely static"
18480
18968
  },
18481
18969
  messages: {
18482
- exceedsTargetLines: "Component '{{name}}' is {{lines}} lines; target is {{target}} (max {{max}}). Consider extracting hooks/components.",
18483
- exceedsMaxLines: "Component '{{name}}' is {{lines}} lines; max allowed is {{max}}. Split into smaller components/hooks.",
18484
- tsxNestingTooDeep: "Component '{{name}}' has TSX nesting depth {{depth}}; max allowed is {{max}}. Extract child components.",
18485
- tooManyStateHooks: "Component '{{name}}' has {{count}} state hooks ({{hooks}}); max allowed is {{max}}. Extract cohesive state into a custom hook.",
18486
- tooManyProps: "Component '{{name}}' destructures {{count}} props; max allowed is {{max}}. Group props or split the component.",
18487
- nullLiteral: "Avoid `null` in components; use `undefined` instead."
18970
+ uselessSpring: "useSpring call has only static inputs and non-updating dependencies; replace it with a constant or remove the hook."
18488
18971
  },
18489
18972
  schema: [
18490
18973
  {
18491
18974
  additionalProperties: false,
18492
18975
  properties: {
18493
- enforceTargetLines: {
18494
- default: true,
18495
- description: "Whether to report when exceeding targetLines (soft limit).",
18496
- type: "boolean"
18497
- },
18498
- ignoreComponents: {
18499
- description: "Component names to ignore.",
18976
+ springHooks: {
18977
+ description: "Hook identifiers that should be treated as spring hooks",
18500
18978
  items: { type: "string" },
18501
18979
  type: "array"
18502
18980
  },
18503
- maxDestructuredProps: {
18504
- default: 5,
18505
- description: "Maximum number of destructured props in a component parameter.",
18506
- type: "number"
18507
- },
18508
- maxLines: {
18509
- default: 200,
18510
- description: "Hard maximum lines for a component.",
18511
- type: "number"
18512
- },
18513
- maxStateHooks: {
18514
- default: 5,
18515
- description: "Maximum number of stateful hook calls in a component.",
18516
- type: "number"
18517
- },
18518
- maxTsxNesting: {
18519
- default: 3,
18520
- description: "Maximum JSX/TSX nesting depth in a component.",
18521
- type: "number"
18522
- },
18523
- stateHooks: {
18524
- default: ["useState", "useReducer", "useBinding"],
18525
- description: "Hook names to count toward state complexity.",
18981
+ staticGlobalFactories: {
18982
+ default: [...DEFAULT_STATIC_GLOBAL_FACTORIES],
18983
+ description: "Global factory identifiers that are treated as static constructors",
18526
18984
  items: { type: "string" },
18527
18985
  type: "array"
18528
18986
  },
18529
- targetLines: {
18530
- default: 120,
18531
- description: "Soft target lines for a component.",
18532
- type: "number"
18987
+ treatEmptyDepsAsViolation: {
18988
+ default: true,
18989
+ description: "Treat static config with an empty dependency array as a violation",
18990
+ type: "boolean"
18533
18991
  }
18534
18992
  },
18535
18993
  type: "object"
18536
18994
  }
18537
18995
  ],
18996
+ type: "suggestion"
18997
+ }
18998
+ };
18999
+ var no_useless_use_spring_default = noUselessUseSpring;
19000
+
19001
+ // src/rules/no-warn.ts
19002
+ var noWarn = {
19003
+ create(context) {
19004
+ return {
19005
+ 'CallExpression[callee.type="Identifier"][callee.name="warn"]'(node) {
19006
+ context.report({
19007
+ messageId: "useLog",
19008
+ node
19009
+ });
19010
+ }
19011
+ };
19012
+ },
19013
+ meta: {
19014
+ docs: {
19015
+ description: "Ban warn() function calls. Use Log instead.",
19016
+ recommended: false
19017
+ },
19018
+ messages: {
19019
+ useLog: "Use Log instead of warn()"
19020
+ },
19021
+ schema: [],
18538
19022
  type: "problem"
18539
19023
  }
18540
19024
  };
18541
- var no_god_components_default = noGodComponents;
19025
+ var no_warn_default = noWarn;
18542
19026
 
18543
19027
  // src/rules/prefer-sequence-overloads.ts
18544
- import { AST_NODE_TYPES as AST_NODE_TYPES4 } from "@typescript-eslint/types";
19028
+ import { AST_NODE_TYPES as AST_NODE_TYPES5 } from "@typescript-eslint/types";
18545
19029
  var sequenceDescriptors = [
18546
19030
  { keypointName: "ColorSequenceKeypoint", sequenceName: "ColorSequence" },
18547
19031
  { keypointName: "NumberSequenceKeypoint", sequenceName: "NumberSequence" }
18548
19032
  ];
18549
19033
  function isSequenceIdentifier(node) {
18550
- if (node.type !== AST_NODE_TYPES4.Identifier)
19034
+ if (node.type !== AST_NODE_TYPES5.Identifier)
18551
19035
  return false;
18552
19036
  for (const { sequenceName } of sequenceDescriptors)
18553
19037
  if (sequenceName === node.name)
@@ -18561,16 +19045,16 @@ function findDescriptor(sequenceName) {
18561
19045
  return;
18562
19046
  }
18563
19047
  var isNumericLiteral = Compile(build_default.Object({
18564
- type: build_default.Literal(AST_NODE_TYPES4.Literal),
19048
+ type: build_default.Literal(AST_NODE_TYPES5.Literal),
18565
19049
  value: build_default.Number()
18566
19050
  }));
18567
19051
  function isExpressionArgument(argument) {
18568
- return argument !== undefined && argument.type !== AST_NODE_TYPES4.SpreadElement;
19052
+ return argument !== undefined && argument.type !== AST_NODE_TYPES5.SpreadElement;
18569
19053
  }
18570
19054
  function extractKeypoint(element, descriptor) {
18571
- if (element === undefined || element.type !== AST_NODE_TYPES4.NewExpression)
19055
+ if (element === undefined || element.type !== AST_NODE_TYPES5.NewExpression)
18572
19056
  return;
18573
- if (element.callee.type !== AST_NODE_TYPES4.Identifier || element.callee.name !== descriptor.keypointName)
19057
+ if (element.callee.type !== AST_NODE_TYPES5.Identifier || element.callee.name !== descriptor.keypointName)
18574
19058
  return;
18575
19059
  if (element.arguments.length !== 2)
18576
19060
  return;
@@ -18600,7 +19084,7 @@ var preferSequenceOverloads = {
18600
19084
  if (descriptor === undefined || node.arguments.length !== 1)
18601
19085
  return;
18602
19086
  const [argument] = node.arguments;
18603
- if (argument === undefined || argument.type !== AST_NODE_TYPES4.ArrayExpression || argument.elements.length !== 2)
19087
+ if (argument === undefined || argument.type !== AST_NODE_TYPES5.ArrayExpression || argument.elements.length !== 2)
18604
19088
  return;
18605
19089
  const firstElement = argument.elements[0] ?? undefined;
18606
19090
  const secondElement = argument.elements[1] ?? undefined;
@@ -18683,7 +19167,7 @@ function reconstructText(node) {
18683
19167
  if (typeof operator !== "string" || !OPERATORS2.has(operator))
18684
19168
  return;
18685
19169
  const { left, right } = node;
18686
- if (!isRecord3(left) || !isRecord3(right))
19170
+ if (!(isRecord3(left) && isRecord3(right)))
18687
19171
  return;
18688
19172
  const leftText = reconstructText(left);
18689
19173
  const rightText = reconstructText(right);
@@ -18744,7 +19228,7 @@ function collectArguments(_context2, parameters3) {
18744
19228
  const texts = [undefined, undefined, undefined, undefined];
18745
19229
  for (let index2 = 0;index2 < 4; index2++) {
18746
19230
  const parameter2 = parameters3[index2];
18747
- if (!isRecord3(parameter2) || !hasTypeProperty(parameter2))
19231
+ if (!(isRecord3(parameter2) && hasTypeProperty(parameter2)))
18748
19232
  return;
18749
19233
  if (parameter2.type === TSESTree7.AST_NODE_TYPES.SpreadElement)
18750
19234
  return;
@@ -18842,12 +19326,14 @@ function parseOptions2(options3) {
18842
19326
  hooks: options3.hooks
18843
19327
  };
18844
19328
  }
18845
- function getHookName2(callExpression) {
19329
+ function getHookName3(callExpression) {
18846
19330
  const { callee } = callExpression;
18847
- if (callee.type === TSESTree8.AST_NODE_TYPES.Identifier && typeof callee.name === "string" && callee.name.length > 0)
19331
+ if (callee.type === TSESTree8.AST_NODE_TYPES.Identifier && typeof callee.name === "string" && callee.name.length > 0) {
18848
19332
  return callee.name;
18849
- if (callee.type === TSESTree8.AST_NODE_TYPES.MemberExpression && callee.property?.type === TSESTree8.AST_NODE_TYPES.Identifier && typeof callee.property.name === "string" && callee.property.name.length > 0)
19333
+ }
19334
+ if (callee.type === TSESTree8.AST_NODE_TYPES.MemberExpression && callee.property?.type === TSESTree8.AST_NODE_TYPES.Identifier && typeof callee.property.name === "string" && callee.property.name.length > 0) {
18850
19335
  return callee.property.name;
19336
+ }
18851
19337
  return;
18852
19338
  }
18853
19339
  function resolveIdentifierToFunction(identifier3, context) {
@@ -18877,7 +19363,7 @@ function resolveIdentifierToFunction(identifier3, context) {
18877
19363
  if (typeof definition !== "object" || definition === null)
18878
19364
  continue;
18879
19365
  const castDefinition = definition;
18880
- const node = castDefinition.node;
19366
+ const { node } = castDefinition;
18881
19367
  if (typeof node !== "object" || node === null)
18882
19368
  continue;
18883
19369
  const castNode = node;
@@ -18940,7 +19426,7 @@ function isCallbackHookResult(identifier3, context) {
18940
19426
  if (typeof definition !== "object" || definition === null)
18941
19427
  continue;
18942
19428
  const castDefinition = definition;
18943
- const node = castDefinition.node;
19429
+ const { node } = castDefinition;
18944
19430
  if (typeof node !== "object" || node === null)
18945
19431
  continue;
18946
19432
  const castNode = node;
@@ -18951,7 +19437,7 @@ function isCallbackHookResult(identifier3, context) {
18951
19437
  const init = castNode.init;
18952
19438
  if (init.type !== TSESTree8.AST_NODE_TYPES.CallExpression)
18953
19439
  continue;
18954
- const calleeHookName = getHookName2(init);
19440
+ const calleeHookName = getHookName3(init);
18955
19441
  if (calleeHookName === "useCallback" || calleeHookName === "useMemo")
18956
19442
  return true;
18957
19443
  }
@@ -18973,7 +19459,7 @@ var requireNamedEffectFunctions = {
18973
19459
  return {
18974
19460
  CallExpression(node) {
18975
19461
  const callExpression = node;
18976
- const hookName = getHookName2(callExpression);
19462
+ const hookName = getHookName3(callExpression);
18977
19463
  if (typeof hookName !== "string" || !effectHooks.has(hookName))
18978
19464
  return;
18979
19465
  const firstArgument = callExpression.arguments?.[0];
@@ -19139,7 +19625,7 @@ var requireNamedEffectFunctions = {
19139
19625
  var require_named_effect_functions_default = requireNamedEffectFunctions;
19140
19626
 
19141
19627
  // src/rules/require-paired-calls.ts
19142
- import { AST_NODE_TYPES as AST_NODE_TYPES5 } from "@typescript-eslint/types";
19628
+ import { AST_NODE_TYPES as AST_NODE_TYPES6 } from "@typescript-eslint/types";
19143
19629
  var isStringArray = Compile(build_default.Readonly(build_default.Array(build_default.String())));
19144
19630
  var isPairConfiguration = Compile(build_default.Readonly(build_default.Object({
19145
19631
  alternatives: build_default.Optional(isStringArray),
@@ -19157,20 +19643,20 @@ var isRuleOptions3 = Compile(build_default.Partial(build_default.Readonly(build_
19157
19643
  pairs: build_default.Readonly(build_default.Array(isPairConfiguration))
19158
19644
  }))));
19159
19645
  var LOOP_NODE_TYPES = new Set([
19160
- AST_NODE_TYPES5.DoWhileStatement,
19161
- AST_NODE_TYPES5.ForInStatement,
19162
- AST_NODE_TYPES5.ForOfStatement,
19163
- AST_NODE_TYPES5.ForStatement,
19164
- AST_NODE_TYPES5.WhileStatement
19646
+ AST_NODE_TYPES6.DoWhileStatement,
19647
+ AST_NODE_TYPES6.ForInStatement,
19648
+ AST_NODE_TYPES6.ForOfStatement,
19649
+ AST_NODE_TYPES6.ForStatement,
19650
+ AST_NODE_TYPES6.WhileStatement
19165
19651
  ]);
19166
19652
  var DEFAULT_ROBLOX_YIELDING_FUNCTIONS = ["task.wait", "wait", "*.WaitForChild", "*.*Async"];
19167
19653
  function getCallName(node) {
19168
19654
  const { callee } = node;
19169
- if (callee.type === AST_NODE_TYPES5.Identifier)
19655
+ if (callee.type === AST_NODE_TYPES6.Identifier)
19170
19656
  return callee.name;
19171
- if (callee.type === AST_NODE_TYPES5.MemberExpression) {
19172
- const object3 = callee.object.type === AST_NODE_TYPES5.Identifier ? callee.object.name : undefined;
19173
- const property = callee.property.type === AST_NODE_TYPES5.Identifier ? callee.property.name : undefined;
19657
+ if (callee.type === AST_NODE_TYPES6.MemberExpression) {
19658
+ const object3 = callee.object.type === AST_NODE_TYPES6.Identifier ? callee.object.name : undefined;
19659
+ const property = callee.property.type === AST_NODE_TYPES6.Identifier ? callee.property.name : undefined;
19174
19660
  if (object3 !== undefined && property !== undefined)
19175
19661
  return `${object3}.${property}`;
19176
19662
  }
@@ -19206,12 +19692,12 @@ function isLoopLikeStatement(node) {
19206
19692
  return LOOP_NODE_TYPES.has(node.type);
19207
19693
  }
19208
19694
  function isSwitchStatement(node) {
19209
- return node?.type === AST_NODE_TYPES5.SwitchStatement;
19695
+ return node?.type === AST_NODE_TYPES6.SwitchStatement;
19210
19696
  }
19211
19697
  function findLabeledStatementBody(label, startingNode) {
19212
19698
  let current = startingNode;
19213
19699
  while (current) {
19214
- if (current.type === AST_NODE_TYPES5.LabeledStatement && current.label.name === label.name)
19700
+ if (current.type === AST_NODE_TYPES6.LabeledStatement && current.label.name === label.name)
19215
19701
  return current.body;
19216
19702
  current = current.parent ?? undefined;
19217
19703
  }
@@ -19248,7 +19734,7 @@ function cloneEntry(value) {
19248
19734
  }
19249
19735
  var rule = {
19250
19736
  create(context) {
19251
- const rawOptions = context.options[0];
19737
+ const [rawOptions] = context.options;
19252
19738
  const baseOptions = isRuleOptions3.Check(rawOptions) ? rawOptions : {};
19253
19739
  const options3 = {
19254
19740
  allowConditionalClosers: baseOptions.allowConditionalClosers ?? false,
@@ -19414,7 +19900,7 @@ var rule = {
19414
19900
  const hasCompleteElse = ifNode.alternate !== undefined && ifNode.alternate !== null;
19415
19901
  for (const branchStack of branches) {
19416
19902
  for (const entry of branchStack) {
19417
- const wasInOriginal = originalStack.some((o) => o.index === entry.index);
19903
+ const wasInOriginal = originalStack.some(({ index: index2 }) => index2 === entry.index);
19418
19904
  if (!wasInOriginal) {
19419
19905
  const validClosers = getValidClosers(entry.config);
19420
19906
  const closer = validClosers.length === 1 ? validClosers[0] ?? "closer" : validClosers.join("' or '");
@@ -19463,8 +19949,8 @@ var rule = {
19463
19949
  }
19464
19950
  function onIfConsequentExit(node) {
19465
19951
  const consequentNode = node;
19466
- const parent = consequentNode.parent;
19467
- if (parent?.type === AST_NODE_TYPES5.IfStatement) {
19952
+ const { parent } = consequentNode;
19953
+ if (parent?.type === AST_NODE_TYPES6.IfStatement) {
19468
19954
  const branches = branchStacks.get(parent) ?? [];
19469
19955
  branches.push(cloneStack());
19470
19956
  branchStacks.set(parent, branches);
@@ -19478,8 +19964,8 @@ var rule = {
19478
19964
  }
19479
19965
  function onIfAlternateExit(node) {
19480
19966
  const alternateNode = node;
19481
- const parent = alternateNode.parent;
19482
- if (parent?.type === AST_NODE_TYPES5.IfStatement) {
19967
+ const { parent } = alternateNode;
19968
+ if (parent?.type === AST_NODE_TYPES6.IfStatement) {
19483
19969
  const branches = branchStacks.get(parent) ?? [];
19484
19970
  branches.push(cloneStack());
19485
19971
  branchStacks.set(parent, branches);
@@ -19528,7 +20014,7 @@ var rule = {
19528
20014
  function onTryBlockExit(node) {
19529
20015
  const blockNode = node;
19530
20016
  const { parent } = blockNode;
19531
- if (parent?.type === AST_NODE_TYPES5.TryStatement) {
20017
+ if (parent?.type === AST_NODE_TYPES6.TryStatement) {
19532
20018
  const branches = branchStacks.get(parent) ?? [];
19533
20019
  branches.push(cloneStack());
19534
20020
  branchStacks.set(parent, branches);
@@ -19547,7 +20033,7 @@ var rule = {
19547
20033
  function onCatchClauseExit(node) {
19548
20034
  const catchNode = node;
19549
20035
  const { parent } = catchNode;
19550
- if (parent?.type === AST_NODE_TYPES5.TryStatement) {
20036
+ if (parent?.type === AST_NODE_TYPES6.TryStatement) {
19551
20037
  const branches = branchStacks.get(parent) ?? [];
19552
20038
  branches.push(cloneStack());
19553
20039
  branchStacks.set(parent, branches);
@@ -19610,7 +20096,7 @@ var rule = {
19610
20096
  function onSwitchCaseExit(node) {
19611
20097
  const caseNode = node;
19612
20098
  const { parent } = caseNode;
19613
- if (parent?.type === AST_NODE_TYPES5.SwitchStatement) {
20099
+ if (parent?.type === AST_NODE_TYPES6.SwitchStatement) {
19614
20100
  const branches = branchStacks.get(parent) ?? [];
19615
20101
  branches.push(cloneStack());
19616
20102
  branchStacks.set(parent, branches);
@@ -19641,7 +20127,7 @@ var rule = {
19641
20127
  for (const { opener, config, node: node2 } of openerStack) {
19642
20128
  const validClosers = getValidClosers(config);
19643
20129
  const closer = validClosers.length === 1 ? validClosers[0] ?? "closer" : validClosers.join("' or '");
19644
- const statementType = statementNode.type === AST_NODE_TYPES5.ReturnStatement ? "return" : "throw";
20130
+ const statementType = statementNode.type === AST_NODE_TYPES6.ReturnStatement ? "return" : "throw";
19645
20131
  const lineNumber = statementNode.loc?.start.line ?? 0;
19646
20132
  context.report({
19647
20133
  data: {
@@ -19658,7 +20144,7 @@ var rule = {
19658
20144
  const statementNode = node;
19659
20145
  if (openerStack.length === 0)
19660
20146
  return;
19661
- const targetLoop = statementNode.type === AST_NODE_TYPES5.ContinueStatement ? resolveContinueTargetLoop(statementNode) : resolveBreakTargetLoop(statementNode);
20147
+ const targetLoop = statementNode.type === AST_NODE_TYPES6.ContinueStatement ? resolveContinueTargetLoop(statementNode) : resolveBreakTargetLoop(statementNode);
19662
20148
  if (!targetLoop)
19663
20149
  return;
19664
20150
  for (const { node: openerNode, config, opener, loopAncestors } of openerStack) {
@@ -19666,7 +20152,7 @@ var rule = {
19666
20152
  continue;
19667
20153
  const validClosers = getValidClosers(config);
19668
20154
  const closer = validClosers.length === 1 ? validClosers[0] ?? "closer" : validClosers.join("' or '");
19669
- const statementType = statementNode.type === AST_NODE_TYPES5.BreakStatement ? "break" : "continue";
20155
+ const statementType = statementNode.type === AST_NODE_TYPES6.BreakStatement ? "break" : "continue";
19670
20156
  const lineNumber = statementNode.loc?.start.line ?? 0;
19671
20157
  context.report({
19672
20158
  data: {
@@ -19804,7 +20290,7 @@ var rule = {
19804
20290
  continue;
19805
20291
  const validClosers = getValidClosers(config);
19806
20292
  const closer = validClosers.length === 1 ? validClosers[0] ?? "closer" : validClosers.join("' or '");
19807
- const asyncType = asyncNode.type === AST_NODE_TYPES5.AwaitExpression ? "await" : "yield";
20293
+ const asyncType = asyncNode.type === AST_NODE_TYPES6.AwaitExpression ? "await" : "yield";
19808
20294
  context.report({
19809
20295
  data: { asyncType, closer, opener },
19810
20296
  messageId: "asyncViolation",
@@ -20021,10 +20507,12 @@ function isIterationOrMemoCallback(callExpr, iterationMethods, memoizationHooks)
20021
20507
  const methodName = callee.property.name;
20022
20508
  if (iterationMethods.has(methodName))
20023
20509
  return true;
20024
- if (methodName === "from" && callee.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.type === TSESTree9.AST_NODE_TYPES.Identifier && callee.object.object.name === "Array" && callExpr.arguments.length >= 2)
20510
+ if (methodName === "from" && callee.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.type === TSESTree9.AST_NODE_TYPES.Identifier && callee.object.object.name === "Array" && callExpr.arguments.length >= 2) {
20025
20511
  return true;
20026
- if (methodName === "call" && callee.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.property.type === TSESTree9.AST_NODE_TYPES.Identifier && iterationMethods.has(callee.object.object.property.name))
20512
+ }
20513
+ if (methodName === "call" && callee.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.object.property.type === TSESTree9.AST_NODE_TYPES.Identifier && iterationMethods.has(callee.object.object.property.name)) {
20027
20514
  return true;
20515
+ }
20028
20516
  }
20029
20517
  return false;
20030
20518
  }
@@ -20036,14 +20524,15 @@ function findEnclosingCallExpression(node) {
20036
20524
  for (const argument of parent.arguments) {
20037
20525
  if (argument === current)
20038
20526
  return parent;
20039
- if (argument.type === TSESTree9.AST_NODE_TYPES.SpreadElement && argument.argument === current)
20527
+ if (argument.type === TSESTree9.AST_NODE_TYPES.SpreadElement && argument.argument === current) {
20040
20528
  return parent;
20529
+ }
20041
20530
  }
20042
20531
  return;
20043
20532
  }
20044
20533
  if (ARGUMENT_WRAPPER_TYPES.has(parent.type)) {
20045
20534
  current = parent;
20046
- parent = parent.parent;
20535
+ ({ parent } = parent);
20047
20536
  continue;
20048
20537
  }
20049
20538
  break;
@@ -20133,14 +20622,16 @@ function isTopLevelReturn(node) {
20133
20622
  return false;
20134
20623
  if (parent.type === TSESTree9.AST_NODE_TYPES.ReturnStatement) {
20135
20624
  let currentNode = ascendPastWrappers(parent.parent);
20136
- while (currentNode && CONTROL_FLOW_TYPES.has(currentNode.type))
20625
+ while (currentNode && CONTROL_FLOW_TYPES.has(currentNode.type)) {
20137
20626
  currentNode = ascendPastWrappers(currentNode.parent);
20627
+ }
20138
20628
  if (!currentNode)
20139
20629
  return false;
20140
20630
  if (IS_FUNCTION_EXPRESSION.has(currentNode.type)) {
20141
20631
  const functionParent = ascendPastWrappers(currentNode.parent);
20142
- if (functionParent?.type === TSESTree9.AST_NODE_TYPES.CallExpression)
20632
+ if (functionParent?.type === TSESTree9.AST_NODE_TYPES.CallExpression) {
20143
20633
  return isReactComponentHOC2(functionParent);
20634
+ }
20144
20635
  return true;
20145
20636
  }
20146
20637
  return currentNode.type === TSESTree9.AST_NODE_TYPES.FunctionDeclaration;
@@ -20158,7 +20649,7 @@ function isIgnoredCallExpression(node, ignoreList) {
20158
20649
  if (!parent)
20159
20650
  return false;
20160
20651
  if (parent.type === TSESTree9.AST_NODE_TYPES.JSXExpressionContainer) {
20161
- parent = parent.parent;
20652
+ ({ parent } = parent);
20162
20653
  if (!parent)
20163
20654
  return false;
20164
20655
  }
@@ -20169,11 +20660,12 @@ function isIgnoredCallExpression(node, ignoreList) {
20169
20660
  const { callee } = parent;
20170
20661
  if (callee.type === TSESTree9.AST_NODE_TYPES.Identifier)
20171
20662
  return ignoreList.includes(callee.name);
20172
- if (callee.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.type === TSESTree9.AST_NODE_TYPES.Identifier && callee.property.type === TSESTree9.AST_NODE_TYPES.Identifier)
20663
+ if (callee.type === TSESTree9.AST_NODE_TYPES.MemberExpression && callee.object.type === TSESTree9.AST_NODE_TYPES.Identifier && callee.property.type === TSESTree9.AST_NODE_TYPES.Identifier) {
20173
20664
  return ignoreList.includes(`${callee.object.name}.${callee.property.name}`);
20665
+ }
20174
20666
  return false;
20175
20667
  }
20176
- parent = parent.parent;
20668
+ ({ parent } = parent);
20177
20669
  }
20178
20670
  return false;
20179
20671
  }
@@ -20181,12 +20673,13 @@ function isJSXPropValue(node) {
20181
20673
  let { parent } = node;
20182
20674
  if (!parent)
20183
20675
  return false;
20184
- while (parent && (parent.type === TSESTree9.AST_NODE_TYPES.ConditionalExpression || parent.type === TSESTree9.AST_NODE_TYPES.LogicalExpression))
20185
- parent = parent.parent;
20676
+ while (parent && (parent.type === TSESTree9.AST_NODE_TYPES.ConditionalExpression || parent.type === TSESTree9.AST_NODE_TYPES.LogicalExpression)) {
20677
+ ({ parent } = parent);
20678
+ }
20186
20679
  if (!parent)
20187
20680
  return false;
20188
20681
  if (parent.type === TSESTree9.AST_NODE_TYPES.JSXExpressionContainer) {
20189
- parent = parent.parent;
20682
+ ({ parent } = parent);
20190
20683
  if (!parent)
20191
20684
  return false;
20192
20685
  }
@@ -20202,7 +20695,7 @@ function isTernaryJSXChild(node) {
20202
20695
  foundTernary = true;
20203
20696
  current = current.parent;
20204
20697
  }
20205
- if (!foundTernary || !current)
20698
+ if (!(foundTernary && current))
20206
20699
  return false;
20207
20700
  if (current.type !== TSESTree9.AST_NODE_TYPES.JSXExpressionContainer)
20208
20701
  return false;
@@ -20411,7 +20904,7 @@ var GLOBAL_BUILTINS = new Set([
20411
20904
  "Window",
20412
20905
  "Event"
20413
20906
  ]);
20414
- function getHookName3(node) {
20907
+ function getHookName4(node) {
20415
20908
  const { callee } = node;
20416
20909
  if (callee.type === TSESTree10.AST_NODE_TYPES.Identifier)
20417
20910
  return callee.name;
@@ -20474,7 +20967,7 @@ function isStableArrayIndex(stableResult, node, identifierName) {
20474
20967
  if (!(stableResult instanceof Set) || node.type !== TSESTree10.AST_NODE_TYPES.VariableDeclarator || node.id.type !== TSESTree10.AST_NODE_TYPES.ArrayPattern) {
20475
20968
  return false;
20476
20969
  }
20477
- const elements = node.id.elements;
20970
+ const { elements } = node.id;
20478
20971
  let index2 = 0;
20479
20972
  for (const element of elements) {
20480
20973
  if (element.type === TSESTree10.AST_NODE_TYPES.Identifier && element.name === identifierName) {
@@ -20488,7 +20981,7 @@ function isStableHookValue(init, node, identifierName, stableHooks) {
20488
20981
  const castInit = init;
20489
20982
  if (castInit.type !== TSESTree10.AST_NODE_TYPES.CallExpression)
20490
20983
  return false;
20491
- const hookName = getHookName3(castInit);
20984
+ const hookName = getHookName4(castInit);
20492
20985
  if (!hookName)
20493
20986
  return false;
20494
20987
  const stableResult = stableHooks.get(hookName);
@@ -20507,7 +21000,7 @@ function isStableValue(variable, identifierName, stableHooks) {
20507
21000
  if (STABLE_VALUE_TYPES.has(type3))
20508
21001
  return true;
20509
21002
  if (type3 === "Variable" && node.type === TSESTree10.AST_NODE_TYPES.VariableDeclarator) {
20510
- const parent = node.parent;
21003
+ const { parent } = node;
20511
21004
  if (!parent || parent.type !== TSESTree10.AST_NODE_TYPES.VariableDeclaration || parent.kind !== "const")
20512
21005
  continue;
20513
21006
  const init = node.init;
@@ -20554,10 +21047,10 @@ function findTopmostMemberExpression(node) {
20554
21047
  const isMemberParent = parent.type === TSESTree10.AST_NODE_TYPES.MemberExpression && parent.object === current;
20555
21048
  const isChainParent = parent.type === TSESTree10.AST_NODE_TYPES.ChainExpression;
20556
21049
  const isNonNullParent = parent.type === TSESTree10.AST_NODE_TYPES.TSNonNullExpression;
20557
- if (!isMemberParent && !isChainParent && !isNonNullParent)
21050
+ if (!(isMemberParent || isChainParent || isNonNullParent))
20558
21051
  break;
20559
21052
  current = parent;
20560
- parent = parent.parent;
21053
+ ({ parent } = parent);
20561
21054
  }
20562
21055
  return current;
20563
21056
  }
@@ -20575,21 +21068,21 @@ var TS_RUNTIME_EXPRESSIONS = new Set([
20575
21068
  TSESTree10.AST_NODE_TYPES.TSInstantiationExpression
20576
21069
  ]);
20577
21070
  function isComputedPropertyIdentifier(identifier3) {
20578
- const parent = identifier3.parent;
21071
+ const { parent } = identifier3;
20579
21072
  return parent?.type === TSESTree10.AST_NODE_TYPES.Property && parent.computed && parent.key === identifier3;
20580
21073
  }
20581
21074
  function isInTypePosition(identifier3) {
20582
21075
  let parent = identifier3.parent;
20583
21076
  while (parent) {
20584
21077
  if (TS_RUNTIME_EXPRESSIONS.has(parent.type)) {
20585
- parent = parent.parent;
21078
+ ({ parent } = parent);
20586
21079
  continue;
20587
21080
  }
20588
21081
  if (parent.type.startsWith("TS"))
20589
21082
  return true;
20590
21083
  if (IS_CEASE_BOUNDARY.has(parent.type))
20591
21084
  return false;
20592
- parent = parent.parent;
21085
+ ({ parent } = parent);
20593
21086
  }
20594
21087
  return false;
20595
21088
  }
@@ -20613,7 +21106,7 @@ function isDeclaredInComponentBody(variable, closureNode) {
20613
21106
  return node === functionParent;
20614
21107
  });
20615
21108
  }
20616
- parent = parent.parent;
21109
+ ({ parent } = parent);
20617
21110
  }
20618
21111
  return false;
20619
21112
  }
@@ -20789,7 +21282,7 @@ var useExhaustiveDependencies = {
20789
21282
  return {
20790
21283
  CallExpression(node) {
20791
21284
  const callNode = node;
20792
- const hookName = getHookName3(callNode);
21285
+ const hookName = getHookName4(callNode);
20793
21286
  if (hookName === undefined || hookName === "")
20794
21287
  return;
20795
21288
  const hookConfig = hookConfigs.get(hookName);
@@ -21213,7 +21706,7 @@ var useHookAtTopLevel = {
21213
21706
  const current = getCurrentContext();
21214
21707
  if (!current)
21215
21708
  return;
21216
- if (!current.isComponentOrHook && !current.inNestedFunction)
21709
+ if (!(current.isComponentOrHook || current.inNestedFunction))
21217
21710
  return;
21218
21711
  if (isInFinallyBlock(callNode))
21219
21712
  return;
@@ -21385,7 +21878,7 @@ var useHookAtTopLevel = {
21385
21878
  };
21386
21879
  var use_hook_at_top_level_default = useHookAtTopLevel;
21387
21880
 
21388
- // src/configure-utilities.ts
21881
+ // src/utilities/configure-utilities.ts
21389
21882
  function createPairConfiguration(opener, closer, options3 = {}) {
21390
21883
  return { closer, opener, ...options3 };
21391
21884
  }
@@ -21487,10 +21980,12 @@ var rules = {
21487
21980
  "ban-instances": ban_instances_default,
21488
21981
  "ban-react-fc": ban_react_fc_default,
21489
21982
  "enforce-ianitor-check-type": enforce_ianitor_check_type_default,
21983
+ "fast-format": fast_format_default,
21490
21984
  "no-async-constructor": no_async_constructor_default,
21491
21985
  "no-color3-constructor": no_color3_constructor_default,
21492
21986
  "no-commented-code": no_commented_code_default,
21493
21987
  "no-god-components": no_god_components_default,
21988
+ "no-identity-map": no_identity_map_default,
21494
21989
  "no-instance-methods-without-this": no_instance_methods_without_this_default,
21495
21990
  "no-print": no_print_default,
21496
21991
  "no-shorthand-names": no_shorthand_names_default,
@@ -21506,17 +22001,17 @@ var rules = {
21506
22001
  };
21507
22002
  var recommended = {
21508
22003
  plugins: {
21509
- "cease-nonsense": {
21510
- rules
21511
- }
22004
+ "cease-nonsense": { rules }
21512
22005
  },
21513
22006
  rules: {
21514
22007
  "cease-nonsense/ban-react-fc": "error",
21515
22008
  "cease-nonsense/enforce-ianitor-check-type": "error",
22009
+ "cease-nonsense/fast-format": "error",
21516
22010
  "cease-nonsense/no-async-constructor": "error",
21517
22011
  "cease-nonsense/no-color3-constructor": "error",
21518
- "cease-nonsense/no-instance-methods-without-this": "error",
21519
22012
  "cease-nonsense/no-god-components": "error",
22013
+ "cease-nonsense/no-identity-map": "error",
22014
+ "cease-nonsense/no-instance-methods-without-this": "error",
21520
22015
  "cease-nonsense/no-print": "error",
21521
22016
  "cease-nonsense/no-shorthand-names": "error",
21522
22017
  "cease-nonsense/no-warn": "error",
@@ -21551,4 +22046,4 @@ export {
21551
22046
  createBanInstancesOptions
21552
22047
  };
21553
22048
 
21554
- //# debugId=BE95AD3504B774A764756E2164756E21
22049
+ //# debugId=F65B81A39A5D507164756E2164756E21