@sarj/eslint-plugin 16.26.0 → 16.26.1

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 (3) hide show
  1. package/dist/index.cjs +144 -54
  2. package/dist/index.js +1877 -1787
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -883,7 +883,7 @@ function isSearchParamReceiver(call, services) {
883
883
  // package.json
884
884
  var package_default = {
885
885
  name: "@sarj/eslint-plugin",
886
- version: "16.26.0",
886
+ version: "16.26.1",
887
887
  packageManager: "npm@12.2.0",
888
888
  description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
889
889
  type: "module",
@@ -8845,6 +8845,14 @@ var import_utils53 = require("@typescript-eslint/utils");
8845
8845
 
8846
8846
  // src/rules/_stable-value-binding.ts
8847
8847
  var import_utils52 = require("@typescript-eslint/utils");
8848
+ function typeOnlyReference2(reference) {
8849
+ if (reference.isTypeReference && !reference.isValueReference) return true;
8850
+ let current = outerExpression(reference.identifier);
8851
+ while (current.parent?.type === import_utils52.AST_NODE_TYPES.TSQualifiedName && current.parent.left === current) {
8852
+ current = current.parent;
8853
+ }
8854
+ return current.parent?.type === import_utils52.AST_NODE_TYPES.TSTypeQuery && current.parent.exprName === current;
8855
+ }
8848
8856
  function stableValueBinding(variable, acceptRead) {
8849
8857
  let initializer;
8850
8858
  return variable.references.every((reference) => {
@@ -20789,6 +20797,7 @@ var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
20789
20797
  "Only direct imports, const bindings, and inline calls with statically proven provenance from crypto or node:crypto are analyzed; arbitrary assignments and dynamic module specifiers are excluded.",
20790
20798
  "Only a literal algorithm with exactly one update call is reported; streaming and incremental hashes remain valid.",
20791
20799
  "Namespace bindings must remain read-only: visible writes, aliases, exports, inherited mutation or alias methods, unknown computed members, and other escaping uses are excluded; type-only references and direct member calls remain eligible.",
20800
+ "CommonJS loads and default imports share one mutable native module object. A visible unsafe use of that object excludes its other loads; ESM named exports remain separate unless visible native export synchronization can update them.",
20792
20801
  "Runtime support and output encoding require manual review; no autofix or guaranteed speedup is promised."
20793
20802
  ],
20794
20803
  references: ["https://nodejs.org/api/crypto.html#cryptohashalgorithm-data-options"],
@@ -20803,39 +20812,57 @@ var UNSAFE_NAMESPACE_METHODS = /* @__PURE__ */ new Set(["__defineGetter__", "__d
20803
20812
  function stableNamespace(variable) {
20804
20813
  if (variable.defs.some((definition) => definition.type === "Variable" && definition.parent.parent.type === import_utils118.AST_NODE_TYPES.ExportNamedDeclaration)) return false;
20805
20814
  return stableValueBinding(variable, (reference) => {
20806
- if (reference.isTypeReference && !reference.isValueReference) return true;
20815
+ if (typeOnlyReference2(reference)) return true;
20816
+ const receiver = outerExpression(reference.identifier);
20817
+ return readonlyNamespaceUse(receiver);
20818
+ });
20819
+ }
20820
+ function readonlyNamespaceUse(receiver) {
20821
+ const member = receiver.parent;
20822
+ if (member?.type !== import_utils118.AST_NODE_TYPES.MemberExpression || member.object !== receiver) {
20823
+ return member?.type === import_utils118.AST_NODE_TYPES.UnaryExpression && member.operator === "typeof";
20824
+ }
20825
+ const use = outerExpression(member);
20826
+ const name = import_utils118.ASTUtils.getPropertyName(member);
20827
+ return name !== null && !UNSAFE_NAMESPACE_METHODS.has(name) && use.parent?.type === import_utils118.AST_NODE_TYPES.CallExpression && use.parent.callee === use;
20828
+ }
20829
+ function readonlyLoaderUse(node, resolve2, stable) {
20830
+ const receiver = outerExpression(node);
20831
+ const parent = receiver.parent;
20832
+ if (parent?.type === import_utils118.AST_NODE_TYPES.VariableDeclarator && parent.init === receiver) {
20833
+ if (parent.id.type === import_utils118.AST_NODE_TYPES.ObjectPattern) return true;
20834
+ if (parent.id.type !== import_utils118.AST_NODE_TYPES.Identifier) return false;
20835
+ const variable = resolve2(parent.id);
20836
+ return variable !== null && stable(variable);
20837
+ }
20838
+ return parent?.type === import_utils118.AST_NODE_TYPES.ExpressionStatement || readonlyNamespaceUse(receiver);
20839
+ }
20840
+ function namespaceDefaultMayEscape(variable) {
20841
+ return variable.references.some((reference) => {
20842
+ if (typeOnlyReference2(reference)) return false;
20807
20843
  const receiver = outerExpression(reference.identifier);
20808
- if (typeQueryReference(receiver)) return true;
20809
20844
  const member = receiver.parent;
20810
20845
  if (member?.type !== import_utils118.AST_NODE_TYPES.MemberExpression || member.object !== receiver) {
20811
- return member?.type === import_utils118.AST_NODE_TYPES.UnaryExpression && member.operator === "typeof";
20846
+ return member?.type !== import_utils118.AST_NODE_TYPES.UnaryExpression || member.operator !== "typeof";
20812
20847
  }
20813
- const use = outerExpression(member);
20814
20848
  const name = import_utils118.ASTUtils.getPropertyName(member);
20815
- return name !== null && !UNSAFE_NAMESPACE_METHODS.has(name) && use.parent?.type === import_utils118.AST_NODE_TYPES.CallExpression && use.parent.callee === use;
20849
+ return (name === null || name === "default") && !readonlyNamespaceUse(outerExpression(member));
20816
20850
  });
20817
20851
  }
20818
- function typeQueryReference(node) {
20819
- let current = node;
20820
- while (current.parent?.type === import_utils118.AST_NODE_TYPES.TSQualifiedName && current.parent.left === current) {
20821
- current = current.parent;
20822
- }
20823
- return current.parent?.type === import_utils118.AST_NODE_TYPES.TSTypeQuery && current.parent.exprName === current;
20824
- }
20825
- function isCryptoLoader(node, resolve2) {
20826
- const unwrappedNodeCallee = node.type === "CallExpression" || node.type === "NewExpression" ? unwrapExpression(node.callee) : null;
20852
+ function isBuiltinLoader(node, resolve2, builtin = "crypto") {
20827
20853
  if (node.type !== import_utils118.AST_NODE_TYPES.CallExpression || node.arguments.length !== 1) return false;
20828
20854
  const [argument] = node.arguments;
20829
- if (argument === void 0 || argument.type === import_utils118.AST_NODE_TYPES.SpreadElement || !isCryptoSpecifier(argument)) {
20855
+ if (argument === void 0 || argument.type === import_utils118.AST_NODE_TYPES.SpreadElement || !isBuiltinSpecifier(argument, builtin)) {
20830
20856
  return false;
20831
20857
  }
20858
+ const unwrappedNodeCallee = unwrapExpression(node.callee);
20832
20859
  if (unwrappedNodeCallee?.type === import_utils118.AST_NODE_TYPES.Identifier) {
20833
20860
  return unwrappedNodeCallee.name === "require" && isUnshadowedBuiltinIdentifier(unwrappedNodeCallee, resolve2);
20834
20861
  }
20835
20862
  return unwrappedNodeCallee?.type === import_utils118.AST_NODE_TYPES.MemberExpression && unwrappedNodeCallee.object.type === import_utils118.AST_NODE_TYPES.Identifier && unwrappedNodeCallee.object.name === "process" && isUnshadowedBuiltinIdentifier(unwrappedNodeCallee.object, resolve2) && import_utils118.ASTUtils.getPropertyName(unwrappedNodeCallee) === "getBuiltinModule";
20836
20863
  }
20837
- function isCryptoSpecifier(node) {
20838
- return node.type === import_utils118.AST_NODE_TYPES.Literal && (node.value === "crypto" || node.value === "node:crypto");
20864
+ function isBuiltinSpecifier(node, builtin) {
20865
+ return node.type === import_utils118.AST_NODE_TYPES.Literal && (node.value === builtin || node.value === `node:${builtin}`);
20839
20866
  }
20840
20867
  function isUnshadowedBuiltinIdentifier(identifier, resolve2) {
20841
20868
  const variable = resolve2(identifier);
@@ -20854,46 +20881,84 @@ var prefer_node_crypto_hash_default = createRule({
20854
20881
  meta: { type: "problem", docs: { description: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION.summary }, schema: [], messages: { preferNodeCryptoHash: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary." } },
20855
20882
  defaultOptions: [],
20856
20883
  create(context) {
20884
+ if (!context.sourceCode.text.includes("crypto") && !context.sourceCode.text.includes("\\")) return {};
20857
20885
  const directBindings = /* @__PURE__ */ new Set();
20858
20886
  const namespaceBindings = /* @__PURE__ */ new Set();
20887
+ const sharedBindings = /* @__PURE__ */ new Set();
20888
+ const syncBindings = /* @__PURE__ */ new Set();
20889
+ const moduleBindings = /* @__PURE__ */ new Set();
20890
+ const namespaceStability = /* @__PURE__ */ new WeakMap();
20891
+ const candidates = [];
20892
+ const possibleSynchronizations = [];
20893
+ let sharedNamespaceUnsafe = false;
20894
+ function namespaceStable(variable) {
20895
+ const cached = namespaceStability.get(variable);
20896
+ if (cached !== void 0) return cached;
20897
+ const stable = stableNamespace(variable);
20898
+ namespaceStability.set(variable, stable);
20899
+ return stable;
20900
+ }
20859
20901
  function resolve2(identifier) {
20860
20902
  return import_utils118.ASTUtils.findVariable(
20861
20903
  context.sourceCode.getScope(identifier),
20862
20904
  identifier.name
20863
20905
  );
20864
20906
  }
20865
- function record(identifier, destination) {
20907
+ function record(identifier, destination, shared = false) {
20866
20908
  const variable = resolve2(identifier);
20867
- if (variable !== null && (destination === namespaceBindings ? stableNamespace(variable) : stableValueBinding(variable))) destination.add(variable);
20909
+ if (variable === null) return;
20910
+ const stable = destination === namespaceBindings ? namespaceStable(variable) : stableValueBinding(variable);
20911
+ if (shared && destination === namespaceBindings && !stable) sharedNamespaceUnsafe = true;
20912
+ if (!stable) return;
20913
+ destination.add(variable);
20914
+ if (shared) sharedBindings.add(variable);
20915
+ }
20916
+ function recordModuleImports(specifiers) {
20917
+ for (const specifier of specifiers) {
20918
+ if (specifier.type === import_utils118.AST_NODE_TYPES.ImportSpecifier) {
20919
+ if (importedName5(specifier.imported) === "syncBuiltinESMExports") record(specifier.local, syncBindings);
20920
+ else if (importedName5(specifier.imported) === "default") record(specifier.local, moduleBindings);
20921
+ } else record(specifier.local, moduleBindings);
20922
+ }
20868
20923
  }
20869
20924
  return {
20870
20925
  ImportDeclaration(node) {
20926
+ if (node.source.value === "module" || node.source.value === "node:module") {
20927
+ recordModuleImports(node.specifiers);
20928
+ return;
20929
+ }
20871
20930
  if (node.source.value !== "crypto" && node.source.value !== "node:crypto") return;
20872
20931
  for (const specifier of node.specifiers) {
20873
- if (specifier.type === import_utils118.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils118.AST_NODE_TYPES.ImportDefaultSpecifier) {
20874
- record(specifier.local, namespaceBindings);
20932
+ const shared = specifier.type === import_utils118.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils118.AST_NODE_TYPES.ImportSpecifier && importedName5(specifier.imported) === "default";
20933
+ if (specifier.type === import_utils118.AST_NODE_TYPES.ImportNamespaceSpecifier || shared) {
20934
+ record(specifier.local, namespaceBindings, shared);
20935
+ const variable = resolve2(specifier.local);
20936
+ if (!shared && variable !== null && namespaceDefaultMayEscape(variable)) sharedNamespaceUnsafe = true;
20875
20937
  } else if (specifier.type === import_utils118.AST_NODE_TYPES.ImportSpecifier && importedName5(specifier.imported) === "createHash") {
20876
20938
  record(specifier.local, directBindings);
20877
20939
  }
20878
20940
  }
20879
20941
  },
20880
20942
  VariableDeclarator(node) {
20881
- if (node.parent.kind !== "const" || node.init === null || !isCryptoLoader(node.init, resolve2)) {
20943
+ if (node.parent.kind !== "const" || node.init === null || !isBuiltinLoader(node.init, resolve2) && !isBuiltinLoader(node.init, resolve2, "module")) {
20882
20944
  return;
20883
20945
  }
20946
+ const crypto = isBuiltinLoader(node.init, resolve2);
20884
20947
  if (node.id.type === import_utils118.AST_NODE_TYPES.Identifier) {
20885
- record(node.id, namespaceBindings);
20948
+ record(node.id, crypto ? namespaceBindings : moduleBindings, crypto);
20886
20949
  return;
20887
20950
  }
20888
20951
  if (node.id.type !== import_utils118.AST_NODE_TYPES.ObjectPattern) return;
20889
20952
  for (const property of node.id.properties) {
20890
- if (property.type === import_utils118.AST_NODE_TYPES.Property && propertyName3(property) === "createHash" && property.value.type === import_utils118.AST_NODE_TYPES.Identifier) {
20891
- record(property.value, directBindings);
20953
+ if (property.type === import_utils118.AST_NODE_TYPES.Property && propertyName3(property) === (crypto ? "createHash" : "syncBuiltinESMExports") && property.value.type === import_utils118.AST_NODE_TYPES.Identifier) {
20954
+ record(property.value, crypto ? directBindings : syncBindings, crypto);
20892
20955
  }
20893
20956
  }
20894
20957
  },
20895
20958
  CallExpression(node) {
20959
+ if (isBuiltinLoader(node, resolve2) && !readonlyLoaderUse(node, resolve2, namespaceStable)) sharedNamespaceUnsafe = true;
20896
20960
  const unwrappedNodeCallee = unwrapExpression(node.callee);
20961
+ if (unwrappedNodeCallee.type === import_utils118.AST_NODE_TYPES.Identifier || unwrappedNodeCallee.type === import_utils118.AST_NODE_TYPES.MemberExpression && import_utils118.ASTUtils.getPropertyName(unwrappedNodeCallee) === "syncBuiltinESMExports") possibleSynchronizations.push(node);
20897
20962
  if (unwrappedNodeCallee.type !== import_utils118.AST_NODE_TYPES.MemberExpression || !isMemberCall(node, "digest")) return;
20898
20963
  const update = unwrapExpression(unwrappedNodeCallee.object);
20899
20964
  if (update.type !== import_utils118.AST_NODE_TYPES.CallExpression || update.arguments.length !== 1 || !isMemberCall(update, "update"))
@@ -20902,14 +20967,16 @@ var prefer_node_crypto_hash_default = createRule({
20902
20967
  if (updateCallee.type !== import_utils118.AST_NODE_TYPES.MemberExpression) return;
20903
20968
  const create = unwrapExpression(updateCallee.object);
20904
20969
  const algorithm = create.type === import_utils118.AST_NODE_TYPES.CallExpression && create.arguments[0] !== void 0 ? unwrapExpression(create.arguments[0]) : null;
20905
- if (create.type !== import_utils118.AST_NODE_TYPES.CallExpression || create.arguments.length !== 1 || staticString(algorithm ?? void 0) === null || !isCreateHashCall(
20906
- create,
20907
- directBindings,
20908
- namespaceBindings,
20909
- resolve2
20910
- ))
20970
+ if (create.type !== import_utils118.AST_NODE_TYPES.CallExpression || create.arguments.length !== 1 || staticString(algorithm ?? void 0) === null)
20911
20971
  return;
20912
- context.report({ node, messageId: "preferNodeCryptoHash" });
20972
+ const provider = builtinCallProvider(create, directBindings, namespaceBindings, sharedBindings, resolve2);
20973
+ if (provider !== null) candidates.push({ node, shared: provider === "shared" });
20974
+ },
20975
+ "Program:exit"() {
20976
+ const exportsMaySynchronize = sharedNamespaceUnsafe && possibleSynchronizations.some((node) => builtinCallProvider(node, syncBindings, moduleBindings, sharedBindings, resolve2, "module") !== null);
20977
+ for (const candidate2 of candidates) {
20978
+ if (!sharedNamespaceUnsafe || !candidate2.shared && !exportsMaySynchronize) context.report({ node: candidate2.node, messageId: "preferNodeCryptoHash" });
20979
+ }
20913
20980
  }
20914
20981
  };
20915
20982
  }
@@ -20921,19 +20988,21 @@ function isMemberCall(node, name) {
20921
20988
  const unwrappedNodeCallee = unwrapExpression(node.callee);
20922
20989
  return unwrappedNodeCallee.type === import_utils118.AST_NODE_TYPES.MemberExpression && import_utils118.ASTUtils.getPropertyName(unwrappedNodeCallee) === name;
20923
20990
  }
20924
- function isCreateHashCall(node, directBindings, namespaceBindings, resolve2) {
20991
+ function builtinCallProvider(node, directBindings, namespaceBindings, sharedBindings, resolve2, builtin = "crypto") {
20925
20992
  const unwrappedNodeCallee = unwrapExpression(node.callee);
20926
20993
  if (unwrappedNodeCallee.type === import_utils118.AST_NODE_TYPES.Identifier) {
20927
20994
  const variable2 = resolve2(unwrappedNodeCallee);
20928
- return variable2 !== null && directBindings.has(variable2);
20995
+ if (variable2 === null || !directBindings.has(variable2)) return null;
20996
+ return sharedBindings.has(variable2) ? "shared" : "snapshot";
20929
20997
  }
20930
- if (unwrappedNodeCallee.type !== import_utils118.AST_NODE_TYPES.MemberExpression || import_utils118.ASTUtils.getPropertyName(unwrappedNodeCallee) !== "createHash") {
20931
- return false;
20998
+ if (unwrappedNodeCallee.type !== import_utils118.AST_NODE_TYPES.MemberExpression || import_utils118.ASTUtils.getPropertyName(unwrappedNodeCallee) !== (builtin === "crypto" ? "createHash" : "syncBuiltinESMExports")) {
20999
+ return null;
20932
21000
  }
20933
- if (isCryptoLoader(unwrappedNodeCallee.object, resolve2)) return true;
20934
- if (unwrappedNodeCallee.object.type !== import_utils118.AST_NODE_TYPES.Identifier) return false;
21001
+ if (isBuiltinLoader(unwrappedNodeCallee.object, resolve2, builtin)) return "shared";
21002
+ if (unwrappedNodeCallee.object.type !== import_utils118.AST_NODE_TYPES.Identifier) return null;
20935
21003
  const variable = resolve2(unwrappedNodeCallee.object);
20936
- return variable !== null && namespaceBindings.has(variable);
21004
+ if (variable === null || !namespaceBindings.has(variable)) return null;
21005
+ return sharedBindings.has(variable) ? "shared" : "snapshot";
20937
21006
  }
20938
21007
 
20939
21008
  // src/rules/prefer-node-fs-promises.ts
@@ -26103,6 +26172,7 @@ var require_static_next_matcher_default = createRule({
26103
26172
 
26104
26173
  // src/rules/require-use-form-default-values.ts
26105
26174
  var import_utils139 = require("@typescript-eslint/utils");
26175
+ var UNSAFE_FORM_MEMBERS = /* @__PURE__ */ new Set(["__defineGetter__", "__defineSetter__", "__proto__", "valueOf"]);
26106
26176
  var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
26107
26177
  summary: "Require explicit form-level initialization or a field default for directly bound Controller fields.",
26108
26178
  rationale: "React Hook Form exposes form-level defaultValues/values and field-level defaultValue as its explicit initialization mechanisms. A directly bound controlled field should not omit both mechanisms.",
@@ -26110,7 +26180,8 @@ var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
26110
26180
  category: "correctness",
26111
26181
  limitations: [
26112
26182
  "The rule proves only that an explicit form-level initialization option or field default is present; it does not prove that a particular field path occurs inside a defaultValues/values object.",
26113
- "The rule reports only scope-resolved Controller/useController fields explicitly bound to a directly created useForm control. FormProvider context, wrapper hooks, dynamic options, spreads, computed properties, and interprocedural flows are intentionally left unreported."
26183
+ "The rule reports only scope-resolved Controller/useController fields explicitly bound to a directly created useForm control. FormProvider context, wrapper hooks, dynamic options, spreads, computed properties, and interprocedural flows are intentionally left unreported.",
26184
+ "Form bindings must have one initializer and remain local and read-only; aliases, exports, property writes, and other escaping uses are left unreported."
26114
26185
  ],
26115
26186
  examples: [
26116
26187
  {
@@ -26139,6 +26210,29 @@ function staticPropertyName2(property) {
26139
26210
  if (property.key.type === import_utils139.AST_NODE_TYPES.Literal && typeof property.key.value === "string") return property.key.value;
26140
26211
  return null;
26141
26212
  }
26213
+ function readonlyFormReference(reference) {
26214
+ if (typeOnlyReference2(reference)) return true;
26215
+ const receiver = outerExpression(reference.identifier);
26216
+ const parent = receiver.parent;
26217
+ if (parent?.type === import_utils139.AST_NODE_TYPES.VariableDeclarator && parent.init === receiver) return parent.id.type === import_utils139.AST_NODE_TYPES.ObjectPattern;
26218
+ if (parent?.type !== import_utils139.AST_NODE_TYPES.MemberExpression || parent.object !== receiver) {
26219
+ return parent?.type === import_utils139.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof";
26220
+ }
26221
+ const name = import_utils139.ASTUtils.getPropertyName(parent);
26222
+ return name !== null && !UNSAFE_FORM_MEMBERS.has(name) && !memberWrite(parent);
26223
+ }
26224
+ function memberWrite(node) {
26225
+ let current = outerExpression(node);
26226
+ let parent = current.parent;
26227
+ while (parent?.type === import_utils139.AST_NODE_TYPES.Property && parent.value === current || parent?.type === import_utils139.AST_NODE_TYPES.ObjectPattern || parent?.type === import_utils139.AST_NODE_TYPES.ArrayPattern || parent?.type === import_utils139.AST_NODE_TYPES.RestElement || parent?.type === import_utils139.AST_NODE_TYPES.AssignmentPattern && parent.left === current) {
26228
+ current = parent;
26229
+ parent = current.parent;
26230
+ }
26231
+ return parent?.type === import_utils139.AST_NODE_TYPES.AssignmentExpression && parent.left === current || parent?.type === import_utils139.AST_NODE_TYPES.UpdateExpression && parent.argument === current || parent?.type === import_utils139.AST_NODE_TYPES.UnaryExpression && parent.operator === "delete" || (parent?.type === import_utils139.AST_NODE_TYPES.ForOfStatement || parent?.type === import_utils139.AST_NODE_TYPES.ForInStatement) && parent.left === current;
26232
+ }
26233
+ function stableForm(variable) {
26234
+ return !variable.defs.some((definition) => definition.type === "Variable" && definition.parent.parent.type === import_utils139.AST_NODE_TYPES.ExportNamedDeclaration) && stableValueBinding(variable, readonlyFormReference);
26235
+ }
26142
26236
  var require_use_form_default_values_default = createRule({
26143
26237
  name: "require-use-form-default-values",
26144
26238
  documentation: REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION,
@@ -26150,19 +26244,15 @@ var require_use_form_default_values_default = createRule({
26150
26244
  },
26151
26245
  defaultOptions: [],
26152
26246
  create(context) {
26247
+ if (!context.sourceCode.ast.body.some((statement) => statement.type === import_utils139.AST_NODE_TYPES.ImportDeclaration && statement.source.value === "react-hook-form")) return {};
26153
26248
  const imported = /* @__PURE__ */ new Map();
26154
26249
  const uninitializedForms = /* @__PURE__ */ new Set();
26155
26250
  const uninitializedControls = /* @__PURE__ */ new Set();
26156
26251
  const bindingNamed = (node, name) => import_utils139.ASTUtils.findVariable(context.sourceCode.getScope(node), name);
26157
26252
  const bindingOf = (node) => bindingNamed(node, node.name);
26158
- const stable = (variable) => !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
26159
26253
  const importedKind = (node) => {
26160
- const variable = bindingOf(node);
26161
- return variable !== null && stable(variable) ? imported.get(variable) ?? null : null;
26162
- };
26163
- const importedJsxKind = (node) => {
26164
26254
  const variable = bindingNamed(node, node.name);
26165
- return variable !== null && stable(variable) ? imported.get(variable) ?? null : null;
26255
+ return variable === null ? null : imported.get(variable) ?? null;
26166
26256
  };
26167
26257
  const isDefinitelyUndefined = (node) => {
26168
26258
  const value = unwrapExpression(node);
@@ -26191,13 +26281,13 @@ var require_use_form_default_values_default = createRule({
26191
26281
  node = unwrapExpression(node);
26192
26282
  if (node.type !== import_utils139.AST_NODE_TYPES.Identifier) return false;
26193
26283
  const variable = bindingOf(node);
26194
- return variable !== null && stable(variable) && uninitializedForms.has(variable);
26284
+ return variable !== null && uninitializedForms.has(variable);
26195
26285
  };
26196
26286
  const isUninitializedControl = (node) => {
26197
26287
  node = unwrapExpression(node);
26198
26288
  if (node.type === import_utils139.AST_NODE_TYPES.Identifier) {
26199
26289
  const variable = bindingOf(node);
26200
- return variable !== null && stable(variable) && uninitializedControls.has(variable);
26290
+ return variable !== null && uninitializedControls.has(variable);
26201
26291
  }
26202
26292
  return node.type === import_utils139.AST_NODE_TYPES.MemberExpression && import_utils139.ASTUtils.getPropertyName(node) !== null && (import_utils139.ASTUtils.getPropertyName(node) ?? "") === "control" && isUninitializedForm(node.object);
26203
26293
  };
@@ -26226,7 +26316,7 @@ var require_use_form_default_values_default = createRule({
26226
26316
  for (const property of pattern.properties) {
26227
26317
  if (property.type !== import_utils139.AST_NODE_TYPES.Property || staticPropertyName2(property) !== "control" || property.value.type !== import_utils139.AST_NODE_TYPES.Identifier) continue;
26228
26318
  const variable = bindingOf(property.value);
26229
- if (variable !== null) uninitializedControls.add(variable);
26319
+ if (variable !== null && stableValueBinding(variable)) uninitializedControls.add(variable);
26230
26320
  }
26231
26321
  };
26232
26322
  return {
@@ -26237,7 +26327,7 @@ var require_use_form_default_values_default = createRule({
26237
26327
  const name = specifier.imported.type === import_utils139.AST_NODE_TYPES.Identifier ? specifier.imported.name : String(specifier.imported.value);
26238
26328
  if (name !== "Controller" && name !== "useController" && name !== "useForm") continue;
26239
26329
  const variable = bindingOf(specifier.local);
26240
- if (variable !== null) imported.set(variable, name);
26330
+ if (variable !== null && stableValueBinding(variable)) imported.set(variable, name);
26241
26331
  }
26242
26332
  },
26243
26333
  VariableDeclarator(node) {
@@ -26245,7 +26335,7 @@ var require_use_form_default_values_default = createRule({
26245
26335
  if (uninitializedUseFormCall(node.init)) {
26246
26336
  if (node.id.type === import_utils139.AST_NODE_TYPES.Identifier) {
26247
26337
  const variable = bindingOf(node.id);
26248
- if (variable !== null) uninitializedForms.add(variable);
26338
+ if (variable !== null && stableForm(variable)) uninitializedForms.add(variable);
26249
26339
  } else if (node.id.type === import_utils139.AST_NODE_TYPES.ObjectPattern) {
26250
26340
  trackDestructuredControl(node.id);
26251
26341
  }
@@ -26257,7 +26347,7 @@ var require_use_form_default_values_default = createRule({
26257
26347
  }
26258
26348
  if (node.id.type === import_utils139.AST_NODE_TYPES.Identifier && node.init.type === import_utils139.AST_NODE_TYPES.MemberExpression && import_utils139.ASTUtils.getPropertyName(node.init) !== null && (import_utils139.ASTUtils.getPropertyName(node.init) ?? "") === "control" && isUninitializedForm(node.init.object)) {
26259
26349
  const variable = bindingOf(node.id);
26260
- if (variable !== null) uninitializedControls.add(variable);
26350
+ if (variable !== null && stableValueBinding(variable)) uninitializedControls.add(variable);
26261
26351
  }
26262
26352
  },
26263
26353
  CallExpression(node) {
@@ -26266,7 +26356,7 @@ var require_use_form_default_values_default = createRule({
26266
26356
  context.report({ node, messageId: "requireUseFormDefaultValues" });
26267
26357
  },
26268
26358
  JSXOpeningElement(node) {
26269
- if (node.name.type !== import_utils139.AST_NODE_TYPES.JSXIdentifier || importedJsxKind(node.name) !== "Controller") return;
26359
+ if (node.name.type !== import_utils139.AST_NODE_TYPES.JSXIdentifier || importedKind(node.name) !== "Controller") return;
26270
26360
  if (node.attributes.some((attribute) => attribute.type === import_utils139.AST_NODE_TYPES.JSXSpreadAttribute)) return;
26271
26361
  const control = jsxAttribute(node, "control");
26272
26362
  if (control?.value?.type !== import_utils139.AST_NODE_TYPES.JSXExpressionContainer || control.value.expression.type === import_utils139.AST_NODE_TYPES.JSXEmptyExpression || !isUninitializedControl(control.value.expression)) return;