@sarj/eslint-plugin 18.2.0 → 18.3.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.
package/dist/index.cjs CHANGED
@@ -49,9 +49,6 @@ __export(src_exports, {
49
49
  });
50
50
  module.exports = __toCommonJS(src_exports);
51
51
 
52
- // src/rules/prefer-zod-enum-validator.ts
53
- var import_utils5 = require("@typescript-eslint/utils");
54
-
55
52
  // src/rules/_eslint-rule.ts
56
53
  var import_utils2 = require("@typescript-eslint/utils");
57
54
 
@@ -538,21 +535,21 @@ function validateExpectedSuggestion(value, exampleId, messageIds) {
538
535
  assertFields(value, ["messageId", "output"], exampleId);
539
536
  }
540
537
  function validateExpectedLocation(value, exampleId) {
541
- if (!isObject(value) || !("line" in value) || !positiveCoordinate(value.line) || !("column" in value) || !positiveCoordinate(value.column)) {
538
+ if (!isObject(value) || !("line" in value) || typeof value.line !== "number" || !positiveCoordinate(value.line) || !("column" in value) || typeof value.column !== "number" || !positiveCoordinate(value.column)) {
542
539
  throw new TypeError(`${exampleId}: expected diagnostic location requires positive integer coordinates`);
543
540
  }
544
541
  if (!("end" in value)) {
545
542
  assertFields(value, ["line", "column"], exampleId);
546
543
  return;
547
544
  }
548
- if (!isObject(value.end) || !("line" in value.end) || !positiveCoordinate(value.end.line) || !("column" in value.end) || !positiveCoordinate(value.end.column) || value.end.line < value.line || value.end.line === value.line && value.end.column < value.column) {
545
+ if (!isObject(value.end) || !("line" in value.end) || typeof value.end.line !== "number" || !positiveCoordinate(value.end.line) || !("column" in value.end) || typeof value.end.column !== "number" || !positiveCoordinate(value.end.column) || value.end.line < value.line || value.end.line === value.line && value.end.column < value.column) {
549
546
  throw new TypeError(`${exampleId}: expected diagnostic end point must be complete and ordered`);
550
547
  }
551
548
  assertFields(value.end, ["line", "column"], exampleId);
552
549
  assertFields(value, ["line", "column", "end"], exampleId);
553
550
  }
554
551
  function positiveCoordinate(value) {
555
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
552
+ return Number.isSafeInteger(value) && value >= 1;
556
553
  }
557
554
  function assertFields(value, expected, exampleId) {
558
555
  const fields2 = Object.keys(value);
@@ -704,6 +701,56 @@ function commentLineEnd(sourceText, start) {
704
701
  return end === -1 ? sourceText.length : start + end;
705
702
  }
706
703
 
704
+ // src/rules/no-explicit-type-predicate.ts
705
+ var NO_EXPLICIT_TYPE_PREDICATE_DOCUMENTATION = {
706
+ defaultLevel: "warning",
707
+ summary: "Use compiler-checked narrowing instead of handwritten type predicates.",
708
+ rationale: "TypeScript trusts an explicit value is Type annotation without proving that its implementation recognizes that type in both branches. A stale or partial predicate can make callers read properties that do not exist. Direct discriminator checks and inferred predicates keep narrowing tied to the implementation.",
709
+ remediation: "For owned variants, check the discriminated union's tag directly or let TypeScript infer a simple discriminator helper or null filter. Parse unknown external data with a specific schema and consume its validated value or discriminated result. Do not replace a predicate with a cast or a schema boolean wrapper that repeats the same unchecked type claim. If a native API cannot express the required static contract, isolate that boundary and use an exact-rule local suppression explaining the constraint.",
710
+ category: "maintainability",
711
+ autofix: "none",
712
+ requiresTypeInformation: false,
713
+ limitations: [
714
+ "This is an explicit design policy, including otherwise correct handwritten predicates. Reports every authored TypeScript is predicate, including asserts value is Type, method and callback annotations, function types, overloads, ambient signatures and predicates inside casts or satisfies expressions.",
715
+ "Direct discriminator checks, compiler-inferred predicates, ordinary boolean returns and plain asserts condition remain valid. A tag on unknown input does not validate its payload. Imported library guard calls and imported predicate types are not redeclarations and are not inspected.",
716
+ "Shared generated, vendored and declaration-file exclusions apply. Maintained test implementations remain checked; strings, comments and JSDoc text are not TypeScript predicate nodes. There is no exemption based on helper names, imports or body shape.",
717
+ "No automatic fix or suggestion removes an annotation: public and callback contracts, overloads, both narrowing branches, emitted declarations and existing TypeScript versions may depend on it. Review callers and preserve intentional runtime behavior when migrating. Existing partial and contradictory predicate rules retain their separate correctness checks."
718
+ ],
719
+ references: [
720
+ "https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions",
721
+ "https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates",
722
+ "https://zod.dev/basics"
723
+ ],
724
+ examples: [
725
+ { id: "manual-predicate", title: "Avoid an unchecked narrowing annotation", outcome: "match", files: [{ path: "src/job.ts", source: "type Job = { kind: 'queued'; queue: string } | { kind: 'done'; result: string }; type Done = Extract<Job, {kind: 'done'}>; function isDone(job: Job): job is Done { return job.kind === 'done'; } function render(job: Job) { return isDone(job) ? job.result : job.queue; }" }], focusPath: "src/job.ts", expectedCount: 1, public: true },
726
+ { id: "direct-discriminator", title: "Let the compiler narrow the tagged union", outcome: "no-match", files: [{ path: "src/job.ts", source: "type Job = { kind: 'queued'; queue: string } | { kind: 'done'; result: string }; function render(job: Job) { return job.kind === 'done' ? job.result : job.queue; }" }], focusPath: "src/job.ts", expectedCount: 0, public: true },
727
+ { id: "inferred-predicate", scenarioId: "inference", title: "Infer a discriminator helper from its body", outcome: "no-match", files: [{ path: "src/job.ts", source: "type Job = { kind: 'queued'; queue: string } | { kind: 'done'; result: string }; const isDone = (job: Job) => job.kind === 'done';" }], focusPath: "src/job.ts", expectedCount: 0, public: true },
728
+ { id: "written-predicate", scenarioId: "inference", title: "A written predicate remains an unchecked promise", outcome: "match", files: [{ path: "src/job.ts", source: "type Job = { kind: 'queued'; queue: string } | { kind: 'done'; result: string }; type Done = Extract<Job, {kind: 'done'}>; const isDone = (job: Job): job is Done => job.kind === 'done';" }], focusPath: "src/job.ts", expectedCount: 1, public: true }
729
+ ]
730
+ };
731
+ var no_explicit_type_predicate_default = createRule({
732
+ name: "no-explicit-type-predicate",
733
+ documentation: NO_EXPLICIT_TYPE_PREDICATE_DOCUMENTATION,
734
+ meta: {
735
+ type: "suggestion",
736
+ docs: { description: NO_EXPLICIT_TYPE_PREDICATE_DOCUMENTATION.summary },
737
+ schema: [],
738
+ messages: { noExplicitTypePredicate: "Replace this handwritten type predicate with a direct discriminator check or compiler-inferred narrowing. Parse unknown data with a schema and consume the validated result; preserve required external callable contracts." }
739
+ },
740
+ defaultOptions: [],
741
+ create(context) {
742
+ if (isGeneratedFile(context, context.sourceCode.text)) return {};
743
+ return {
744
+ TSTypePredicate(node) {
745
+ if (node.typeAnnotation != null) context.report({ node, messageId: "noExplicitTypePredicate" });
746
+ }
747
+ };
748
+ }
749
+ });
750
+
751
+ // src/rules/prefer-zod-enum-validator.ts
752
+ var import_utils5 = require("@typescript-eslint/utils");
753
+
707
754
  // src/rules/_static-string.ts
708
755
  var import_utils4 = require("@typescript-eslint/utils");
709
756
 
@@ -1824,19 +1871,19 @@ function firstParameterBindings(source, node) {
1824
1871
  function collectParameterBindings(source, node) {
1825
1872
  if (hasDirectEval(source)) return /* @__PURE__ */ new Set();
1826
1873
  const parameter = node.params[0];
1827
- const identifiers = [];
1874
+ const identifiers = /* @__PURE__ */ new Set();
1828
1875
  if (parameter?.type === import_utils14.AST_NODE_TYPES.Identifier)
1829
- identifiers.push(parameter);
1876
+ identifiers.add(parameter);
1830
1877
  if (parameter?.type === import_utils14.AST_NODE_TYPES.ObjectPattern) {
1831
1878
  for (const property of parameter.properties) {
1832
1879
  if (property.type === import_utils14.AST_NODE_TYPES.Property && !property.computed && property.value.type === import_utils14.AST_NODE_TYPES.Identifier)
1833
- identifiers.push(property.value);
1880
+ identifiers.add(property.value);
1834
1881
  }
1835
1882
  }
1836
1883
  return new Set(
1837
1884
  source.getDeclaredVariables(node).filter(
1838
- (variable) => identifiers.some(
1839
- (identifier) => variable.identifiers.includes(identifier)
1885
+ (variable) => variable.identifiers.some(
1886
+ (identifier) => identifiers.has(identifier)
1840
1887
  ) && stableValueBinding(variable)
1841
1888
  )
1842
1889
  );
@@ -1879,8 +1926,10 @@ function reactHook(source, callee, hook) {
1879
1926
  let identifier;
1880
1927
  let namespace = false;
1881
1928
  if (callee.type === import_utils14.AST_NODE_TYPES.Identifier) identifier = callee;
1882
- else if (callee.type === import_utils14.AST_NODE_TYPES.MemberExpression && !callee.optional && import_utils14.ASTUtils.getPropertyName(callee) === hook && callee.object.type === import_utils14.AST_NODE_TYPES.Identifier) {
1883
- identifier = callee.object;
1929
+ else if (callee.type === import_utils14.AST_NODE_TYPES.MemberExpression && !callee.optional && import_utils14.ASTUtils.getPropertyName(callee) === hook) {
1930
+ const object = unwrapExpression(callee.object);
1931
+ if (object.type !== import_utils14.AST_NODE_TYPES.Identifier) return false;
1932
+ identifier = object;
1884
1933
  namespace = true;
1885
1934
  } else return false;
1886
1935
  const variable = import_utils14.ASTUtils.findVariable(
@@ -1888,17 +1937,33 @@ function reactHook(source, callee, hook) {
1888
1937
  identifier.name
1889
1938
  );
1890
1939
  if (variable === null) return false;
1891
- const specifier = reactImportSpecifier(variable);
1892
- if (specifier === null) return false;
1893
- return namespace ? specifier.type === import_utils14.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils14.AST_NODE_TYPES.ImportNamespaceSpecifier : specifier.type === import_utils14.AST_NODE_TYPES.ImportSpecifier && specifier.importKind !== "type" && importSpecifierName(specifier) === hook;
1894
- }
1895
- function reactImportSpecifier(variable) {
1896
- let specifier = REACT_IMPORTS.get(variable);
1897
- if (specifier !== void 0) return specifier;
1940
+ const imported = reactImport(variable);
1941
+ if (imported === null) return false;
1942
+ const { specifier, replacedMembers } = imported;
1943
+ return namespace ? (specifier.type === import_utils14.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils14.AST_NODE_TYPES.ImportNamespaceSpecifier) && replacedMembers?.has(null) !== true && replacedMembers?.has(hook) !== true : specifier.type === import_utils14.AST_NODE_TYPES.ImportSpecifier && specifier.importKind !== "type" && importSpecifierName(specifier) === hook;
1944
+ }
1945
+ function reactImport(variable) {
1946
+ let imported = REACT_IMPORTS.get(variable);
1947
+ if (imported !== void 0) return imported;
1898
1948
  const definition = variable.defs[0];
1899
- specifier = variable.defs.length === 1 && definition?.type === "ImportBinding" && definition.parent.type === import_utils14.AST_NODE_TYPES.ImportDeclaration && definition.parent.source.value === "react" && definition.parent.importKind !== "type" && stableValueBinding(variable) ? definition.node : null;
1900
- REACT_IMPORTS.set(variable, specifier);
1901
- return specifier;
1949
+ imported = null;
1950
+ if (variable.defs.length === 1 && definition?.type === "ImportBinding" && definition.parent.type === import_utils14.AST_NODE_TYPES.ImportDeclaration && definition.parent.source.value === "react" && definition.parent.importKind !== "type") {
1951
+ const specifier = definition.node;
1952
+ const replacedMembers = specifier.type === import_utils14.AST_NODE_TYPES.ImportSpecifier ? void 0 : /* @__PURE__ */ new Set();
1953
+ if (stableValueBinding(variable, replacedMembers === void 0 ? void 0 : (reference) => {
1954
+ const object = outerExpression(reference.identifier);
1955
+ const member3 = object.parent;
1956
+ if (member3?.type !== import_utils14.AST_NODE_TYPES.MemberExpression || member3.object !== object)
1957
+ return true;
1958
+ const target = outerExpression(member3);
1959
+ if (target.parent?.type === import_utils14.AST_NODE_TYPES.MemberExpression && target.parent.object === target)
1960
+ return true;
1961
+ if (writtenMember(member3)) replacedMembers.add(import_utils14.ASTUtils.getPropertyName(member3));
1962
+ return true;
1963
+ })) imported = { specifier, replacedMembers };
1964
+ }
1965
+ REACT_IMPORTS.set(variable, imported);
1966
+ return imported;
1902
1967
  }
1903
1968
  function containsView(node) {
1904
1969
  if (node.type === import_utils14.AST_NODE_TYPES.JSXElement || node.type === import_utils14.AST_NODE_TYPES.JSXFragment)
@@ -1953,6 +2018,7 @@ var PREFER_SERVER_DATA_PREPARATION_DOCUMENTATION = {
1953
2018
  "Advisory only. Local syntax cannot establish whether a caller is a Server Component, whether props change interactively or whether server preparation reduces the total cost. This rule is a review lead, never proof that code can be moved to the server. No automatic fix is provided.",
1954
2019
  "Requires an explicit use client directive and parser-owned TypeScript services resolving map/filter/flatMap to the standard Array or ReadonlyArray library signature. The receiver beneath erased wrappers must itself have an Array, ReadonlyArray or tuple type after nullish narrowing; casts from opaque or custom collections do not establish this. Subclass and structural collection types outside those native array types are excluded. The containing view must have an independent React useState/useReducer call or a native callable type on an intrinsic DOM onClick/onChange/onInput/onSubmit handler. Nullish, noncallable and opaque handler types do not establish interaction. Noninteractive boundaries remain owned by no-unnecessary-use-client; custom hooks and indirect client requirements are unsupported.",
1955
2020
  "Every runtime reference to the source parameter binding must be a supported native data projection or a field-only JSX display loop. Inputs also needed for editing, whole-record forwarding, lookup, mutation, other fields or opaque helpers are excluded. Files containing direct eval are excluded because it can observe or change lexical bindings; indirect eval and properties named eval do not establish lexical access. Only direct first-parameter paths and synchronous single-expression callbacks are supported. Whole-row identity maps and constant maps are excluded; supported projections must read a fixed input field.",
2021
+ "Field-only object and dense array literals can form nested data shapes, including readonly tuples and flatMap outputs. Array holes, spreads, captured values and JSX outputs remain unsupported. Hook recognition follows erased namespace wrappers and excludes direct writes to the requested imported member; reflective or external API patches are not modeled.",
1956
2022
  "JSX-rendering callbacks are never reported as preparation findings. Callback calls, captured values, destructuring defaults/rest/nesting, async callbacks, event handlers, effects, memo callbacks, opaque helpers, dynamic/optional paths, custom collection signatures, missing type services, generated source and tests are excluded. First-parameter provenance is syntactic; annotations cannot prove absence of runtime getters or patched array methods. Analysis does not claim callback purity or preserve semantics of a hypothetical move.",
1957
2023
  "Reports the direct source projection once; chained operations with a call receiver are not independently reported. A static subprojection may still be prepared by its producer while a union with pending local edits remains in the client."
1958
2024
  ],
@@ -2107,6 +2173,10 @@ function projection(source, callback, mode = "data") {
2107
2173
  return inspect(node.left, depth + 1) && inspect(node.right, depth + 1);
2108
2174
  if (node.type === import_utils15.AST_NODE_TYPES.ConditionalExpression)
2109
2175
  return inspect(node.test, depth + 1) && inspect(node.consequent, depth + 1) && inspect(node.alternate, depth + 1);
2176
+ if (node.type === import_utils15.AST_NODE_TYPES.ArrayExpression)
2177
+ return node.elements.every(
2178
+ (element) => element !== null && element.type !== import_utils15.AST_NODE_TYPES.SpreadElement && inspect(element, depth + 1)
2179
+ );
2110
2180
  if (node.type === import_utils15.AST_NODE_TYPES.ObjectExpression)
2111
2181
  return node.properties.every(
2112
2182
  (property) => property.type === import_utils15.AST_NODE_TYPES.Property && property.kind === "init" && !property.method && !property.computed && inspect(property.value, depth + 1)
@@ -2191,8 +2261,9 @@ var NO_READONLY_PROP_STATE_DOCUMENTATION = {
2191
2261
  category: "correctness",
2192
2262
  limitations: [
2193
2263
  "Advisory only: initial snapshots can be intentional. There is no automatic fix because replacing state with current props changes how later updates behave.",
2194
- "Recognizes direct React useState imports and default/namespace member calls, including renamed imports, through lexical binding identity. Checks a direct array destructure in a function containing its own JSX and a direct first-parameter property path, or a zero-argument synchronous lazy initializer returning that path.",
2264
+ "Recognizes direct React useState imports and default/namespace member calls, including renamed imports and erased wrappers around imported namespaces, through lexical binding identity. Checks a direct array destructure in a function containing its own JSX and a direct first-parameter property path, or a zero-argument synchronous lazy initializer returning that path.",
2195
2265
  "Eager initializers require parser-owned TypeScript services and primitive types, including unions composed entirely of primitives. Object and void types can hide callable values through structural assignment or ignored return values, so eager nonprimitive values, Any, unknown and unresolved generics are excluded. React executes function arguments as lazy initializers. Explicit zero-argument lazy callbacks returning a prop directly remain supported for all value types without type services. Opaque casts cannot prove runtime identity; lifecycle changes stay manual.",
2266
+ "Direct writes to the requested imported namespace member exclude its hook calls. Unknown computed writes exclude all namespace hooks; unrelated member writes and a hook function's own properties do not replace the callable. Reflective mutation and external API patches are not modeled.",
2196
2267
  "An updater read, escape, reassignment or nontrivial destructuring excludes the finding. Unused state values remain owned by unused-variable checks. Files containing direct eval are excluded because it can observe or change lexical bindings. Indirect eval and properties named eval do not establish lexical access. Opaque initialization, property aliases, optional/dynamic paths, rest/default bindings, non-JSX hooks, generated source and tests are outside scope. This does not ban interactive useState or replace the upstream set-state-in-effect rule."
2197
2268
  ],
2198
2269
  references: [
@@ -2481,18 +2552,8 @@ var FRONTEND_IMPORT = /^(?:react(?:-dom)?|next|preact|vue|svelte|@angular\/core|
2481
2552
  function isFrontendSource(context) {
2482
2553
  return /\.[jt]sx$/u.test(context.filename) || frontendModule(context.sourceCode.ast) || frontendPackage(context.filename);
2483
2554
  }
2484
- var FRONTEND_PACKAGE_BY_DIRECTORY = /* @__PURE__ */ new Map();
2485
2555
  function frontendPackage(filename) {
2486
- const directory = (0, import_node_path2.dirname)((0, import_node_path2.resolve)(filename));
2487
- let cached = FRONTEND_PACKAGE_BY_DIRECTORY.get(directory);
2488
- if (cached === void 0) {
2489
- cached = nearestManifestDeclaresFrontend(directory);
2490
- FRONTEND_PACKAGE_BY_DIRECTORY.set(directory, cached);
2491
- }
2492
- return cached;
2493
- }
2494
- function nearestManifestDeclaresFrontend(start) {
2495
- let directory = start;
2556
+ let directory = (0, import_node_path2.dirname)((0, import_node_path2.resolve)(filename));
2496
2557
  for (; ; ) {
2497
2558
  const manifestPath = (0, import_node_path2.join)(directory, "package.json");
2498
2559
  if ((0, import_node_fs.existsSync)(manifestPath)) {
@@ -2838,6 +2899,23 @@ function ownsTestComments(context) {
2838
2899
  const framework = context.sourceCode.ast.body.some((statement) => statement.type === import_utils22.AST_NODE_TYPES.ImportDeclaration && statement.importKind !== "type" && (statement.specifiers.length === 0 || statement.specifiers.some((specifier) => specifier.type !== import_utils22.AST_NODE_TYPES.ImportSpecifier || specifier.importKind !== "type")) && ["vitest", "@jest/globals", "@playwright/test", "bun:test", "node:test"].includes(statement.source.value));
2839
2900
  return unambiguous || framework;
2840
2901
  }
2902
+ function legalNoticeComments(comments) {
2903
+ const legal = /* @__PURE__ */ new Set();
2904
+ for (const [index, comment] of comments.entries()) {
2905
+ if (legal.has(comment) || comment.type !== "Line" || !LEGAL.test(comment.value)) continue;
2906
+ legal.add(comment);
2907
+ for (const direction of [-1, 1]) {
2908
+ let previous = comment;
2909
+ for (let next = index + direction; next >= 0 && next < comments.length; next += direction) {
2910
+ const neighbor = comments[next];
2911
+ if (neighbor?.type !== "Line" || Math.abs(neighbor.loc.start.line - previous.loc.start.line) !== 1) break;
2912
+ legal.add(neighbor);
2913
+ previous = neighbor;
2914
+ }
2915
+ }
2916
+ }
2917
+ return legal;
2918
+ }
2841
2919
  var no_test_comments_default = createRule({
2842
2920
  name: "no-test-comments",
2843
2921
  documentation: NO_TEST_COMMENTS_DOCUMENTATION,
@@ -2856,23 +2934,10 @@ var no_test_comments_default = createRule({
2856
2934
  return {
2857
2935
  Program() {
2858
2936
  const comments = context.sourceCode.getAllComments();
2859
- const legalLines = /* @__PURE__ */ new Set();
2860
- for (const [index, comment] of comments.entries()) {
2861
- if (comment.type !== "Line" || !LEGAL.test(comment.value)) continue;
2862
- legalLines.add(index);
2863
- for (const direction of [-1, 1]) {
2864
- let previous = comment;
2865
- for (let next = index + direction; next >= 0 && next < comments.length; next += direction) {
2866
- const neighbor = comments[next];
2867
- if (neighbor?.type !== "Line" || Math.abs(neighbor.loc.start.line - previous.loc.start.line) !== 1) break;
2868
- legalLines.add(next);
2869
- previous = neighbor;
2870
- }
2871
- }
2872
- }
2873
- for (const [index, comment] of comments.entries()) {
2937
+ const legal = frontend ? void 0 : legalNoticeComments(comments);
2938
+ for (const comment of comments) {
2874
2939
  const body3 = comment.value.trim().replace(/^\*\s*/u, "");
2875
- if (!frontend && (DIRECTIVE.test(body3) || BEHAVIORAL_DIRECTIVE.test(comment.value) || LEGAL.test(comment.value) || legalLines.has(index) || TYPE_CONTRACT.test(comment.value) || hasDetectSecretsPragma(comment, context.sourceCode.text))) continue;
2940
+ if (!frontend && (DIRECTIVE.test(body3) || BEHAVIORAL_DIRECTIVE.test(comment.value) || LEGAL.test(comment.value) || legal?.has(comment) || TYPE_CONTRACT.test(comment.value) || hasDetectSecretsPragma(comment, context.sourceCode.text))) continue;
2876
2941
  context.report({
2877
2942
  node: comment,
2878
2943
  messageId: "testComment",
@@ -3687,7 +3752,7 @@ function fixtureConstructor(source, value) {
3687
3752
  const use = value.params[1];
3688
3753
  if (use?.type !== import_utils29.AST_NODE_TYPES.Identifier) return null;
3689
3754
  const binding3 = stableBinding(source, use);
3690
- const calls = scopeNodes(value.body, source).filter((node) => node.type === import_utils29.AST_NODE_TYPES.CallExpression && !node.optional && node.arguments.length === 1 && node.callee.type === import_utils29.AST_NODE_TYPES.Identifier && stableBinding(source, node.callee) === binding3);
3755
+ const calls = scopeNodes(value.body, source).filter((node) => node.type === import_utils29.AST_NODE_TYPES.CallExpression).filter((node) => !node.optional && node.arguments.length === 1 && node.callee.type === import_utils29.AST_NODE_TYPES.Identifier && stableBinding(source, node.callee) === binding3);
3691
3756
  if (calls.length !== 1 || binding3 === null) return null;
3692
3757
  const argument = calls[0]?.arguments[0];
3693
3758
  return argument === void 0 || argument.type === import_utils29.AST_NODE_TYPES.SpreadElement ? null : newConstructor(source, argument);
@@ -3710,17 +3775,12 @@ function scopeNodes(root, source) {
3710
3775
  if (node === void 0) continue;
3711
3776
  result.push(node);
3712
3777
  if (node !== root && (node.type === import_utils29.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils29.AST_NODE_TYPES.FunctionExpression || node.type === import_utils29.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils29.AST_NODE_TYPES.ClassDeclaration || node.type === import_utils29.AST_NODE_TYPES.ClassExpression)) continue;
3713
- for (const key of source.visitorKeys[node.type] ?? []) {
3714
- const value = Reflect.get(node, key);
3715
- if (Array.isArray(value)) pending.push(...value.filter(isNode2));
3716
- else if (isNode2(value)) pending.push(value);
3717
- }
3778
+ forEachAstChild(node, source.visitorKeys, (child) => {
3779
+ pending.push(child);
3780
+ });
3718
3781
  }
3719
3782
  return result;
3720
3783
  }
3721
- function isNode2(value) {
3722
- return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
3723
- }
3724
3784
  function testApiCallee(expression) {
3725
3785
  let node = unwrapExpression(expression);
3726
3786
  while (node.type === import_utils29.AST_NODE_TYPES.MemberExpression && !node.optional && TEST_MODIFIERS.has(import_utils29.ASTUtils.getPropertyName(node) ?? "")) node = unwrapExpression(node.object);
@@ -6287,7 +6347,7 @@ function isSearchParamReceiver(call, services) {
6287
6347
  // package.json
6288
6348
  var package_default = {
6289
6349
  name: "@sarj/eslint-plugin",
6290
- version: "18.2.0",
6350
+ version: "18.3.0",
6291
6351
  packageManager: "npm@12.2.1",
6292
6352
  description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
6293
6353
  type: "module",
@@ -6933,7 +6993,7 @@ function existingFactoryContractFix(sourceCode, candidate2) {
6933
6993
  const contract = contractStatement?.type === import_utils48.AST_NODE_TYPES.ExportNamedDeclaration ? contractStatement.declaration : null;
6934
6994
  const implementation = classStatement?.type === import_utils48.AST_NODE_TYPES.ExportNamedDeclaration ? classStatement.declaration : classStatement;
6935
6995
  const factory = factoryStatement?.type === import_utils48.AST_NODE_TYPES.ExportNamedDeclaration ? factoryStatement.declaration : null;
6936
- if (contract?.type !== import_utils48.AST_NODE_TYPES.TSTypeAliasDeclaration || worker?.type !== import_utils48.AST_NODE_TYPES.TSInterfaceDeclaration || implementation?.type !== import_utils48.AST_NODE_TYPES.ClassDeclaration || implementation !== candidate2 || !ordinaryClass(implementation) || !ordinaryFactory(factory))
6996
+ if (contract?.type !== import_utils48.AST_NODE_TYPES.TSTypeAliasDeclaration || worker?.type !== import_utils48.AST_NODE_TYPES.TSInterfaceDeclaration || implementation?.type !== import_utils48.AST_NODE_TYPES.ClassDeclaration || implementation !== candidate2 || !ordinaryClass(implementation) || factory?.type !== import_utils48.AST_NODE_TYPES.FunctionDeclaration || !ordinaryFactory(factory))
6937
6997
  return null;
6938
6998
  const operation2 = contractOperation(contract);
6939
6999
  if (operation2 === null || interfaceOperation(worker) !== operation2)
@@ -6952,7 +7012,7 @@ function ordinaryClass(node) {
6952
7012
  return node.id !== null && !node.declare && !node.abstract && node.decorators.length === 0 && node.superClass === null && node.implements.length === 0 && node.typeParameters === void 0 && node.body.body.length === 2;
6953
7013
  }
6954
7014
  function ordinaryFactory(node) {
6955
- return node?.type === import_utils48.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 1 && node.body.body.length === 1;
7015
+ return node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 1 && node.body.body.length === 1;
6956
7016
  }
6957
7017
  function interfaceOperation(node) {
6958
7018
  return !node.declare && node.extends.length === 0 && node.typeParameters === void 0 ? singletonOperation(node.body.body) : null;
@@ -7525,8 +7585,8 @@ var publicMethodNames = (body3, functionAliases) => {
7525
7585
  };
7526
7586
  var isFluentConstructionObject = (node, getText) => {
7527
7587
  if (node.id === null) return false;
7528
- const methods = node.body.body.filter(
7529
- (member3) => member3.type === import_utils49.AST_NODE_TYPES.MethodDefinition && member3.kind === "method" && !member3.static && member3.accessibility !== "private" && member3.accessibility !== "protected" && member3.value.body !== null
7588
+ const methods = node.body.body.filter((member3) => member3.type === import_utils49.AST_NODE_TYPES.MethodDefinition).filter(
7589
+ (member3) => member3.kind === "method" && !member3.static && member3.accessibility !== "private" && member3.accessibility !== "protected" && member3.value.body !== null
7530
7590
  );
7531
7591
  if (methods.length === 0) return false;
7532
7592
  return methods.every((member3) => {
@@ -7690,7 +7750,7 @@ var require_port_for_service_default = createRule({
7690
7750
  const ctor = node.body.body.find(
7691
7751
  (member3) => member3.type === import_utils49.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null && member3.value.body !== void 0
7692
7752
  );
7693
- if (ctor === void 0) return;
7753
+ if (ctor?.type !== import_utils49.AST_NODE_TYPES.MethodDefinition) return;
7694
7754
  const constructorFacts = readConstructor(
7695
7755
  ctor,
7696
7756
  objectTypes,
@@ -7757,7 +7817,7 @@ function createServiceOperationResolver(program) {
7757
7817
  const ctor = node.body.body.find(
7758
7818
  (member3) => member3.type === import_utils49.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null
7759
7819
  );
7760
- if (ctor === void 0) return [];
7820
+ if (ctor?.type !== import_utils49.AST_NODE_TYPES.MethodDefinition) return [];
7761
7821
  const declared = () => declaredTypes ??= fileTypeIndex(program);
7762
7822
  const facts = readConstructor(
7763
7823
  ctor,
@@ -9332,7 +9392,7 @@ function ordinaryHostReference(reference) {
9332
9392
  }
9333
9393
 
9334
9394
  // src/rules/no-contradictory-type-predicate.ts
9335
- var RUNTIME_KINDS = /* @__PURE__ */ new Set(["string", "number", "bigint", "boolean", "symbol", "undefined", "object", "function"]);
9395
+ var RUNTIME_KINDS = ["string", "number", "bigint", "boolean", "symbol", "undefined", "object", "function"];
9336
9396
  var PRIMITIVE_KINDS = [
9337
9397
  [import_typescript23.default.TypeFlags.String, "string"],
9338
9398
  [import_typescript23.default.TypeFlags.Number, "number"],
@@ -9411,7 +9471,7 @@ var no_contradictory_type_predicate_default = createRule({
9411
9471
  if (hasSeparatePredicateContract(services.esTreeNodeToTSNodeMap.get(node), checker)) return;
9412
9472
  const parameter = node.params.find((candidate2) => candidate2.type === import_utils59.AST_NODE_TYPES.Identifier && candidate2.name === name);
9413
9473
  const expression = singleReturn(node);
9414
- if (parameter?.typeAnnotation === void 0 || expression === void 0) return;
9474
+ if (parameter?.type !== import_utils59.AST_NODE_TYPES.Identifier || parameter.typeAnnotation === void 0 || expression === void 0) return;
9415
9475
  const check = typeofCheck(expression);
9416
9476
  if (check !== void 0 && !sameParameter(parameter, check.parameter, context.sourceCode)) return;
9417
9477
  const input = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(check?.parameter ?? parameter));
@@ -9502,15 +9562,13 @@ function typeofCheck(expression) {
9502
9562
  if (value.type !== import_utils59.AST_NODE_TYPES.BinaryExpression || value.operator !== "===" && value.operator !== "==") return void 0;
9503
9563
  for (const [tested, expected] of [[value.left, value.right], [value.right, value.left]]) {
9504
9564
  const operand = unwrapExpression(tested);
9505
- const kind = staticString(expected);
9506
- if (operand.type !== import_utils59.AST_NODE_TYPES.UnaryExpression || operand.operator !== "typeof" || operand.argument.type !== import_utils59.AST_NODE_TYPES.Identifier || kind === null || !isRuntimeKind(kind)) continue;
9565
+ const expectedKind = staticString(expected);
9566
+ const kind = RUNTIME_KINDS.find((candidate2) => candidate2 === expectedKind);
9567
+ if (operand.type !== import_utils59.AST_NODE_TYPES.UnaryExpression || operand.operator !== "typeof" || operand.argument.type !== import_utils59.AST_NODE_TYPES.Identifier || kind === void 0) continue;
9507
9568
  return { parameter: operand.argument, kind };
9508
9569
  }
9509
9570
  return void 0;
9510
9571
  }
9511
- function isRuntimeKind(value) {
9512
- return RUNTIME_KINDS.has(value);
9513
- }
9514
9572
  function sameParameter(declared, tested, sourceCode) {
9515
9573
  const parameter = import_utils59.ASTUtils.findVariable(sourceCode.getScope(declared), declared.name);
9516
9574
  return parameter !== null && parameter === import_utils59.ASTUtils.findVariable(sourceCode.getScope(tested), tested.name);
@@ -9559,9 +9617,9 @@ var import_utils60 = require("@typescript-eslint/utils");
9559
9617
  var import_typescript24 = __toESM(require("typescript"), 1);
9560
9618
  function uuidPredicateWitness(expression, parameter, sourceCode, services) {
9561
9619
  const success = unwrapExpression(expression);
9562
- if (!member(success, "success")) return void 0;
9620
+ if (success.type !== import_utils60.AST_NODE_TYPES.MemberExpression || !member(success, "success")) return void 0;
9563
9621
  const parse2 = unwrapExpression(success.object);
9564
- if (parse2.type !== import_utils60.AST_NODE_TYPES.CallExpression || parse2.optional || parse2.arguments.length !== 1 || !member(parse2.callee, "safeParse")) return void 0;
9622
+ if (parse2.type !== import_utils60.AST_NODE_TYPES.CallExpression || parse2.optional || parse2.arguments.length !== 1 || parse2.callee.type !== import_utils60.AST_NODE_TYPES.MemberExpression || !member(parse2.callee, "safeParse")) return void 0;
9565
9623
  const argument = parse2.arguments[0];
9566
9624
  if (argument === void 0 || unwrapExpression(argument).type !== import_utils60.AST_NODE_TYPES.Identifier) return void 0;
9567
9625
  const value = unwrapExpression(argument);
@@ -9580,13 +9638,13 @@ function binding(node, sourceCode) {
9580
9638
  return import_utils60.ASTUtils.findVariable(sourceCode.getScope(node), node.name);
9581
9639
  }
9582
9640
  function member(node, name) {
9583
- return node?.type === import_utils60.AST_NODE_TYPES.MemberExpression && !node.optional && !node.computed && node.property.type === import_utils60.AST_NODE_TYPES.Identifier && node.property.name === name;
9641
+ return !node.optional && !node.computed && node.property.type === import_utils60.AST_NODE_TYPES.Identifier && node.property.name === name;
9584
9642
  }
9585
9643
  function uuidNamespace(initializer, sourceCode, services) {
9586
- if (!noArguments(initializer) || !member(initializer.callee, "uuid")) return null;
9644
+ if (initializer.type !== import_utils60.AST_NODE_TYPES.CallExpression || !noArguments(initializer) || initializer.callee.type !== import_utils60.AST_NODE_TYPES.MemberExpression || !member(initializer.callee, "uuid")) return null;
9587
9645
  let receiver = unwrapExpression(initializer.callee.object);
9588
9646
  let legacy = false;
9589
- if (noArguments(receiver) && member(receiver.callee, "string")) {
9647
+ if (receiver.type === import_utils60.AST_NODE_TYPES.CallExpression && noArguments(receiver) && receiver.callee.type === import_utils60.AST_NODE_TYPES.MemberExpression && member(receiver.callee, "string")) {
9590
9648
  receiver = unwrapExpression(receiver.callee.object);
9591
9649
  legacy = true;
9592
9650
  }
@@ -9602,7 +9660,7 @@ function uuidNamespace(initializer, sourceCode, services) {
9602
9660
  return namespace ?? null;
9603
9661
  }
9604
9662
  function noArguments(node) {
9605
- return node.type === import_utils60.AST_NODE_TYPES.CallExpression && !node.optional && node.arguments.length === 0;
9663
+ return !node.optional && node.arguments.length === 0;
9606
9664
  }
9607
9665
  function installedZod(node, services) {
9608
9666
  const checker = services.program.getTypeChecker();
@@ -9622,7 +9680,7 @@ function closedSchema(schema) {
9622
9680
  const receiver = outerExpression(reference.identifier);
9623
9681
  const property = receiver.parent;
9624
9682
  if (property?.type === import_utils60.AST_NODE_TYPES.ExportSpecifier && property.local === receiver) return true;
9625
- if (!member(property, "safeParse") || property.object !== receiver) return false;
9683
+ if (property?.type !== import_utils60.AST_NODE_TYPES.MemberExpression || !member(property, "safeParse") || property.object !== receiver) return false;
9626
9684
  const call = property.parent;
9627
9685
  return call?.type === import_utils60.AST_NODE_TYPES.CallExpression && call.callee === property && !call.optional && call.arguments.length === 1 && call.arguments[0]?.type !== import_utils60.AST_NODE_TYPES.SpreadElement;
9628
9686
  });
@@ -10088,10 +10146,10 @@ function literalSelectorFix(sourceCode, parameter) {
10088
10146
  if (sourceCode.ast.body.length !== 4 || sourceCode.getAllComments().length > 0)
10089
10147
  return null;
10090
10148
  const [first, second, declaration, statement] = sourceCode.ast.body;
10091
- if (!isLiteralOperation(first) || !isLiteralOperation(second) || declaration?.type !== import_utils63.AST_NODE_TYPES.VariableDeclaration || declaration.declare || declaration.kind !== "const" || declaration.declarations.length !== 1 || statement?.type !== import_utils63.AST_NODE_TYPES.ExportNamedDeclaration || statement.declaration?.type !== import_utils63.AST_NODE_TYPES.FunctionDeclaration)
10149
+ if (first?.type !== import_utils63.AST_NODE_TYPES.FunctionDeclaration || !isLiteralOperation(first) || second?.type !== import_utils63.AST_NODE_TYPES.FunctionDeclaration || !isLiteralOperation(second) || declaration?.type !== import_utils63.AST_NODE_TYPES.VariableDeclaration || declaration.declare || declaration.kind !== "const" || declaration.declarations.length !== 1 || statement?.type !== import_utils63.AST_NODE_TYPES.ExportNamedDeclaration || statement.declaration?.type !== import_utils63.AST_NODE_TYPES.FunctionDeclaration)
10092
10150
  return null;
10093
10151
  const binding3 = declaration.declarations[0];
10094
- if (binding3?.id.type !== import_utils63.AST_NODE_TYPES.Identifier || binding3.id.typeAnnotation !== void 0 || !isSelector(binding3.init, parameter))
10152
+ if (binding3?.id.type !== import_utils63.AST_NODE_TYPES.Identifier || binding3.id.typeAnnotation !== void 0 || binding3.init?.type !== import_utils63.AST_NODE_TYPES.ArrowFunctionExpression || binding3.init.body.type !== import_utils63.AST_NODE_TYPES.ConditionalExpression || !isSelector(binding3.init, parameter))
10095
10153
  return null;
10096
10154
  const branch = binding3.init.body;
10097
10155
  const whenTrue = operation(sourceCode, branch.consequent, first, second);
@@ -10113,13 +10171,12 @@ function literalSelectorFix(sourceCode, parameter) {
10113
10171
  ];
10114
10172
  }
10115
10173
  function isLiteralOperation(node) {
10116
- if (node?.type !== import_utils63.AST_NODE_TYPES.FunctionDeclaration || node.id === null || node.declare || node.async || node.generator || node.params.length !== 0 || node.typeParameters !== void 0 || node.returnType !== void 0 || node.body.body.length !== 1)
10174
+ if (node.id === null || node.declare || node.async || node.generator || node.params.length !== 0 || node.typeParameters !== void 0 || node.returnType !== void 0 || node.body.body.length !== 1)
10117
10175
  return false;
10118
10176
  const returned2 = node.body.body[0];
10119
10177
  return returned2?.type === import_utils63.AST_NODE_TYPES.ReturnStatement && returned2.argument?.type === import_utils63.AST_NODE_TYPES.Literal && typeof returned2.argument.value === "string";
10120
10178
  }
10121
10179
  function isSelector(node, parameter) {
10122
- if (node?.type !== import_utils63.AST_NODE_TYPES.ArrowFunctionExpression) return false;
10123
10180
  const actual = node.params[0];
10124
10181
  return actual?.type === import_utils63.AST_NODE_TYPES.Identifier && actual.name === parameter.name && !node.async && node.typeParameters === void 0 && node.returnType === void 0 && node.params.length === 1 && !actual.optional && actual.typeAnnotation?.typeAnnotation.type === import_utils63.AST_NODE_TYPES.TSBooleanKeyword && node.body.type === import_utils63.AST_NODE_TYPES.ConditionalExpression && node.body.test === parameter;
10125
10182
  }
@@ -11946,10 +12003,6 @@ var import_utils77 = require("@typescript-eslint/utils");
11946
12003
  var TEST_CALLERS = /* @__PURE__ */ new Set(["it", "test"]);
11947
12004
  var ASSERTION_NAMES = /* @__PURE__ */ new Set(["assert", "expect"]);
11948
12005
  var TEST_MODIFIERS2 = /* @__PURE__ */ new Set(["concurrent", "fails", "only", "sequential", "skip"]);
11949
- var FUNCTION_TYPES = /* @__PURE__ */ new Set([
11950
- import_utils77.AST_NODE_TYPES.FunctionExpression,
11951
- import_utils77.AST_NODE_TYPES.ArrowFunctionExpression
11952
- ]);
11953
12006
  var OMITTED_AST_KEYS = /* @__PURE__ */ new Set([
11954
12007
  "end",
11955
12008
  "loc",
@@ -12131,7 +12184,7 @@ function testBody(call, sourceCode) {
12131
12184
  return null;
12132
12185
  }
12133
12186
  const callback = call.arguments.map(unwrapExpression).find(
12134
- (argument) => argument.type !== import_utils77.AST_NODE_TYPES.SpreadElement && FUNCTION_TYPES.has(argument.type)
12187
+ (argument) => argument.type === import_utils77.AST_NODE_TYPES.FunctionExpression || argument.type === import_utils77.AST_NODE_TYPES.ArrowFunctionExpression
12135
12188
  );
12136
12189
  if (callback === void 0 || call.arguments.length !== 2 || containsInlineSnapshot(callback.body)) {
12137
12190
  return null;
@@ -15425,7 +15478,7 @@ function uuidModule(sourceCode, kind) {
15425
15478
  const native = statements[offset + 1];
15426
15479
  const legacy = statements[offset + 2];
15427
15480
  const exported = statements[offset + 3];
15428
- if (imported !== null && imported?.type !== import_utils93.AST_NODE_TYPES.ImportDeclaration || declaration?.type !== import_utils93.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare || declaration.declarations.length !== 1 || !stringFunction(native) || !stringFunction(legacy) || exported?.type !== import_utils93.AST_NODE_TYPES.ExportNamedDeclaration || exported.specifiers.length !== 0 || exported.source !== null || !arrayFunction(exported.declaration))
15481
+ if (imported !== null && imported?.type !== import_utils93.AST_NODE_TYPES.ImportDeclaration || declaration?.type !== import_utils93.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare || declaration.declarations.length !== 1 || native?.type !== import_utils93.AST_NODE_TYPES.FunctionDeclaration || !stringFunction(native) || legacy?.type !== import_utils93.AST_NODE_TYPES.FunctionDeclaration || !stringFunction(legacy) || exported?.type !== import_utils93.AST_NODE_TYPES.ExportNamedDeclaration || exported.specifiers.length !== 0 || exported.source !== null || exported.declaration?.type !== import_utils93.AST_NODE_TYPES.FunctionDeclaration || !arrayFunction(exported.declaration))
15429
15482
  return null;
15430
15483
  const provider = declaration.declarations[0];
15431
15484
  if (provider === void 0 || !nativeProvider(sourceCode, provider) || !providerRead(sourceCode, returned(native), provider) || !exportedReads(
@@ -15447,7 +15500,7 @@ function arrayFunction(node) {
15447
15500
  return annotation?.type === import_utils93.AST_NODE_TYPES.TSArrayType && annotation.elementType.type === import_utils93.AST_NODE_TYPES.TSStringKeyword;
15448
15501
  }
15449
15502
  function ordinaryFunction(node) {
15450
- return node?.type === import_utils93.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 0 && node.body.body.length === 1 && node.body.body[0]?.type === import_utils93.AST_NODE_TYPES.ReturnStatement && node.body.body[0].argument !== null;
15503
+ return node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 0 && node.body.body.length === 1 && node.body.body[0]?.type === import_utils93.AST_NODE_TYPES.ReturnStatement && node.body.body[0].argument !== null;
15451
15504
  }
15452
15505
  function returned(node) {
15453
15506
  const statement = node.body.body[0];
@@ -15459,14 +15512,14 @@ function nativeProvider(sourceCode, node) {
15459
15512
  if (node.id.type !== import_utils93.AST_NODE_TYPES.Identifier || node.id.typeAnnotation !== void 0)
15460
15513
  return false;
15461
15514
  const call = node.init;
15462
- if (call?.type !== import_utils93.AST_NODE_TYPES.CallExpression || call.optional || call.typeArguments !== void 0 || call.arguments.length !== 1 || !member2(call.callee, "bind") || !member2(call.callee.object, "randomUUID"))
15515
+ if (call?.type !== import_utils93.AST_NODE_TYPES.CallExpression || call.optional || call.typeArguments !== void 0 || call.arguments.length !== 1 || call.callee.type !== import_utils93.AST_NODE_TYPES.MemberExpression || !member2(call.callee, "bind") || call.callee.object.type !== import_utils93.AST_NODE_TYPES.MemberExpression || !member2(call.callee.object, "randomUUID"))
15463
15516
  return false;
15464
15517
  const receiver = call.callee.object.object;
15465
15518
  const argument = call.arguments[0];
15466
15519
  return receiver.type === import_utils93.AST_NODE_TYPES.Identifier && receiver.name === "crypto" && argument?.type === import_utils93.AST_NODE_TYPES.Identifier && argument.name === "crypto" && (import_utils93.ASTUtils.findVariable(sourceCode.getScope(receiver), "crypto")?.defs.length ?? 0) === 0 && (import_utils93.ASTUtils.findVariable(sourceCode.getScope(argument), "crypto")?.defs.length ?? 0) === 0;
15467
15520
  }
15468
15521
  function member2(node, property) {
15469
- return node.type === import_utils93.AST_NODE_TYPES.MemberExpression && !node.computed && !node.optional && node.property.type === import_utils93.AST_NODE_TYPES.Identifier && node.property.name === property;
15522
+ return !node.computed && !node.optional && node.property.type === import_utils93.AST_NODE_TYPES.Identifier && node.property.name === property;
15470
15523
  }
15471
15524
  function providerRead(sourceCode, node, declaration) {
15472
15525
  return node.type === import_utils93.AST_NODE_TYPES.CallExpression && !node.optional && node.typeArguments === void 0 && node.arguments.length === 0 && node.callee.type === import_utils93.AST_NODE_TYPES.Identifier && sameBinding2(sourceCode, node.callee, declaration);
@@ -15495,7 +15548,7 @@ function exportedReads(sourceCode, node, native, legacy, imported) {
15495
15548
  return nilImport !== void 0 && sameBinding2(sourceCode, nil, nilImport);
15496
15549
  }
15497
15550
  function isUuidRecipe(sourceCode, node, reported) {
15498
- if (node.type !== import_utils93.AST_NODE_TYPES.CallExpression || node.optional || node.typeArguments !== void 0 || !member2(node.callee, "replace") || node.callee.object.type !== import_utils93.AST_NODE_TYPES.Literal || node.callee.object.value !== UUID_TEMPLATE || node.arguments.length !== IMPORT_COUNT)
15551
+ if (node.type !== import_utils93.AST_NODE_TYPES.CallExpression || node.optional || node.typeArguments !== void 0 || node.callee.type !== import_utils93.AST_NODE_TYPES.MemberExpression || !member2(node.callee, "replace") || node.callee.object.type !== import_utils93.AST_NODE_TYPES.Literal || node.callee.object.value !== UUID_TEMPLATE || node.arguments.length !== IMPORT_COUNT)
15499
15552
  return false;
15500
15553
  const [pattern, callback] = node.arguments;
15501
15554
  if (pattern?.type !== import_utils93.AST_NODE_TYPES.Literal || !("regex" in pattern) || pattern.regex.pattern !== "[xy]" || pattern.regex.flags !== "g" || callback?.type !== import_utils93.AST_NODE_TYPES.ArrowFunctionExpression || callback.async || callback.typeParameters !== void 0 || callback.returnType !== void 0 || callback.params.length !== 1 || callback.params[0]?.type !== import_utils93.AST_NODE_TYPES.Identifier || callback.params[0].typeAnnotation !== void 0 || callback.params[0].optional || callback.body.type !== import_utils93.AST_NODE_TYPES.BlockStatement || callback.body.body.length !== IMPORT_COUNT)
@@ -16044,8 +16097,8 @@ function serverActionErrorResults(sourceCode) {
16044
16097
  if (nodes.some((node) => node.type === import_utils98.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils98.AST_NODE_TYPES.Identifier && node.callee.name === "eval")) return [];
16045
16098
  const analysis = new ActionResults(sourceCode);
16046
16099
  const actionSet = new Set(actions);
16047
- return nodes.filter((node) => {
16048
- if (node.type !== import_utils98.AST_NODE_TYPES.ReturnStatement || node.argument === null) return false;
16100
+ return nodes.filter((node) => node.type === import_utils98.AST_NODE_TYPES.ReturnStatement).filter((node) => {
16101
+ if (node.argument === null) return false;
16049
16102
  const owner = functionOwner(node);
16050
16103
  return owner !== null && actionSet.has(owner) && escapingActionReturn(node, owner, sourceCode) && analysis.payload(node.argument, owner);
16051
16104
  });
@@ -17027,7 +17080,7 @@ function existingDomainComparisonFix(sourceCode, comparison2) {
17027
17080
  if (comparison2.operator !== "===" || sourceCode.ast.body.length !== 2 || sourceCode.getAllComments().length !== 0)
17028
17081
  return null;
17029
17082
  const [comparator, exported] = sourceCode.ast.body;
17030
- if (!isOrdinary(comparator) || comparator.id === null || exported?.type !== import_utils101.AST_NODE_TYPES.ExportNamedDeclaration || exported.exportKind !== "value" || !isOrdinary(exported.declaration))
17083
+ if (comparator?.type !== import_utils101.AST_NODE_TYPES.FunctionDeclaration || !isOrdinary(comparator) || comparator.id === null || exported?.type !== import_utils101.AST_NODE_TYPES.ExportNamedDeclaration || exported.exportKind !== "value" || exported.declaration?.type !== import_utils101.AST_NODE_TYPES.FunctionDeclaration || !isOrdinary(exported.declaration))
17031
17084
  return null;
17032
17085
  const fields2 = comparatorFields(comparator);
17033
17086
  const elements = callerElements(exported.declaration);
@@ -17046,7 +17099,7 @@ function existingDomainComparisonFix(sourceCode, comparison2) {
17046
17099
  );
17047
17100
  }
17048
17101
  function isOrdinary(node) {
17049
- return node?.type === import_utils101.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.body.body.length === 1;
17102
+ return node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.body.body.length === 1;
17050
17103
  }
17051
17104
  function comparatorFields(node) {
17052
17105
  const [left, right] = node.params;
@@ -18278,7 +18331,7 @@ function reportClass(context, services, owner) {
18278
18331
  if (contract === null) return;
18279
18332
  const groups = /* @__PURE__ */ new Map();
18280
18333
  for (const member3 of owner.body.body) {
18281
- if (!candidate(member3)) continue;
18334
+ if (member3.type !== import_utils109.AST_NODE_TYPES.MethodDefinition || !candidate(member3)) continue;
18282
18335
  const name = convertibleMemberName(member3);
18283
18336
  if (name === null || contract.has(name)) continue;
18284
18337
  if (member3.accessibility === "private" || member3.key.type === import_utils109.AST_NODE_TYPES.PrivateIdentifier) continue;
@@ -18298,7 +18351,7 @@ function reportClass(context, services, owner) {
18298
18351
  }
18299
18352
  }
18300
18353
  function candidate(member3) {
18301
- return member3.type === import_utils109.AST_NODE_TYPES.MethodDefinition && member3.kind !== "constructor" && !member3.static && member3.accessibility !== "protected" && !member3.override && !member3.computed && member3.key.type === import_utils109.AST_NODE_TYPES.Identifier && member3.value.body !== null;
18354
+ return member3.kind !== "constructor" && !member3.static && member3.accessibility !== "protected" && !member3.override && !member3.computed && member3.key.type === import_utils109.AST_NODE_TYPES.Identifier && member3.value.body !== null;
18302
18355
  }
18303
18356
  function interfaceNames(services, owner) {
18304
18357
  const tsOwner = services.esTreeNodeToTSNodeMap.get(owner);
@@ -18470,7 +18523,7 @@ var SINGLE_STATEMENT_HOSTS = /* @__PURE__ */ new Set([
18470
18523
  import_utils111.AST_NODE_TYPES.IfStatement,
18471
18524
  import_utils111.AST_NODE_TYPES.WhileStatement
18472
18525
  ]);
18473
- var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
18526
+ var FUNCTION_TYPES = /* @__PURE__ */ new Set([
18474
18527
  import_utils111.AST_NODE_TYPES.ArrowFunctionExpression,
18475
18528
  import_utils111.AST_NODE_TYPES.FunctionDeclaration,
18476
18529
  import_utils111.AST_NODE_TYPES.FunctionExpression
@@ -18500,7 +18553,7 @@ function fallbackFollowsTry(tryStatement) {
18500
18553
  return last?.type === import_utils111.AST_NODE_TYPES.ReturnStatement && hasFollowingStatement(tryStatement);
18501
18554
  }
18502
18555
  function hasFollowingStatement(node) {
18503
- for (let current = node; current !== void 0 && !FUNCTION_TYPES2.has(current.type); current = current.parent) {
18556
+ for (let current = node; current !== void 0 && !FUNCTION_TYPES.has(current.type); current = current.parent) {
18504
18557
  const slot = statementSlot(current);
18505
18558
  if (slot !== null && slot.index < slot.list.length - 1) return true;
18506
18559
  }
@@ -18588,7 +18641,7 @@ var no_log_only_catch_default = createRule({
18588
18641
  function hasFollowingCoercionCheck(owner, left, coercion) {
18589
18642
  let current = owner;
18590
18643
  let slot = statementSlot(current);
18591
- while (slot === null && current.parent !== void 0 && !FUNCTION_TYPES2.has(current.parent.type)) {
18644
+ while (slot === null && current.parent !== void 0 && !FUNCTION_TYPES.has(current.parent.type)) {
18592
18645
  current = current.parent;
18593
18646
  slot = statementSlot(current);
18594
18647
  }
@@ -18673,7 +18726,7 @@ var TEST_NAMES = /* @__PURE__ */ new Set(["it", "test"]);
18673
18726
  var TEST_MODIFIERS3 = /* @__PURE__ */ new Set(["concurrent", "fails", "only", "sequential", "skip"]);
18674
18727
  var TEST_BUILDERS = /* @__PURE__ */ new Set(["each", "for", "runIf", "skipIf"]);
18675
18728
  var ASSERTION_NAMES2 = /* @__PURE__ */ new Set(["assert", "assertType", "expect", "expectTypeOf"]);
18676
- var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([import_utils112.AST_NODE_TYPES.ArrowFunctionExpression, import_utils112.AST_NODE_TYPES.FunctionExpression, import_utils112.AST_NODE_TYPES.FunctionDeclaration]);
18729
+ var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([import_utils112.AST_NODE_TYPES.ArrowFunctionExpression, import_utils112.AST_NODE_TYPES.FunctionExpression, import_utils112.AST_NODE_TYPES.FunctionDeclaration]);
18677
18730
  function staticMemberName3(node) {
18678
18731
  if (!node.computed && node.property.type === import_utils112.AST_NODE_TYPES.Identifier) return node.property.name;
18679
18732
  if (node.computed && node.property.type === import_utils112.AST_NODE_TYPES.Literal && typeof node.property.value === "string") return node.property.value;
@@ -18686,7 +18739,6 @@ function rootIdentifier2(callee) {
18686
18739
  return null;
18687
18740
  }
18688
18741
  function isDirectTestCallback(node, context) {
18689
- if (node.type !== import_utils112.AST_NODE_TYPES.ArrowFunctionExpression && node.type !== import_utils112.AST_NODE_TYPES.FunctionExpression) return false;
18690
18742
  const call = directArgumentCall(node);
18691
18743
  if (call === null) return false;
18692
18744
  const root = testRoot(call.callee);
@@ -18706,12 +18758,12 @@ function testRoot(callee) {
18706
18758
  return modifier !== null && TEST_MODIFIERS3.has(modifier) ? testRoot(callee.object) : null;
18707
18759
  }
18708
18760
  function nearestFunction(node) {
18709
- for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) if (FUNCTION_TYPES3.has(current.type)) return current;
18761
+ for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) if (FUNCTION_TYPES2.has(current.type)) return current;
18710
18762
  return null;
18711
18763
  }
18712
18764
  function walkOwnScope(node, predicate) {
18713
18765
  if (predicate(node)) return true;
18714
- return forEachOwnAstChild(node, (child) => !FUNCTION_TYPES3.has(child.type) && walkOwnScope(child, predicate));
18766
+ return forEachOwnAstChild(node, (child) => !FUNCTION_TYPES2.has(child.type) && walkOwnScope(child, predicate));
18715
18767
  }
18716
18768
  function isAssertion(node, context) {
18717
18769
  if (node.type !== import_utils112.AST_NODE_TYPES.CallExpression) return false;
@@ -18803,7 +18855,7 @@ var no_bare_return_from_test_catch_default = createRule({
18803
18855
  ReturnStatement(node) {
18804
18856
  if (node.argument !== null) return;
18805
18857
  const owner = nearestFunction(node);
18806
- if (owner === null || !isDirectTestCallback(owner, context)) return;
18858
+ if (owner?.type !== import_utils112.AST_NODE_TYPES.ArrowFunctionExpression && owner?.type !== import_utils112.AST_NODE_TYPES.FunctionExpression || !isDirectTestCallback(owner, context)) return;
18807
18859
  let catchClause = null;
18808
18860
  for (let current = node.parent; current !== owner; current = current?.parent) {
18809
18861
  if (current?.type === import_utils112.AST_NODE_TYPES.CatchClause) {
@@ -19433,7 +19485,7 @@ function labeledTupleObjectFix(sourceCode, annotation) {
19433
19485
  if (sourceCode.ast.body.length !== 2 || sourceCode.getAllComments().length > 0)
19434
19486
  return null;
19435
19487
  const [helper, statement] = sourceCode.ast.body;
19436
- if (!isOrdinary2(helper) || statement?.type !== import_utils117.AST_NODE_TYPES.ExportNamedDeclaration || !isOrdinary2(statement.declaration) || helper.returnType?.typeAnnotation !== annotation)
19488
+ if (helper?.type !== import_utils117.AST_NODE_TYPES.FunctionDeclaration || !isOrdinary2(helper) || statement?.type !== import_utils117.AST_NODE_TYPES.ExportNamedDeclaration || statement.declaration?.type !== import_utils117.AST_NODE_TYPES.FunctionDeclaration || !isOrdinary2(statement.declaration) || helper.returnType?.typeAnnotation !== annotation)
19437
19489
  return null;
19438
19490
  const caller = statement.declaration;
19439
19491
  const fields2 = tupleFields(helper);
@@ -19458,7 +19510,7 @@ function labeledTupleObjectFix(sourceCode, annotation) {
19458
19510
  ];
19459
19511
  }
19460
19512
  function isOrdinary2(node) {
19461
- return node?.type === import_utils117.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.params.length === 0 && node.typeParameters === void 0;
19513
+ return node.id !== null && !node.declare && !node.async && !node.generator && node.params.length === 0 && node.typeParameters === void 0;
19462
19514
  }
19463
19515
  function tupleFields(helper) {
19464
19516
  const tuple = helper.returnType?.typeAnnotation;
@@ -20786,7 +20838,7 @@ var PREVIEW_LENGTH = 40;
20786
20838
  var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
20787
20839
  var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
20788
20840
  var URL_PATH_RE = /^\/(?=[^\s]*[A-Za-z0-9])[A-Za-z0-9._~!$&'()*+,;=:@%/?#{}\u005B\u005D-]+$/;
20789
- var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
20841
+ var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
20790
20842
  import_utils124.AST_NODE_TYPES.FunctionDeclaration,
20791
20843
  import_utils124.AST_NODE_TYPES.FunctionExpression,
20792
20844
  import_utils124.AST_NODE_TYPES.ArrowFunctionExpression
@@ -20860,7 +20912,7 @@ function preview(value) {
20860
20912
  }
20861
20913
  function enclosingFunction4(node) {
20862
20914
  for (let current = node.parent; current != null; current = current.parent) {
20863
- if (FUNCTION_TYPES4.has(current.type)) {
20915
+ if (FUNCTION_TYPES3.has(current.type)) {
20864
20916
  return current;
20865
20917
  }
20866
20918
  }
@@ -22325,9 +22377,6 @@ function isSentinelArgument(arg) {
22325
22377
  function isFunctionNode(node) {
22326
22378
  return node.type === import_utils132.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils132.AST_NODE_TYPES.FunctionExpression || node.type === import_utils132.AST_NODE_TYPES.ArrowFunctionExpression;
22327
22379
  }
22328
- function isNode3(value) {
22329
- return typeof value === "object" && value !== null && typeof value.type === "string";
22330
- }
22331
22380
  function walkWithinScope(node, visit) {
22332
22381
  let found = false;
22333
22382
  const recurse = (current) => {
@@ -22454,7 +22503,7 @@ function enclosingFunctionName(node) {
22454
22503
  let current = node.parent;
22455
22504
  while (current !== void 0 && current !== null) {
22456
22505
  if (isFunctionNode(current)) {
22457
- if ("id" in current && isNode3(current.id) && current.id.type === import_utils132.AST_NODE_TYPES.Identifier) {
22506
+ if ("id" in current && current.id !== null && current.id.type === import_utils132.AST_NODE_TYPES.Identifier) {
22458
22507
  return current.id.name;
22459
22508
  }
22460
22509
  const parent = current.parent;
@@ -22555,7 +22604,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
22555
22604
  function enclosingFunctionBody(node) {
22556
22605
  let current = node.parent;
22557
22606
  while (current !== void 0 && current !== null) {
22558
- if (isFunctionNode(current) && "body" in current && isNode3(current.body) && current.body.type === import_utils132.AST_NODE_TYPES.BlockStatement) {
22607
+ if (isFunctionNode(current) && current.body?.type === import_utils132.AST_NODE_TYPES.BlockStatement) {
22559
22608
  return current.body;
22560
22609
  }
22561
22610
  current = current.parent;
@@ -22962,7 +23011,7 @@ var TEST_CALLERS2 = /* @__PURE__ */ new Set([
22962
23011
  "beforeEach",
22963
23012
  "afterEach"
22964
23013
  ]);
22965
- var FUNCTION_TYPES5 = /* @__PURE__ */ new Set([
23014
+ var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
22966
23015
  import_utils134.AST_NODE_TYPES.FunctionDeclaration,
22967
23016
  import_utils134.AST_NODE_TYPES.FunctionExpression,
22968
23017
  import_utils134.AST_NODE_TYPES.ArrowFunctionExpression
@@ -22997,7 +23046,7 @@ function isHelperSleep(node) {
22997
23046
  }
22998
23047
  function nearestEnclosingFunction(node) {
22999
23048
  for (let current = node.parent; current != null; current = current.parent) {
23000
- if (!FUNCTION_TYPES5.has(current.type)) {
23049
+ if (!FUNCTION_TYPES4.has(current.type)) {
23001
23050
  continue;
23002
23051
  }
23003
23052
  const grandparent = current.parent;
@@ -26002,7 +26051,7 @@ var ASSERTION_ROOTS = /* @__PURE__ */ new Set([
26002
26051
  "expect",
26003
26052
  "expectTypeOf"
26004
26053
  ]);
26005
- var FUNCTION_TYPES6 = /* @__PURE__ */ new Set([
26054
+ var FUNCTION_TYPES5 = /* @__PURE__ */ new Set([
26006
26055
  import_utils150.AST_NODE_TYPES.FunctionDeclaration,
26007
26056
  import_utils150.AST_NODE_TYPES.FunctionExpression,
26008
26057
  import_utils150.AST_NODE_TYPES.ArrowFunctionExpression
@@ -26037,7 +26086,7 @@ function isTestCaller(callee, isFrameworkTest) {
26037
26086
  }
26038
26087
  function nearestEnclosingFunction2(node) {
26039
26088
  for (let current = node.parent; current != null; current = current.parent) {
26040
- if (FUNCTION_TYPES6.has(current.type)) {
26089
+ if (FUNCTION_TYPES5.has(current.type)) {
26041
26090
  return current;
26042
26091
  }
26043
26092
  }
@@ -26070,7 +26119,7 @@ function walkOwnScope2(node, predicate) {
26070
26119
  if (predicate(node)) {
26071
26120
  return true;
26072
26121
  }
26073
- return forEachOwnAstChild(node, (child) => !FUNCTION_TYPES6.has(child.type) && walkOwnScope2(child, predicate));
26122
+ return forEachOwnAstChild(node, (child) => !FUNCTION_TYPES5.has(child.type) && walkOwnScope2(child, predicate));
26074
26123
  }
26075
26124
  function isAssertion2(node, isFrameworkAssertion) {
26076
26125
  if (node.type !== import_utils150.AST_NODE_TYPES.CallExpression) return false;
@@ -26083,7 +26132,7 @@ function opensSubtest(node, callbackParameters) {
26083
26132
  }
26084
26133
  const callee = unwrapExpression(node.callee);
26085
26134
  return callee.type === import_utils150.AST_NODE_TYPES.MemberExpression && staticMemberName6(callee) === "test" && callee.object.type === import_utils150.AST_NODE_TYPES.Identifier && callbackParameters.has(callee.object.name) && node.arguments.some(
26086
- (argument) => argument.type !== import_utils150.AST_NODE_TYPES.SpreadElement && FUNCTION_TYPES6.has(argument.type)
26135
+ (argument) => argument.type !== import_utils150.AST_NODE_TYPES.SpreadElement && FUNCTION_TYPES5.has(argument.type)
26087
26136
  );
26088
26137
  }
26089
26138
  var LOOP_CARRIED_CONTROL = /* @__PURE__ */ new Set([
@@ -26449,7 +26498,7 @@ var PREFER_ECMASCRIPT_PRIVATE_MEMBERS_DOCUMENTATION = {
26449
26498
  function reportClass2(context, owner, services) {
26450
26499
  const groups = /* @__PURE__ */ new Map();
26451
26500
  for (const member3 of owner.body.body) {
26452
- if (!isConvertible(member3)) continue;
26501
+ if (member3.type !== import_utils153.AST_NODE_TYPES.MethodDefinition && member3.type !== import_utils153.AST_NODE_TYPES.PropertyDefinition && member3.type !== import_utils153.AST_NODE_TYPES.AccessorProperty || !isConvertible(member3)) continue;
26453
26502
  const name = convertibleMemberName(member3);
26454
26503
  if (name === null) continue;
26455
26504
  const members = groups.get(name) ?? [];
@@ -26468,7 +26517,6 @@ function reportClass2(context, owner, services) {
26468
26517
  }
26469
26518
  }
26470
26519
  function isConvertible(member3) {
26471
- if (member3.type !== import_utils153.AST_NODE_TYPES.MethodDefinition && member3.type !== import_utils153.AST_NODE_TYPES.PropertyDefinition && member3.type !== import_utils153.AST_NODE_TYPES.AccessorProperty) return false;
26472
26520
  return member3.accessibility === "private" && !(member3.type === import_utils153.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor") && !member3.computed && member3.key.type === import_utils153.AST_NODE_TYPES.Identifier && member3.decorators.length === 0 && !("declare" in member3 && member3.declare) && !member3.override && !(member3.type === import_utils153.AST_NODE_TYPES.MethodDefinition && member3.value.body === null);
26473
26521
  }
26474
26522
  var prefer_ecmascript_private_members_default = createRule({
@@ -28160,7 +28208,7 @@ var MUTATING_METHODS2 = /* @__PURE__ */ new Set([
28160
28208
  // Object-ish escape hatches
28161
28209
  "assign"
28162
28210
  ]);
28163
- var FUNCTION_TYPES7 = /* @__PURE__ */ new Set([
28211
+ var FUNCTION_TYPES6 = /* @__PURE__ */ new Set([
28164
28212
  import_utils162.AST_NODE_TYPES.FunctionDeclaration,
28165
28213
  import_utils162.AST_NODE_TYPES.FunctionExpression,
28166
28214
  import_utils162.AST_NODE_TYPES.ArrowFunctionExpression
@@ -28182,8 +28230,8 @@ function unwrap3(node) {
28182
28230
  return node;
28183
28231
  }
28184
28232
  var HAS_STATEFUL_FLAG_RE = /[gy]/;
28185
- function isRegexLiteral(node) {
28186
- return node.type === import_utils162.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
28233
+ function literalRegex(node) {
28234
+ return node.type === import_utils162.AST_NODE_TYPES.Literal && "regex" in node ? node.regex : void 0;
28187
28235
  }
28188
28236
  function isLiteralOnly(node, depth) {
28189
28237
  if (depth > MAX_LITERAL_DEPTH) {
@@ -28192,7 +28240,7 @@ function isLiteralOnly(node, depth) {
28192
28240
  const inner = unwrap3(node);
28193
28241
  switch (inner.type) {
28194
28242
  case import_utils162.AST_NODE_TYPES.Literal: {
28195
- return !(isRegexLiteral(inner) && HAS_STATEFUL_FLAG_RE.test(inner.regex.flags));
28243
+ return !HAS_STATEFUL_FLAG_RE.test(literalRegex(inner)?.flags ?? "");
28196
28244
  }
28197
28245
  case import_utils162.AST_NODE_TYPES.TemplateLiteral: {
28198
28246
  return inner.expressions.length === 0;
@@ -28226,11 +28274,12 @@ function isLiteralOnly(node, depth) {
28226
28274
  }
28227
28275
  function classify(init, checkRegex, sourceCode) {
28228
28276
  const node = unwrapObjectFreeze(init, sourceCode);
28229
- if (isRegexLiteral(node)) {
28277
+ const regex = literalRegex(node);
28278
+ if (regex !== void 0) {
28230
28279
  if (!checkRegex) {
28231
28280
  return null;
28232
28281
  }
28233
- if (HAS_STATEFUL_FLAG_RE.test(node.regex.flags)) {
28282
+ if (HAS_STATEFUL_FLAG_RE.test(regex.flags)) {
28234
28283
  return null;
28235
28284
  }
28236
28285
  return { kind: "regex", size: 1 };
@@ -28257,7 +28306,7 @@ function unwrapObjectFreeze(node, sourceCode) {
28257
28306
  function enclosingFunction5(node) {
28258
28307
  let current = node.parent;
28259
28308
  while (current !== void 0 && current !== null) {
28260
- if (FUNCTION_TYPES7.has(current.type)) {
28309
+ if (FUNCTION_TYPES6.has(current.type)) {
28261
28310
  return current;
28262
28311
  }
28263
28312
  current = current.parent;
@@ -28561,7 +28610,7 @@ var I18N_RECEIVER_NAMES = /* @__PURE__ */ new Set([
28561
28610
  "i18n",
28562
28611
  "intl"
28563
28612
  ]);
28564
- var FUNCTION_TYPES8 = /* @__PURE__ */ new Set([
28613
+ var FUNCTION_TYPES7 = /* @__PURE__ */ new Set([
28565
28614
  import_utils163.AST_NODE_TYPES.ArrowFunctionExpression,
28566
28615
  import_utils163.AST_NODE_TYPES.FunctionDeclaration,
28567
28616
  import_utils163.AST_NODE_TYPES.FunctionExpression
@@ -28587,7 +28636,7 @@ function outermostEnclosingFunction(node) {
28587
28636
  let outermost;
28588
28637
  let current = node.parent ?? void 0;
28589
28638
  while (current !== void 0) {
28590
- if (FUNCTION_TYPES8.has(current.type)) {
28639
+ if (FUNCTION_TYPES7.has(current.type)) {
28591
28640
  outermost = current;
28592
28641
  }
28593
28642
  current = current.parent ?? void 0;
@@ -28610,7 +28659,7 @@ function subtreeSome(root, predicate, skipDeferredFunctions = false) {
28610
28659
  if (typeof candidate2.type !== "string") {
28611
28660
  return;
28612
28661
  }
28613
- if (skipDeferredFunctions && FUNCTION_TYPES8.has(candidate2.type)) return;
28662
+ if (skipDeferredFunctions && FUNCTION_TYPES7.has(candidate2.type)) return;
28614
28663
  if (predicate(candidate2)) {
28615
28664
  found = true;
28616
28665
  return;
@@ -28725,7 +28774,7 @@ var prefer_module_level_schema_default = createRule({
28725
28774
  function isCovered(node) {
28726
28775
  let current = node.parent ?? void 0;
28727
28776
  while (current !== void 0) {
28728
- if (current !== node && isZodCall(current) && current.callee.type === import_utils163.AST_NODE_TYPES.MemberExpression && import_utils163.ASTUtils.getPropertyName(current.callee) !== null && factories.has(import_utils163.ASTUtils.getPropertyName(current.callee) ?? "")) {
28777
+ if (current !== node && current.type === import_utils163.AST_NODE_TYPES.CallExpression && isZodCall(current) && current.callee.type === import_utils163.AST_NODE_TYPES.MemberExpression && import_utils163.ASTUtils.getPropertyName(current.callee) !== null && factories.has(import_utils163.ASTUtils.getPropertyName(current.callee) ?? "")) {
28729
28778
  return true;
28730
28779
  }
28731
28780
  if (current.type === import_utils163.AST_NODE_TYPES.CallExpression && (current.callee.type === import_utils163.AST_NODE_TYPES.Identifier && memoCallees.has(current.callee.name) || current.callee.type === import_utils163.AST_NODE_TYPES.MemberExpression && import_utils163.ASTUtils.getPropertyName(current.callee) !== null && memoCallees.has(import_utils163.ASTUtils.getPropertyName(current.callee) ?? ""))) {
@@ -28981,7 +29030,7 @@ var I18N_RECEIVER_NAMES2 = /* @__PURE__ */ new Set([
28981
29030
  "i18n",
28982
29031
  "intl"
28983
29032
  ]);
28984
- var FUNCTION_TYPES9 = /* @__PURE__ */ new Set([
29033
+ var FUNCTION_TYPES8 = /* @__PURE__ */ new Set([
28985
29034
  import_utils164.AST_NODE_TYPES.ArrowFunctionExpression,
28986
29035
  import_utils164.AST_NODE_TYPES.FunctionDeclaration,
28987
29036
  import_utils164.AST_NODE_TYPES.FunctionExpression
@@ -29029,7 +29078,7 @@ function outermostEnclosingFunction2(node) {
29029
29078
  let outermost;
29030
29079
  let current = node.parent ?? void 0;
29031
29080
  while (current !== void 0) {
29032
- if (FUNCTION_TYPES9.has(current.type)) outermost = current;
29081
+ if (FUNCTION_TYPES8.has(current.type)) outermost = current;
29033
29082
  current = current.parent ?? void 0;
29034
29083
  }
29035
29084
  return outermost;
@@ -29048,7 +29097,7 @@ function subtreeSome2(root, predicate, skipDeferredFunctions = false) {
29048
29097
  }
29049
29098
  const candidate2 = value;
29050
29099
  if (typeof candidate2.type !== "string") return;
29051
- if (skipDeferredFunctions && FUNCTION_TYPES9.has(candidate2.type)) return;
29100
+ if (skipDeferredFunctions && FUNCTION_TYPES8.has(candidate2.type)) return;
29052
29101
  if (predicate(candidate2)) {
29053
29102
  found = true;
29054
29103
  return;
@@ -29194,7 +29243,7 @@ var prefer_module_level_refined_schema_default = createRule({
29194
29243
  let current = node;
29195
29244
  while (current.parent != null) {
29196
29245
  current = current.parent;
29197
- if (FUNCTION_TYPES9.has(current.type)) return false;
29246
+ if (FUNCTION_TYPES8.has(current.type)) return false;
29198
29247
  if (current.type === import_utils164.AST_NODE_TYPES.CallExpression && (factoryName(current, FACTORIES) !== null || factoryName(current, COMPOSITE_FACTORIES) !== null))
29199
29248
  return true;
29200
29249
  }
@@ -31059,7 +31108,7 @@ var prefer_non_nullable_collection_default = createRule({
31059
31108
  const bindingProperty = parameter.properties.find(
31060
31109
  (entry) => entry.type === import_utils174.AST_NODE_TYPES.Property && !entry.computed && import_utils174.ASTUtils.getPropertyName(entry) === property.name
31061
31110
  );
31062
- if (bindingProperty === void 0) continue;
31111
+ if (bindingProperty?.type !== import_utils174.AST_NODE_TYPES.Property) continue;
31063
31112
  const value = bindingProperty.value;
31064
31113
  const binding3 = value.type === import_utils174.AST_NODE_TYPES.AssignmentPattern ? value.left : value;
31065
31114
  if (binding3.type !== import_utils174.AST_NODE_TYPES.Identifier) {
@@ -35872,7 +35921,7 @@ function injectedMembers(owner) {
35872
35921
  const constructor = owner.body.body.find(
35873
35922
  (member3) => member3.type === import_utils191.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor"
35874
35923
  );
35875
- if (constructor === void 0) return injected;
35924
+ if (constructor?.type !== import_utils191.AST_NODE_TYPES.MethodDefinition) return injected;
35876
35925
  const parameters = /* @__PURE__ */ new Set();
35877
35926
  for (const parameter of constructor.value.params) {
35878
35927
  for (const name of parameterNames(parameter)) parameters.add(name);
@@ -38606,6 +38655,7 @@ var RETIRED_RULES = {
38606
38655
 
38607
38656
  // src/index.ts
38608
38657
  var RULES = {
38658
+ "no-explicit-type-predicate": no_explicit_type_predicate_default,
38609
38659
  "prefer-zod-enum-validator": prefer_zod_enum_validator_default,
38610
38660
  "no-growing-array-spread-in-loop": no_growing_array_spread_in_loop_default,
38611
38661
  "no-logical-or-fallback": no_logical_or_fallback_default,
@@ -38788,6 +38838,7 @@ var RULE_POLICY = {
38788
38838
  "@sarj/no-invalid-typed-mutation": ["error", "both"],
38789
38839
  "@sarj/no-contradictory-type-predicate": ["error", "both"],
38790
38840
  "@sarj/no-partial-type-predicate": ["error", "both"],
38841
+ "@sarj/no-explicit-type-predicate": ["warn", "both"],
38791
38842
  "@sarj/no-boolean-selector-parameter": ["warn", "both"],
38792
38843
  "@sarj/no-invalid-zod-custom-parse": ["error", "both"],
38793
38844
  "@sarj/no-contradictory-overload-return": ["error", "both"],