@sarj/eslint-plugin 15.17.9 → 15.17.10
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 +122 -190
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +189 -257
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2406,7 +2406,7 @@ var no_duplicate_lifecycle_refresh_listeners_default = createRule({
|
|
|
2406
2406
|
VariableDeclarator(node) {
|
|
2407
2407
|
if (node.id.type !== AST_NODE_TYPES9.Identifier) return;
|
|
2408
2408
|
const variable = ASTUtils3.findVariable(context.sourceCode.getScope(node.id), node.id.name);
|
|
2409
|
-
if (variable === null) return;
|
|
2409
|
+
if (variable === null || variable.references.some((reference) => reference.isWrite() && !reference.init)) return;
|
|
2410
2410
|
if (node.init?.type === AST_NODE_TYPES9.ArrowFunctionExpression || node.init?.type === AST_NODE_TYPES9.FunctionExpression) {
|
|
2411
2411
|
functionCallbacks.set(node.init, variable);
|
|
2412
2412
|
}
|
|
@@ -2417,7 +2417,7 @@ var no_duplicate_lifecycle_refresh_listeners_default = createRule({
|
|
|
2417
2417
|
FunctionDeclaration(node) {
|
|
2418
2418
|
if (node.id === null) return;
|
|
2419
2419
|
const variable = ASTUtils3.findVariable(context.sourceCode.getScope(node.id), node.id.name);
|
|
2420
|
-
if (variable !== null) functionCallbacks.set(node, variable);
|
|
2420
|
+
if (variable !== null && !variable.references.some((reference) => reference.isWrite() && !reference.init)) functionCallbacks.set(node, variable);
|
|
2421
2421
|
},
|
|
2422
2422
|
CallExpression(node) {
|
|
2423
2423
|
const item = registration(context.sourceCode, node);
|
|
@@ -4434,105 +4434,9 @@ import * as ts from "typescript";
|
|
|
4434
4434
|
import {
|
|
4435
4435
|
AST_NODE_TYPES as AST_NODE_TYPES16
|
|
4436
4436
|
} from "@typescript-eslint/utils";
|
|
4437
|
-
function symbolAt(services, checker, node) {
|
|
4438
|
-
return checker.getSymbolAtLocation(services.esTreeNodeToTSNodeMap.get(node));
|
|
4439
|
-
}
|
|
4440
|
-
function sameSymbol(left, right) {
|
|
4441
|
-
return left !== void 0 && right !== void 0 && left === right;
|
|
4442
|
-
}
|
|
4443
|
-
function enclosingClass(node) {
|
|
4444
|
-
let current = node.parent;
|
|
4445
|
-
while (current !== void 0) {
|
|
4446
|
-
if (current.type === AST_NODE_TYPES16.ClassDeclaration || current.type === AST_NODE_TYPES16.ClassExpression) {
|
|
4447
|
-
return current;
|
|
4448
|
-
}
|
|
4449
|
-
current = current.parent;
|
|
4450
|
-
}
|
|
4451
|
-
return null;
|
|
4452
|
-
}
|
|
4453
4437
|
function memberName2(member) {
|
|
4454
4438
|
return !member.computed && member.key.type === AST_NODE_TYPES16.Identifier ? member.key.name : null;
|
|
4455
4439
|
}
|
|
4456
|
-
function privateMemberFixes(context, services, owner, members, removePrivateKeyword) {
|
|
4457
|
-
const first = members[0];
|
|
4458
|
-
const name = first === void 0 ? null : memberName2(first);
|
|
4459
|
-
if (first === void 0 || name === null || members.some((member) => member.static || member.decorators.length > 0)) {
|
|
4460
|
-
return void 0;
|
|
4461
|
-
}
|
|
4462
|
-
if (owner.body.body.some((member) => {
|
|
4463
|
-
if (member.type !== AST_NODE_TYPES16.MethodDefinition && member.type !== AST_NODE_TYPES16.PropertyDefinition && member.type !== AST_NODE_TYPES16.AccessorProperty) return false;
|
|
4464
|
-
return member.key.type === AST_NODE_TYPES16.PrivateIdentifier && member.key.name === name;
|
|
4465
|
-
})) return void 0;
|
|
4466
|
-
const selectedMembers = new Set(members);
|
|
4467
|
-
if (owner.body.body.some((member) => {
|
|
4468
|
-
if (member.type !== AST_NODE_TYPES16.MethodDefinition && member.type !== AST_NODE_TYPES16.PropertyDefinition && member.type !== AST_NODE_TYPES16.AccessorProperty) return false;
|
|
4469
|
-
return memberName2(member) === name && !selectedMembers.has(member);
|
|
4470
|
-
})) return void 0;
|
|
4471
|
-
const checker = services.program.getTypeChecker();
|
|
4472
|
-
const symbols = members.map((member) => symbolAt(services, checker, member.key)).filter(
|
|
4473
|
-
(symbol) => symbol !== void 0
|
|
4474
|
-
);
|
|
4475
|
-
if (symbols.length === 0) return void 0;
|
|
4476
|
-
const references = [];
|
|
4477
|
-
let unsafe = false;
|
|
4478
|
-
walk(context.sourceCode.ast, context.sourceCode.visitorKeys, (node) => {
|
|
4479
|
-
if (node.type === AST_NODE_TYPES16.Literal && node.value === name) {
|
|
4480
|
-
unsafe = true;
|
|
4481
|
-
return;
|
|
4482
|
-
}
|
|
4483
|
-
if (node.type !== AST_NODE_TYPES16.MemberExpression) return;
|
|
4484
|
-
const propertyName6 = node.property.type === AST_NODE_TYPES16.Identifier || node.property.type === AST_NODE_TYPES16.PrivateIdentifier ? node.property.name : node.property.type === AST_NODE_TYPES16.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
4485
|
-
if (propertyName6 !== name) return;
|
|
4486
|
-
const propertySymbol = symbolAt(services, checker, node.property);
|
|
4487
|
-
if (node.computed || node.property.type !== AST_NODE_TYPES16.Identifier || node.object.type !== AST_NODE_TYPES16.ThisExpression || enclosingClass(node) !== owner || !symbols.some((symbol) => sameSymbol(symbol, propertySymbol))) {
|
|
4488
|
-
unsafe = true;
|
|
4489
|
-
return;
|
|
4490
|
-
}
|
|
4491
|
-
references.push(node);
|
|
4492
|
-
});
|
|
4493
|
-
if (unsafe) return void 0;
|
|
4494
|
-
const privateKeywordRanges = /* @__PURE__ */ new Map();
|
|
4495
|
-
if (removePrivateKeyword) {
|
|
4496
|
-
const comments = context.sourceCode.getAllComments();
|
|
4497
|
-
for (const member of members) {
|
|
4498
|
-
const keyword = context.sourceCode.getTokens(member).find((token) => token.value === "private");
|
|
4499
|
-
const next = keyword === void 0 ? void 0 : context.sourceCode.getTokenAfter(keyword);
|
|
4500
|
-
if (keyword === void 0 || next === null || next === void 0) return void 0;
|
|
4501
|
-
if (comments.some((comment) => comment.range[0] >= keyword.range[1] && comment.range[1] <= next.range[0])) {
|
|
4502
|
-
return void 0;
|
|
4503
|
-
}
|
|
4504
|
-
privateKeywordRanges.set(member, [keyword.range[0], next.range[0]]);
|
|
4505
|
-
}
|
|
4506
|
-
}
|
|
4507
|
-
return (fixer) => {
|
|
4508
|
-
const fixes = [];
|
|
4509
|
-
for (const member of members) {
|
|
4510
|
-
fixes.push(fixer.replaceText(member.key, `#${name}`));
|
|
4511
|
-
if (removePrivateKeyword) {
|
|
4512
|
-
const range = privateKeywordRanges.get(member);
|
|
4513
|
-
if (range === void 0) return [];
|
|
4514
|
-
fixes.push(fixer.removeRange(range));
|
|
4515
|
-
}
|
|
4516
|
-
}
|
|
4517
|
-
for (const reference of references) fixes.push(fixer.replaceText(reference.property, `#${name}`));
|
|
4518
|
-
return fixes;
|
|
4519
|
-
};
|
|
4520
|
-
}
|
|
4521
|
-
function walk(node, visitorKeys, visit) {
|
|
4522
|
-
visit(node);
|
|
4523
|
-
for (const key of visitorKeys[node.type] ?? []) {
|
|
4524
|
-
const child = node[key];
|
|
4525
|
-
if (Array.isArray(child)) {
|
|
4526
|
-
for (const item of child) {
|
|
4527
|
-
if (typeof item === "object" && item !== null && "type" in item) {
|
|
4528
|
-
walk(item, visitorKeys, visit);
|
|
4529
|
-
}
|
|
4530
|
-
}
|
|
4531
|
-
} else if (typeof child === "object" && child !== null && "type" in child) {
|
|
4532
|
-
walk(child, visitorKeys, visit);
|
|
4533
|
-
}
|
|
4534
|
-
}
|
|
4535
|
-
}
|
|
4536
4440
|
function convertibleMemberName(member) {
|
|
4537
4441
|
if (member.type !== AST_NODE_TYPES16.MethodDefinition && member.type !== AST_NODE_TYPES16.PropertyDefinition && member.type !== AST_NODE_TYPES16.AccessorProperty) return null;
|
|
4538
4442
|
return memberName2(member);
|
|
@@ -5337,9 +5241,9 @@ var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
|
|
|
5337
5241
|
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
5338
5242
|
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
5339
5243
|
category: "maintainability",
|
|
5340
|
-
limitations: ["Only
|
|
5244
|
+
limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
|
|
5341
5245
|
examples: [
|
|
5342
|
-
{ id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/order
|
|
5246
|
+
{ id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/parse-order.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/parse-order.ts", expectedCount: 0, public: true },
|
|
5343
5247
|
{ id: "generic-module-name", title: "Do not hide one export in a generic module", outcome: "match", files: [{ path: "src/utils.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/utils.ts", expectedCount: 1, public: true }
|
|
5344
5248
|
]
|
|
5345
5249
|
};
|
|
@@ -5400,6 +5304,7 @@ function runtimeExports(program) {
|
|
|
5400
5304
|
}
|
|
5401
5305
|
if (statement.declaration !== null) {
|
|
5402
5306
|
const declaration = statement.declaration;
|
|
5307
|
+
if (declaration.type === AST_NODE_TYPES22.VariableDeclaration && declaration.declarations.some((item) => item.id.type !== AST_NODE_TYPES22.Identifier)) ambiguous = true;
|
|
5403
5308
|
exports.push(...declaredNames(declaration).map((name) => ({ key: name, name, node: declaration })));
|
|
5404
5309
|
}
|
|
5405
5310
|
for (const specifier of statement.specifiers) {
|
|
@@ -5558,7 +5463,7 @@ var no_offset_pagination_default = createRule({
|
|
|
5558
5463
|
});
|
|
5559
5464
|
|
|
5560
5465
|
// src/rules/no-positional-tuple-return.ts
|
|
5561
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES23 } from "@typescript-eslint/utils";
|
|
5466
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23, ASTUtils as ASTUtils9 } from "@typescript-eslint/utils";
|
|
5562
5467
|
var NO_POSITIONAL_TUPLE_RETURN_DOCUMENTATION = {
|
|
5563
5468
|
summary: "Disallow returning a multi-field tuple from a named function; return a named object so call sites cannot mismatch slots.",
|
|
5564
5469
|
rationale: "Tuple fields are identified only by position, so reordering can preserve types while changing meaning.",
|
|
@@ -5588,7 +5493,7 @@ function tupleReturnType(node, aliases, resolving = /* @__PURE__ */ new Set()) {
|
|
|
5588
5493
|
return argument === void 0 ? null : tupleReturnType(argument, aliases, resolving);
|
|
5589
5494
|
}
|
|
5590
5495
|
if (node.type === AST_NODE_TYPES23.TSTypeReference && node.typeName.type === AST_NODE_TYPES23.Identifier && !resolving.has(node.typeName.name)) {
|
|
5591
|
-
const target = aliases.get(node.typeName
|
|
5496
|
+
const target = aliases.get(node.typeName);
|
|
5592
5497
|
if (target !== void 0) return tupleReturnType(target, aliases, /* @__PURE__ */ new Set([...resolving, node.typeName.name]));
|
|
5593
5498
|
}
|
|
5594
5499
|
if (node.type === AST_NODE_TYPES23.TSTypeOperator && node.operator === "readonly") {
|
|
@@ -5680,20 +5585,27 @@ function exportedTypeNames(program) {
|
|
|
5680
5585
|
}
|
|
5681
5586
|
return names;
|
|
5682
5587
|
}
|
|
5683
|
-
function typeAliases(
|
|
5588
|
+
function typeAliases(sourceCode) {
|
|
5684
5589
|
const aliases = /* @__PURE__ */ new Map();
|
|
5685
|
-
for (const statement of
|
|
5590
|
+
for (const statement of sourceCode.ast.body) {
|
|
5686
5591
|
const declaration = statement.type === AST_NODE_TYPES23.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5687
5592
|
if (declaration?.type === AST_NODE_TYPES23.TSTypeAliasDeclaration) {
|
|
5688
|
-
aliases.set(declaration.id.name, declaration
|
|
5593
|
+
aliases.set(declaration.id.name, declaration);
|
|
5689
5594
|
}
|
|
5690
5595
|
}
|
|
5691
|
-
return
|
|
5596
|
+
return {
|
|
5597
|
+
get(identifier) {
|
|
5598
|
+
const declaration = aliases.get(identifier.name);
|
|
5599
|
+
if (declaration === void 0) return void 0;
|
|
5600
|
+
const binding = ASTUtils9.findVariable(sourceCode.getScope(identifier), identifier.name);
|
|
5601
|
+
return binding?.defs.length === 1 && binding.defs[0]?.node === declaration ? declaration.typeAnnotation : void 0;
|
|
5602
|
+
}
|
|
5603
|
+
};
|
|
5692
5604
|
}
|
|
5693
5605
|
function callableReturnType(node, aliases, resolving = /* @__PURE__ */ new Set()) {
|
|
5694
5606
|
if (node.type === AST_NODE_TYPES23.TSFunctionType) return node.returnType?.typeAnnotation ?? null;
|
|
5695
5607
|
if (node.type === AST_NODE_TYPES23.TSTypeReference && node.typeName.type === AST_NODE_TYPES23.Identifier && !resolving.has(node.typeName.name)) {
|
|
5696
|
-
const target = aliases.get(node.typeName
|
|
5608
|
+
const target = aliases.get(node.typeName);
|
|
5697
5609
|
if (target !== void 0) {
|
|
5698
5610
|
return callableReturnType(target, aliases, /* @__PURE__ */ new Set([...resolving, node.typeName.name]));
|
|
5699
5611
|
}
|
|
@@ -5822,7 +5734,7 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5822
5734
|
context.sourceCode.ast,
|
|
5823
5735
|
exportedTypeNames(context.sourceCode.ast)
|
|
5824
5736
|
);
|
|
5825
|
-
const aliases = typeAliases(context.sourceCode
|
|
5737
|
+
const aliases = typeAliases(context.sourceCode);
|
|
5826
5738
|
const reportedFunctions = /* @__PURE__ */ new WeakSet();
|
|
5827
5739
|
const functionStack = [];
|
|
5828
5740
|
const report2 = (annotation, name) => {
|
|
@@ -5986,7 +5898,7 @@ var no_production_browser_source_maps_default = createRule({
|
|
|
5986
5898
|
});
|
|
5987
5899
|
|
|
5988
5900
|
// src/rules/no-raw-env.ts
|
|
5989
|
-
import { ASTUtils as
|
|
5901
|
+
import { ASTUtils as ASTUtils10 } from "@typescript-eslint/utils";
|
|
5990
5902
|
var NO_RAW_ENV_DOCUMENTATION = {
|
|
5991
5903
|
summary: "Disallow direct `process.env` and `import.meta.env` reads outside validated boundaries.",
|
|
5992
5904
|
rationale: "Raw environment reads are untyped and defer invalid configuration failures until use.",
|
|
@@ -6068,7 +5980,7 @@ var no_raw_env_default = createRule({
|
|
|
6068
5980
|
},
|
|
6069
5981
|
MemberExpression(node) {
|
|
6070
5982
|
if (isProcessEnv(node) && node.object.type === "Identifier") {
|
|
6071
|
-
const binding =
|
|
5983
|
+
const binding = ASTUtils10.findVariable(context.sourceCode.getScope(node), node.object.name);
|
|
6072
5984
|
if (binding !== null && binding.defs.length > 0 && !binding.defs.every((definition) => definition.type === "ImportBinding" && definition.parent.type === "ImportDeclaration" && ["node:process", "process"].includes(definition.parent.source.value) && ["ImportDefaultSpecifier", "ImportNamespaceSpecifier"].includes(definition.node.type))) return;
|
|
6073
5985
|
}
|
|
6074
5986
|
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !isExemptVariableAccess(node) && !isWriteTarget(node) && !isWholeEnvSpread(node)) {
|
|
@@ -6084,7 +5996,7 @@ var no_raw_env_default = createRule({
|
|
|
6084
5996
|
});
|
|
6085
5997
|
|
|
6086
5998
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
6087
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES24, ASTUtils as
|
|
5999
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ASTUtils as ASTUtils11 } from "@typescript-eslint/utils";
|
|
6088
6000
|
var NO_RAW_FETCH_OUTSIDE_CLIENTS_DOCUMENTATION = {
|
|
6089
6001
|
summary: "Disallow calling the global `fetch` outside the client layer; route outbound HTTP through a client module that owns retry, timeout and status handling.",
|
|
6090
6002
|
rationale: "Scattered fetch calls bypass shared transport policy and are harder to stub and observe consistently.",
|
|
@@ -6272,7 +6184,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
6272
6184
|
internalApiPrefixes.push(`${options.basePath}/api`);
|
|
6273
6185
|
}
|
|
6274
6186
|
function resolvesToGlobal(identifier) {
|
|
6275
|
-
const variable =
|
|
6187
|
+
const variable = ASTUtils11.findVariable(
|
|
6276
6188
|
context.sourceCode.getScope(identifier),
|
|
6277
6189
|
identifier.name
|
|
6278
6190
|
);
|
|
@@ -6281,7 +6193,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
6281
6193
|
function resolveNode2(node) {
|
|
6282
6194
|
if (node === void 0) return null;
|
|
6283
6195
|
if (node.type !== AST_NODE_TYPES24.Identifier) return node;
|
|
6284
|
-
const variable =
|
|
6196
|
+
const variable = ASTUtils11.findVariable(
|
|
6285
6197
|
context.sourceCode.getScope(node),
|
|
6286
6198
|
node.name
|
|
6287
6199
|
);
|
|
@@ -6360,13 +6272,13 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
6360
6272
|
});
|
|
6361
6273
|
|
|
6362
6274
|
// src/rules/no-restricted-library-load.ts
|
|
6363
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES25, ASTUtils as
|
|
6275
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ASTUtils as ASTUtils12 } from "@typescript-eslint/utils";
|
|
6364
6276
|
var NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION = {
|
|
6365
|
-
summary: "Apply
|
|
6366
|
-
rationale: "
|
|
6367
|
-
remediation: "
|
|
6277
|
+
summary: "Apply configured library restrictions to literal runtime loads and CommonJS resolution references.",
|
|
6278
|
+
rationale: "Dynamic imports, CommonJS loads, and package resolution checks can bypass library restrictions enforced for static imports.",
|
|
6279
|
+
remediation: "Use the configured replacement for the runtime dependency reference; resolution checks do not themselves load a module.",
|
|
6368
6280
|
category: "architecture",
|
|
6369
|
-
limitations: ["Only literal dynamic imports, unshadowed CommonJS loads, and TypeScript import-equals declarations are checked."],
|
|
6281
|
+
limitations: ["Only literal dynamic imports, unshadowed CommonJS loads/resolution calls, and runtime TypeScript import-equals declarations are checked; erased type imports are excluded. A configured restriction list is required."],
|
|
6370
6282
|
examples: [
|
|
6371
6283
|
{ id: "static-import", title: "Static imports remain the static-import rule's responsibility", outcome: "no-match", files: [{ path: "src/client.ts", source: "import axios from 'axios';" }], focusPath: "src/client.ts", expectedCount: 0, public: true },
|
|
6372
6284
|
{ id: "runtime-load", title: "Do not load a restricted library at runtime", outcome: "match", files: [{ path: "src/client.ts", source: "const client = require('axios');" }], focusPath: "src/client.ts", expectedCount: 1, public: true }
|
|
@@ -6384,7 +6296,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
6384
6296
|
meta: {
|
|
6385
6297
|
type: "problem",
|
|
6386
6298
|
docs: {
|
|
6387
|
-
description:
|
|
6299
|
+
description: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION.summary
|
|
6388
6300
|
},
|
|
6389
6301
|
schema: [
|
|
6390
6302
|
{
|
|
@@ -6410,7 +6322,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
6410
6322
|
}
|
|
6411
6323
|
],
|
|
6412
6324
|
messages: {
|
|
6413
|
-
restrictedLibraryLoad: "{{id}}: Replace runtime
|
|
6325
|
+
restrictedLibraryLoad: "{{id}}: Replace this runtime dependency reference to {{module}} with {{replacement}}.{{note}}"
|
|
6414
6326
|
}
|
|
6415
6327
|
},
|
|
6416
6328
|
defaultOptions: [{ libraries: [] }],
|
|
@@ -6433,7 +6345,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
6433
6345
|
});
|
|
6434
6346
|
}
|
|
6435
6347
|
function isUnshadowedRequire(node) {
|
|
6436
|
-
const variable =
|
|
6348
|
+
const variable = ASTUtils12.findVariable(
|
|
6437
6349
|
context.sourceCode.getScope(node),
|
|
6438
6350
|
node.name
|
|
6439
6351
|
);
|
|
@@ -6456,6 +6368,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
6456
6368
|
if (source !== null) report2(node.arguments[0], source);
|
|
6457
6369
|
},
|
|
6458
6370
|
TSImportEqualsDeclaration(node) {
|
|
6371
|
+
if (node.importKind === "type") return;
|
|
6459
6372
|
if (node.moduleReference.type !== AST_NODE_TYPES25.TSExternalModuleReference) return;
|
|
6460
6373
|
const source = literalModule(node.moduleReference.expression);
|
|
6461
6374
|
if (source !== null) report2(node.moduleReference.expression, source);
|
|
@@ -6465,7 +6378,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
6465
6378
|
});
|
|
6466
6379
|
|
|
6467
6380
|
// src/rules/no-router-refresh-polling.ts
|
|
6468
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES26, ASTUtils as
|
|
6381
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ASTUtils as ASTUtils13 } from "@typescript-eslint/utils";
|
|
6469
6382
|
var NO_ROUTER_REFRESH_POLLING_DOCUMENTATION = {
|
|
6470
6383
|
summary: "Do not poll by calling a Next.js router's refresh method from a timer.",
|
|
6471
6384
|
rationale: "A route refresh refetches and rerenders the whole route on every tick instead of loading the named resource that changed.",
|
|
@@ -6495,7 +6408,7 @@ function isIntervalCallee(sourceCode, node) {
|
|
|
6495
6408
|
return node.type === AST_NODE_TYPES26.Identifier && node.name === "setInterval" && isUnshadowedGlobal2(sourceCode, node) || node.type === AST_NODE_TYPES26.MemberExpression && !node.computed && node.object.type === AST_NODE_TYPES26.Identifier && (node.object.name === "window" || node.object.name === "globalThis") && isUnshadowedGlobal2(sourceCode, node.object) && node.property.type === AST_NODE_TYPES26.Identifier && node.property.name === "setInterval";
|
|
6496
6409
|
}
|
|
6497
6410
|
function isUnshadowedGlobal2(sourceCode, node) {
|
|
6498
|
-
const variable =
|
|
6411
|
+
const variable = ASTUtils13.findVariable(sourceCode.getScope(node), node.name);
|
|
6499
6412
|
return variable === null || variable.defs.length === 0;
|
|
6500
6413
|
}
|
|
6501
6414
|
var no_router_refresh_polling_default = createRule({
|
|
@@ -6518,21 +6431,21 @@ var no_router_refresh_polling_default = createRule({
|
|
|
6518
6431
|
if (node.source.value !== "next/navigation") return;
|
|
6519
6432
|
for (const specifier of node.specifiers) {
|
|
6520
6433
|
if (specifier.type === AST_NODE_TYPES26.ImportSpecifier && importedName4(specifier) === "useRouter") {
|
|
6521
|
-
const variable =
|
|
6434
|
+
const variable = ASTUtils13.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
6522
6435
|
if (variable !== null) routerHooks.add(variable);
|
|
6523
6436
|
}
|
|
6524
6437
|
}
|
|
6525
6438
|
},
|
|
6526
6439
|
VariableDeclarator(node) {
|
|
6527
6440
|
if (node.id.type === AST_NODE_TYPES26.Identifier && node.init?.type === AST_NODE_TYPES26.CallExpression && node.init.callee.type === AST_NODE_TYPES26.Identifier) {
|
|
6528
|
-
const hook =
|
|
6529
|
-
const router =
|
|
6441
|
+
const hook = ASTUtils13.findVariable(context.sourceCode.getScope(node.init.callee), node.init.callee.name);
|
|
6442
|
+
const router = ASTUtils13.findVariable(context.sourceCode.getScope(node.id), node.id.name);
|
|
6530
6443
|
if (hook !== null && router !== null && routerHooks.has(hook)) routers.add(router);
|
|
6531
6444
|
}
|
|
6532
6445
|
},
|
|
6533
6446
|
CallExpression(node) {
|
|
6534
6447
|
if (node.callee.type !== AST_NODE_TYPES26.MemberExpression || node.callee.computed || node.callee.object.type !== AST_NODE_TYPES26.Identifier || node.callee.property.type !== AST_NODE_TYPES26.Identifier || node.callee.property.name !== "refresh") return;
|
|
6535
|
-
const router =
|
|
6448
|
+
const router = ASTUtils13.findVariable(
|
|
6536
6449
|
context.sourceCode.getScope(node.callee.object),
|
|
6537
6450
|
node.callee.object.name
|
|
6538
6451
|
);
|
|
@@ -7590,13 +7503,13 @@ var no_select_star_default = createRule({
|
|
|
7590
7503
|
});
|
|
7591
7504
|
|
|
7592
7505
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
7593
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES30 } from "@typescript-eslint/utils";
|
|
7506
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES30, ASTUtils as ASTUtils14 } from "@typescript-eslint/utils";
|
|
7594
7507
|
var NO_SENTINEL_RETURN_ON_CATCH_DOCUMENTATION = {
|
|
7595
7508
|
summary: "Disallow swallowing a caught error by returning an empty sentinel unless the error is handled or the sentinel is part of the function contract.",
|
|
7596
7509
|
rationale: "An unreported fallback makes operational failure indistinguishable from a legitimate empty result.",
|
|
7597
7510
|
remediation: "Rethrow, report the error before returning, or model expected absence with an explicit predicate, safe-parse, or result contract.",
|
|
7598
7511
|
category: "correctness",
|
|
7599
|
-
limitations: ["Recognized predicate, safe-parse, normal-path sentinel, deliberate parse, generated-client, and configured logging patterns are excluded."],
|
|
7512
|
+
limitations: ["Recognized predicate, safe-parse, normal-path sentinel, deliberate parse, generated-client, and configured logging patterns are excluded. Locally shadowed undefined bindings are not treated as sentinels; recognized handling patterns are not a proof that every control-flow path handles the error."],
|
|
7600
7513
|
examples: [
|
|
7601
7514
|
{ id: "reported-fallback", title: "Report an error before returning a fallback", outcome: "no-match", files: [{ path: "src/load.ts", source: "function load() { try { return read(); } catch (error) { logger.warn('load failed', error); return null; } }" }], focusPath: "src/load.ts", expectedCount: 0, public: true },
|
|
7602
7515
|
{ id: "silent-fallback", title: "Do not turn an unreported error into absence", outcome: "match", files: [{ path: "src/load.ts", source: "function load() { try { return read(); } catch { return null; } }" }], focusPath: "src/load.ts", expectedCount: 1, public: true }
|
|
@@ -8011,6 +7924,8 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
8011
7924
|
if (!isSentinelArgument(last.argument)) {
|
|
8012
7925
|
return;
|
|
8013
7926
|
}
|
|
7927
|
+
const returned = unwrapSentinelExpression(last.argument);
|
|
7928
|
+
if (returned?.type === AST_NODE_TYPES30.Identifier && returned.name === "undefined" && (ASTUtils14.findVariable(context.sourceCode.getScope(returned), returned.name)?.defs.length ?? 0) > 0) return;
|
|
8014
7929
|
if (containsThrow(node.body)) {
|
|
8015
7930
|
return;
|
|
8016
7931
|
}
|
|
@@ -8460,12 +8375,13 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
8460
8375
|
// src/rules/no-string-concat-in-loop.ts
|
|
8461
8376
|
import "@typescript-eslint/utils";
|
|
8462
8377
|
var NO_STRING_CONCAT_IN_LOOP_DOCUMENTATION = {
|
|
8463
|
-
summary: "
|
|
8378
|
+
summary: "Prefer collecting string fragments over repeatedly accumulating a growing string inside a loop.",
|
|
8464
8379
|
rationale: "Repeatedly rebuilding a growing string can copy all prior content on each iteration, making total work grow quadratically.",
|
|
8465
|
-
remediation: "
|
|
8380
|
+
remediation: "Consider collecting fragments and joining once; preserve intermediate observations and coercion timing, and measure hot paths.",
|
|
8466
8381
|
category: "performance",
|
|
8467
8382
|
limitations: [
|
|
8468
|
-
"Only local identifiers initialized with a string or template literal and accumulated in a loop body are inspected."
|
|
8383
|
+
"Only local identifiers initialized with a string or template literal and accumulated in a loop body are inspected.",
|
|
8384
|
+
"Deferred function bodies are excluded except recognized direct forEach callbacks. Syntax does not establish engine-specific string allocation complexity."
|
|
8469
8385
|
],
|
|
8470
8386
|
examples: [
|
|
8471
8387
|
{
|
|
@@ -8583,6 +8499,7 @@ function enclosingLoop(node) {
|
|
|
8583
8499
|
if ((parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression") && parent.parent.type === "CallExpression" && parent.parent.arguments[0] === parent && parent.parent.callee.type === "MemberExpression" && !parent.parent.callee.computed && parent.parent.callee.property.type === "Identifier" && parent.parent.callee.property.name === "forEach") {
|
|
8584
8500
|
return parent.parent;
|
|
8585
8501
|
}
|
|
8502
|
+
if (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") return null;
|
|
8586
8503
|
if (LOOP_NODE_TYPES.has(parent.type)) {
|
|
8587
8504
|
const loop = parent;
|
|
8588
8505
|
if (loop.body === child) {
|
|
@@ -8594,6 +8511,19 @@ function enclosingLoop(node) {
|
|
|
8594
8511
|
}
|
|
8595
8512
|
return null;
|
|
8596
8513
|
}
|
|
8514
|
+
function immediatelyExitsLoop(node, loop) {
|
|
8515
|
+
if (!LOOP_NODE_TYPES.has(loop.type) || node.parent.type !== "ExpressionStatement") return false;
|
|
8516
|
+
const statement = node.parent;
|
|
8517
|
+
const block = statement.parent;
|
|
8518
|
+
if (block.type !== "BlockStatement") return false;
|
|
8519
|
+
const next = block.body[block.body.indexOf(statement) + 1];
|
|
8520
|
+
if (next?.type !== "BreakStatement" && next?.type !== "ReturnStatement" && next?.type !== "ThrowStatement") return false;
|
|
8521
|
+
if (next.type === "BreakStatement" && next.label !== null) return false;
|
|
8522
|
+
for (let current = block; current !== void 0 && current !== loop; current = current.parent) {
|
|
8523
|
+
if (current.type === "TryStatement" || next.type === "BreakStatement" && current.type === "SwitchStatement") return false;
|
|
8524
|
+
}
|
|
8525
|
+
return true;
|
|
8526
|
+
}
|
|
8597
8527
|
function isSmallStaticForLoop(node) {
|
|
8598
8528
|
if (node.type !== "ForStatement" || node.init?.type !== "VariableDeclaration" || node.init.declarations.length !== 1 || node.test?.type !== "BinaryExpression" || node.test.operator !== "<" && node.test.operator !== "<=" || node.update?.type !== "UpdateExpression" || node.update.operator !== "++") {
|
|
8599
8529
|
return false;
|
|
@@ -8632,12 +8562,12 @@ var no_string_concat_in_loop_default = createRule({
|
|
|
8632
8562
|
meta: {
|
|
8633
8563
|
type: "suggestion",
|
|
8634
8564
|
docs: {
|
|
8635
|
-
description:
|
|
8565
|
+
description: NO_STRING_CONCAT_IN_LOOP_DOCUMENTATION.summary
|
|
8636
8566
|
},
|
|
8637
8567
|
schema: [],
|
|
8638
8568
|
messages: {
|
|
8639
|
-
noStringConcatInLoop:
|
|
8640
|
-
noStringReduce: "
|
|
8569
|
+
noStringConcatInLoop: "This loop repeatedly accumulates a growing string. Consider collecting fragments and joining once; preserve coercion timing and intermediate reads, and measure performance-sensitive paths.",
|
|
8570
|
+
noStringReduce: "This reduce repeatedly accumulates a growing string. Consider mapping fragments and joining once if coercion timing and intermediate observations are unchanged."
|
|
8641
8571
|
}
|
|
8642
8572
|
},
|
|
8643
8573
|
defaultOptions: [],
|
|
@@ -8664,6 +8594,7 @@ var no_string_concat_in_loop_default = createRule({
|
|
|
8664
8594
|
if (loop === null) {
|
|
8665
8595
|
return;
|
|
8666
8596
|
}
|
|
8597
|
+
if (immediatelyExitsLoop(node, loop)) return;
|
|
8667
8598
|
if (isSmallStaticForLoop(loop)) {
|
|
8668
8599
|
return;
|
|
8669
8600
|
}
|
|
@@ -10037,7 +9968,7 @@ var no_unnecessary_use_client_default = createRule({
|
|
|
10037
9968
|
// src/rules/no-unsafe-mock-casting.ts
|
|
10038
9969
|
import {
|
|
10039
9970
|
AST_NODE_TYPES as AST_NODE_TYPES40,
|
|
10040
|
-
ASTUtils as
|
|
9971
|
+
ASTUtils as ASTUtils15
|
|
10041
9972
|
} from "@typescript-eslint/utils";
|
|
10042
9973
|
var MOCK_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
10043
9974
|
"Mock",
|
|
@@ -10103,7 +10034,7 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
10103
10034
|
const directBindings = /* @__PURE__ */ new Set();
|
|
10104
10035
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
10105
10036
|
function resolve2(identifier) {
|
|
10106
|
-
return
|
|
10037
|
+
return ASTUtils15.findVariable(
|
|
10107
10038
|
context.sourceCode.getScope(identifier),
|
|
10108
10039
|
identifier.name
|
|
10109
10040
|
);
|
|
@@ -10153,7 +10084,7 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
10153
10084
|
import {
|
|
10154
10085
|
ESLintUtils as ESLintUtils3,
|
|
10155
10086
|
AST_NODE_TYPES as AST_NODE_TYPES41,
|
|
10156
|
-
ASTUtils as
|
|
10087
|
+
ASTUtils as ASTUtils16
|
|
10157
10088
|
} from "@typescript-eslint/utils";
|
|
10158
10089
|
import * as ts2 from "typescript";
|
|
10159
10090
|
var NO_ZOD_NATIVE_ENUM_DOCUMENTATION = {
|
|
@@ -10263,7 +10194,7 @@ var no_zod_native_enum_default = createRule({
|
|
|
10263
10194
|
const zodImportedBindings = /* @__PURE__ */ new Map();
|
|
10264
10195
|
const zodNamespaceBindings = /* @__PURE__ */ new Set();
|
|
10265
10196
|
function resolvedBinding(identifier) {
|
|
10266
|
-
return
|
|
10197
|
+
return ASTUtils16.findVariable(
|
|
10267
10198
|
sourceCode.getScope(identifier),
|
|
10268
10199
|
identifier.name
|
|
10269
10200
|
);
|
|
@@ -10329,7 +10260,7 @@ var no_zod_native_enum_default = createRule({
|
|
|
10329
10260
|
});
|
|
10330
10261
|
|
|
10331
10262
|
// src/rules/test-loops-over-literal-cases.ts
|
|
10332
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES42, ASTUtils as
|
|
10263
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES42, ASTUtils as ASTUtils17 } from "@typescript-eslint/utils";
|
|
10333
10264
|
var TEST_LOOPS_OVER_LITERAL_CASES_DOCUMENTATION = {
|
|
10334
10265
|
summary: "Disallow assertions over an inline literal case loop in a test; parameterization reports and names every case independently.",
|
|
10335
10266
|
rationale: "A loop is reported as one test, so failures hide the individual case name and may stop later cases from running.",
|
|
@@ -10492,7 +10423,7 @@ var test_loops_over_literal_cases_default = createRule({
|
|
|
10492
10423
|
return {};
|
|
10493
10424
|
}
|
|
10494
10425
|
const isFrameworkIdentifier = (identifier, modules) => {
|
|
10495
|
-
const variable =
|
|
10426
|
+
const variable = ASTUtils17.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
10496
10427
|
if (variable === null || variable.defs.length === 0) return true;
|
|
10497
10428
|
return variable.defs.some((definition) => {
|
|
10498
10429
|
let current = definition.node;
|
|
@@ -10740,13 +10671,12 @@ import {
|
|
|
10740
10671
|
var PREFER_ECMASCRIPT_PRIVATE_MEMBERS_DOCUMENTATION = {
|
|
10741
10672
|
summary: "Prefer ECMAScript `#private` class members over TypeScript-only `private` members.",
|
|
10742
10673
|
rationale: "ECMAScript private names enforce encapsulation at runtime instead of erasing the boundary during compilation.",
|
|
10743
|
-
remediation: "
|
|
10674
|
+
remediation: "Review reflection, instance escape and framework contracts before replacing TypeScript privacy with ECMAScript private names and updating references.",
|
|
10744
10675
|
category: "maintainability",
|
|
10745
|
-
autofix: "
|
|
10676
|
+
autofix: "none",
|
|
10746
10677
|
limitations: [
|
|
10747
10678
|
"Ambient, abstract, computed, decorated, override, parameter-property, and generated declarations are excluded.",
|
|
10748
|
-
"
|
|
10749
|
-
"Overloads, modifier-adjacent comments, reflection, and any potentially cross-file or escaping class remain report-only."
|
|
10679
|
+
"Migration is report-only: type information cannot prove that instances or constructors never escape through this, or that reflection and framework serialization do not observe ordinary private properties."
|
|
10750
10680
|
],
|
|
10751
10681
|
references: ["https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_elements"],
|
|
10752
10682
|
examples: [
|
|
@@ -10766,19 +10696,11 @@ var PREFER_ECMASCRIPT_PRIVATE_MEMBERS_DOCUMENTATION = {
|
|
|
10766
10696
|
files: [{ path: "src/vault.ts", source: "class Vault { private read() { return 1; } open() { return this.read(); } }" }],
|
|
10767
10697
|
focusPath: "src/vault.ts",
|
|
10768
10698
|
expectedCount: 1,
|
|
10769
|
-
public: true
|
|
10770
|
-
fixedFiles: [{ path: "src/vault.ts", source: "class Vault { #read() { return 1; } open() { return this.#read(); } }" }]
|
|
10699
|
+
public: true
|
|
10771
10700
|
}
|
|
10772
10701
|
]
|
|
10773
10702
|
};
|
|
10774
|
-
function reportClass2(context,
|
|
10775
|
-
const parent = owner.parent;
|
|
10776
|
-
const directlyExported = parent.type === AST_NODE_TYPES45.ExportNamedDeclaration || parent.type === AST_NODE_TYPES45.ExportDefaultDeclaration;
|
|
10777
|
-
const locallyClosed = !directlyExported && owner.decorators.length === 0 && owner.type === AST_NODE_TYPES45.ClassDeclaration && context.sourceCode.getDeclaredVariables(owner).every(
|
|
10778
|
-
(variable) => variable.references.every(
|
|
10779
|
-
(reference) => reference.identifier.range[0] >= owner.range[0] && reference.identifier.range[1] <= owner.range[1]
|
|
10780
|
-
)
|
|
10781
|
-
);
|
|
10703
|
+
function reportClass2(context, owner) {
|
|
10782
10704
|
const groups = /* @__PURE__ */ new Map();
|
|
10783
10705
|
for (const member of owner.body.body) {
|
|
10784
10706
|
if (!isConvertible(member)) continue;
|
|
@@ -10791,18 +10713,10 @@ function reportClass2(context, services, owner) {
|
|
|
10791
10713
|
for (const [name, members] of groups) {
|
|
10792
10714
|
const first = members[0];
|
|
10793
10715
|
if (first === void 0) continue;
|
|
10794
|
-
const fix = locallyClosed ? privateMemberFixes(
|
|
10795
|
-
context,
|
|
10796
|
-
services,
|
|
10797
|
-
owner,
|
|
10798
|
-
members,
|
|
10799
|
-
true
|
|
10800
|
-
) : void 0;
|
|
10801
10716
|
context.report({
|
|
10802
10717
|
node: first.key,
|
|
10803
10718
|
messageId: "preferEcmascriptPrivate",
|
|
10804
|
-
data: { name }
|
|
10805
|
-
...fix === void 0 ? {} : { fix }
|
|
10719
|
+
data: { name }
|
|
10806
10720
|
});
|
|
10807
10721
|
}
|
|
10808
10722
|
}
|
|
@@ -10816,7 +10730,6 @@ var prefer_ecmascript_private_members_default = createRule({
|
|
|
10816
10730
|
meta: {
|
|
10817
10731
|
type: "suggestion",
|
|
10818
10732
|
docs: { description: "Prefer ECMAScript `#private` class members over TypeScript-only `private` members." },
|
|
10819
|
-
fixable: "code",
|
|
10820
10733
|
schema: [],
|
|
10821
10734
|
messages: {
|
|
10822
10735
|
preferEcmascriptPrivate: "TypeScript `private {{name}}` is erased at runtime; use the ECMAScript private name `#{{name}}`."
|
|
@@ -10833,8 +10746,8 @@ var prefer_ecmascript_private_members_default = createRule({
|
|
|
10833
10746
|
}
|
|
10834
10747
|
if (services === null) return {};
|
|
10835
10748
|
return {
|
|
10836
|
-
ClassDeclaration: (node) => reportClass2(context,
|
|
10837
|
-
ClassExpression: (node) => reportClass2(context,
|
|
10749
|
+
ClassDeclaration: (node) => reportClass2(context, node),
|
|
10750
|
+
ClassExpression: (node) => reportClass2(context, node)
|
|
10838
10751
|
};
|
|
10839
10752
|
}
|
|
10840
10753
|
});
|
|
@@ -10844,10 +10757,10 @@ import "@typescript-eslint/utils";
|
|
|
10844
10757
|
import { AST_NODE_TYPES as AST_NODE_TYPES46 } from "@typescript-eslint/utils";
|
|
10845
10758
|
var PREFER_DISCRIMINATED_UNION_DOCUMENTATION = {
|
|
10846
10759
|
summary: "Flag flat result objects with a required positive boolean status and optional success/failure payloads.",
|
|
10847
|
-
rationale: "
|
|
10848
|
-
remediation: "
|
|
10760
|
+
rationale: "When success and failure are mutually exclusive outcomes, a boolean plus optional branch data permits contradictory and incomplete states.",
|
|
10761
|
+
remediation: "If the outcomes are mutually exclusive, represent each branch as a discriminated union member with its required payload.",
|
|
10849
10762
|
category: "correctness",
|
|
10850
|
-
limitations: ["Only local object shapes with recognized
|
|
10763
|
+
limitations: ["Only local object shapes with recognized non-computed status and payload names are inspected. Names do not prove that partial-success outcomes are forbidden; review the domain before changing its representation."],
|
|
10851
10764
|
examples: [
|
|
10852
10765
|
{ id: "explicit-result-branches", title: "Use explicit result branches", outcome: "no-match", files: [{ path: "src/result.ts", source: "type Result = { ok: true; data: string } | { ok: false; error: string };" }], focusPath: "src/result.ts", expectedCount: 0, public: true },
|
|
10853
10766
|
{ id: "optional-result-payloads", title: "Do not make both result payloads optional", outcome: "match", files: [{ path: "src/result.ts", source: "type Result = { ok: boolean; data?: string; error?: string };" }], focusPath: "src/result.ts", expectedCount: 1, public: true }
|
|
@@ -10911,7 +10824,7 @@ function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
|
10911
10824
|
return statusMemberCount === REQUIRED_STATUS_MEMBER_COUNT && hasFailurePayload && (hasSuccessPayload || !hasUnrecognizedMember);
|
|
10912
10825
|
}
|
|
10913
10826
|
function getMemberName(member) {
|
|
10914
|
-
if (member.type !== AST_NODE_TYPES46.TSPropertySignature) {
|
|
10827
|
+
if (member.type !== AST_NODE_TYPES46.TSPropertySignature || member.computed) {
|
|
10915
10828
|
return null;
|
|
10916
10829
|
}
|
|
10917
10830
|
const { key } = member;
|
|
@@ -10947,7 +10860,7 @@ var prefer_discriminated_union_default = createRule({
|
|
|
10947
10860
|
},
|
|
10948
10861
|
schema: [],
|
|
10949
10862
|
messages: {
|
|
10950
|
-
preferDiscriminatedUnion: "This object type
|
|
10863
|
+
preferDiscriminatedUnion: "This object type combines a boolean status with optional payloads. If success and failure are mutually exclusive, consider a discriminated union such as `{ ok: true; data: T } | { ok: false; error: E }`."
|
|
10951
10864
|
}
|
|
10952
10865
|
},
|
|
10953
10866
|
defaultOptions: [],
|
|
@@ -10987,7 +10900,7 @@ var prefer_discriminated_union_default = createRule({
|
|
|
10987
10900
|
});
|
|
10988
10901
|
|
|
10989
10902
|
// src/rules/prefer-input-group-search.ts
|
|
10990
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES47, ASTUtils as
|
|
10903
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES47, ASTUtils as ASTUtils18 } from "@typescript-eslint/utils";
|
|
10991
10904
|
var PREFER_INPUT_GROUP_SEARCH_DOCUMENTATION = {
|
|
10992
10905
|
summary: "Require search icons and shared Input controls in the same visual wrapper to use InputGroup.",
|
|
10993
10906
|
rationale: "The shared compound control provides consistent spacing, focus behavior, and accessible composition.",
|
|
@@ -11111,7 +11024,7 @@ var prefer_input_group_search_default = createRule({
|
|
|
11111
11024
|
JSXOpeningElement(node) {
|
|
11112
11025
|
const name = elementName(node);
|
|
11113
11026
|
if (name === null) return;
|
|
11114
|
-
const binding =
|
|
11027
|
+
const binding = ASTUtils18.findVariable(context.sourceCode.getScope(node), name);
|
|
11115
11028
|
if (binding?.defs.length !== 1 || binding.defs[0]?.node.type !== AST_NODE_TYPES47.ImportSpecifier || binding.defs[0].node.importKind === "type") return;
|
|
11116
11029
|
const occurrence = {
|
|
11117
11030
|
ancestors: context.sourceCode.getAncestors(node),
|
|
@@ -11151,7 +11064,7 @@ var prefer_input_group_search_default = createRule({
|
|
|
11151
11064
|
|
|
11152
11065
|
// src/rules/prefer-millisecond-control-duration-schema.ts
|
|
11153
11066
|
import {
|
|
11154
|
-
ASTUtils as
|
|
11067
|
+
ASTUtils as ASTUtils19,
|
|
11155
11068
|
AST_NODE_TYPES as AST_NODE_TYPES48
|
|
11156
11069
|
} from "@typescript-eslint/utils";
|
|
11157
11070
|
var PREFER_MILLISECOND_CONTROL_DURATION_SCHEMA_DOCUMENTATION = {
|
|
@@ -11220,7 +11133,7 @@ var prefer_millisecond_control_duration_schema_default = createRule({
|
|
|
11220
11133
|
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
11221
11134
|
const objectFactories = /* @__PURE__ */ new Set();
|
|
11222
11135
|
function binding(identifier) {
|
|
11223
|
-
return
|
|
11136
|
+
return ASTUtils19.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
11224
11137
|
}
|
|
11225
11138
|
function record(target, identifier) {
|
|
11226
11139
|
const variable = binding(identifier);
|
|
@@ -11267,7 +11180,7 @@ var prefer_millisecond_control_duration_schema_default = createRule({
|
|
|
11267
11180
|
});
|
|
11268
11181
|
|
|
11269
11182
|
// src/rules/prefer-immutable-module-constant.ts
|
|
11270
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES49, ASTUtils as
|
|
11183
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES49, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
|
|
11271
11184
|
var PREFER_IMMUTABLE_MODULE_CONSTANT_DOCUMENTATION = {
|
|
11272
11185
|
summary: "Require module-level constant collections to expose readonly state.",
|
|
11273
11186
|
rationale: "A const binding prevents reassignment but does not stop callers from mutating its array, object, Set, or Map contents.",
|
|
@@ -11420,7 +11333,7 @@ var prefer_immutable_module_constant_default = createRule({
|
|
|
11420
11333
|
create(context) {
|
|
11421
11334
|
const sourceCode = context.sourceCode;
|
|
11422
11335
|
const isUnshadowedGlobal3 = (identifier) => {
|
|
11423
|
-
const variable =
|
|
11336
|
+
const variable = ASTUtils20.findVariable(sourceCode.getScope(identifier), identifier.name);
|
|
11424
11337
|
return variable === null || variable.defs.length === 0;
|
|
11425
11338
|
};
|
|
11426
11339
|
if (JAVASCRIPT_FILE_RE.test(context.filename) || isTestFile(context.filename) || isGeneratedFile(context.filename, sourceCode.getText())) {
|
|
@@ -12579,7 +12492,7 @@ var prefer_module_level_schema_default = createRule({
|
|
|
12579
12492
|
// src/rules/prefer-module-level-refined-schema.ts
|
|
12580
12493
|
import {
|
|
12581
12494
|
AST_NODE_TYPES as AST_NODE_TYPES53,
|
|
12582
|
-
ASTUtils as
|
|
12495
|
+
ASTUtils as ASTUtils21
|
|
12583
12496
|
} from "@typescript-eslint/utils";
|
|
12584
12497
|
var BENCHMARK_PATH_RE = /(^|[/\\])(?:benchmarks?|bench)[/\\]/;
|
|
12585
12498
|
var FACTORIES = /* @__PURE__ */ new Set([
|
|
@@ -12850,7 +12763,7 @@ var prefer_module_level_refined_schema_default = createRule({
|
|
|
12850
12763
|
return {};
|
|
12851
12764
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
12852
12765
|
function resolvedBinding(identifier) {
|
|
12853
|
-
return
|
|
12766
|
+
return ASTUtils21.findVariable(
|
|
12854
12767
|
context.sourceCode.getScope(identifier),
|
|
12855
12768
|
identifier.name
|
|
12856
12769
|
);
|
|
@@ -12951,7 +12864,7 @@ var prefer_module_level_refined_schema_default = createRule({
|
|
|
12951
12864
|
// src/rules/prefer-multi-value-zod-literal.ts
|
|
12952
12865
|
import {
|
|
12953
12866
|
AST_NODE_TYPES as AST_NODE_TYPES54,
|
|
12954
|
-
ASTUtils as
|
|
12867
|
+
ASTUtils as ASTUtils22
|
|
12955
12868
|
} from "@typescript-eslint/utils";
|
|
12956
12869
|
var PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION = {
|
|
12957
12870
|
summary: "Use the Zod 4 multi-value literal API instead of a union of literal schemas.",
|
|
@@ -12998,7 +12911,7 @@ function isStaticPrimitive(node, context) {
|
|
|
12998
12911
|
if (node.type === AST_NODE_TYPES54.TemplateLiteral && node.expressions.length === 0)
|
|
12999
12912
|
return true;
|
|
13000
12913
|
if (node.type === AST_NODE_TYPES54.Identifier && node.name === "undefined") {
|
|
13001
|
-
const binding =
|
|
12914
|
+
const binding = ASTUtils22.findVariable(
|
|
13002
12915
|
context.sourceCode.getScope(node),
|
|
13003
12916
|
node.name
|
|
13004
12917
|
);
|
|
@@ -13035,7 +12948,7 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
13035
12948
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
13036
12949
|
const zod4Bindings = /* @__PURE__ */ new Set();
|
|
13037
12950
|
function resolvedBinding(identifier) {
|
|
13038
|
-
return
|
|
12951
|
+
return ASTUtils22.findVariable(
|
|
13039
12952
|
context.sourceCode.getScope(identifier),
|
|
13040
12953
|
identifier.name
|
|
13041
12954
|
);
|
|
@@ -13106,7 +13019,7 @@ function isLiteralUnion(node) {
|
|
|
13106
13019
|
function exportedContract(node) {
|
|
13107
13020
|
let current = node;
|
|
13108
13021
|
while (current !== void 0) {
|
|
13109
|
-
if (current.type === AST_NODE_TYPES55.
|
|
13022
|
+
if (current.type === AST_NODE_TYPES55.TSTypeAliasDeclaration || current.type === AST_NODE_TYPES55.TSInterfaceDeclaration) return current.parent.type === AST_NODE_TYPES55.ExportNamedDeclaration;
|
|
13110
13023
|
if (current.type === AST_NODE_TYPES55.Program) return false;
|
|
13111
13024
|
current = current.parent ?? void 0;
|
|
13112
13025
|
}
|
|
@@ -13197,14 +13110,14 @@ var prefer_named_complex_return_type_default = createRule({
|
|
|
13197
13110
|
});
|
|
13198
13111
|
|
|
13199
13112
|
// src/rules/prefer-native-random-uuid.ts
|
|
13200
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES57, ASTUtils as
|
|
13113
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES57, ASTUtils as ASTUtils23 } from "@typescript-eslint/utils";
|
|
13201
13114
|
var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
|
|
13202
13115
|
summary: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
|
|
13203
13116
|
rationale: "The platform implementation avoids an unnecessary dependency for standard random UUID generation.",
|
|
13204
13117
|
remediation: "Call `globalThis.crypto.randomUUID()` and remove the unused `uuid` v4 import when possible.",
|
|
13205
13118
|
category: "maintainability",
|
|
13206
13119
|
autofix: "suggestion",
|
|
13207
|
-
limitations: ["Only resolved zero-argument UUID v4 calls are reported; customized and other UUID versions are excluded."],
|
|
13120
|
+
limitations: ["Only resolved zero-argument UUID v4 calls are reported; customized and other UUID versions are excluded. Suggestions require unshadowed globalThis and comment-free calls; verify native randomUUID availability in the deployment runtime."],
|
|
13208
13121
|
examples: [
|
|
13209
13122
|
{ id: "native-random-uuid", title: "Use the platform UUID generator", outcome: "no-match", files: [{ path: "src/id.ts", source: "const id = globalThis.crypto.randomUUID();" }], focusPath: "src/id.ts", expectedCount: 0, public: true },
|
|
13210
13123
|
{ id: "uuid-v4-package", title: "Do not call uuid v4 without options", outcome: "match", files: [{ path: "src/id.ts", source: "import { v4 } from 'uuid'; const id = v4();" }], focusPath: "src/id.ts", expectedCount: 1, public: true }
|
|
@@ -13224,7 +13137,7 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
13224
13137
|
hasSuggestions: true,
|
|
13225
13138
|
schema: [],
|
|
13226
13139
|
messages: {
|
|
13227
|
-
preferNative: "
|
|
13140
|
+
preferNative: "Where supported by the deployment runtime, prefer native `globalThis.crypto.randomUUID()` over the `uuid` package for UUID v4.",
|
|
13228
13141
|
replaceWithNative: "Replace this UUID v4 call with the native implementation."
|
|
13229
13142
|
}
|
|
13230
13143
|
},
|
|
@@ -13233,22 +13146,24 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
13233
13146
|
const directBindings = /* @__PURE__ */ new Set();
|
|
13234
13147
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
13235
13148
|
function resolve2(identifier) {
|
|
13236
|
-
return
|
|
13149
|
+
return ASTUtils23.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
13237
13150
|
}
|
|
13238
13151
|
function record(identifier, destination) {
|
|
13239
13152
|
const variable = resolve2(identifier);
|
|
13240
13153
|
if (variable !== null) destination.add(variable);
|
|
13241
13154
|
}
|
|
13242
13155
|
function report2(node) {
|
|
13156
|
+
const globalBinding = ASTUtils23.findVariable(context.sourceCode.getScope(node), "globalThis");
|
|
13157
|
+
const canSuggest = (globalBinding?.defs.length ?? 0) === 0 && context.sourceCode.getCommentsInside(node).length === 0;
|
|
13243
13158
|
context.report({
|
|
13244
13159
|
node,
|
|
13245
13160
|
messageId: "preferNative",
|
|
13246
|
-
suggest: [
|
|
13161
|
+
suggest: canSuggest ? [
|
|
13247
13162
|
{
|
|
13248
13163
|
messageId: "replaceWithNative",
|
|
13249
13164
|
fix: (fixer) => fixer.replaceText(node, "globalThis.crypto.randomUUID()")
|
|
13250
13165
|
}
|
|
13251
|
-
]
|
|
13166
|
+
] : []
|
|
13252
13167
|
});
|
|
13253
13168
|
}
|
|
13254
13169
|
return {
|
|
@@ -13296,7 +13211,7 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
13296
13211
|
});
|
|
13297
13212
|
|
|
13298
13213
|
// src/rules/prefer-node-crypto-hash.ts
|
|
13299
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES58, ASTUtils as
|
|
13214
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES58, ASTUtils as ASTUtils24 } from "@typescript-eslint/utils";
|
|
13300
13215
|
var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
|
|
13301
13216
|
summary: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
|
|
13302
13217
|
rationale: "A createHash-update-digest chain allocates mutable streaming state for a single in-memory value; Node's built-in hash function expresses the one-shot operation directly and can use its optimized fast path.",
|
|
@@ -13352,7 +13267,7 @@ var prefer_node_crypto_hash_default = createRule({
|
|
|
13352
13267
|
const directBindings = /* @__PURE__ */ new Set();
|
|
13353
13268
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
13354
13269
|
function resolve2(identifier) {
|
|
13355
|
-
return
|
|
13270
|
+
return ASTUtils24.findVariable(
|
|
13356
13271
|
context.sourceCode.getScope(identifier),
|
|
13357
13272
|
identifier.name
|
|
13358
13273
|
);
|
|
@@ -13539,7 +13454,7 @@ var prefer_node_fs_promises_default = createRule({
|
|
|
13539
13454
|
});
|
|
13540
13455
|
|
|
13541
13456
|
// src/rules/prefer-non-nullable-collection.ts
|
|
13542
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as
|
|
13457
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as ASTUtils25 } from "@typescript-eslint/utils";
|
|
13543
13458
|
var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
13544
13459
|
summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
|
|
13545
13460
|
rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
|
|
@@ -13669,14 +13584,14 @@ function directlyCoalesced(node) {
|
|
|
13669
13584
|
return parent?.type === AST_NODE_TYPES60.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
|
|
13670
13585
|
}
|
|
13671
13586
|
function identifierIsOnlyCoalesced(context, binding, fn) {
|
|
13672
|
-
const variable =
|
|
13587
|
+
const variable = ASTUtils25.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
13673
13588
|
if (variable === null || variable.references.length === 0) return false;
|
|
13674
13589
|
return variable.references.every(
|
|
13675
13590
|
(reference) => belongsToFunction(reference.identifier, fn) && directlyCoalesced(reference.identifier)
|
|
13676
13591
|
);
|
|
13677
13592
|
}
|
|
13678
13593
|
function memberIsOnlyCoalesced(context, object, property, fn) {
|
|
13679
|
-
const variable =
|
|
13594
|
+
const variable = ASTUtils25.findVariable(context.sourceCode.getScope(object), object.name);
|
|
13680
13595
|
if (variable === null) return false;
|
|
13681
13596
|
const accesses = variable.references.flatMap((reference) => {
|
|
13682
13597
|
if (!belongsToFunction(reference.identifier, fn)) return [null];
|
|
@@ -13786,7 +13701,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
13786
13701
|
// src/rules/prefer-nullish-filter-predicate.ts
|
|
13787
13702
|
import {
|
|
13788
13703
|
AST_NODE_TYPES as AST_NODE_TYPES61,
|
|
13789
|
-
ASTUtils as
|
|
13704
|
+
ASTUtils as ASTUtils26,
|
|
13790
13705
|
ESLintUtils as ESLintUtils5
|
|
13791
13706
|
} from "@typescript-eslint/utils";
|
|
13792
13707
|
import ts3 from "typescript";
|
|
@@ -13832,7 +13747,7 @@ var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
|
13832
13747
|
]
|
|
13833
13748
|
};
|
|
13834
13749
|
function isUnshadowedBoolean(node, context) {
|
|
13835
|
-
const variable =
|
|
13750
|
+
const variable = ASTUtils26.findVariable(context.sourceCode.getScope(node), node.name);
|
|
13836
13751
|
return variable === null || variable.defs.length === 0;
|
|
13837
13752
|
}
|
|
13838
13753
|
function isBuiltinArrayFilter(node, services) {
|
|
@@ -13891,7 +13806,7 @@ function isProvablyTruthy(type, checker) {
|
|
|
13891
13806
|
}
|
|
13892
13807
|
function availableParameterName(node, context) {
|
|
13893
13808
|
for (const name of ["value", "item", "element", "candidate"]) {
|
|
13894
|
-
if (
|
|
13809
|
+
if (ASTUtils26.findVariable(context.sourceCode.getScope(node), name) === null) return name;
|
|
13895
13810
|
}
|
|
13896
13811
|
return null;
|
|
13897
13812
|
}
|
|
@@ -13945,7 +13860,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
13945
13860
|
|
|
13946
13861
|
// src/rules/prefer-await-in-async-return.ts
|
|
13947
13862
|
import {
|
|
13948
|
-
ASTUtils as
|
|
13863
|
+
ASTUtils as ASTUtils27,
|
|
13949
13864
|
ESLintUtils as ESLintUtils6,
|
|
13950
13865
|
AST_NODE_TYPES as AST_NODE_TYPES62
|
|
13951
13866
|
} from "@typescript-eslint/utils";
|
|
@@ -14059,13 +13974,13 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
14059
13974
|
if (services === null) return {};
|
|
14060
13975
|
const frameworkLoaders = /* @__PURE__ */ new Set();
|
|
14061
13976
|
const rememberFrameworkLoader = (identifier) => {
|
|
14062
|
-
const variable =
|
|
13977
|
+
const variable = ASTUtils27.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
14063
13978
|
if (variable !== null) frameworkLoaders.add(variable);
|
|
14064
13979
|
};
|
|
14065
13980
|
const isFrameworkLoaderCallback = (owner) => {
|
|
14066
13981
|
const parent = owner.parent;
|
|
14067
13982
|
if (parent.type !== AST_NODE_TYPES62.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== AST_NODE_TYPES62.Identifier) return false;
|
|
14068
|
-
const variable =
|
|
13983
|
+
const variable = ASTUtils27.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
|
|
14069
13984
|
return variable !== null && frameworkLoaders.has(variable);
|
|
14070
13985
|
};
|
|
14071
13986
|
return {
|
|
@@ -14691,6 +14606,7 @@ var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
|
|
|
14691
14606
|
category: "maintainability",
|
|
14692
14607
|
limitations: [
|
|
14693
14608
|
"Only direct if/else-if chains with at least three strict-equality tests are reported.",
|
|
14609
|
+
"The discriminant must be a bare identifier; calls, getters, indexed reads and other repeatedly evaluated expressions are excluded. Review case-value effects, selector mutation, branch scoping, and break/continue targets when converting manually; this is not an equivalence proof.",
|
|
14694
14610
|
"Case values may be literals, enum-like member references, or upper-case named constants; dynamic expressions are excluded.",
|
|
14695
14611
|
"The rule deliberately ignores compound predicates, loose equality, ranges, and chains that compare different discriminants."
|
|
14696
14612
|
],
|
|
@@ -14704,7 +14620,8 @@ function discriminantText(sourceCode, test) {
|
|
|
14704
14620
|
const leftIsCase = isCaseValue(test.left);
|
|
14705
14621
|
const rightIsCase = isCaseValue(test.right);
|
|
14706
14622
|
if (leftIsCase === rightIsCase) return null;
|
|
14707
|
-
|
|
14623
|
+
const discriminant = leftIsCase ? test.right : test.left;
|
|
14624
|
+
return discriminant.type === AST_NODE_TYPES65.Identifier ? sourceCode.getText(discriminant) : null;
|
|
14708
14625
|
}
|
|
14709
14626
|
function isCaseValue(node) {
|
|
14710
14627
|
if (node.type === AST_NODE_TYPES65.Literal) return true;
|
|
@@ -15294,7 +15211,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
15294
15211
|
});
|
|
15295
15212
|
|
|
15296
15213
|
// src/rules/prefer-server-actions.ts
|
|
15297
|
-
import { ASTUtils as
|
|
15214
|
+
import { ASTUtils as ASTUtils28 } from "@typescript-eslint/utils";
|
|
15298
15215
|
var PREFER_SERVER_ACTIONS_DOCUMENTATION = {
|
|
15299
15216
|
summary: "Prefer Next.js Server Actions over same-origin API mutations.",
|
|
15300
15217
|
rationale: "Server Actions can remove a hand-written internal API wrapper while retaining typed application calls. Client invocations still cross a network and serialization boundary.",
|
|
@@ -15326,7 +15243,7 @@ function resolvesToGlobalFetch(context, identifier) {
|
|
|
15326
15243
|
function resolveNode(node, context) {
|
|
15327
15244
|
if (!node) return null;
|
|
15328
15245
|
if (node.type !== "Identifier") return node;
|
|
15329
|
-
const variable =
|
|
15246
|
+
const variable = ASTUtils28.findVariable(getScope(context, node), node.name);
|
|
15330
15247
|
const definition = variable?.defs.length === 1 ? variable.defs[0] : void 0;
|
|
15331
15248
|
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init === null || variable?.references.some((reference) => reference.isWrite() && reference.init !== true)) return node;
|
|
15332
15249
|
if (definition.node.init.type === "ObjectExpression" && variable?.references.some((reference) => reference.identifier !== node && reference.init !== true)) return node;
|
|
@@ -15335,7 +15252,7 @@ function resolveNode(node, context) {
|
|
|
15335
15252
|
function isAxiosClient(node, context, seen = /* @__PURE__ */ new Set()) {
|
|
15336
15253
|
if (node.type !== "Identifier" || seen.has(node)) return false;
|
|
15337
15254
|
seen.add(node);
|
|
15338
|
-
const variable =
|
|
15255
|
+
const variable = ASTUtils28.findVariable(getScope(context, node), node.name);
|
|
15339
15256
|
const definition = variable?.defs.length === 1 ? variable.defs[0] : void 0;
|
|
15340
15257
|
if (definition === void 0 || variable?.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
15341
15258
|
if (variable?.references.some((reference) => {
|
|
@@ -15804,7 +15721,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
15804
15721
|
});
|
|
15805
15722
|
|
|
15806
15723
|
// src/rules/repeated-static-call-cases.ts
|
|
15807
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES68, ASTUtils as
|
|
15724
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES68, ASTUtils as ASTUtils29 } from "@typescript-eslint/utils";
|
|
15808
15725
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
15809
15726
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
15810
15727
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
@@ -15830,7 +15747,7 @@ function staticMemberName5(node) {
|
|
|
15830
15747
|
return null;
|
|
15831
15748
|
}
|
|
15832
15749
|
function importedName6(identifier, context, modules) {
|
|
15833
|
-
const variable =
|
|
15750
|
+
const variable = ASTUtils29.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
15834
15751
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
15835
15752
|
for (const definition of variable.defs) {
|
|
15836
15753
|
if (definition.node.type !== AST_NODE_TYPES68.ImportSpecifier) continue;
|
|
@@ -15993,6 +15910,11 @@ var PREFER_ZOD_INFER_DOCUMENTATION = {
|
|
|
15993
15910
|
rationale: "A derived type stays synchronized when the runtime schema changes.",
|
|
15994
15911
|
remediation: "Replace the hand-written twin with `z.infer<typeof Schema>`.",
|
|
15995
15912
|
category: "correctness",
|
|
15913
|
+
limitations: [
|
|
15914
|
+
"Only module-level const schemas and module-level type declarations are paired; local declarations are excluded rather than matched by spelling across scopes.",
|
|
15915
|
+
"By default every field must positively agree; collection, nested-object and referenced-schema equivalence is not inferred from outer syntax alone.",
|
|
15916
|
+
"This is a bounded syntactic comparison, not general type equivalence. Review schema input versus output, interface augmentation, and separately evolving domain contracts before replacing a declaration."
|
|
15917
|
+
],
|
|
15996
15918
|
examples: [
|
|
15997
15919
|
{ id: "inferred-type", title: "Infer the schema type", outcome: "no-match", files: [{ path: "src/user.ts", source: 'import { z } from "zod"; const UserSchema = z.object({ id: z.string() }); type User = z.infer<typeof UserSchema>;' }], focusPath: "src/user.ts", expectedCount: 0, public: true },
|
|
15998
15920
|
{ id: "handwritten-twin", title: "Do not duplicate the schema shape", outcome: "match", files: [{ path: "src/user.ts", source: 'import { z } from "zod"; const UserSchema = z.object({ id: z.string() }); interface User { id: string }' }], focusPath: "src/user.ts", expectedCount: 1, public: true }
|
|
@@ -16172,6 +16094,10 @@ function sameDomain(left, right) {
|
|
|
16172
16094
|
function isExportedDeclaration(node) {
|
|
16173
16095
|
return node.parent?.type === AST_NODE_TYPES69.ExportNamedDeclaration;
|
|
16174
16096
|
}
|
|
16097
|
+
function isModuleLevelDeclaration(node) {
|
|
16098
|
+
const parent = node.parent;
|
|
16099
|
+
return parent?.type === AST_NODE_TYPES69.Program || parent?.type === AST_NODE_TYPES69.ExportNamedDeclaration && parent.parent.type === AST_NODE_TYPES69.Program;
|
|
16100
|
+
}
|
|
16175
16101
|
function isModuleLevelConst(node) {
|
|
16176
16102
|
const declaration = node.parent;
|
|
16177
16103
|
if (declaration.type !== AST_NODE_TYPES69.VariableDeclaration || declaration.kind !== "const") {
|
|
@@ -16222,6 +16148,9 @@ function leafAgrees(field, annotation) {
|
|
|
16222
16148
|
return annotationDomain !== null && sameDomain(field.domain, annotationDomain);
|
|
16223
16149
|
}
|
|
16224
16150
|
const { leaf } = field;
|
|
16151
|
+
if (leaf !== null && ["array", "tuple", "object", "strictObject", "looseObject", "record", "map", "set", "promise", "intersection"].includes(leaf)) {
|
|
16152
|
+
return false;
|
|
16153
|
+
}
|
|
16225
16154
|
if (leaf === null || annotation === null) {
|
|
16226
16155
|
return null;
|
|
16227
16156
|
}
|
|
@@ -16514,7 +16443,6 @@ var prefer_zod_infer_default = createRule({
|
|
|
16514
16443
|
if (fields.size !== members.size) {
|
|
16515
16444
|
return false;
|
|
16516
16445
|
}
|
|
16517
|
-
let agreements = 0;
|
|
16518
16446
|
for (const [name, field] of fields) {
|
|
16519
16447
|
const member = members.get(name);
|
|
16520
16448
|
if (member === void 0) {
|
|
@@ -16533,14 +16461,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
16533
16461
|
return false;
|
|
16534
16462
|
}
|
|
16535
16463
|
const agrees = leafAgrees(field, member.annotation);
|
|
16536
|
-
if (agrees
|
|
16464
|
+
if (agrees !== true) {
|
|
16537
16465
|
return false;
|
|
16538
16466
|
}
|
|
16539
|
-
if (agrees === true) {
|
|
16540
|
-
agreements += 1;
|
|
16541
|
-
}
|
|
16542
16467
|
}
|
|
16543
|
-
return
|
|
16468
|
+
return true;
|
|
16544
16469
|
}
|
|
16545
16470
|
return {
|
|
16546
16471
|
Program(node) {
|
|
@@ -16554,7 +16479,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
16554
16479
|
recordZodImport(node);
|
|
16555
16480
|
},
|
|
16556
16481
|
VariableDeclarator(node) {
|
|
16557
|
-
if (node.id.type !== AST_NODE_TYPES69.Identifier || node.init == null) {
|
|
16482
|
+
if (node.id.type !== AST_NODE_TYPES69.Identifier || node.init == null || !isModuleLevelConst(node)) {
|
|
16558
16483
|
return;
|
|
16559
16484
|
}
|
|
16560
16485
|
const fields = schemaFields(node.init);
|
|
@@ -16587,6 +16512,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
16587
16512
|
}
|
|
16588
16513
|
},
|
|
16589
16514
|
TSInterfaceDeclaration(node) {
|
|
16515
|
+
if (!isModuleLevelDeclaration(node)) return;
|
|
16590
16516
|
if (node.typeParameters !== void 0 || (node.extends?.length ?? 0) > 0) {
|
|
16591
16517
|
return;
|
|
16592
16518
|
}
|
|
@@ -16602,6 +16528,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
16602
16528
|
);
|
|
16603
16529
|
},
|
|
16604
16530
|
TSTypeAliasDeclaration(node) {
|
|
16531
|
+
if (!isModuleLevelDeclaration(node)) return;
|
|
16605
16532
|
const schemaName = inferredSchemaName(node.typeAnnotation);
|
|
16606
16533
|
if (schemaName !== null) {
|
|
16607
16534
|
inferredAliases.push({
|
|
@@ -16719,6 +16646,7 @@ var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
|
16719
16646
|
rationale: "An empty default silently accepts new union members instead of making the compiler identify the missing case.",
|
|
16720
16647
|
remediation: "Call `assertNever` with the discriminant in the exhaustive switch default.",
|
|
16721
16648
|
category: "correctness",
|
|
16649
|
+
limitations: ["Requires type information and singleton case values covering the current union. The helper must accept never to provide a compile-time check; its spelling alone is not a proof of that contract. Review the desired runtime behavior for unexpected external values."],
|
|
16722
16650
|
examples: [
|
|
16723
16651
|
{ id: "assert-never-default", title: "Make the default exhaustive", outcome: "no-match", files: [{ path: "src/render.ts", source: "declare const kind: 'a' | 'b';\nswitch (kind) { case 'a': break; case 'b': break; default: assertNever(kind); }" }], focusPath: "src/render.ts", expectedCount: 0, public: true },
|
|
16724
16652
|
{ id: "empty-default", title: "Do not leave an exhaustive default empty", outcome: "match", files: [{ path: "src/render.ts", source: "declare const kind: 'a' | 'b';\nswitch (kind) { case 'a': break; case 'b': break; default: }" }], focusPath: "src/render.ts", expectedCount: 1, public: true }
|
|
@@ -16775,11 +16703,9 @@ function isExhaustiveFiniteSwitch(node, services) {
|
|
|
16775
16703
|
if (caseNode.test === null) continue;
|
|
16776
16704
|
const test = services.esTreeNodeToTSNodeMap.get(caseNode.test);
|
|
16777
16705
|
const testType = checker.getTypeAtLocation(test);
|
|
16778
|
-
|
|
16779
|
-
|
|
16780
|
-
|
|
16781
|
-
if (key !== null) handled.add(key);
|
|
16782
|
-
}
|
|
16706
|
+
if (testType.isUnion()) continue;
|
|
16707
|
+
const key = finiteTypeKey(testType, checker);
|
|
16708
|
+
if (key !== null) handled.add(key);
|
|
16783
16709
|
}
|
|
16784
16710
|
return [...expected].every((key) => handled.has(key));
|
|
16785
16711
|
}
|
|
@@ -16831,7 +16757,7 @@ var require_assert_never_default = createRule({
|
|
|
16831
16757
|
});
|
|
16832
16758
|
|
|
16833
16759
|
// src/rules/require-fetch-timeout.ts
|
|
16834
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as
|
|
16760
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as ASTUtils30 } from "@typescript-eslint/utils";
|
|
16835
16761
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
16836
16762
|
summary: "Require an explicit abort signal on locally analyzable global fetch calls.",
|
|
16837
16763
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -16913,7 +16839,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
16913
16839
|
}
|
|
16914
16840
|
function resolvesToGlobal(identifier) {
|
|
16915
16841
|
const scope = context.sourceCode.getScope(identifier);
|
|
16916
|
-
const variable =
|
|
16842
|
+
const variable = ASTUtils30.findVariable(scope, identifier.name);
|
|
16917
16843
|
return variable === null || variable.defs.length === 0;
|
|
16918
16844
|
}
|
|
16919
16845
|
function isGlobalFetchCall2(callee) {
|
|
@@ -16923,7 +16849,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
16923
16849
|
return callee.type === AST_NODE_TYPES71.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES71.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES71.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
16924
16850
|
}
|
|
16925
16851
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
16926
|
-
const variable =
|
|
16852
|
+
const variable = ASTUtils30.findVariable(
|
|
16927
16853
|
context.sourceCode.getScope(identifier),
|
|
16928
16854
|
identifier.name
|
|
16929
16855
|
);
|
|
@@ -16945,7 +16871,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
16945
16871
|
function isForwardedRequest(argument) {
|
|
16946
16872
|
let value = argument;
|
|
16947
16873
|
if (value.type === AST_NODE_TYPES71.Identifier) {
|
|
16948
|
-
const binding =
|
|
16874
|
+
const binding = ASTUtils30.findVariable(context.sourceCode.getScope(value), value.name);
|
|
16949
16875
|
const definition = binding?.defs.length === 1 ? binding.defs[0] : void 0;
|
|
16950
16876
|
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init === null || binding?.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
16951
16877
|
value = definition.node.init;
|
|
@@ -17434,15 +17360,14 @@ var publicMethodNames = (body2, functionAliases) => {
|
|
|
17434
17360
|
if (member.static || member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
17435
17361
|
if (member.key.type === AST_NODE_TYPES73.PrivateIdentifier) continue;
|
|
17436
17362
|
if (member.value?.type !== AST_NODE_TYPES73.ArrowFunctionExpression && member.value?.type !== AST_NODE_TYPES73.FunctionExpression && member.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES73.TSFunctionType && !(member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES73.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES73.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name))) continue;
|
|
17437
|
-
names.push(member
|
|
17363
|
+
names.push(declaredMemberName(member) ?? "\u2026");
|
|
17438
17364
|
continue;
|
|
17439
17365
|
}
|
|
17440
17366
|
if (member.type !== AST_NODE_TYPES73.MethodDefinition) continue;
|
|
17441
17367
|
if (member.kind !== "method" || member.static) continue;
|
|
17442
17368
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
17443
17369
|
if (member.key.type === AST_NODE_TYPES73.PrivateIdentifier) continue;
|
|
17444
|
-
|
|
17445
|
-
else names.push("\u2026");
|
|
17370
|
+
names.push(declaredMemberName(member) ?? "\u2026");
|
|
17446
17371
|
}
|
|
17447
17372
|
return names;
|
|
17448
17373
|
};
|
|
@@ -17483,6 +17408,11 @@ function localClassAbstractness(program) {
|
|
|
17483
17408
|
}
|
|
17484
17409
|
return classes;
|
|
17485
17410
|
}
|
|
17411
|
+
function declaredMemberName(member) {
|
|
17412
|
+
if (!member.computed && member.key.type === AST_NODE_TYPES73.Identifier) return member.key.name;
|
|
17413
|
+
if (member.key.type === AST_NODE_TYPES73.Literal && typeof member.key.value === "string") return member.key.value;
|
|
17414
|
+
return null;
|
|
17415
|
+
}
|
|
17486
17416
|
function localInterfaceSurfaces(program) {
|
|
17487
17417
|
const interfaces = /* @__PURE__ */ new Map();
|
|
17488
17418
|
const parents = /* @__PURE__ */ new Map();
|
|
@@ -17505,14 +17435,15 @@ function localInterfaceSurfaces(program) {
|
|
|
17505
17435
|
if (part.type !== AST_NODE_TYPES73.TSTypeLiteral) continue;
|
|
17506
17436
|
for (const member of part.members) {
|
|
17507
17437
|
if (member.type !== AST_NODE_TYPES73.TSMethodSignature && member.type !== AST_NODE_TYPES73.TSPropertySignature) continue;
|
|
17508
|
-
|
|
17438
|
+
const name = declaredMemberName(member);
|
|
17439
|
+
if (name === null) continue;
|
|
17509
17440
|
if (member.type === AST_NODE_TYPES73.TSMethodSignature) {
|
|
17510
|
-
callables2.add(
|
|
17441
|
+
callables2.add(name);
|
|
17511
17442
|
continue;
|
|
17512
17443
|
}
|
|
17513
17444
|
if (member.type !== AST_NODE_TYPES73.TSPropertySignature) continue;
|
|
17514
17445
|
const annotation = member.typeAnnotation?.typeAnnotation;
|
|
17515
|
-
if (annotation?.type === AST_NODE_TYPES73.TSFunctionType || annotation?.type === AST_NODE_TYPES73.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES73.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(
|
|
17446
|
+
if (annotation?.type === AST_NODE_TYPES73.TSFunctionType || annotation?.type === AST_NODE_TYPES73.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES73.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(name);
|
|
17516
17447
|
}
|
|
17517
17448
|
}
|
|
17518
17449
|
interfaces.set(declaration.id.name, callables2);
|
|
@@ -17523,8 +17454,9 @@ function localInterfaceSurfaces(program) {
|
|
|
17523
17454
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
17524
17455
|
for (const member of declaration.body.body) {
|
|
17525
17456
|
if (member.type !== AST_NODE_TYPES73.TSMethodSignature && member.type !== AST_NODE_TYPES73.TSPropertySignature) continue;
|
|
17526
|
-
|
|
17527
|
-
if (
|
|
17457
|
+
const name = declaredMemberName(member);
|
|
17458
|
+
if (name === null) continue;
|
|
17459
|
+
if (member.type === AST_NODE_TYPES73.TSMethodSignature || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES73.TSFunctionType || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES73.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES73.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name)) callables.add(name);
|
|
17528
17460
|
}
|
|
17529
17461
|
interfaces.set(declaration.id.name, callables);
|
|
17530
17462
|
parents.set(
|
|
@@ -18022,7 +17954,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
18022
17954
|
});
|
|
18023
17955
|
|
|
18024
17956
|
// src/rules/require-use-form-default-values.ts
|
|
18025
|
-
import { ASTUtils as
|
|
17957
|
+
import { ASTUtils as ASTUtils31 } from "@typescript-eslint/utils";
|
|
18026
17958
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
18027
17959
|
summary: "react-hook-form useForm call without explicit initial or reactive values",
|
|
18028
17960
|
rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
|
|
@@ -18076,13 +18008,13 @@ var require_use_form_default_values_default = createRule({
|
|
|
18076
18008
|
if (node.source.value !== "react-hook-form") return;
|
|
18077
18009
|
for (const specifier of node.specifiers) {
|
|
18078
18010
|
if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
|
|
18079
|
-
const variable =
|
|
18011
|
+
const variable = ASTUtils31.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
18080
18012
|
if (variable) importedHooks.add(variable);
|
|
18081
18013
|
}
|
|
18082
18014
|
},
|
|
18083
18015
|
CallExpression(node) {
|
|
18084
18016
|
if (node.callee.type !== "Identifier") return;
|
|
18085
|
-
const variable =
|
|
18017
|
+
const variable = ASTUtils31.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
|
|
18086
18018
|
const options = node.arguments[0];
|
|
18087
18019
|
if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasInitializationOrUnknownOptions(options)) return;
|
|
18088
18020
|
context.report({ node, messageId: "requireUseFormDefaultValues" });
|
|
@@ -18161,7 +18093,7 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
18161
18093
|
// src/rules/require-zod-form-validation.ts
|
|
18162
18094
|
import {
|
|
18163
18095
|
AST_NODE_TYPES as AST_NODE_TYPES76,
|
|
18164
|
-
ASTUtils as
|
|
18096
|
+
ASTUtils as ASTUtils32
|
|
18165
18097
|
} from "@typescript-eslint/utils";
|
|
18166
18098
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
18167
18099
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
@@ -18229,7 +18161,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
18229
18161
|
return {};
|
|
18230
18162
|
}
|
|
18231
18163
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
18232
|
-
const resolvedBinding = (identifier) =>
|
|
18164
|
+
const resolvedBinding = (identifier) => ASTUtils32.findVariable(
|
|
18233
18165
|
context.sourceCode.getScope(identifier),
|
|
18234
18166
|
identifier.name
|
|
18235
18167
|
);
|
|
@@ -18526,7 +18458,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
18526
18458
|
});
|
|
18527
18459
|
|
|
18528
18460
|
// src/rules/stepdown.ts
|
|
18529
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES77, ASTUtils as
|
|
18461
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES77, ASTUtils as ASTUtils33 } from "@typescript-eslint/utils";
|
|
18530
18462
|
var STEPDOWN_DOCUMENTATION = {
|
|
18531
18463
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
18532
18464
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -18731,7 +18663,7 @@ function methodName(node) {
|
|
|
18731
18663
|
return !node.computed && node.key.type === AST_NODE_TYPES77.Identifier ? node.key.name : null;
|
|
18732
18664
|
}
|
|
18733
18665
|
function referencedMethod(context, node, classVariables) {
|
|
18734
|
-
const objectVariable = node.object.type === AST_NODE_TYPES77.Identifier ?
|
|
18666
|
+
const objectVariable = node.object.type === AST_NODE_TYPES77.Identifier ? ASTUtils33.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
|
|
18735
18667
|
const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
|
|
18736
18668
|
if (node.object.type !== AST_NODE_TYPES77.ThisExpression && !isClassReference) return null;
|
|
18737
18669
|
if (node.property.type === AST_NODE_TYPES77.PrivateIdentifier) return `#${node.property.name}`;
|
|
@@ -18743,15 +18675,15 @@ function referencedPropertyName(node) {
|
|
|
18743
18675
|
if (!node.computed && node.property.type === AST_NODE_TYPES77.Identifier) return node.property.name;
|
|
18744
18676
|
return node.computed && node.property.type === AST_NODE_TYPES77.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
18745
18677
|
}
|
|
18746
|
-
function
|
|
18678
|
+
function walk(node, visitorKeys, visit, nestedFunction = false) {
|
|
18747
18679
|
visit(node, nestedFunction);
|
|
18748
18680
|
const nested = nestedFunction || isFunction(node);
|
|
18749
18681
|
for (const key of visitorKeys[node.type] ?? []) {
|
|
18750
18682
|
const child = node[key];
|
|
18751
18683
|
if (Array.isArray(child)) {
|
|
18752
|
-
for (const item of child) if (typeof item === "object" && item !== null && "type" in item)
|
|
18684
|
+
for (const item of child) if (typeof item === "object" && item !== null && "type" in item) walk(item, visitorKeys, visit, nested);
|
|
18753
18685
|
} else if (typeof child === "object" && child !== null && "type" in child) {
|
|
18754
|
-
|
|
18686
|
+
walk(child, visitorKeys, visit, nested);
|
|
18755
18687
|
}
|
|
18756
18688
|
}
|
|
18757
18689
|
}
|
|
@@ -18784,11 +18716,11 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
18784
18716
|
const pinned = /* @__PURE__ */ new Set();
|
|
18785
18717
|
const classVariables = /* @__PURE__ */ new Set();
|
|
18786
18718
|
if (node.id !== null) {
|
|
18787
|
-
const internal =
|
|
18719
|
+
const internal = ASTUtils33.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
18788
18720
|
if (internal !== null) classVariables.add(internal);
|
|
18789
18721
|
}
|
|
18790
18722
|
if (node.type === AST_NODE_TYPES77.ClassExpression && node.parent.type === AST_NODE_TYPES77.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES77.Identifier) {
|
|
18791
|
-
const outer =
|
|
18723
|
+
const outer = ASTUtils33.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
18792
18724
|
if (outer !== null) classVariables.add(outer);
|
|
18793
18725
|
}
|
|
18794
18726
|
for (const method of methods) {
|
|
@@ -18799,7 +18731,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
18799
18731
|
const parameterDecoratorNodes = /* @__PURE__ */ new Set();
|
|
18800
18732
|
for (const parameter of method.value.params) {
|
|
18801
18733
|
for (const decorator of parameter.decorators) {
|
|
18802
|
-
|
|
18734
|
+
walk(decorator, context.sourceCode.visitorKeys, (current) => parameterDecoratorNodes.add(current));
|
|
18803
18735
|
}
|
|
18804
18736
|
}
|
|
18805
18737
|
const thisValue = (value) => {
|
|
@@ -18824,17 +18756,17 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
18824
18756
|
return;
|
|
18825
18757
|
}
|
|
18826
18758
|
if (binding.type !== AST_NODE_TYPES77.Identifier) return;
|
|
18827
|
-
const variable =
|
|
18759
|
+
const variable = ASTUtils33.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
18828
18760
|
if (variable !== null) {
|
|
18829
18761
|
methodClassVariables.add(variable);
|
|
18830
18762
|
methodAliases.add(variable);
|
|
18831
18763
|
}
|
|
18832
18764
|
};
|
|
18833
18765
|
for (const parameter of method.value.params) {
|
|
18834
|
-
|
|
18766
|
+
walk(parameter, context.sourceCode.visitorKeys, collectAlias);
|
|
18835
18767
|
}
|
|
18836
18768
|
for (const statement of method.value.body.body) {
|
|
18837
|
-
|
|
18769
|
+
walk(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
18838
18770
|
}
|
|
18839
18771
|
const visitCall = (current, nestedFunction) => {
|
|
18840
18772
|
if (current.type === AST_NODE_TYPES77.VariableDeclarator && current.id.type === AST_NODE_TYPES77.ObjectPattern && thisValue(current.init)) {
|
|
@@ -18854,7 +18786,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
18854
18786
|
return;
|
|
18855
18787
|
}
|
|
18856
18788
|
if (!privateNames.has(target)) return;
|
|
18857
|
-
const objectVariable = current.object.type === AST_NODE_TYPES77.Identifier ?
|
|
18789
|
+
const objectVariable = current.object.type === AST_NODE_TYPES77.Identifier ? ASTUtils33.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
|
|
18858
18790
|
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
18859
18791
|
pinned.add(target);
|
|
18860
18792
|
return;
|
|
@@ -18868,19 +18800,19 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
18868
18800
|
calls.set(caller, callees);
|
|
18869
18801
|
};
|
|
18870
18802
|
for (const decorator of method.decorators) {
|
|
18871
|
-
|
|
18803
|
+
walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
|
|
18872
18804
|
}
|
|
18873
|
-
if (method.computed)
|
|
18805
|
+
if (method.computed) walk(method.key, context.sourceCode.visitorKeys, visitCall, true);
|
|
18874
18806
|
for (const parameter of method.value.params) {
|
|
18875
|
-
|
|
18807
|
+
walk(parameter, context.sourceCode.visitorKeys, visitCall);
|
|
18876
18808
|
}
|
|
18877
18809
|
for (const statement of method.value.body.body) {
|
|
18878
|
-
|
|
18810
|
+
walk(statement, context.sourceCode.visitorKeys, visitCall);
|
|
18879
18811
|
}
|
|
18880
18812
|
}
|
|
18881
18813
|
for (const member of node.body.body) {
|
|
18882
18814
|
if (member.type === AST_NODE_TYPES77.MethodDefinition || member.type === AST_NODE_TYPES77.TSAbstractMethodDefinition) continue;
|
|
18883
|
-
|
|
18815
|
+
walk(member, context.sourceCode.visitorKeys, (current) => {
|
|
18884
18816
|
if (current.type !== AST_NODE_TYPES77.MemberExpression) return;
|
|
18885
18817
|
const target = referencedMethod(context, current, classVariables);
|
|
18886
18818
|
const possibleTarget = target ?? referencedPropertyName(current);
|
|
@@ -18970,7 +18902,7 @@ var stepdown_default = createRule({
|
|
|
18970
18902
|
"Program:exit": (program) => {
|
|
18971
18903
|
moduleScope(context, program);
|
|
18972
18904
|
const computedReferenceNames = /* @__PURE__ */ new Set();
|
|
18973
|
-
|
|
18905
|
+
walk(program, context.sourceCode.visitorKeys, (node) => {
|
|
18974
18906
|
if (node.type === AST_NODE_TYPES77.MemberExpression && node.computed && node.property.type === AST_NODE_TYPES77.Literal && typeof node.property.value === "string") computedReferenceNames.add(node.property.value);
|
|
18975
18907
|
});
|
|
18976
18908
|
for (const node of classes) classScope(context, node, computedReferenceNames);
|
|
@@ -19441,7 +19373,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
19441
19373
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
19442
19374
|
import {
|
|
19443
19375
|
AST_NODE_TYPES as AST_NODE_TYPES80,
|
|
19444
|
-
ASTUtils as
|
|
19376
|
+
ASTUtils as ASTUtils34
|
|
19445
19377
|
} from "@typescript-eslint/utils";
|
|
19446
19378
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
19447
19379
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
@@ -19642,7 +19574,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
19642
19574
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
19643
19575
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
19644
19576
|
function resolvedBinding(identifier) {
|
|
19645
|
-
return
|
|
19577
|
+
return ASTUtils34.findVariable(
|
|
19646
19578
|
context.sourceCode.getScope(identifier),
|
|
19647
19579
|
identifier.name
|
|
19648
19580
|
);
|
|
@@ -19887,7 +19819,7 @@ var RULES = {
|
|
|
19887
19819
|
};
|
|
19888
19820
|
var meta = {
|
|
19889
19821
|
name: "@sarj/eslint-plugin",
|
|
19890
|
-
version: "15.17.
|
|
19822
|
+
version: "15.17.10"
|
|
19891
19823
|
};
|
|
19892
19824
|
var APPLICATION_ONLY_RULES = [];
|
|
19893
19825
|
var LIBRARY_IMPORT_POLICY = ["error", {
|