@sarj/eslint-plugin 18.0.4 → 18.0.5
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 +923 -898
- package/dist/index.js +841 -816
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -809,14 +809,14 @@ function sameShape(checker, input, output, location) {
|
|
|
809
809
|
|
|
810
810
|
// src/rules/prefer-server-data-preparation.ts
|
|
811
811
|
import {
|
|
812
|
-
AST_NODE_TYPES as
|
|
812
|
+
AST_NODE_TYPES as AST_NODE_TYPES9,
|
|
813
813
|
ASTUtils as ASTUtils4
|
|
814
814
|
} from "@typescript-eslint/utils";
|
|
815
|
-
import
|
|
815
|
+
import ts7 from "typescript";
|
|
816
816
|
|
|
817
817
|
// src/rules/_react-prop-bindings.ts
|
|
818
818
|
import {
|
|
819
|
-
AST_NODE_TYPES as
|
|
819
|
+
AST_NODE_TYPES as AST_NODE_TYPES8,
|
|
820
820
|
ASTUtils as ASTUtils3
|
|
821
821
|
} from "@typescript-eslint/utils";
|
|
822
822
|
|
|
@@ -826,6 +826,206 @@ function importSpecifierName(node) {
|
|
|
826
826
|
return node.imported.type === AST_NODE_TYPES5.Identifier ? node.imported.name : node.imported.value;
|
|
827
827
|
}
|
|
828
828
|
|
|
829
|
+
// src/rules/_private-scalar-consumer.ts
|
|
830
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
831
|
+
import ts6 from "typescript";
|
|
832
|
+
|
|
833
|
+
// src/rules/_scalar-parameter-view.ts
|
|
834
|
+
import ts5 from "typescript";
|
|
835
|
+
|
|
836
|
+
// src/rules/_checked-native-source.ts
|
|
837
|
+
import ts3 from "typescript";
|
|
838
|
+
var CHECKED = /* @__PURE__ */ new WeakMap();
|
|
839
|
+
var SINGLE_LINE_DIRECTIVE = /^\/\/\/?\s*@(?:ts-expect-error|ts-ignore)/u;
|
|
840
|
+
var MULTI_LINE_DIRECTIVE = /^[/*]*\s*@(?:ts-expect-error|ts-ignore)/u;
|
|
841
|
+
var SINGLE_LINE_PRAGMA = /^\/\/\/?\s*@([^\s:]+)(?:(?:[^\S\r\n]|:).*)?$/mu;
|
|
842
|
+
function currentNativeSource(sourceCode, services) {
|
|
843
|
+
const source = services.esTreeNodeToTSNodeMap.get(sourceCode.ast);
|
|
844
|
+
return ts3.isSourceFile(source) && services.program.getSourceFile(source.fileName) === source && source.text === sourceCode.text ? source : null;
|
|
845
|
+
}
|
|
846
|
+
function checkedNativeSource(program, source) {
|
|
847
|
+
let files = CHECKED.get(program);
|
|
848
|
+
if (!files) {
|
|
849
|
+
files = /* @__PURE__ */ new WeakMap();
|
|
850
|
+
CHECKED.set(program, files);
|
|
851
|
+
}
|
|
852
|
+
const known2 = files.get(source);
|
|
853
|
+
if (known2 !== void 0) return known2;
|
|
854
|
+
const available = !program.getCompilerOptions().noCheck && !source.isDeclarationFile && (source.flags & (ts3.NodeFlags.JavaScriptFile | ts3.NodeFlags.JsonFile)) === 0 && !program.getProjectReferences()?.length && !program.getResolvedProjectReferences()?.length && program.getSourceFile(source.fileName) === source && !program.isSourceFileFromExternalLibrary(source) && !program.isSourceFileDefaultLibrary(source) && !program.getSyntacticDiagnostics(source).some((diagnostic) => diagnostic.category === ts3.DiagnosticCategory.Error && diagnostic.file === source) && !checkingSuppressed(source) && !program.getSemanticDiagnostics(source).some((diagnostic) => diagnostic.category === ts3.DiagnosticCategory.Error && diagnostic.file === source);
|
|
855
|
+
files.set(source, available);
|
|
856
|
+
return available;
|
|
857
|
+
}
|
|
858
|
+
function checkingSuppressed(source) {
|
|
859
|
+
if (!/@ts-/iu.test(source.text)) return false;
|
|
860
|
+
if (ts3.getLeadingCommentRanges(source.text, 0)?.some((comment) => comment.kind === ts3.SyntaxKind.SingleLineCommentTrivia && SINGLE_LINE_PRAGMA.exec(source.text.slice(comment.pos, comment.end))?.[1]?.toLowerCase() === "ts-nocheck")) return true;
|
|
861
|
+
const pending = [source];
|
|
862
|
+
while (pending.length) {
|
|
863
|
+
const node = pending.pop();
|
|
864
|
+
if (!node || ts3.isJsxText(node) || ts3.isJSDoc(node) || (node.flags & ts3.NodeFlags.JSDoc) !== 0) continue;
|
|
865
|
+
if (!ts3.isToken(node)) {
|
|
866
|
+
for (const child of node.getChildren(source)) pending.push(child);
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
if (tokenTriviaSuppressesChecking(node, source)) return true;
|
|
870
|
+
}
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
873
|
+
function tokenTriviaSuppressesChecking(node, source) {
|
|
874
|
+
const start = node.getStart(source);
|
|
875
|
+
for (const comment of [...ts3.getLeadingCommentRanges(source.text, node.pos) ?? [], ...ts3.getTrailingCommentRanges(source.text, node.pos) ?? []]) {
|
|
876
|
+
if (comment.pos < node.pos || comment.end > start) continue;
|
|
877
|
+
if (commentSuppressesChecking(source.text.slice(comment.pos, comment.end), comment.kind)) return true;
|
|
878
|
+
}
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
function commentSuppressesChecking(text, kind) {
|
|
882
|
+
if (kind === ts3.SyntaxKind.SingleLineCommentTrivia) return SINGLE_LINE_DIRECTIVE.test(text);
|
|
883
|
+
let lastLine = text.length;
|
|
884
|
+
while (lastLine > 0 && !ts3.isLineBreak(text.charCodeAt(lastLine - 1))) lastLine--;
|
|
885
|
+
return MULTI_LINE_DIRECTIVE.test(text.slice(lastLine).trimStart());
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// src/rules/_native-const-value.ts
|
|
889
|
+
import ts4 from "typescript";
|
|
890
|
+
function constInitializer(declaration) {
|
|
891
|
+
if (!declaration || !ts4.isVariableDeclaration(declaration) || !ts4.isVariableDeclarationList(declaration.parent) || (declaration.parent.flags & ts4.NodeFlags.BlockScoped) !== ts4.NodeFlags.Const) return void 0;
|
|
892
|
+
let initializer = declaration.initializer;
|
|
893
|
+
while (initializer && ts4.isParenthesizedExpression(initializer)) initializer = initializer.expression;
|
|
894
|
+
return initializer;
|
|
895
|
+
}
|
|
896
|
+
function unassertedValue(node) {
|
|
897
|
+
let value = node;
|
|
898
|
+
while (ts4.isParenthesizedExpression(value) || ts4.isAsExpression(value) || ts4.isTypeAssertionExpression(value) || ts4.isNonNullExpression(value) || ts4.isSatisfiesExpression(value)) value = value.expression;
|
|
899
|
+
return value;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/rules/_scalar-parameter-view.ts
|
|
903
|
+
var SCALAR_OPERATORS = /* @__PURE__ */ new Set([
|
|
904
|
+
ts5.SyntaxKind.PlusToken,
|
|
905
|
+
ts5.SyntaxKind.MinusToken,
|
|
906
|
+
ts5.SyntaxKind.AsteriskToken,
|
|
907
|
+
ts5.SyntaxKind.SlashToken,
|
|
908
|
+
ts5.SyntaxKind.PercentToken,
|
|
909
|
+
ts5.SyntaxKind.AsteriskAsteriskToken,
|
|
910
|
+
ts5.SyntaxKind.LessThanToken,
|
|
911
|
+
ts5.SyntaxKind.LessThanEqualsToken,
|
|
912
|
+
ts5.SyntaxKind.GreaterThanToken,
|
|
913
|
+
ts5.SyntaxKind.GreaterThanEqualsToken,
|
|
914
|
+
ts5.SyntaxKind.EqualsEqualsEqualsToken,
|
|
915
|
+
ts5.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
916
|
+
ts5.SyntaxKind.EqualsEqualsToken,
|
|
917
|
+
ts5.SyntaxKind.ExclamationEqualsToken,
|
|
918
|
+
ts5.SyntaxKind.AmpersandAmpersandToken,
|
|
919
|
+
ts5.SyntaxKind.BarBarToken,
|
|
920
|
+
ts5.SyntaxKind.QuestionQuestionToken
|
|
921
|
+
]);
|
|
922
|
+
var SCALAR_PREFIXES = /* @__PURE__ */ new Set([ts5.SyntaxKind.PlusToken, ts5.SyntaxKind.MinusToken, ts5.SyntaxKind.ExclamationToken, ts5.SyntaxKind.TildeToken]);
|
|
923
|
+
var RETURNED_OPERANDS = /* @__PURE__ */ new Set([ts5.SyntaxKind.AmpersandAmpersandToken, ts5.SyntaxKind.BarBarToken, ts5.SyntaxKind.QuestionQuestionToken]);
|
|
924
|
+
function scalarParameterView(parameter, body3, checker) {
|
|
925
|
+
return parameterReads(parameter, body3, checker, true);
|
|
926
|
+
}
|
|
927
|
+
function scalarParameterReads(parameter, body3, checker, callProgram, auxiliaries) {
|
|
928
|
+
return parameterReads(parameter, body3, checker, false, callProgram, auxiliaries);
|
|
929
|
+
}
|
|
930
|
+
function parameterReads(parameter, body3, checker, jsx, callProgram, auxiliaries) {
|
|
931
|
+
if (parameter.dotDotDotToken || parameter.initializer || ts5.isArrayBindingPattern(parameter.name)) return null;
|
|
932
|
+
const root = ts5.isIdentifier(parameter.name) ? checker.getSymbolAtLocation(parameter.name) : void 0;
|
|
933
|
+
if (ts5.isIdentifier(parameter.name) && !root) return null;
|
|
934
|
+
const reads = /* @__PURE__ */ new Set();
|
|
935
|
+
const aliases = parameterAliases(parameter.name, checker, reads);
|
|
936
|
+
if (!aliases) return null;
|
|
937
|
+
const expression = returnedExpression(body3);
|
|
938
|
+
const view = { checker, props: checker.getTypeAtLocation(parameter), root, aliases, reads, callProgram, auxiliaries };
|
|
939
|
+
return expression && scalarView(expression, view, jsx) ? reads : null;
|
|
940
|
+
}
|
|
941
|
+
function scalarType(type, allowUndefined = true) {
|
|
942
|
+
if (type.isUnion()) return type.types.every((part) => scalarType(part, allowUndefined));
|
|
943
|
+
const flags = ts5.TypeFlags.StringLike | ts5.TypeFlags.NumberLike | ts5.TypeFlags.BooleanLike | ts5.TypeFlags.BigIntLike | ts5.TypeFlags.Null;
|
|
944
|
+
return (type.flags & (allowUndefined ? flags | ts5.TypeFlags.Undefined : flags)) !== 0;
|
|
945
|
+
}
|
|
946
|
+
function parameterAliases(name, checker, reads) {
|
|
947
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
948
|
+
if (ts5.isIdentifier(name)) return aliases;
|
|
949
|
+
for (const element of name.elements) {
|
|
950
|
+
const key = element.propertyName ?? element.name;
|
|
951
|
+
if (element.dotDotDotToken || element.initializer || !ts5.isIdentifier(element.name) || !ts5.isIdentifier(key) && !ts5.isStringLiteralLike(key) && !ts5.isNumericLiteral(key)) return null;
|
|
952
|
+
const binding3 = checker.getSymbolAtLocation(element.name);
|
|
953
|
+
if (!binding3) return null;
|
|
954
|
+
reads.add(key.text);
|
|
955
|
+
aliases.set(binding3, key.text);
|
|
956
|
+
}
|
|
957
|
+
return aliases;
|
|
958
|
+
}
|
|
959
|
+
function returnedExpression(body3) {
|
|
960
|
+
if (!ts5.isBlock(body3)) return body3;
|
|
961
|
+
const statement = body3.statements.length === 1 ? body3.statements[0] : void 0;
|
|
962
|
+
return statement && ts5.isReturnStatement(statement) ? statement.expression : void 0;
|
|
963
|
+
}
|
|
964
|
+
function scalarView(node, view, jsx = false) {
|
|
965
|
+
if (scalarLiteral(node)) return true;
|
|
966
|
+
if (ts5.isCallExpression(node)) return !jsx && scalarCall(node, view);
|
|
967
|
+
if (ts5.isJsxExpression(node)) return !node.dotDotDotToken && (!node.expression || scalarView(node.expression, view, jsx));
|
|
968
|
+
if (ts5.isIdentifier(node)) {
|
|
969
|
+
const binding3 = view.checker.getSymbolAtLocation(node);
|
|
970
|
+
if (binding3 && view.auxiliaries?.has(binding3)) return scalarType(view.checker.getTypeAtLocation(node));
|
|
971
|
+
const key = binding3 && view.aliases.get(binding3);
|
|
972
|
+
return key !== void 0 && readField(node, key, view);
|
|
973
|
+
}
|
|
974
|
+
if (ts5.isPropertyAccessExpression(node) || ts5.isElementAccessExpression(node)) return memberRead(node, view);
|
|
975
|
+
return scalarOperation(node, view, jsx);
|
|
976
|
+
}
|
|
977
|
+
function scalarOperation(node, view, jsx) {
|
|
978
|
+
if (ts5.isParenthesizedExpression(node) || ts5.isNonNullExpression(node)) return scalarView(node.expression, view, jsx);
|
|
979
|
+
if (ts5.isTypeOfExpression(node)) return scalarView(node.expression, view);
|
|
980
|
+
if (ts5.isConditionalExpression(node)) return scalarView(node.condition, view) && scalarView(node.whenTrue, view, jsx) && scalarView(node.whenFalse, view, jsx);
|
|
981
|
+
if (ts5.isBinaryExpression(node)) return binaryView(node, view, jsx);
|
|
982
|
+
if (ts5.isPrefixUnaryExpression(node)) return SCALAR_PREFIXES.has(node.operator) && scalarView(node.operand, view);
|
|
983
|
+
if (ts5.isTemplateExpression(node)) return node.templateSpans.every((span) => scalarView(span.expression, view));
|
|
984
|
+
return jsx && jsxView(node, view);
|
|
985
|
+
}
|
|
986
|
+
function scalarCall(node, view) {
|
|
987
|
+
if (!view.callProgram || node.questionDotToken || node.typeArguments?.length || !ts5.isIdentifier(node.expression) || !node.arguments.length || node.arguments.some(ts5.isSpreadElement)) return false;
|
|
988
|
+
const declarations = view.checker.getSymbolAtLocation(node.expression)?.declarations;
|
|
989
|
+
const declaration = declarations?.length === 1 ? declarations[0] : void 0;
|
|
990
|
+
const helper = declaration && localHelper(declaration);
|
|
991
|
+
if (!helper || helper.getSourceFile() !== node.getSourceFile() || helper.typeParameters?.length || !helper.type || !node.arguments.every((argument) => scalarView(argument, view))) return false;
|
|
992
|
+
if (!checkedNativeSource(view.callProgram, node.getSourceFile())) return false;
|
|
993
|
+
const signature = view.checker.getResolvedSignature(node);
|
|
994
|
+
return signature?.declaration === helper && !view.checker.getTypePredicateOfSignature(signature) && scalarType(view.checker.getTypeAtLocation(node));
|
|
995
|
+
}
|
|
996
|
+
function localHelper(node) {
|
|
997
|
+
if (ts5.isFunctionDeclaration(node)) return node.body && ts5.isSourceFile(node.parent) ? node : void 0;
|
|
998
|
+
if (!ts5.isVariableDeclaration(node) || node.type || !node.initializer || constInitializer(node) !== node.initializer || !ts5.isArrowFunction(node.initializer) || !ts5.isVariableStatement(node.parent.parent) || !ts5.isSourceFile(node.parent.parent.parent)) return void 0;
|
|
999
|
+
return node.initializer;
|
|
1000
|
+
}
|
|
1001
|
+
function binaryView(node, view, jsx) {
|
|
1002
|
+
const returned2 = jsx && RETURNED_OPERANDS.has(node.operatorToken.kind);
|
|
1003
|
+
return SCALAR_OPERATORS.has(node.operatorToken.kind) && scalarView(node.left, view, returned2) && scalarView(node.right, view, returned2);
|
|
1004
|
+
}
|
|
1005
|
+
function scalarLiteral(node) {
|
|
1006
|
+
return ts5.isStringLiteralLike(node) || ts5.isNumericLiteral(node) || ts5.isBigIntLiteral(node) || ts5.isJsxText(node) || node.kind === ts5.SyntaxKind.TrueKeyword || node.kind === ts5.SyntaxKind.FalseKeyword || node.kind === ts5.SyntaxKind.NullKeyword;
|
|
1007
|
+
}
|
|
1008
|
+
function memberRead(node, view) {
|
|
1009
|
+
if (!view.root || !ts5.isIdentifier(node.expression) || view.checker.getSymbolAtLocation(node.expression) !== view.root) return false;
|
|
1010
|
+
const key = ts5.isPropertyAccessExpression(node) ? node.name.text : node.argumentExpression && (ts5.isStringLiteralLike(node.argumentExpression) || ts5.isNumericLiteral(node.argumentExpression)) ? node.argumentExpression.text : void 0;
|
|
1011
|
+
return key !== void 0 && readField(node, key, view);
|
|
1012
|
+
}
|
|
1013
|
+
function readField(node, key, view) {
|
|
1014
|
+
if (!view.checker.getPropertyOfType(view.props, key) || !scalarType(view.checker.getTypeAtLocation(node))) return false;
|
|
1015
|
+
view.reads.add(key);
|
|
1016
|
+
return true;
|
|
1017
|
+
}
|
|
1018
|
+
function jsxView(node, view) {
|
|
1019
|
+
if (ts5.isJsxFragment(node)) return node.children.every((child) => scalarView(child, view, true));
|
|
1020
|
+
if (ts5.isJsxElement(node)) return jsxView(node.openingElement, view) && node.children.every((child) => scalarView(child, view, true));
|
|
1021
|
+
if (!ts5.isJsxOpeningElement(node) && !ts5.isJsxSelfClosingElement(node)) return false;
|
|
1022
|
+
if (!ts5.isIdentifier(node.tagName) || !/^[a-z][A-Za-z0-9]*$/u.test(node.tagName.text)) return false;
|
|
1023
|
+
return node.attributes.properties.every((attribute) => intrinsicAttribute(attribute, view));
|
|
1024
|
+
}
|
|
1025
|
+
function intrinsicAttribute(attribute, view) {
|
|
1026
|
+
return ts5.isJsxAttribute(attribute) && ts5.isIdentifier(attribute.name) && attribute.name.text !== "is" && (!attribute.initializer || scalarView(attribute.initializer, view));
|
|
1027
|
+
}
|
|
1028
|
+
|
|
829
1029
|
// src/rules/_stable-value-binding.ts
|
|
830
1030
|
import { AST_NODE_TYPES as AST_NODE_TYPES6 } from "@typescript-eslint/utils";
|
|
831
1031
|
function typeOnlyReference(reference) {
|
|
@@ -846,8 +1046,106 @@ function stableValueBinding(variable, acceptRead) {
|
|
|
846
1046
|
});
|
|
847
1047
|
}
|
|
848
1048
|
|
|
1049
|
+
// src/rules/_private-scalar-consumer.ts
|
|
1050
|
+
function directEval(node) {
|
|
1051
|
+
let callee = unwrapExpression(node.callee);
|
|
1052
|
+
while (callee.type === AST_NODE_TYPES7.TSInstantiationExpression) callee = unwrapExpression(callee.expression);
|
|
1053
|
+
return callee.type === AST_NODE_TYPES7.Identifier && callee.name === "eval";
|
|
1054
|
+
}
|
|
1055
|
+
function primitiveKeyword(node) {
|
|
1056
|
+
return node !== void 0 && (node.kind === ts6.SyntaxKind.StringKeyword || node.kind === ts6.SyntaxKind.NumberKeyword || node.kind === ts6.SyntaxKind.BooleanKeyword || node.kind === ts6.SyntaxKind.BigIntKeyword);
|
|
1057
|
+
}
|
|
1058
|
+
function nullishPrimitiveUnion(node) {
|
|
1059
|
+
return node !== void 0 && ts6.isUnionTypeNode(node) && node.types.length === 2 && node.types.some(primitiveKeyword) && node.types.some((part) => part.kind === ts6.SyntaxKind.UndefinedKeyword || ts6.isLiteralTypeNode(part) && part.literal.kind === ts6.SyntaxKind.NullKeyword);
|
|
1060
|
+
}
|
|
1061
|
+
function consumerAnnotation(node, auxiliaryScalars = false) {
|
|
1062
|
+
if (node.params.length !== 1) {
|
|
1063
|
+
if (!auxiliaryScalars) return void 0;
|
|
1064
|
+
let annotation;
|
|
1065
|
+
for (const parameter2 of node.params) {
|
|
1066
|
+
if (parameter2.type !== AST_NODE_TYPES7.Identifier && parameter2.type !== AST_NODE_TYPES7.ObjectPattern) continue;
|
|
1067
|
+
const current = parameter2.typeAnnotation?.typeAnnotation;
|
|
1068
|
+
if (current?.type !== AST_NODE_TYPES7.TSTypeLiteral) continue;
|
|
1069
|
+
if (annotation) return void 0;
|
|
1070
|
+
annotation = current;
|
|
1071
|
+
}
|
|
1072
|
+
return annotation;
|
|
1073
|
+
}
|
|
1074
|
+
const parameter = node.params[0];
|
|
1075
|
+
return parameter?.type === AST_NODE_TYPES7.Identifier || parameter?.type === AST_NODE_TYPES7.ObjectPattern ? parameter.typeAnnotation?.typeAnnotation : void 0;
|
|
1076
|
+
}
|
|
1077
|
+
function exportedSymbols(source, checker) {
|
|
1078
|
+
const symbol = checker.getSymbolAtLocation(source);
|
|
1079
|
+
return new Set(symbol ? checker.getExportsOfModule(symbol).map((entry) => (entry.flags & ts6.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(entry) : entry) : []);
|
|
1080
|
+
}
|
|
1081
|
+
function privateScalarConsumer(node, sourceCode, services, exports, options = {}) {
|
|
1082
|
+
const native = services.esTreeNodeToTSNodeMap.get(node);
|
|
1083
|
+
if (!ts6.isFunctionDeclaration(native) && !ts6.isArrowFunction(native) || !native.body) return null;
|
|
1084
|
+
let parameter = native.parameters[0];
|
|
1085
|
+
if (native.parameters.length !== 1) {
|
|
1086
|
+
const annotation = consumerAnnotation(node, options.auxiliaryScalars);
|
|
1087
|
+
const selected = annotation && services.esTreeNodeToTSNodeMap.get(annotation);
|
|
1088
|
+
parameter = native.parameters.find((entry) => entry.type === selected);
|
|
1089
|
+
}
|
|
1090
|
+
if (!parameter || !independentSignature(native, parameter, options.auxiliaryScalars === true)) return null;
|
|
1091
|
+
const checker = services.program.getTypeChecker();
|
|
1092
|
+
if (!ts6.isExternalModule(native.getSourceFile()) || !services.program.getCompilerOptions().strict) return null;
|
|
1093
|
+
if (!privateDirectCallable(node, native, sourceCode, checker, exports)) return null;
|
|
1094
|
+
const signature = checker.getSignatureFromDeclaration(native);
|
|
1095
|
+
if (!signature || signature.typeParameters?.length || checker.getTypePredicateOfSignature(signature)) return null;
|
|
1096
|
+
const expression = returnedExpression(native.body);
|
|
1097
|
+
if (!expression || !checker.isTypeAssignableTo(checker.getTypeAtLocation(expression), checker.getReturnTypeOfSignature(signature))) return null;
|
|
1098
|
+
const auxiliaries = native.parameters.length > 1 ? auxiliaryBindings(native, parameter, checker) : void 0;
|
|
1099
|
+
if (auxiliaries === null) return null;
|
|
1100
|
+
const reads = scalarParameterReads(parameter, native.body, checker, options.scalarCalls ? services.program : void 0, auxiliaries);
|
|
1101
|
+
return reads?.size ? { parameter, reads } : null;
|
|
1102
|
+
}
|
|
1103
|
+
function privateDirectCallable(node, native, sourceCode, checker, exports) {
|
|
1104
|
+
const binding3 = callableBinding(node, sourceCode);
|
|
1105
|
+
if (!binding3 || binding3.defs.length !== 1) return false;
|
|
1106
|
+
const name = ts6.isFunctionDeclaration(native) ? native.name : ts6.isVariableDeclaration(native.parent) ? native.parent.name : void 0;
|
|
1107
|
+
const symbol = name && checker.getSymbolAtLocation(name);
|
|
1108
|
+
return symbol !== void 0 && symbol.declarations?.length === 1 && !exports.has(symbol) && directCalls(binding3, native.parameters.length);
|
|
1109
|
+
}
|
|
1110
|
+
function independentSignature(native, selected, auxiliaryScalars) {
|
|
1111
|
+
if (!auxiliaryScalars && native.parameters.length !== 1 || native.typeParameters?.length || native.asteriskToken || native.modifiers?.length || !primitiveKeyword(native.type)) return false;
|
|
1112
|
+
return native.parameters.every((parameter) => parameter.type !== void 0 && !parameter.modifiers?.length && !parameter.questionToken && !parameter.initializer && !parameter.dotDotDotToken && (!ts6.isIdentifier(parameter.name) || parameter.name.text !== "this") && (parameter === selected || ts6.isIdentifier(parameter.name) && primitiveKeyword(parameter.type)));
|
|
1113
|
+
}
|
|
1114
|
+
function auxiliaryBindings(native, selected, checker) {
|
|
1115
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
1116
|
+
for (const parameter of native.parameters) {
|
|
1117
|
+
if (parameter === selected) continue;
|
|
1118
|
+
const symbol = ts6.isIdentifier(parameter.name) ? checker.getSymbolAtLocation(parameter.name) : void 0;
|
|
1119
|
+
if (!symbol || symbol.declarations?.length !== 1 || symbol.declarations[0] !== parameter || bindings.has(symbol)) return null;
|
|
1120
|
+
bindings.add(symbol);
|
|
1121
|
+
}
|
|
1122
|
+
return bindings;
|
|
1123
|
+
}
|
|
1124
|
+
function callableBinding(node, sourceCode) {
|
|
1125
|
+
if (node.type === AST_NODE_TYPES7.FunctionDeclaration) {
|
|
1126
|
+
if (node.parent.type !== AST_NODE_TYPES7.Program) return void 0;
|
|
1127
|
+
return sourceCode.getDeclaredVariables(node).find((variable) => variable.defs.some((definition) => definition.type === "FunctionName" && definition.node === node));
|
|
1128
|
+
}
|
|
1129
|
+
const declaration = node.parent;
|
|
1130
|
+
if (declaration.type !== AST_NODE_TYPES7.VariableDeclarator || declaration.init !== node || declaration.id.type !== AST_NODE_TYPES7.Identifier || declaration.id.typeAnnotation || declaration.parent.kind !== "const" || declaration.parent.parent.type !== AST_NODE_TYPES7.Program) return void 0;
|
|
1131
|
+
return sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
1132
|
+
}
|
|
1133
|
+
function directCalls(binding3, arity) {
|
|
1134
|
+
let calls = 0;
|
|
1135
|
+
const stable2 = stableValueBinding(binding3, (reference) => {
|
|
1136
|
+
const identifier = reference.identifier;
|
|
1137
|
+
const call = identifier.parent;
|
|
1138
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== AST_NODE_TYPES7.CallExpression || call.callee !== identifier || call.optional || call.typeArguments || call.arguments.length !== arity || !call.arguments.every((argument) => argument.type === AST_NODE_TYPES7.Identifier)) return false;
|
|
1139
|
+
calls += 1;
|
|
1140
|
+
return true;
|
|
1141
|
+
});
|
|
1142
|
+
return stable2 && calls > 0;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
849
1145
|
// src/rules/_react-prop-bindings.ts
|
|
850
1146
|
var VIEWS = /* @__PURE__ */ new WeakMap();
|
|
1147
|
+
var DIRECT_EVAL = /* @__PURE__ */ new WeakMap();
|
|
1148
|
+
var REACT_IMPORTS = /* @__PURE__ */ new WeakMap();
|
|
851
1149
|
var PARAMETER_BINDINGS = /* @__PURE__ */ new WeakMap();
|
|
852
1150
|
function renderFunction(node) {
|
|
853
1151
|
let parent = node.parent;
|
|
@@ -878,13 +1176,14 @@ function firstParameterBindings(source, node) {
|
|
|
878
1176
|
return bindings;
|
|
879
1177
|
}
|
|
880
1178
|
function collectParameterBindings(source, node) {
|
|
1179
|
+
if (hasDirectEval(source)) return /* @__PURE__ */ new Set();
|
|
881
1180
|
const parameter = node.params[0];
|
|
882
1181
|
const identifiers = [];
|
|
883
|
-
if (parameter?.type ===
|
|
1182
|
+
if (parameter?.type === AST_NODE_TYPES8.Identifier)
|
|
884
1183
|
identifiers.push(parameter);
|
|
885
|
-
if (parameter?.type ===
|
|
1184
|
+
if (parameter?.type === AST_NODE_TYPES8.ObjectPattern) {
|
|
886
1185
|
for (const property of parameter.properties) {
|
|
887
|
-
if (property.type ===
|
|
1186
|
+
if (property.type === AST_NODE_TYPES8.Property && !property.computed && property.value.type === AST_NODE_TYPES8.Identifier)
|
|
888
1187
|
identifiers.push(property.value);
|
|
889
1188
|
}
|
|
890
1189
|
}
|
|
@@ -896,17 +1195,34 @@ function collectParameterBindings(source, node) {
|
|
|
896
1195
|
)
|
|
897
1196
|
);
|
|
898
1197
|
}
|
|
1198
|
+
function hasDirectEval(source) {
|
|
1199
|
+
let found = DIRECT_EVAL.get(source);
|
|
1200
|
+
if (found !== void 0) return found;
|
|
1201
|
+
found = source.scopeManager?.scopes.some(
|
|
1202
|
+
(scope) => scope.references.some(({ identifier }) => {
|
|
1203
|
+
if (identifier.type !== AST_NODE_TYPES8.Identifier || identifier.name !== "eval")
|
|
1204
|
+
return false;
|
|
1205
|
+
let callee = outerExpression(identifier);
|
|
1206
|
+
while (callee.parent?.type === AST_NODE_TYPES8.TSInstantiationExpression && callee.parent.expression === callee)
|
|
1207
|
+
callee = outerExpression(callee.parent);
|
|
1208
|
+
const call = callee.parent;
|
|
1209
|
+
return call?.type === AST_NODE_TYPES8.CallExpression && call.callee === callee && !call.optional && directEval(call);
|
|
1210
|
+
})
|
|
1211
|
+
) ?? true;
|
|
1212
|
+
DIRECT_EVAL.set(source, found);
|
|
1213
|
+
return found;
|
|
1214
|
+
}
|
|
899
1215
|
function parameterPath(source, node, bindings) {
|
|
900
1216
|
let current = unwrapExpression(node);
|
|
901
1217
|
for (let depth = 0; depth < 64; depth += 1) {
|
|
902
|
-
if (current.type ===
|
|
1218
|
+
if (current.type === AST_NODE_TYPES8.Identifier) {
|
|
903
1219
|
const variable = ASTUtils3.findVariable(
|
|
904
1220
|
source.getScope(current),
|
|
905
1221
|
current.name
|
|
906
1222
|
);
|
|
907
1223
|
return variable !== null && bindings.has(variable);
|
|
908
1224
|
}
|
|
909
|
-
if (current.type !==
|
|
1225
|
+
if (current.type !== AST_NODE_TYPES8.MemberExpression || current.optional || current.computed && (current.property.type !== AST_NODE_TYPES8.Literal || typeof current.property.value !== "string"))
|
|
910
1226
|
return false;
|
|
911
1227
|
current = unwrapExpression(current.object);
|
|
912
1228
|
}
|
|
@@ -916,8 +1232,8 @@ function reactHook(source, callee, hook) {
|
|
|
916
1232
|
callee = unwrapExpression(callee);
|
|
917
1233
|
let identifier;
|
|
918
1234
|
let namespace = false;
|
|
919
|
-
if (callee.type ===
|
|
920
|
-
else if (callee.type ===
|
|
1235
|
+
if (callee.type === AST_NODE_TYPES8.Identifier) identifier = callee;
|
|
1236
|
+
else if (callee.type === AST_NODE_TYPES8.MemberExpression && !callee.optional && ASTUtils3.getPropertyName(callee) === hook && callee.object.type === AST_NODE_TYPES8.Identifier) {
|
|
921
1237
|
identifier = callee.object;
|
|
922
1238
|
namespace = true;
|
|
923
1239
|
} else return false;
|
|
@@ -925,16 +1241,21 @@ function reactHook(source, callee, hook) {
|
|
|
925
1241
|
source.getScope(identifier),
|
|
926
1242
|
identifier.name
|
|
927
1243
|
);
|
|
928
|
-
if (variable === null
|
|
929
|
-
|
|
1244
|
+
if (variable === null) return false;
|
|
1245
|
+
const specifier = reactImportSpecifier(variable);
|
|
1246
|
+
if (specifier === null) return false;
|
|
1247
|
+
return namespace ? specifier.type === AST_NODE_TYPES8.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES8.ImportNamespaceSpecifier : specifier.type === AST_NODE_TYPES8.ImportSpecifier && specifier.importKind !== "type" && importSpecifierName(specifier) === hook;
|
|
1248
|
+
}
|
|
1249
|
+
function reactImportSpecifier(variable) {
|
|
1250
|
+
let specifier = REACT_IMPORTS.get(variable);
|
|
1251
|
+
if (specifier !== void 0) return specifier;
|
|
930
1252
|
const definition = variable.defs[0];
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
return namespace ? specifier.type === AST_NODE_TYPES7.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES7.ImportNamespaceSpecifier : specifier.type === AST_NODE_TYPES7.ImportSpecifier && specifier.importKind !== "type" && importSpecifierName(specifier) === hook;
|
|
1253
|
+
specifier = variable.defs.length === 1 && definition?.type === "ImportBinding" && definition.parent.type === AST_NODE_TYPES8.ImportDeclaration && definition.parent.source.value === "react" && definition.parent.importKind !== "type" && stableValueBinding(variable) ? definition.node : null;
|
|
1254
|
+
REACT_IMPORTS.set(variable, specifier);
|
|
1255
|
+
return specifier;
|
|
935
1256
|
}
|
|
936
1257
|
function containsView(node) {
|
|
937
|
-
if (node.type ===
|
|
1258
|
+
if (node.type === AST_NODE_TYPES8.JSXElement || node.type === AST_NODE_TYPES8.JSXFragment)
|
|
938
1259
|
return true;
|
|
939
1260
|
if (isFunction(node)) return false;
|
|
940
1261
|
return forEachOwnAstChild(
|
|
@@ -944,7 +1265,7 @@ function containsView(node) {
|
|
|
944
1265
|
);
|
|
945
1266
|
}
|
|
946
1267
|
function isFunction(node) {
|
|
947
|
-
return node.type ===
|
|
1268
|
+
return node.type === AST_NODE_TYPES8.ArrowFunctionExpression || node.type === AST_NODE_TYPES8.FunctionDeclaration || node.type === AST_NODE_TYPES8.FunctionExpression;
|
|
948
1269
|
}
|
|
949
1270
|
|
|
950
1271
|
// src/rules/prefer-server-data-preparation.ts
|
|
@@ -985,7 +1306,7 @@ var PREFER_SERVER_DATA_PREPARATION_DOCUMENTATION = {
|
|
|
985
1306
|
limitations: [
|
|
986
1307
|
"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.",
|
|
987
1308
|
"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.",
|
|
988
|
-
"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. 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.",
|
|
1309
|
+
"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.",
|
|
989
1310
|
"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.",
|
|
990
1311
|
"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."
|
|
991
1312
|
],
|
|
@@ -1042,7 +1363,7 @@ var prefer_server_data_preparation_default = createRule({
|
|
|
1042
1363
|
};
|
|
1043
1364
|
const nativeArray = (node) => {
|
|
1044
1365
|
const callee = unwrapExpression(node.callee);
|
|
1045
|
-
if (callee.type !==
|
|
1366
|
+
if (callee.type !== AST_NODE_TYPES9.MemberExpression) return false;
|
|
1046
1367
|
const receiver = checker.getNonNullableType(
|
|
1047
1368
|
checker.getTypeAtLocation(
|
|
1048
1369
|
services.esTreeNodeToTSNodeMap.get(unwrapExpression(callee.object))
|
|
@@ -1058,15 +1379,15 @@ var prefer_server_data_preparation_default = createRule({
|
|
|
1058
1379
|
)?.declaration;
|
|
1059
1380
|
return declaration !== void 0 && services.program.isSourceFileDefaultLibrary(
|
|
1060
1381
|
declaration.getSourceFile()
|
|
1061
|
-
) &&
|
|
1382
|
+
) && ts7.isInterfaceDeclaration(declaration.parent) && ["Array", "ReadonlyArray"].includes(declaration.parent.name.text);
|
|
1062
1383
|
};
|
|
1063
1384
|
return {
|
|
1064
1385
|
CallExpression(node) {
|
|
1065
1386
|
const callee = unwrapExpression(node.callee);
|
|
1066
|
-
if (node.optional || callee.type !==
|
|
1387
|
+
if (node.optional || callee.type !== AST_NODE_TYPES9.MemberExpression || callee.optional || node.arguments.length !== 1 || !METHODS.has(ASTUtils4.getPropertyName(callee) ?? ""))
|
|
1067
1388
|
return;
|
|
1068
1389
|
const callback = node.arguments[0];
|
|
1069
|
-
if (callback?.type !==
|
|
1390
|
+
if (callback?.type !== AST_NODE_TYPES9.ArrowFunctionExpression && callback?.type !== AST_NODE_TYPES9.FunctionExpression)
|
|
1070
1391
|
return;
|
|
1071
1392
|
const component = renderFunction(node);
|
|
1072
1393
|
if (component === null || !parameterPath(
|
|
@@ -1098,7 +1419,7 @@ var prefer_server_data_preparation_default = createRule({
|
|
|
1098
1419
|
});
|
|
1099
1420
|
function clientDirective(program) {
|
|
1100
1421
|
for (const statement of program.body) {
|
|
1101
|
-
if (statement.type !==
|
|
1422
|
+
if (statement.type !== AST_NODE_TYPES9.ExpressionStatement || statement.directive === void 0)
|
|
1102
1423
|
return false;
|
|
1103
1424
|
if (statement.directive === "use client") return true;
|
|
1104
1425
|
}
|
|
@@ -1108,16 +1429,16 @@ function projection(source, callback, mode = "data") {
|
|
|
1108
1429
|
if (callback.async || callback.generator || callback.params.length !== 1)
|
|
1109
1430
|
return false;
|
|
1110
1431
|
const parameter = callback.params[0];
|
|
1111
|
-
if (parameter?.type ===
|
|
1112
|
-
(property) => property.type !==
|
|
1432
|
+
if (parameter?.type === AST_NODE_TYPES9.ObjectPattern && parameter.properties.some(
|
|
1433
|
+
(property) => property.type !== AST_NODE_TYPES9.Property || property.computed || property.value.type !== AST_NODE_TYPES9.Identifier
|
|
1113
1434
|
))
|
|
1114
1435
|
return false;
|
|
1115
1436
|
const parameters = firstParameterBindings(source, callback);
|
|
1116
1437
|
if (parameters.size === 0) return false;
|
|
1117
1438
|
let body3 = callback.body;
|
|
1118
|
-
if (body3.type ===
|
|
1439
|
+
if (body3.type === AST_NODE_TYPES9.BlockStatement) {
|
|
1119
1440
|
const [statement] = body3.body;
|
|
1120
|
-
if (body3.body.length !== 1 || statement?.type !==
|
|
1441
|
+
if (body3.body.length !== 1 || statement?.type !== AST_NODE_TYPES9.ReturnStatement || statement.argument === null)
|
|
1121
1442
|
return false;
|
|
1122
1443
|
body3 = statement.argument;
|
|
1123
1444
|
}
|
|
@@ -1126,45 +1447,45 @@ function projection(source, callback, mode = "data") {
|
|
|
1126
1447
|
if (depth > 64) return false;
|
|
1127
1448
|
node = unwrapExpression(node);
|
|
1128
1449
|
if (parameterPath(source, node, parameters)) {
|
|
1129
|
-
if (node.type !==
|
|
1450
|
+
if (node.type !== AST_NODE_TYPES9.MemberExpression && callback.params[0]?.type !== AST_NODE_TYPES9.ObjectPattern)
|
|
1130
1451
|
return false;
|
|
1131
1452
|
fieldRead = true;
|
|
1132
1453
|
return true;
|
|
1133
1454
|
}
|
|
1134
|
-
if (node.type ===
|
|
1135
|
-
if (node.type ===
|
|
1455
|
+
if (node.type === AST_NODE_TYPES9.Literal) return !("regex" in node);
|
|
1456
|
+
if (node.type === AST_NODE_TYPES9.UnaryExpression)
|
|
1136
1457
|
return ["!", "+", "-", "~", "typeof"].includes(node.operator) && inspect(node.argument, depth + 1);
|
|
1137
|
-
if (node.type ===
|
|
1458
|
+
if (node.type === AST_NODE_TYPES9.BinaryExpression)
|
|
1138
1459
|
return BINARY.has(node.operator) && inspect(node.left, depth + 1) && inspect(node.right, depth + 1);
|
|
1139
|
-
if (node.type ===
|
|
1460
|
+
if (node.type === AST_NODE_TYPES9.LogicalExpression)
|
|
1140
1461
|
return inspect(node.left, depth + 1) && inspect(node.right, depth + 1);
|
|
1141
|
-
if (node.type ===
|
|
1462
|
+
if (node.type === AST_NODE_TYPES9.ConditionalExpression)
|
|
1142
1463
|
return inspect(node.test, depth + 1) && inspect(node.consequent, depth + 1) && inspect(node.alternate, depth + 1);
|
|
1143
|
-
if (node.type ===
|
|
1464
|
+
if (node.type === AST_NODE_TYPES9.ObjectExpression)
|
|
1144
1465
|
return node.properties.every(
|
|
1145
|
-
(property) => property.type ===
|
|
1466
|
+
(property) => property.type === AST_NODE_TYPES9.Property && property.kind === "init" && !property.method && !property.computed && inspect(property.value, depth + 1)
|
|
1146
1467
|
);
|
|
1147
1468
|
return mode === "view" && displayProjection(node, (child) => inspect(child, depth + 1));
|
|
1148
1469
|
};
|
|
1149
1470
|
return inspect(body3, 0) && fieldRead;
|
|
1150
1471
|
}
|
|
1151
1472
|
function displayProjection(node, inspectChild) {
|
|
1152
|
-
if (node.type ===
|
|
1473
|
+
if (node.type === AST_NODE_TYPES9.JSXElement)
|
|
1153
1474
|
return node.openingElement.attributes.every(
|
|
1154
|
-
(attribute) => attribute.type ===
|
|
1475
|
+
(attribute) => attribute.type === AST_NODE_TYPES9.JSXAttribute && (attribute.value === null || inspectChild(attribute.value))
|
|
1155
1476
|
) && node.children.every(inspectChild);
|
|
1156
|
-
if (node.type ===
|
|
1477
|
+
if (node.type === AST_NODE_TYPES9.JSXFragment)
|
|
1157
1478
|
return node.children.every(inspectChild);
|
|
1158
|
-
if (node.type ===
|
|
1159
|
-
if (node.type ===
|
|
1160
|
-
return node.expression.type ===
|
|
1479
|
+
if (node.type === AST_NODE_TYPES9.JSXText) return true;
|
|
1480
|
+
if (node.type === AST_NODE_TYPES9.JSXExpressionContainer)
|
|
1481
|
+
return node.expression.type === AST_NODE_TYPES9.JSXEmptyExpression || inspectChild(node.expression);
|
|
1161
1482
|
return false;
|
|
1162
1483
|
}
|
|
1163
1484
|
function onlyProjectedInput(source, receiver, nativeArray, cache) {
|
|
1164
1485
|
let root = unwrapExpression(receiver);
|
|
1165
|
-
while (root.type ===
|
|
1486
|
+
while (root.type === AST_NODE_TYPES9.MemberExpression)
|
|
1166
1487
|
root = unwrapExpression(root.object);
|
|
1167
|
-
if (root.type !==
|
|
1488
|
+
if (root.type !== AST_NODE_TYPES9.Identifier) return false;
|
|
1168
1489
|
const variable = ASTUtils4.findVariable(source.getScope(root), root.name);
|
|
1169
1490
|
if (variable === null) return false;
|
|
1170
1491
|
const cached = cache.get(variable);
|
|
@@ -1174,28 +1495,28 @@ function onlyProjectedInput(source, receiver, nativeArray, cache) {
|
|
|
1174
1495
|
if (!reference.isRead()) return false;
|
|
1175
1496
|
let access = outerExpression(reference.identifier);
|
|
1176
1497
|
let parent = access.parent;
|
|
1177
|
-
while (parent?.type ===
|
|
1498
|
+
while (parent?.type === AST_NODE_TYPES9.MemberExpression && parent.object === access) {
|
|
1178
1499
|
access = outerExpression(parent);
|
|
1179
1500
|
parent = access.parent;
|
|
1180
1501
|
}
|
|
1181
1502
|
const member3 = unwrapExpression(access);
|
|
1182
1503
|
const call = parent;
|
|
1183
|
-
if (call?.type !==
|
|
1184
|
-
if (member3.type !==
|
|
1504
|
+
if (call?.type !== AST_NODE_TYPES9.CallExpression) return false;
|
|
1505
|
+
if (member3.type !== AST_NODE_TYPES9.MemberExpression || member3.optional || !METHODS.has(ASTUtils4.getPropertyName(member3) ?? "") || call.optional || call.arguments.length !== 1 || !nativeArray(call))
|
|
1185
1506
|
return false;
|
|
1186
1507
|
const callback = call.arguments[0];
|
|
1187
|
-
return (callback?.type ===
|
|
1508
|
+
return (callback?.type === AST_NODE_TYPES9.ArrowFunctionExpression || callback?.type === AST_NODE_TYPES9.FunctionExpression) && (projection(source, callback) || projection(source, callback, "view")) && call.callee === access;
|
|
1188
1509
|
});
|
|
1189
1510
|
cache.set(variable, projected);
|
|
1190
1511
|
return projected;
|
|
1191
1512
|
}
|
|
1192
1513
|
function clientInteraction(source, node, callable) {
|
|
1193
|
-
if (node.type ===
|
|
1514
|
+
if (node.type === AST_NODE_TYPES9.ArrowFunctionExpression || node.type === AST_NODE_TYPES9.FunctionExpression || node.type === AST_NODE_TYPES9.FunctionDeclaration)
|
|
1194
1515
|
return false;
|
|
1195
|
-
if (node.type ===
|
|
1516
|
+
if (node.type === AST_NODE_TYPES9.CallExpression && (reactHook(source, node.callee, "useState") || reactHook(source, node.callee, "useReducer")))
|
|
1196
1517
|
return true;
|
|
1197
|
-
if (node.type ===
|
|
1198
|
-
(attribute) => attribute.type ===
|
|
1518
|
+
if (node.type === AST_NODE_TYPES9.JSXOpeningElement && node.name.type === AST_NODE_TYPES9.JSXIdentifier && /^[a-z]/u.test(node.name.name) && node.attributes.some(
|
|
1519
|
+
(attribute) => attribute.type === AST_NODE_TYPES9.JSXAttribute && attribute.name.type === AST_NODE_TYPES9.JSXIdentifier && DOM_EVENTS.has(attribute.name.name) && attribute.value?.type === AST_NODE_TYPES9.JSXExpressionContainer && attribute.value.expression.type !== AST_NODE_TYPES9.JSXEmptyExpression && callable(attribute.value.expression)
|
|
1199
1520
|
))
|
|
1200
1521
|
return true;
|
|
1201
1522
|
return forEachOwnAstChild(
|
|
@@ -1206,165 +1527,15 @@ function clientInteraction(source, node, callable) {
|
|
|
1206
1527
|
}
|
|
1207
1528
|
|
|
1208
1529
|
// src/rules/no-readonly-prop-state.ts
|
|
1209
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES11 } from "@typescript-eslint/utils";
|
|
1210
|
-
import ts4 from "typescript";
|
|
1211
|
-
|
|
1212
|
-
// src/rules/_unused-private-binding.ts
|
|
1213
1530
|
import { AST_NODE_TYPES as AST_NODE_TYPES10 } from "@typescript-eslint/utils";
|
|
1214
|
-
|
|
1215
|
-
// src/rules/_type-binding.ts
|
|
1216
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES9 } from "@typescript-eslint/utils";
|
|
1217
|
-
function typeBinding(source, identifier) {
|
|
1218
|
-
let scope = source.getScope(identifier);
|
|
1219
|
-
while (scope !== null) {
|
|
1220
|
-
const variable = scope.set.get(identifier.name);
|
|
1221
|
-
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
1222
|
-
return variable;
|
|
1223
|
-
}
|
|
1224
|
-
scope = scope.upper;
|
|
1225
|
-
}
|
|
1226
|
-
return null;
|
|
1227
|
-
}
|
|
1228
|
-
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
1229
|
-
function retainsNamedTypeUses(source, removed) {
|
|
1230
|
-
const manager = source.scopeManager;
|
|
1231
|
-
if (manager === null) return false;
|
|
1232
|
-
const index = referenceIndex(source, manager);
|
|
1233
|
-
for (const reference of referencesWithin(index.references, removed)) {
|
|
1234
|
-
if (!reference.isRead()) continue;
|
|
1235
|
-
const binding3 = reference.resolved;
|
|
1236
|
-
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
1237
|
-
if (binding3.defs.length === 0) continue;
|
|
1238
|
-
const reads = publicReadExtents(index, binding3);
|
|
1239
|
-
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
1240
|
-
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
1241
|
-
}
|
|
1242
|
-
return true;
|
|
1243
|
-
}
|
|
1244
|
-
function referenceIndex(source, manager) {
|
|
1245
|
-
const cached = REFERENCE_INDEXES.get(source);
|
|
1246
|
-
if (cached?.manager === manager) return cached;
|
|
1247
|
-
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
1248
|
-
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
1249
|
-
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
1250
|
-
REFERENCE_INDEXES.set(source, index);
|
|
1251
|
-
return index;
|
|
1252
|
-
}
|
|
1253
|
-
function* referencesWithin(references, removed) {
|
|
1254
|
-
let low = 0;
|
|
1255
|
-
let high = references.length;
|
|
1256
|
-
while (low < high) {
|
|
1257
|
-
const middle = low + Math.floor((high - low) / 2);
|
|
1258
|
-
const reference = references[middle];
|
|
1259
|
-
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
1260
|
-
else low = middle + 1;
|
|
1261
|
-
}
|
|
1262
|
-
for (let index = low; index < references.length; index++) {
|
|
1263
|
-
const reference = references[index];
|
|
1264
|
-
if (reference === void 0) continue;
|
|
1265
|
-
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
1266
|
-
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
function publicReadExtents(index, binding3) {
|
|
1270
|
-
const cached = index.publicReads.get(binding3);
|
|
1271
|
-
if (cached !== void 0) return cached;
|
|
1272
|
-
let type = null;
|
|
1273
|
-
let value = null;
|
|
1274
|
-
let both = null;
|
|
1275
|
-
for (const retained of binding3.references) {
|
|
1276
|
-
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
1277
|
-
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
1278
|
-
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
1279
|
-
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
1280
|
-
}
|
|
1281
|
-
const result = { type, value, both };
|
|
1282
|
-
index.publicReads.set(binding3, result);
|
|
1283
|
-
return result;
|
|
1284
|
-
}
|
|
1285
|
-
function extendExtent(extent, identifier) {
|
|
1286
|
-
return {
|
|
1287
|
-
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
1288
|
-
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
1289
|
-
};
|
|
1290
|
-
}
|
|
1291
|
-
function publicTypeUse(identifier) {
|
|
1292
|
-
let node = identifier;
|
|
1293
|
-
while (node.parent) {
|
|
1294
|
-
if (node.type === AST_NODE_TYPES9.TSTypeAnnotation || node.type === AST_NODE_TYPES9.TSTypePredicate || node.type === AST_NODE_TYPES9.TSAsExpression || node.type === AST_NODE_TYPES9.TSTypeAssertion) return false;
|
|
1295
|
-
if (node.type === AST_NODE_TYPES9.TSTypeAliasDeclaration) {
|
|
1296
|
-
return node.parent.type === AST_NODE_TYPES9.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === AST_NODE_TYPES9.Program;
|
|
1297
|
-
}
|
|
1298
|
-
if (node.type === AST_NODE_TYPES9.ExportSpecifier) {
|
|
1299
|
-
return node.parent.type === AST_NODE_TYPES9.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === AST_NODE_TYPES9.Program;
|
|
1300
|
-
}
|
|
1301
|
-
node = node.parent;
|
|
1302
|
-
}
|
|
1303
|
-
return false;
|
|
1304
|
-
}
|
|
1305
|
-
function insideTypeRange(node, range) {
|
|
1306
|
-
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
// src/rules/_unused-private-binding.ts
|
|
1310
|
-
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
1311
|
-
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
1312
|
-
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
1313
|
-
if (bindings.length === 0 || bindings.some((binding3) => binding3.defs.length !== allowedDeclarations.length || binding3.defs.some((definition) => !allowedDeclarations.includes(definition.node)) || binding3.eslintUsed || binding3.references.some((reference) => reference.isRead() || reference.init !== true))) return false;
|
|
1314
|
-
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
1315
|
-
const statement = declaration.type === AST_NODE_TYPES10.VariableDeclarator ? declaration.parent : declaration;
|
|
1316
|
-
if (statement.parent.type === AST_NODE_TYPES10.ExportNamedDeclaration || statement.parent.type === AST_NODE_TYPES10.ExportDefaultDeclaration) return false;
|
|
1317
|
-
if (statement.parent.type !== AST_NODE_TYPES10.Program) return statement.parent.type === AST_NODE_TYPES10.BlockStatement;
|
|
1318
|
-
return sourceCode.ast.body.some((node) => node.type === AST_NODE_TYPES10.ImportDeclaration || node.type === AST_NODE_TYPES10.ExportNamedDeclaration || node.type === AST_NODE_TYPES10.ExportDefaultDeclaration || node.type === AST_NODE_TYPES10.ExportAllDeclaration);
|
|
1319
|
-
}
|
|
1320
|
-
function hasOnlyDirectFactoryUses(variable) {
|
|
1321
|
-
return variable.references.every((reference) => {
|
|
1322
|
-
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
1323
|
-
const identifier = reference.identifier;
|
|
1324
|
-
const parent = identifier.parent;
|
|
1325
|
-
if (parent.type === AST_NODE_TYPES10.CallExpression && parent.callee === identifier) return true;
|
|
1326
|
-
return parent.type === AST_NODE_TYPES10.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === AST_NODE_TYPES10.CallExpression && parent.parent.callee === parent;
|
|
1327
|
-
});
|
|
1328
|
-
}
|
|
1329
|
-
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
1330
|
-
function hasIdentifierNamed(node, name) {
|
|
1331
|
-
let names = IDENTIFIER_NAMES.get(node);
|
|
1332
|
-
if (names === void 0) {
|
|
1333
|
-
const collected = /* @__PURE__ */ new Set();
|
|
1334
|
-
const pending = [node];
|
|
1335
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
1336
|
-
while (pending.length > 0) {
|
|
1337
|
-
const current = pending.pop();
|
|
1338
|
-
if (current === void 0 || seen.has(current)) continue;
|
|
1339
|
-
seen.add(current);
|
|
1340
|
-
if (current.type === AST_NODE_TYPES10.Identifier || current.type === AST_NODE_TYPES10.JSXIdentifier) collected.add(current.name);
|
|
1341
|
-
forEachOwnAstChild(current, (child) => {
|
|
1342
|
-
pending.push(child);
|
|
1343
|
-
}, (key) => key !== "tokens" && key !== "comments");
|
|
1344
|
-
}
|
|
1345
|
-
names = collected;
|
|
1346
|
-
IDENTIFIER_NAMES.set(node, names);
|
|
1347
|
-
}
|
|
1348
|
-
return names.has(name);
|
|
1349
|
-
}
|
|
1350
|
-
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
1351
|
-
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== AST_NODE_TYPES10.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
1352
|
-
const text = `boolean${sourceCode.getText(annotation).replace(/[^\r\n\u2028\u2029]/gu, "")}`;
|
|
1353
|
-
const neighbor = Math.max(0, annotation.range[0] - 1);
|
|
1354
|
-
const before = sourceCode.text.slice(neighbor, annotation.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1355
|
-
const after = (sourceCode.text.slice(neighbor, annotation.range[0]) + text + sourceCode.text.slice(annotation.range[1], annotation.range[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1356
|
-
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
1357
|
-
return (fixer) => fixer.replaceText(annotation, text);
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
// src/rules/no-readonly-prop-state.ts
|
|
1531
|
+
import ts8 from "typescript";
|
|
1361
1532
|
var BEFORE2 = "import { useState } from 'react'; export function Status({ status }: { status: string }) { const [savedStatus] = useState(status); return <p>{savedStatus}</p>; }";
|
|
1362
1533
|
var AFTER2 = "export function Status({ status }: { status: string }) { return <p>{status}</p>; }";
|
|
1363
1534
|
var CONFIG2 = {
|
|
1364
1535
|
path: "tsconfig.json",
|
|
1365
1536
|
source: '{"compilerOptions":{"strict":true,"target":"ESNext","module":"ESNext","moduleResolution":"Bundler","jsx":"preserve"},"include":["src/**/*"]}'
|
|
1366
1537
|
};
|
|
1367
|
-
var PRIMITIVE_TYPES =
|
|
1538
|
+
var PRIMITIVE_TYPES = ts8.TypeFlags.StringLike | ts8.TypeFlags.NumberLike | ts8.TypeFlags.BigIntLike | ts8.TypeFlags.BooleanLike | ts8.TypeFlags.ESSymbolLike | ts8.TypeFlags.Null | ts8.TypeFlags.Undefined;
|
|
1368
1539
|
var MAX_TYPE_DEPTH = 16;
|
|
1369
1540
|
var NO_READONLY_PROP_STATE_DOCUMENTATION = {
|
|
1370
1541
|
defaultLevel: "warning",
|
|
@@ -1376,7 +1547,7 @@ var NO_READONLY_PROP_STATE_DOCUMENTATION = {
|
|
|
1376
1547
|
"Advisory only: initial snapshots can be intentional. There is no automatic fix because replacing state with current props changes how later updates behave.",
|
|
1377
1548
|
"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.",
|
|
1378
1549
|
"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.",
|
|
1379
|
-
"An updater read, escape, reassignment or nontrivial destructuring excludes the finding. Unused state values remain owned by unused-variable checks. Opaque initialization, property aliases, optional/dynamic paths, rest/default bindings,
|
|
1550
|
+
"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."
|
|
1380
1551
|
],
|
|
1381
1552
|
references: [
|
|
1382
1553
|
"https://react.dev/learn/choosing-the-state-structure",
|
|
@@ -1418,19 +1589,19 @@ var no_readonly_prop_state_default = createRule({
|
|
|
1418
1589
|
defaultOptions: [],
|
|
1419
1590
|
create(context) {
|
|
1420
1591
|
if (isGeneratedFile(context, context.sourceCode.text) || isTestFile(context) || !context.sourceCode.ast.body.some(
|
|
1421
|
-
(statement) => statement.type ===
|
|
1422
|
-
)
|
|
1592
|
+
(statement) => statement.type === AST_NODE_TYPES10.ImportDeclaration && statement.source.value === "react" && statement.importKind !== "type"
|
|
1593
|
+
))
|
|
1423
1594
|
return {};
|
|
1424
1595
|
return {
|
|
1425
1596
|
CallExpression(node) {
|
|
1426
1597
|
if (node.optional || node.arguments.length !== 1 || !reactHook(context.sourceCode, node.callee, "useState"))
|
|
1427
1598
|
return;
|
|
1428
1599
|
const declaration = outerExpression(node).parent;
|
|
1429
|
-
if (declaration.type !==
|
|
1600
|
+
if (declaration.type !== AST_NODE_TYPES10.VariableDeclarator || declaration.parent.kind !== "const" || !hasReadonlyStateBinding(context.sourceCode, declaration))
|
|
1430
1601
|
return;
|
|
1431
1602
|
const component = renderFunction(node);
|
|
1432
1603
|
const argument = node.arguments[0];
|
|
1433
|
-
if (component === null || argument === void 0 || argument.type ===
|
|
1604
|
+
if (component === null || argument === void 0 || argument.type === AST_NODE_TYPES10.SpreadElement)
|
|
1434
1605
|
return;
|
|
1435
1606
|
const initial = initializerValue(argument);
|
|
1436
1607
|
if (initial === null || !parameterPath(
|
|
@@ -1440,7 +1611,7 @@ var no_readonly_prop_state_default = createRule({
|
|
|
1440
1611
|
))
|
|
1441
1612
|
return;
|
|
1442
1613
|
const lazy = unwrapExpression(argument);
|
|
1443
|
-
if (lazy.type !==
|
|
1614
|
+
if (lazy.type !== AST_NODE_TYPES10.ArrowFunctionExpression && lazy.type !== AST_NODE_TYPES10.FunctionExpression) {
|
|
1444
1615
|
if (!context.sourceCode.parserServices?.program || !context.sourceCode.parserServices.esTreeNodeToTSNodeMap)
|
|
1445
1616
|
return;
|
|
1446
1617
|
const services = getTypeServices(context);
|
|
@@ -1453,9 +1624,9 @@ var no_readonly_prop_state_default = createRule({
|
|
|
1453
1624
|
}
|
|
1454
1625
|
});
|
|
1455
1626
|
function hasReadonlyStateBinding(source, declaration) {
|
|
1456
|
-
if (declaration.id.type !==
|
|
1627
|
+
if (declaration.id.type !== AST_NODE_TYPES10.ArrayPattern) return false;
|
|
1457
1628
|
const [value, setter] = declaration.id.elements;
|
|
1458
|
-
if (value?.type !==
|
|
1629
|
+
if (value?.type !== AST_NODE_TYPES10.Identifier || declaration.id.elements.length > 2 || setter !== void 0 && setter !== null && setter.type !== AST_NODE_TYPES10.Identifier)
|
|
1459
1630
|
return false;
|
|
1460
1631
|
const variables = source.getDeclaredVariables(declaration);
|
|
1461
1632
|
const state = variables.find(
|
|
@@ -1465,7 +1636,7 @@ function hasReadonlyStateBinding(source, declaration) {
|
|
|
1465
1636
|
(reference) => reference.isRead() && !typeOnlyReference(reference)
|
|
1466
1637
|
))
|
|
1467
1638
|
return false;
|
|
1468
|
-
if (setter?.type ===
|
|
1639
|
+
if (setter?.type === AST_NODE_TYPES10.Identifier) {
|
|
1469
1640
|
const updater = variables.find(
|
|
1470
1641
|
(variable) => variable.identifiers.includes(setter)
|
|
1471
1642
|
);
|
|
@@ -1478,12 +1649,12 @@ function hasReadonlyStateBinding(source, declaration) {
|
|
|
1478
1649
|
}
|
|
1479
1650
|
function initializerValue(node) {
|
|
1480
1651
|
node = unwrapExpression(node);
|
|
1481
|
-
if (node.type !==
|
|
1652
|
+
if (node.type !== AST_NODE_TYPES10.ArrowFunctionExpression && node.type !== AST_NODE_TYPES10.FunctionExpression)
|
|
1482
1653
|
return node;
|
|
1483
1654
|
if (node.async || node.generator || node.params.length !== 0) return null;
|
|
1484
|
-
if (node.body.type !==
|
|
1655
|
+
if (node.body.type !== AST_NODE_TYPES10.BlockStatement) return node.body;
|
|
1485
1656
|
const [statement] = node.body.body;
|
|
1486
|
-
return node.body.body.length === 1 && statement?.type ===
|
|
1657
|
+
return node.body.body.length === 1 && statement?.type === AST_NODE_TYPES10.ReturnStatement ? statement.argument : null;
|
|
1487
1658
|
}
|
|
1488
1659
|
function isPrimitiveType(type, depth = 0) {
|
|
1489
1660
|
if (depth >= MAX_TYPE_DEPTH) return false;
|
|
@@ -1493,7 +1664,7 @@ function isPrimitiveType(type, depth = 0) {
|
|
|
1493
1664
|
}
|
|
1494
1665
|
|
|
1495
1666
|
// src/rules/no-runtime-typeof.ts
|
|
1496
|
-
import { AST_NODE_TYPES as
|
|
1667
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES11, ASTUtils as ASTUtils5 } from "@typescript-eslint/utils";
|
|
1497
1668
|
var NO_RUNTIME_TYPEOF_DOCUMENTATION = {
|
|
1498
1669
|
defaultLevel: "error",
|
|
1499
1670
|
summary: "Prefer Zod boundary schemas or discriminated unions over runtime typeof checks.",
|
|
@@ -1611,9 +1782,9 @@ var no_runtime_typeof_default = createRule({
|
|
|
1611
1782
|
UnaryExpression(node) {
|
|
1612
1783
|
if (node.operator !== "typeof") return;
|
|
1613
1784
|
const parent = node.parent;
|
|
1614
|
-
if (node.argument.type ===
|
|
1785
|
+
if (node.argument.type === AST_NODE_TYPES11.Identifier && parent.type === AST_NODE_TYPES11.BinaryExpression && ["===", "!==", "==", "!="].includes(parent.operator)) {
|
|
1615
1786
|
const other = parent.left === node ? parent.right : parent.left;
|
|
1616
|
-
if (other.type ===
|
|
1787
|
+
if (other.type === AST_NODE_TYPES11.Literal && other.value === "undefined" && !ASTUtils5.findVariable(context.sourceCode.getScope(node.argument), node.argument.name)?.defs.length) return;
|
|
1617
1788
|
}
|
|
1618
1789
|
context.report({ node, messageId: "runtimeTypeof" });
|
|
1619
1790
|
}
|
|
@@ -1624,7 +1795,7 @@ var no_runtime_typeof_default = createRule({
|
|
|
1624
1795
|
// src/rules/_is-frontend-source.ts
|
|
1625
1796
|
import { existsSync, readFileSync } from "fs";
|
|
1626
1797
|
import { dirname, join, resolve } from "path";
|
|
1627
|
-
import { AST_NODE_TYPES as
|
|
1798
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
1628
1799
|
var FRONTEND_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom", "next", "preact", "vue", "svelte", "@angular/core", "solid-js", "@sveltejs/kit", "astro"]);
|
|
1629
1800
|
var FRONTEND_IMPORT = /^(?:react(?:-dom)?|next|preact|vue|svelte|@angular\/core|solid-js|@sveltejs\/kit)(?:\/|$)/u;
|
|
1630
1801
|
function isFrontendSource(context) {
|
|
@@ -1652,15 +1823,15 @@ function declaresFrontend(value) {
|
|
|
1652
1823
|
}
|
|
1653
1824
|
function frontendModule(program) {
|
|
1654
1825
|
return program.body.some(
|
|
1655
|
-
(statement) => statement.type ===
|
|
1826
|
+
(statement) => statement.type === AST_NODE_TYPES12.ExpressionStatement && (statement.directive === "use client" || statement.directive === "use server") || statement.type === AST_NODE_TYPES12.ImportDeclaration && FRONTEND_IMPORT.test(statement.source.value)
|
|
1656
1827
|
);
|
|
1657
1828
|
}
|
|
1658
1829
|
|
|
1659
1830
|
// src/rules/no-test-comments.ts
|
|
1660
|
-
import { AST_NODE_TYPES as
|
|
1831
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES14 } from "@typescript-eslint/utils";
|
|
1661
1832
|
|
|
1662
1833
|
// src/rules/_comments.ts
|
|
1663
|
-
import { AST_NODE_TYPES as
|
|
1834
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
1664
1835
|
var REF_RE = /https?:\/\/|\bRFC[- ]?\d+|\bPEP[- ]?\d+|\bCVE-\d{4}|\b(?!UTF-|SHA-|ISO-|AES-|CRC-|MD-|PCM-|EOF-|API-|BASE-)[A-Z][A-Z0-9]{1,9}-\d[A-Z0-9]{0,5}\b|(?<![&\w])#\d{2,6}\b|@[a-z][\w.-]*\.(?:us|com|ai|io|net|org|dev)\b/;
|
|
1665
1836
|
var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
|
|
1666
1837
|
var UNITS_RE = /[~<>]?\d+(?:\.\d+)?\s?(?:ms|s\b|sec\b|seconds?\b|min\b|minutes?\b|hours?\b|days?\b|KB|MB|MiB|GiB|kHz|Hz|bytes?\b|bit\b|-bit\b|%|px\b|rps\b|qps\b)|\b[1-5]xx\b|\b(?:301|302|304|307|308|400|401|403|404|405|409|410|412|422|425|429|500|501|502|503|504)\b/;
|
|
@@ -1746,10 +1917,10 @@ var NARRATION_MAX_WORDS = 6;
|
|
|
1746
1917
|
var NARRATION_MIN_CONTENT = 1;
|
|
1747
1918
|
var TOKEN_PLURAL_MIN = 4;
|
|
1748
1919
|
var RESTATABLE_STATEMENTS = /* @__PURE__ */ new Set([
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1920
|
+
AST_NODE_TYPES13.ExpressionStatement,
|
|
1921
|
+
AST_NODE_TYPES13.ReturnStatement,
|
|
1922
|
+
AST_NODE_TYPES13.ThrowStatement,
|
|
1923
|
+
AST_NODE_TYPES13.VariableDeclaration
|
|
1753
1924
|
]);
|
|
1754
1925
|
var NARRATION_VERB_RE = /^(?:add|append|assign|build|calculate|call|check|clear|close|compute|convert|copy|count|create|declare|decrement|define|delete|extract|fetch|filter|find|format|generate|get|handle|increment|init|initialise|initialize|insert|iterate|join|load|log|loop|make|map|merge|open|parse|print|process|push|read|remove|render|reset|return|save|send|set|setup|sort|split|start|stop|store|update|validate|wrap|write)(?:s|es|d|ed|ing)?$/i;
|
|
1755
1926
|
var NARRATION_STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -1808,12 +1979,12 @@ function restatableStatementBelow(comment, sourceCode) {
|
|
|
1808
1979
|
function restatableStatementNodeBelow(comment, sourceCode) {
|
|
1809
1980
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
1810
1981
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) return null;
|
|
1811
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
1982
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES13.Program; node = node.parent) {
|
|
1812
1983
|
if (!RESTATABLE_STATEMENTS.has(node.type)) continue;
|
|
1813
1984
|
if (node.loc.start.line !== token.loc.start.line || node.loc.end.line !== node.loc.start.line) {
|
|
1814
1985
|
return null;
|
|
1815
1986
|
}
|
|
1816
|
-
if (node.type ===
|
|
1987
|
+
if (node.type === AST_NODE_TYPES13.VariableDeclaration && isTrivialInitializer(node)) {
|
|
1817
1988
|
return null;
|
|
1818
1989
|
}
|
|
1819
1990
|
return node;
|
|
@@ -1823,8 +1994,8 @@ function restatableStatementNodeBelow(comment, sourceCode) {
|
|
|
1823
1994
|
function isTrivialInitializer(node) {
|
|
1824
1995
|
return node.declarations.every((declarator) => {
|
|
1825
1996
|
const init = declarator.init;
|
|
1826
|
-
if (init == null || init.type ===
|
|
1827
|
-
return init.type ===
|
|
1997
|
+
if (init == null || init.type === AST_NODE_TYPES13.Literal) return true;
|
|
1998
|
+
return init.type === AST_NODE_TYPES13.ArrayExpression && init.elements.length === 0 || init.type === AST_NODE_TYPES13.ObjectExpression && init.properties.length === 0;
|
|
1828
1999
|
});
|
|
1829
2000
|
}
|
|
1830
2001
|
function restatesStatementHead(body3, statement) {
|
|
@@ -1974,7 +2145,7 @@ function ownsTestComments(context) {
|
|
|
1974
2145
|
if (!isTestFile(context)) return false;
|
|
1975
2146
|
const filename = scopedFilename(context);
|
|
1976
2147
|
const unambiguous = /(?:^|\/)(?:tests?|__tests__|fixtures|__fixtures__|__mocks__)\//u.test(filename) || /\.(?:test|spec|e2e|integration)\.[cm]?[jt]sx?$/u.test(filename);
|
|
1977
|
-
const framework = context.sourceCode.ast.body.some((statement) => statement.type ===
|
|
2148
|
+
const framework = context.sourceCode.ast.body.some((statement) => statement.type === AST_NODE_TYPES14.ImportDeclaration && statement.importKind !== "type" && (statement.specifiers.length === 0 || statement.specifiers.some((specifier) => specifier.type !== AST_NODE_TYPES14.ImportSpecifier || specifier.importKind !== "type")) && ["vitest", "@jest/globals", "@playwright/test", "bun:test", "node:test"].includes(statement.source.value));
|
|
1978
2149
|
return unambiguous || framework;
|
|
1979
2150
|
}
|
|
1980
2151
|
var no_test_comments_default = createRule({
|
|
@@ -2157,7 +2328,7 @@ function emptyCommentRange(text, comment) {
|
|
|
2157
2328
|
}
|
|
2158
2329
|
|
|
2159
2330
|
// src/rules/prefer-dependency-interface.ts
|
|
2160
|
-
import { AST_NODE_TYPES as
|
|
2331
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES15, ASTUtils as ASTUtils6 } from "@typescript-eslint/utils";
|
|
2161
2332
|
var PREFER_DEPENDENCY_INTERFACE_DOCUMENTATION = {
|
|
2162
2333
|
defaultLevel: "warning",
|
|
2163
2334
|
summary: "Annotate retained collaborators with their existing interface when the consumer uses only that contract.",
|
|
@@ -2182,11 +2353,11 @@ var prefer_dependency_interface_default = createRule({
|
|
|
2182
2353
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2183
2354
|
function contract(node) {
|
|
2184
2355
|
const concrete = definition(node);
|
|
2185
|
-
if (concrete?.type !==
|
|
2356
|
+
if (concrete?.type !== AST_NODE_TYPES15.ClassDeclaration || concrete.abstract || concrete.superClass !== null || concrete.decorators.length !== 0 || concrete.typeParameters !== void 0 || concrete.implements.length !== 1) return null;
|
|
2186
2357
|
const heritage = concrete.implements[0];
|
|
2187
|
-
if (heritage?.expression.type !==
|
|
2358
|
+
if (heritage?.expression.type !== AST_NODE_TYPES15.Identifier) return null;
|
|
2188
2359
|
const port = definition(heritage.expression);
|
|
2189
|
-
return port?.type ===
|
|
2360
|
+
return port?.type === AST_NODE_TYPES15.TSInterfaceDeclaration && port.extends.length === 0 && port.typeParameters === void 0 ? port : null;
|
|
2190
2361
|
}
|
|
2191
2362
|
function definition(node) {
|
|
2192
2363
|
const variable = ASTUtils6.findVariable(context.sourceCode.getScope(node), node.name);
|
|
@@ -2195,18 +2366,18 @@ var prefer_dependency_interface_default = createRule({
|
|
|
2195
2366
|
function usesOnlyInterface(owner, name, port) {
|
|
2196
2367
|
const members = /* @__PURE__ */ new Set();
|
|
2197
2368
|
for (const member3 of port.body.body) {
|
|
2198
|
-
if (member3.type !==
|
|
2369
|
+
if (member3.type !== AST_NODE_TYPES15.TSMethodSignature && member3.type !== AST_NODE_TYPES15.TSPropertySignature || member3.computed || member3.key.type !== AST_NODE_TYPES15.Identifier) return false;
|
|
2199
2370
|
members.add(member3.key.name);
|
|
2200
2371
|
}
|
|
2201
2372
|
let uses = 0;
|
|
2202
2373
|
let compatible = true;
|
|
2203
2374
|
function visit(node) {
|
|
2204
|
-
if (node.type ===
|
|
2375
|
+
if (node.type === AST_NODE_TYPES15.MemberExpression && node.object.type === AST_NODE_TYPES15.ThisExpression && ASTUtils6.getPropertyName(node) === name) {
|
|
2205
2376
|
uses += 1;
|
|
2206
2377
|
const parent = node.parent;
|
|
2207
|
-
if (parent.type !==
|
|
2378
|
+
if (parent.type !== AST_NODE_TYPES15.MemberExpression || parent.object !== node || !members.has(ASTUtils6.getPropertyName(parent) ?? "") || parent.parent.type === AST_NODE_TYPES15.AssignmentExpression && parent.parent.left === parent || parent.parent.type === AST_NODE_TYPES15.UpdateExpression) compatible = false;
|
|
2208
2379
|
}
|
|
2209
|
-
if (node !== owner && (node.type ===
|
|
2380
|
+
if (node !== owner && (node.type === AST_NODE_TYPES15.ClassDeclaration || node.type === AST_NODE_TYPES15.ClassExpression)) return;
|
|
2210
2381
|
forEachOwnAstChild(node, visit);
|
|
2211
2382
|
}
|
|
2212
2383
|
visit(owner);
|
|
@@ -2216,9 +2387,9 @@ var prefer_dependency_interface_default = createRule({
|
|
|
2216
2387
|
TSParameterProperty(node) {
|
|
2217
2388
|
const parameter = node.parameter;
|
|
2218
2389
|
const constructor = node.parent.parent;
|
|
2219
|
-
if (!node.readonly || node.accessibility !== "private" || node.decorators.length !== 0 || parameter.type !==
|
|
2390
|
+
if (!node.readonly || node.accessibility !== "private" || node.decorators.length !== 0 || parameter.type !== AST_NODE_TYPES15.Identifier || parameter.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES15.TSTypeReference || parameter.typeAnnotation.typeAnnotation.typeName.type !== AST_NODE_TYPES15.Identifier || constructor.type !== AST_NODE_TYPES15.MethodDefinition || constructor.kind !== "constructor" || constructor.value.body?.body.length !== 0 || constructor.parent.type !== AST_NODE_TYPES15.ClassBody) return;
|
|
2220
2391
|
const owner = constructor.parent.parent;
|
|
2221
|
-
if (owner.type !==
|
|
2392
|
+
if (owner.type !== AST_NODE_TYPES15.ClassDeclaration && owner.type !== AST_NODE_TYPES15.ClassExpression) return;
|
|
2222
2393
|
if (owner.decorators.length !== 0 || owner.typeParameters !== void 0) return;
|
|
2223
2394
|
const port = contract(parameter.typeAnnotation.typeAnnotation.typeName);
|
|
2224
2395
|
if (port !== null && usesOnlyInterface(owner, parameter.name, port)) context.report({ node: parameter.typeAnnotation, messageId: "interface", data: { contract: port.id.name } });
|
|
@@ -2228,7 +2399,7 @@ var prefer_dependency_interface_default = createRule({
|
|
|
2228
2399
|
});
|
|
2229
2400
|
|
|
2230
2401
|
// src/rules/no-mutating-input-with-result.ts
|
|
2231
|
-
import { AST_NODE_TYPES as
|
|
2402
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES16, ASTUtils as ASTUtils7 } from "@typescript-eslint/utils";
|
|
2232
2403
|
var NO_MUTATING_INPUT_WITH_RESULT_DOCUMENTATION = {
|
|
2233
2404
|
defaultLevel: "warning",
|
|
2234
2405
|
summary: "Return replacement object values instead of writing input fields in result-returning functions.",
|
|
@@ -2246,8 +2417,8 @@ var NO_MUTATING_INPUT_WITH_RESULT_DOCUMENTATION = {
|
|
|
2246
2417
|
]
|
|
2247
2418
|
};
|
|
2248
2419
|
function command(annotation) {
|
|
2249
|
-
if (annotation.type ===
|
|
2250
|
-
if (annotation.type ===
|
|
2420
|
+
if (annotation.type === AST_NODE_TYPES16.TSVoidKeyword || annotation.type === AST_NODE_TYPES16.TSUndefinedKeyword || annotation.type === AST_NODE_TYPES16.TSNeverKeyword) return true;
|
|
2421
|
+
if (annotation.type === AST_NODE_TYPES16.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES16.Identifier && annotation.typeName.name === "Promise" && annotation.typeArguments?.params.length === 1) {
|
|
2251
2422
|
const result = annotation.typeArguments.params[0];
|
|
2252
2423
|
return result !== void 0 && command(result);
|
|
2253
2424
|
}
|
|
@@ -2262,35 +2433,35 @@ function fields(annotation, sourceCode) {
|
|
|
2262
2433
|
return names;
|
|
2263
2434
|
}
|
|
2264
2435
|
function membersOf(annotation, sourceCode) {
|
|
2265
|
-
if (annotation.type ===
|
|
2266
|
-
if (annotation.type !==
|
|
2436
|
+
if (annotation.type === AST_NODE_TYPES16.TSTypeLiteral) return annotation.members;
|
|
2437
|
+
if (annotation.type !== AST_NODE_TYPES16.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES16.Identifier || annotation.typeArguments !== void 0) return [];
|
|
2267
2438
|
const variable = ASTUtils7.findVariable(sourceCode.getScope(annotation.typeName), annotation.typeName.name);
|
|
2268
2439
|
if (variable?.defs.length !== 1) return [];
|
|
2269
2440
|
const definition = variable.defs[0]?.node;
|
|
2270
2441
|
switch (definition?.type) {
|
|
2271
|
-
case
|
|
2442
|
+
case AST_NODE_TYPES16.TSInterfaceDeclaration:
|
|
2272
2443
|
return definition.extends.length === 0 && definition.typeParameters === void 0 ? definition.body.body : [];
|
|
2273
|
-
case
|
|
2274
|
-
return definition.typeParameters === void 0 && definition.typeAnnotation.type ===
|
|
2275
|
-
case
|
|
2444
|
+
case AST_NODE_TYPES16.TSTypeAliasDeclaration:
|
|
2445
|
+
return definition.typeParameters === void 0 && definition.typeAnnotation.type === AST_NODE_TYPES16.TSTypeLiteral ? definition.typeAnnotation.members : [];
|
|
2446
|
+
case AST_NODE_TYPES16.ClassDeclaration:
|
|
2276
2447
|
return definition.superClass === null && definition.typeParameters === void 0 && definition.decorators.length === 0 ? definition.body.body : [];
|
|
2277
2448
|
default:
|
|
2278
2449
|
return [];
|
|
2279
2450
|
}
|
|
2280
2451
|
}
|
|
2281
2452
|
function mutableField(member3) {
|
|
2282
|
-
if (member3.type !==
|
|
2283
|
-
if (member3.type ===
|
|
2284
|
-
if (member3.key.type ===
|
|
2285
|
-
return member3.key.type ===
|
|
2453
|
+
if (member3.type !== AST_NODE_TYPES16.TSPropertySignature && member3.type !== AST_NODE_TYPES16.PropertyDefinition || member3.readonly || member3.computed) return null;
|
|
2454
|
+
if (member3.type === AST_NODE_TYPES16.PropertyDefinition && (member3.static || member3.accessibility === "private" || member3.accessibility === "protected")) return null;
|
|
2455
|
+
if (member3.key.type === AST_NODE_TYPES16.Identifier) return member3.key.name;
|
|
2456
|
+
return member3.key.type === AST_NODE_TYPES16.Literal && (typeof member3.key.value === "string" || typeof member3.key.value === "number") ? String(member3.key.value) : null;
|
|
2286
2457
|
}
|
|
2287
2458
|
function walkBody(node, visit) {
|
|
2288
|
-
if (node.type ===
|
|
2459
|
+
if (node.type === AST_NODE_TYPES16.FunctionDeclaration || node.type === AST_NODE_TYPES16.FunctionExpression || node.type === AST_NODE_TYPES16.ArrowFunctionExpression || node.type === AST_NODE_TYPES16.ClassDeclaration || node.type === AST_NODE_TYPES16.ClassExpression) return;
|
|
2289
2460
|
visit(node);
|
|
2290
|
-
if (node.type ===
|
|
2461
|
+
if (node.type === AST_NODE_TYPES16.BlockStatement) {
|
|
2291
2462
|
for (const statement of node.body) {
|
|
2292
2463
|
walkBody(statement, visit);
|
|
2293
|
-
if (statement.type ===
|
|
2464
|
+
if (statement.type === AST_NODE_TYPES16.ReturnStatement || statement.type === AST_NODE_TYPES16.ThrowStatement) break;
|
|
2294
2465
|
}
|
|
2295
2466
|
return;
|
|
2296
2467
|
}
|
|
@@ -2302,15 +2473,15 @@ function walkBody(node, visit) {
|
|
|
2302
2473
|
forEachOwnAstChild(node, (child) => walkBody(child, visit), (key) => key !== "typeAnnotation" && key !== "returnType");
|
|
2303
2474
|
}
|
|
2304
2475
|
function selectedChildren(node) {
|
|
2305
|
-
if (node.type ===
|
|
2476
|
+
if (node.type === AST_NODE_TYPES16.IfStatement && node.test.type === AST_NODE_TYPES16.Literal) {
|
|
2306
2477
|
const branch = node.test.value ? node.consequent : node.alternate;
|
|
2307
2478
|
return branch === null ? [node.test] : [node.test, branch];
|
|
2308
2479
|
}
|
|
2309
|
-
if (node.type ===
|
|
2480
|
+
if (node.type === AST_NODE_TYPES16.LogicalExpression && node.left.type === AST_NODE_TYPES16.Literal) {
|
|
2310
2481
|
const skips = node.operator === "&&" && !node.left.value || node.operator === "||" && !!node.left.value || node.operator === "??" && node.left.value !== null;
|
|
2311
2482
|
return skips ? [node.left] : [node.left, node.right];
|
|
2312
2483
|
}
|
|
2313
|
-
if (node.type ===
|
|
2484
|
+
if (node.type === AST_NODE_TYPES16.ConditionalExpression && node.test.type === AST_NODE_TYPES16.Literal) return [node.test, node.test.value ? node.consequent : node.alternate];
|
|
2314
2485
|
return null;
|
|
2315
2486
|
}
|
|
2316
2487
|
var no_mutating_input_with_result_default = createRule({
|
|
@@ -2331,21 +2502,21 @@ var no_mutating_input_with_result_default = createRule({
|
|
|
2331
2502
|
if (annotation === void 0 || command(annotation) || node.body === void 0) return;
|
|
2332
2503
|
const inputs = /* @__PURE__ */ new Map();
|
|
2333
2504
|
for (const parameter of node.params) {
|
|
2334
|
-
if (parameter.type !==
|
|
2505
|
+
if (parameter.type !== AST_NODE_TYPES16.Identifier || parameter.typeAnnotation === void 0) continue;
|
|
2335
2506
|
const variable = ASTUtils7.findVariable(sourceCode.getScope(parameter), parameter.name);
|
|
2336
2507
|
if (variable === null || variable.references.some((reference) => reference.isWrite())) continue;
|
|
2337
2508
|
const names = fields(parameter.typeAnnotation.typeAnnotation, sourceCode);
|
|
2338
2509
|
if (names.size > 0) inputs.set(variable, names);
|
|
2339
2510
|
}
|
|
2340
2511
|
if (inputs.size === 0) return;
|
|
2341
|
-
let returned2 = node.body.type !==
|
|
2512
|
+
let returned2 = node.body.type !== AST_NODE_TYPES16.BlockStatement;
|
|
2342
2513
|
const writes = [];
|
|
2343
2514
|
walkBody(node.body, (current) => {
|
|
2344
|
-
if (current.type ===
|
|
2345
|
-
const candidate2 = current.type ===
|
|
2515
|
+
if (current.type === AST_NODE_TYPES16.ReturnStatement && current.argument !== null) returned2 = true;
|
|
2516
|
+
const candidate2 = current.type === AST_NODE_TYPES16.AssignmentExpression ? current.left : current.type === AST_NODE_TYPES16.UpdateExpression || current.type === AST_NODE_TYPES16.UnaryExpression && current.operator === "delete" ? current.argument : null;
|
|
2346
2517
|
if (candidate2 === null) return;
|
|
2347
2518
|
const target = unwrapExpression(candidate2);
|
|
2348
|
-
if (target.type !==
|
|
2519
|
+
if (target.type !== AST_NODE_TYPES16.MemberExpression || target.object.type !== AST_NODE_TYPES16.Identifier) return;
|
|
2349
2520
|
const variable = ASTUtils7.findVariable(sourceCode.getScope(target.object), target.object.name);
|
|
2350
2521
|
const property = ASTUtils7.getPropertyName(target);
|
|
2351
2522
|
if (variable !== null && property !== null && inputs.get(variable)?.has(property)) writes.push({ node: target, name: target.object.name });
|
|
@@ -2358,26 +2529,26 @@ var no_mutating_input_with_result_default = createRule({
|
|
|
2358
2529
|
});
|
|
2359
2530
|
|
|
2360
2531
|
// src/rules/no-negative-only-http-status-assertion.ts
|
|
2361
|
-
import { AST_NODE_TYPES as
|
|
2532
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES21, ASTUtils as ASTUtils12 } from "@typescript-eslint/utils";
|
|
2362
2533
|
|
|
2363
2534
|
// src/rules/_native-fetch-reference.ts
|
|
2364
|
-
import { AST_NODE_TYPES as
|
|
2535
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19, ASTUtils as ASTUtils10 } from "@typescript-eslint/utils";
|
|
2365
2536
|
|
|
2366
2537
|
// src/rules/_native-runtime-unchanged.ts
|
|
2367
|
-
import { AST_NODE_TYPES as
|
|
2538
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES18, ASTUtils as ASTUtils9 } from "@typescript-eslint/utils";
|
|
2368
2539
|
|
|
2369
2540
|
// src/rules/_static-string.ts
|
|
2370
|
-
import { AST_NODE_TYPES as
|
|
2541
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17, ASTUtils as ASTUtils8 } from "@typescript-eslint/utils";
|
|
2371
2542
|
function staticString(node) {
|
|
2372
2543
|
if (node === void 0) return null;
|
|
2373
2544
|
const value = unwrapExpression(node);
|
|
2374
|
-
if (value.type ===
|
|
2375
|
-
return value.type ===
|
|
2545
|
+
if (value.type === AST_NODE_TYPES17.Literal && typeof value.value === "string") return value.value;
|
|
2546
|
+
return value.type === AST_NODE_TYPES17.TemplateLiteral && value.expressions.length === 0 ? value.quasis[0]?.value.cooked ?? null : null;
|
|
2376
2547
|
}
|
|
2377
2548
|
var SCOPED_STRING_VALUES = /* @__PURE__ */ new WeakMap();
|
|
2378
2549
|
function scopedStaticString(node, sourceCode) {
|
|
2379
2550
|
let value = unwrapExpression(node);
|
|
2380
|
-
if (value.type !==
|
|
2551
|
+
if (value.type !== AST_NODE_TYPES17.Identifier) return staticString(value);
|
|
2381
2552
|
let values = SCOPED_STRING_VALUES.get(sourceCode);
|
|
2382
2553
|
if (values === void 0) {
|
|
2383
2554
|
values = /* @__PURE__ */ new WeakMap();
|
|
@@ -2386,7 +2557,7 @@ function scopedStaticString(node, sourceCode) {
|
|
|
2386
2557
|
const seen = /* @__PURE__ */ new Set();
|
|
2387
2558
|
const pending = [];
|
|
2388
2559
|
let result = null;
|
|
2389
|
-
while (value.type ===
|
|
2560
|
+
while (value.type === AST_NODE_TYPES17.Identifier) {
|
|
2390
2561
|
const binding3 = ASTUtils8.findVariable(sourceCode.getScope(value), value.name);
|
|
2391
2562
|
if (binding3 === null || seen.has(binding3)) break;
|
|
2392
2563
|
if (values.has(binding3)) {
|
|
@@ -2396,9 +2567,9 @@ function scopedStaticString(node, sourceCode) {
|
|
|
2396
2567
|
seen.add(binding3);
|
|
2397
2568
|
pending.push(binding3);
|
|
2398
2569
|
const definition = binding3.defs.length === 1 ? binding3.defs[0] : void 0;
|
|
2399
|
-
if (definition?.type !== "Variable" || definition.node.id.type !==
|
|
2570
|
+
if (definition?.type !== "Variable" || definition.node.id.type !== AST_NODE_TYPES17.Identifier || definition.node.init === null || binding3.references.some((reference) => reference.isWrite() && reference.init !== true)) break;
|
|
2400
2571
|
value = unwrapExpression(definition.node.init);
|
|
2401
|
-
if (value.type !==
|
|
2572
|
+
if (value.type !== AST_NODE_TYPES17.Identifier) result = staticString(value);
|
|
2402
2573
|
}
|
|
2403
2574
|
for (const binding3 of pending) values.set(binding3, result);
|
|
2404
2575
|
return result;
|
|
@@ -2406,7 +2577,7 @@ function scopedStaticString(node, sourceCode) {
|
|
|
2406
2577
|
function staticPropertyName(node, sourceCode) {
|
|
2407
2578
|
const direct = ASTUtils8.getPropertyName(node);
|
|
2408
2579
|
if (direct !== null || !node.computed) return direct;
|
|
2409
|
-
const key = node.type ===
|
|
2580
|
+
const key = node.type === AST_NODE_TYPES17.MemberExpression ? node.property : node.key;
|
|
2410
2581
|
return scopedStaticString(key, sourceCode);
|
|
2411
2582
|
}
|
|
2412
2583
|
|
|
@@ -2417,7 +2588,7 @@ function nativeRuntimeUnchanged(sourceCode, name) {
|
|
|
2417
2588
|
const index = runtimeIndex(sourceCode);
|
|
2418
2589
|
const cached = index.results.get(name);
|
|
2419
2590
|
if (cached !== void 0) return cached;
|
|
2420
|
-
const changed = index.nodes.some((node) => node.type ===
|
|
2591
|
+
const changed = index.nodes.some((node) => node.type === AST_NODE_TYPES18.MemberExpression && staticPropertyName(node, sourceCode) === "constructor" || name === "fetch" && node.type === AST_NODE_TYPES18.Property && node.parent.type === AST_NODE_TYPES18.ObjectPattern && staticPropertyName(node, sourceCode) === "constructor" || name === "RegExp" && node.type === AST_NODE_TYPES18.Literal && "regex" in node) || index.references.some((reference) => (name !== "fetch" || !typeOnlyReference(reference)) && unsafeReference(reference.identifier, sourceCode, name, index));
|
|
2421
2592
|
index.results.set(name, !changed);
|
|
2422
2593
|
return !changed;
|
|
2423
2594
|
}
|
|
@@ -2446,8 +2617,8 @@ function unsafeReference(node, sourceCode, name, index) {
|
|
|
2446
2617
|
if (!GLOBAL_OBJECTS.has(node.name)) return false;
|
|
2447
2618
|
const value = outerExpression(node);
|
|
2448
2619
|
const property = value.parent;
|
|
2449
|
-
if (name === "fetch" && property?.type ===
|
|
2450
|
-
if (property?.type !==
|
|
2620
|
+
if (name === "fetch" && property?.type === AST_NODE_TYPES18.UnaryExpression && property.operator === "typeof") return false;
|
|
2621
|
+
if (property?.type !== AST_NODE_TYPES18.MemberExpression || property.object !== value) {
|
|
2451
2622
|
return name !== "fetch" || !fetchProjection(value, sourceCode, index);
|
|
2452
2623
|
}
|
|
2453
2624
|
const key = staticPropertyName(property, sourceCode);
|
|
@@ -2462,15 +2633,15 @@ function ambient(node, sourceCode) {
|
|
|
2462
2633
|
function fetchUse(node, sourceCode) {
|
|
2463
2634
|
const value = outerExpression(node);
|
|
2464
2635
|
const parent = value.parent;
|
|
2465
|
-
if (parent?.type ===
|
|
2466
|
-
if (parent?.type !==
|
|
2636
|
+
if (parent?.type === AST_NODE_TYPES18.CallExpression && parent.callee === value || parent?.type === AST_NODE_TYPES18.UnaryExpression && parent.operator === "typeof") return true;
|
|
2637
|
+
if (parent?.type !== AST_NODE_TYPES18.VariableDeclarator || parent.init !== value || parent.id.type !== AST_NODE_TYPES18.Identifier) return false;
|
|
2467
2638
|
return stableConstBinding(parent.id, sourceCode) ?? false;
|
|
2468
2639
|
}
|
|
2469
2640
|
function stableConstBinding(node, sourceCode) {
|
|
2470
2641
|
const binding3 = ASTUtils9.findVariable(sourceCode.getScope(node), node.name);
|
|
2471
2642
|
if (binding3 === null || binding3.defs.length !== 1) return null;
|
|
2472
2643
|
const [definition] = binding3.defs;
|
|
2473
|
-
return definition?.type === "Variable" && definition.parent.kind === "const" && definition.node.init !== null && definition.parent.parent.type !==
|
|
2644
|
+
return definition?.type === "Variable" && definition.parent.kind === "const" && definition.node.init !== null && definition.parent.parent.type !== AST_NODE_TYPES18.ExportNamedDeclaration && !binding3.references.some((reference) => reference.isWrite() && reference.init !== true) ? binding3 : null;
|
|
2474
2645
|
}
|
|
2475
2646
|
function fetchRead(node, sourceCode, index) {
|
|
2476
2647
|
const use = fetchUse(node, sourceCode);
|
|
@@ -2513,18 +2684,18 @@ function fetchAliasCaptures(binding3, sourceCode) {
|
|
|
2513
2684
|
}
|
|
2514
2685
|
function fetchProjection(node, sourceCode, index) {
|
|
2515
2686
|
const declaration = node.parent;
|
|
2516
|
-
if (declaration?.type !==
|
|
2687
|
+
if (declaration?.type !== AST_NODE_TYPES18.VariableDeclarator || declaration.init !== node || declaration.id.type !== AST_NODE_TYPES18.ObjectPattern || declaration.id.properties.length !== 1) return false;
|
|
2517
2688
|
const [property] = declaration.id.properties;
|
|
2518
|
-
if (property?.type !==
|
|
2689
|
+
if (property?.type !== AST_NODE_TYPES18.Property || staticPropertyName(property, sourceCode) !== "fetch" || property.value.type !== AST_NODE_TYPES18.Identifier) return false;
|
|
2519
2690
|
const binding3 = stableConstBinding(property.value, sourceCode);
|
|
2520
2691
|
return binding3 !== null && fetchAliasRead(binding3, sourceCode, index);
|
|
2521
2692
|
}
|
|
2522
2693
|
function nativeRead(node, name) {
|
|
2523
2694
|
const value = outerExpression(node);
|
|
2524
2695
|
const parent = value.parent;
|
|
2525
|
-
if (parent?.type ===
|
|
2696
|
+
if (parent?.type === AST_NODE_TYPES18.UnaryExpression && parent.operator === "typeof") return true;
|
|
2526
2697
|
if (name !== "Error") return false;
|
|
2527
|
-
return parent?.type ===
|
|
2698
|
+
return parent?.type === AST_NODE_TYPES18.NewExpression && parent.callee === value || parent?.type === AST_NODE_TYPES18.BinaryExpression && parent.operator === "instanceof" && parent.right === value;
|
|
2528
2699
|
}
|
|
2529
2700
|
|
|
2530
2701
|
// src/rules/_native-fetch-reference.ts
|
|
@@ -2534,34 +2705,34 @@ function nativeFetchReference(node, sourceCode) {
|
|
|
2534
2705
|
}
|
|
2535
2706
|
function lexicalFetchReference(node, sourceCode, seen = /* @__PURE__ */ new Set()) {
|
|
2536
2707
|
const expression = unwrapExpression(node);
|
|
2537
|
-
if (expression.type ===
|
|
2708
|
+
if (expression.type === AST_NODE_TYPES19.MemberExpression) {
|
|
2538
2709
|
return staticPropertyName(expression, sourceCode) === "fetch" && globalReceiver(expression.object, sourceCode);
|
|
2539
2710
|
}
|
|
2540
|
-
if (expression.type !==
|
|
2711
|
+
if (expression.type !== AST_NODE_TYPES19.Identifier) return false;
|
|
2541
2712
|
const binding3 = ASTUtils10.findVariable(sourceCode.getScope(expression), expression.name);
|
|
2542
2713
|
if (binding3 === null || binding3.defs.length === 0) return expression.name === "fetch";
|
|
2543
2714
|
if (seen.has(binding3) || seen.size >= 8 || binding3.defs.length !== 1 || binding3.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
2544
2715
|
seen.add(binding3);
|
|
2545
2716
|
const [definition] = binding3.defs;
|
|
2546
2717
|
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init === null) return false;
|
|
2547
|
-
if (definition.node.id.type ===
|
|
2718
|
+
if (definition.node.id.type === AST_NODE_TYPES19.Identifier) {
|
|
2548
2719
|
return lexicalFetchReference(definition.node.init, sourceCode, seen);
|
|
2549
2720
|
}
|
|
2550
|
-
return definition.node.id.type ===
|
|
2721
|
+
return definition.node.id.type === AST_NODE_TYPES19.ObjectPattern && globalReceiver(definition.node.init, sourceCode) && definition.node.id.properties.some((property) => property.type === AST_NODE_TYPES19.Property && staticPropertyName(property, sourceCode) === "fetch" && property.value.type === AST_NODE_TYPES19.Identifier && ASTUtils10.findVariable(sourceCode.getScope(property.value), property.value.name) === binding3);
|
|
2551
2722
|
}
|
|
2552
2723
|
function globalReceiver(node, sourceCode) {
|
|
2553
2724
|
const receiver = unwrapExpression(node);
|
|
2554
|
-
return receiver.type ===
|
|
2725
|
+
return receiver.type === AST_NODE_TYPES19.Identifier && GLOBAL_RECEIVERS2.has(receiver.name) && !ASTUtils10.findVariable(sourceCode.getScope(receiver), receiver.name)?.defs.length;
|
|
2555
2726
|
}
|
|
2556
2727
|
|
|
2557
2728
|
// src/rules/_test-mock-provenance.ts
|
|
2558
|
-
import { AST_NODE_TYPES as
|
|
2729
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES20, ASTUtils as ASTUtils11 } from "@typescript-eslint/utils";
|
|
2559
2730
|
function importedTestMockNamespace(source, identifier) {
|
|
2560
2731
|
const binding3 = ASTUtils11.findVariable(source.getScope(identifier), identifier.name);
|
|
2561
2732
|
const importedBinding = runtimeImportBinding(binding3);
|
|
2562
|
-
if (importedBinding === null || importedBinding.specifier.type !==
|
|
2733
|
+
if (importedBinding === null || importedBinding.specifier.type !== AST_NODE_TYPES20.ImportSpecifier) return null;
|
|
2563
2734
|
const specifier = importedBinding.specifier;
|
|
2564
|
-
const imported = specifier.imported.type ===
|
|
2735
|
+
const imported = specifier.imported.type === AST_NODE_TYPES20.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
2565
2736
|
const module = importedBinding.module;
|
|
2566
2737
|
if (module === "vitest" && (imported === "vi" || imported === "vitest")) return "vitest";
|
|
2567
2738
|
if (module === "@jest/globals" && imported === "jest") return "jest";
|
|
@@ -2582,22 +2753,22 @@ function runtimeTestFrameworkName(source, identifier, kind) {
|
|
|
2582
2753
|
if (importedBinding === null) return null;
|
|
2583
2754
|
const { specifier, module } = importedBinding;
|
|
2584
2755
|
const isNodeAssertion = kind === "assertion" && (module === "node:assert" || module === "node:assert/strict");
|
|
2585
|
-
if (specifier.type ===
|
|
2756
|
+
if (specifier.type === AST_NODE_TYPES20.ImportSpecifier) {
|
|
2586
2757
|
if (isNodeAssertion) return "assert";
|
|
2587
2758
|
if (!TEST_FRAMEWORK_MODULES.has(module)) return null;
|
|
2588
|
-
const imported = specifier.imported.type ===
|
|
2759
|
+
const imported = specifier.imported.type === AST_NODE_TYPES20.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
2589
2760
|
return imported;
|
|
2590
2761
|
}
|
|
2591
2762
|
if (isNodeAssertion) return "assert";
|
|
2592
|
-
return kind === "test" && module === "node:test" && specifier.type ===
|
|
2763
|
+
return kind === "test" && module === "node:test" && specifier.type === AST_NODE_TYPES20.ImportDefaultSpecifier ? "test" : null;
|
|
2593
2764
|
}
|
|
2594
2765
|
function runtimeImportBinding(binding3) {
|
|
2595
2766
|
if (binding3?.defs.length !== 1) return null;
|
|
2596
2767
|
const definition = binding3.defs[0];
|
|
2597
|
-
if (definition?.type !== "ImportBinding" || definition.parent.type !==
|
|
2768
|
+
if (definition?.type !== "ImportBinding" || definition.parent.type !== AST_NODE_TYPES20.ImportDeclaration || definition.parent.importKind === "type") return null;
|
|
2598
2769
|
const specifier = definition.node;
|
|
2599
|
-
if (specifier.type !==
|
|
2600
|
-
if (specifier.type ===
|
|
2770
|
+
if (specifier.type !== AST_NODE_TYPES20.ImportSpecifier && specifier.type !== AST_NODE_TYPES20.ImportDefaultSpecifier && specifier.type !== AST_NODE_TYPES20.ImportNamespaceSpecifier) return null;
|
|
2771
|
+
if (specifier.type === AST_NODE_TYPES20.ImportSpecifier && specifier.importKind === "type") return null;
|
|
2601
2772
|
return { module: definition.parent.source.value, specifier };
|
|
2602
2773
|
}
|
|
2603
2774
|
function vitestFixtureTestName(source, identifier) {
|
|
@@ -2605,24 +2776,24 @@ function vitestFixtureTestName(source, identifier) {
|
|
|
2605
2776
|
}
|
|
2606
2777
|
function fixtureTestName(node, source, seen) {
|
|
2607
2778
|
node = unwrapExpression(node);
|
|
2608
|
-
if (node.type ===
|
|
2779
|
+
if (node.type === AST_NODE_TYPES20.CallExpression) {
|
|
2609
2780
|
const callee = unwrapExpression(node.callee);
|
|
2610
|
-
return !node.optional && callee.type ===
|
|
2781
|
+
return !node.optional && callee.type === AST_NODE_TYPES20.MemberExpression && !callee.optional && ASTUtils11.getPropertyName(callee) === "extend" && node.arguments.length > 0 && !node.arguments.some((argument) => argument.type === AST_NODE_TYPES20.SpreadElement) ? fixtureTestName(callee.object, source, seen) : null;
|
|
2611
2782
|
}
|
|
2612
|
-
if (node.type !==
|
|
2783
|
+
if (node.type !== AST_NODE_TYPES20.Identifier) return null;
|
|
2613
2784
|
const binding3 = ASTUtils11.findVariable(source.getScope(node), node.name);
|
|
2614
2785
|
if (binding3 === null || seen.has(binding3) || !unchangedFixtureApi(binding3)) return null;
|
|
2615
2786
|
seen.add(binding3);
|
|
2616
2787
|
const imported = runtimeImportBinding(binding3);
|
|
2617
|
-
if (imported?.module === "vitest" && imported.specifier.type ===
|
|
2788
|
+
if (imported?.module === "vitest" && imported.specifier.type === AST_NODE_TYPES20.ImportSpecifier) {
|
|
2618
2789
|
const name = imported.specifier.imported;
|
|
2619
|
-
const value = name.type ===
|
|
2790
|
+
const value = name.type === AST_NODE_TYPES20.Identifier ? name.name : name.value;
|
|
2620
2791
|
return value === "test" || value === "it" ? value : null;
|
|
2621
2792
|
}
|
|
2622
2793
|
const definition = binding3.defs[0];
|
|
2623
|
-
if (binding3.defs.length !== 1 || definition?.node.type !==
|
|
2794
|
+
if (binding3.defs.length !== 1 || definition?.node.type !== AST_NODE_TYPES20.VariableDeclarator || definition.node.id.type !== AST_NODE_TYPES20.Identifier || definition.node.parent.kind !== "const" || definition.node.init === null || definition.node.init.range[1] > node.range[0]) return null;
|
|
2624
2795
|
const initializer = unwrapExpression(definition.node.init);
|
|
2625
|
-
return initializer.type ===
|
|
2796
|
+
return initializer.type === AST_NODE_TYPES20.CallExpression ? fixtureTestName(initializer, source, seen) : null;
|
|
2626
2797
|
}
|
|
2627
2798
|
var FIXTURE_API_STABILITY = /* @__PURE__ */ new WeakMap();
|
|
2628
2799
|
function unchangedFixtureApi(binding3) {
|
|
@@ -2632,9 +2803,9 @@ function unchangedFixtureApi(binding3) {
|
|
|
2632
2803
|
if (reference.isWrite()) return reference.init === true;
|
|
2633
2804
|
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
2634
2805
|
let use = outerExpression(reference.identifier);
|
|
2635
|
-
while (use.parent?.type ===
|
|
2806
|
+
while (use.parent?.type === AST_NODE_TYPES20.MemberExpression && use.parent.object === use) use = outerExpression(use.parent);
|
|
2636
2807
|
const parent = use.parent;
|
|
2637
|
-
return parent?.type ===
|
|
2808
|
+
return parent?.type === AST_NODE_TYPES20.CallExpression && parent.callee === use || parent?.type === AST_NODE_TYPES20.ExportSpecifier || parent?.type === AST_NODE_TYPES20.ExportDefaultDeclaration || parent?.type === AST_NODE_TYPES20.TSTypeQuery || parent?.type === AST_NODE_TYPES20.UnaryExpression && parent.operator === "typeof";
|
|
2638
2809
|
});
|
|
2639
2810
|
FIXTURE_API_STABILITY.set(binding3, unchanged);
|
|
2640
2811
|
return unchanged;
|
|
@@ -2664,20 +2835,20 @@ var NO_NEGATIVE_ONLY_HTTP_STATUS_ASSERTION_DOCUMENTATION = {
|
|
|
2664
2835
|
]
|
|
2665
2836
|
};
|
|
2666
2837
|
function statusAssertion(source, call) {
|
|
2667
|
-
if (call.arguments.length !== 1 || call.arguments[0]?.type !==
|
|
2838
|
+
if (call.arguments.length !== 1 || call.arguments[0]?.type !== AST_NODE_TYPES21.Literal || typeof call.arguments[0].value !== "number" || call.callee.type !== AST_NODE_TYPES21.MemberExpression) return null;
|
|
2668
2839
|
const matcher = ASTUtils12.getPropertyName(call.callee);
|
|
2669
2840
|
if (matcher === null) return null;
|
|
2670
2841
|
let object = unwrapExpression(call.callee.object);
|
|
2671
|
-
const negative = object.type ===
|
|
2672
|
-
if (negative && object.type ===
|
|
2673
|
-
if (object.type !==
|
|
2842
|
+
const negative = object.type === AST_NODE_TYPES21.MemberExpression && ASTUtils12.getPropertyName(object) === "not";
|
|
2843
|
+
if (negative && object.type === AST_NODE_TYPES21.MemberExpression) object = unwrapExpression(object.object);
|
|
2844
|
+
if (object.type !== AST_NODE_TYPES21.CallExpression || object.arguments.length !== 1 || object.callee.type !== AST_NODE_TYPES21.Identifier || runtimeTestFrameworkName(source, object.callee, "assertion") !== "expect") return null;
|
|
2674
2845
|
const argument = object.arguments[0];
|
|
2675
|
-
const response = argument === void 0 || argument.type ===
|
|
2846
|
+
const response = argument === void 0 || argument.type === AST_NODE_TYPES21.SpreadElement ? null : fetchResponse(source, argument);
|
|
2676
2847
|
return response === null ? null : { response, expected: call.arguments[0].value, matcher, negative };
|
|
2677
2848
|
}
|
|
2678
2849
|
function fetchResponse(source, value) {
|
|
2679
2850
|
const node = unwrapExpression(value);
|
|
2680
|
-
if (node.type !==
|
|
2851
|
+
if (node.type !== AST_NODE_TYPES21.MemberExpression || ASTUtils12.getPropertyName(node) !== "status" || node.object.type !== AST_NODE_TYPES21.Identifier) return null;
|
|
2681
2852
|
return responseBinding(source, node.object);
|
|
2682
2853
|
}
|
|
2683
2854
|
function responseBinding(source, node, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -2686,50 +2857,50 @@ function responseBinding(source, node, seen = /* @__PURE__ */ new Set()) {
|
|
|
2686
2857
|
if (variable?.defs.length !== 1 || seen.has(variable) || variable.references.some((reference) => reference.isWrite() && !reference.init)) return null;
|
|
2687
2858
|
seen.add(variable);
|
|
2688
2859
|
const parameter = variable.defs[0];
|
|
2689
|
-
if (parameter?.type === "Parameter" && parameter.name.type ===
|
|
2860
|
+
if (parameter?.type === "Parameter" && parameter.name.type === AST_NODE_TYPES21.Identifier) {
|
|
2690
2861
|
const annotation = parameter.name.typeAnnotation?.typeAnnotation;
|
|
2691
|
-
return annotation?.type ===
|
|
2862
|
+
return annotation?.type === AST_NODE_TYPES21.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES21.Identifier && annotation.typeName.name === "Response" && (ASTUtils12.findVariable(source.getScope(annotation.typeName), "Response")?.defs.length ?? 0) === 0 ? variable : null;
|
|
2692
2863
|
}
|
|
2693
|
-
if (definition?.type !==
|
|
2864
|
+
if (definition?.type !== AST_NODE_TYPES21.VariableDeclarator || definition.parent.kind !== "const" || definition.init === null) return null;
|
|
2694
2865
|
let initial = unwrapExpression(definition.init);
|
|
2695
|
-
if (initial.type ===
|
|
2696
|
-
if (initial.type ===
|
|
2866
|
+
if (initial.type === AST_NODE_TYPES21.AwaitExpression) initial = unwrapExpression(initial.argument);
|
|
2867
|
+
if (initial.type === AST_NODE_TYPES21.Identifier) return responseBinding(source, initial, seen);
|
|
2697
2868
|
return nativeResponse(initial, source) ? variable : null;
|
|
2698
2869
|
}
|
|
2699
2870
|
function nativeResponse(initial, source) {
|
|
2700
|
-
if (initial.type ===
|
|
2701
|
-
if (initial.type ===
|
|
2702
|
-
if (initial.type !==
|
|
2871
|
+
if (initial.type === AST_NODE_TYPES21.NewExpression && initial.callee.type === AST_NODE_TYPES21.Identifier && initial.callee.name === "Response" && (ASTUtils12.findVariable(source.getScope(initial.callee), "Response")?.defs.length ?? 0) === 0) return true;
|
|
2872
|
+
if (initial.type === AST_NODE_TYPES21.CallExpression && nativeFetchReference(initial.callee, source)) return true;
|
|
2873
|
+
if (initial.type !== AST_NODE_TYPES21.CallExpression || initial.callee.type !== AST_NODE_TYPES21.Identifier) return false;
|
|
2703
2874
|
const callee = initial.callee;
|
|
2704
2875
|
const binding3 = ASTUtils12.findVariable(source.getScope(callee), callee.name);
|
|
2705
2876
|
if ((binding3?.defs.length ?? 0) === 0) return callee.name === "fetch";
|
|
2706
2877
|
const imported = binding3?.defs[0];
|
|
2707
|
-
if (binding3?.defs.length !== 1 || imported?.type !== "ImportBinding" || imported.parent.type !==
|
|
2878
|
+
if (binding3?.defs.length !== 1 || imported?.type !== "ImportBinding" || imported.parent.type !== AST_NODE_TYPES21.ImportDeclaration || imported.parent.importKind === "type" || !FETCH_MODULES.has(imported.parent.source.value)) return false;
|
|
2708
2879
|
const specifier = imported.node;
|
|
2709
|
-
if (specifier.type ===
|
|
2710
|
-
if (specifier.type !==
|
|
2711
|
-
const importedName7 = specifier.imported.type ===
|
|
2880
|
+
if (specifier.type === AST_NODE_TYPES21.ImportDefaultSpecifier) return imported.parent.source.value === "node-fetch";
|
|
2881
|
+
if (specifier.type !== AST_NODE_TYPES21.ImportSpecifier || specifier.importKind === "type") return false;
|
|
2882
|
+
const importedName7 = specifier.imported.type === AST_NODE_TYPES21.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
2712
2883
|
return importedName7 === "fetch";
|
|
2713
2884
|
}
|
|
2714
2885
|
function enclosingTest(source, node) {
|
|
2715
2886
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
2716
|
-
if (current.type ===
|
|
2717
|
-
if (current.type !==
|
|
2887
|
+
if (current.type === AST_NODE_TYPES21.FunctionDeclaration) return null;
|
|
2888
|
+
if (current.type !== AST_NODE_TYPES21.ArrowFunctionExpression && current.type !== AST_NODE_TYPES21.FunctionExpression) continue;
|
|
2718
2889
|
const registration2 = directArgumentCall(current);
|
|
2719
2890
|
const callee = registration2?.callee;
|
|
2720
|
-
if (callee?.type !==
|
|
2891
|
+
if (callee?.type !== AST_NODE_TYPES21.Identifier) return null;
|
|
2721
2892
|
const name = runtimeTestFrameworkName(source, callee, "test") ?? vitestFixtureTestName(source, callee);
|
|
2722
2893
|
return name === "test" || name === "it" ? current : null;
|
|
2723
2894
|
}
|
|
2724
2895
|
return null;
|
|
2725
2896
|
}
|
|
2726
2897
|
function hasExactStatus(source, test, response) {
|
|
2727
|
-
if (test.body.type !==
|
|
2898
|
+
if (test.body.type !== AST_NODE_TYPES21.BlockStatement) return false;
|
|
2728
2899
|
return test.body.body.some((statement) => {
|
|
2729
|
-
if (statement.type !==
|
|
2900
|
+
if (statement.type !== AST_NODE_TYPES21.ExpressionStatement) return false;
|
|
2730
2901
|
let expression = unwrapExpression(statement.expression);
|
|
2731
|
-
if (expression.type ===
|
|
2732
|
-
if (expression.type !==
|
|
2902
|
+
if (expression.type === AST_NODE_TYPES21.AwaitExpression) expression = unwrapExpression(expression.argument);
|
|
2903
|
+
if (expression.type !== AST_NODE_TYPES21.CallExpression) return false;
|
|
2733
2904
|
const assertion = statusAssertion(source, expression);
|
|
2734
2905
|
return assertion !== null && assertion.response === response && !assertion.negative && EXACT_MATCHERS.has(assertion.matcher) && Number.isInteger(assertion.expected) && assertion.expected >= HTTP_STATUS_MIN && assertion.expected <= SERVER_ERROR_MAX;
|
|
2735
2906
|
});
|
|
@@ -2760,7 +2931,7 @@ var no_negative_only_http_status_assertion_default = createRule({
|
|
|
2760
2931
|
});
|
|
2761
2932
|
|
|
2762
2933
|
// src/rules/prefer-test-fixture-reuse.ts
|
|
2763
|
-
import { AST_NODE_TYPES as
|
|
2934
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES22, ASTUtils as ASTUtils13 } from "@typescript-eslint/utils";
|
|
2764
2935
|
var MAX_DEPTH = 8;
|
|
2765
2936
|
var FRAMEWORKS = /* @__PURE__ */ new Set(["vitest", "@playwright/test"]);
|
|
2766
2937
|
var TEST_MODIFIERS = /* @__PURE__ */ new Set(["only", "skip", "concurrent", "sequential"]);
|
|
@@ -2788,18 +2959,18 @@ function stableBinding(source, identifier) {
|
|
|
2788
2959
|
}
|
|
2789
2960
|
function constructorBinding(source, node, depth = 0) {
|
|
2790
2961
|
node = unwrapExpression(node);
|
|
2791
|
-
if (node.type !==
|
|
2962
|
+
if (node.type !== AST_NODE_TYPES22.Identifier || depth >= MAX_DEPTH) return null;
|
|
2792
2963
|
const variable = stableBinding(source, node);
|
|
2793
2964
|
const definition = variable?.defs[0];
|
|
2794
2965
|
if (variable === null || definition === void 0) return null;
|
|
2795
2966
|
if (definition.type === "ClassName") return variable;
|
|
2796
|
-
if (definition.type === "ImportBinding" && definition.parent.type ===
|
|
2797
|
-
if (definition.node.type ===
|
|
2967
|
+
if (definition.type === "ImportBinding" && definition.parent.type === AST_NODE_TYPES22.ImportDeclaration && definition.parent.importKind !== "type" && (definition.node.type !== AST_NODE_TYPES22.ImportSpecifier || definition.node.importKind !== "type")) return variable;
|
|
2968
|
+
if (definition.node.type === AST_NODE_TYPES22.VariableDeclarator && definition.node.parent.kind === "const" && definition.node.init !== null && definition.node.range[1] < node.range[0]) return constructorBinding(source, definition.node.init, depth + 1);
|
|
2798
2969
|
return null;
|
|
2799
2970
|
}
|
|
2800
2971
|
function fixtureApi(source, expression, depth = 0) {
|
|
2801
2972
|
const node = unwrapExpression(expression);
|
|
2802
|
-
if (node.type !==
|
|
2973
|
+
if (node.type !== AST_NODE_TYPES22.Identifier || depth >= MAX_DEPTH) return null;
|
|
2803
2974
|
const variable = stableBinding(source, node);
|
|
2804
2975
|
const definition = variable?.defs[0];
|
|
2805
2976
|
if (variable === null || definition === void 0) return null;
|
|
@@ -2811,35 +2982,35 @@ function fixtureApi(source, expression, depth = 0) {
|
|
|
2811
2982
|
}
|
|
2812
2983
|
function importedFixtureApi(variable) {
|
|
2813
2984
|
const definition = variable.defs[0];
|
|
2814
|
-
if (definition?.type === "ImportBinding" && definition.parent.type ===
|
|
2985
|
+
if (definition?.type === "ImportBinding" && definition.parent.type === AST_NODE_TYPES22.ImportDeclaration && FRAMEWORKS.has(definition.parent.source.value) && definition.parent.importKind !== "type" && definition.node.type === AST_NODE_TYPES22.ImportSpecifier && definition.node.importKind !== "type") {
|
|
2815
2986
|
const imported = definition.node.imported;
|
|
2816
|
-
const name = imported.type ===
|
|
2987
|
+
const name = imported.type === AST_NODE_TYPES22.Identifier ? imported.name : imported.value;
|
|
2817
2988
|
return name === "test" || name === "it";
|
|
2818
2989
|
}
|
|
2819
2990
|
return false;
|
|
2820
2991
|
}
|
|
2821
2992
|
function fixtureExtension(declaration, before) {
|
|
2822
|
-
if (declaration.type !==
|
|
2993
|
+
if (declaration.type !== AST_NODE_TYPES22.VariableDeclarator || declaration.parent.kind !== "const" || declaration.init === null || declaration.range[1] >= before) return null;
|
|
2823
2994
|
const initial = unwrapExpression(declaration.init);
|
|
2824
|
-
if (initial.type !==
|
|
2995
|
+
if (initial.type !== AST_NODE_TYPES22.CallExpression || initial.optional || initial.arguments.length !== 1 || initial.callee.type !== AST_NODE_TYPES22.MemberExpression || initial.callee.optional || ASTUtils13.getPropertyName(initial.callee) !== "extend") return null;
|
|
2825
2996
|
const declarations = initial.arguments[0];
|
|
2826
|
-
if (declarations?.type !==
|
|
2997
|
+
if (declarations?.type !== AST_NODE_TYPES22.ObjectExpression || declarations.properties.some((property) => property.type !== AST_NODE_TYPES22.Property || property.computed || property.kind !== "init")) return null;
|
|
2827
2998
|
return { receiver: initial.callee.object, declarations };
|
|
2828
2999
|
}
|
|
2829
3000
|
function fixtureApiStable(variable) {
|
|
2830
3001
|
return !variable.references.some((reference) => {
|
|
2831
3002
|
if (reference.isWrite() || reference.isTypeReference && !reference.isValueReference) return false;
|
|
2832
3003
|
let use = reference.identifier;
|
|
2833
|
-
while (use.parent?.type ===
|
|
2834
|
-
return use.parent?.type !==
|
|
3004
|
+
while (use.parent?.type === AST_NODE_TYPES22.MemberExpression && use.parent.object === use) use = use.parent;
|
|
3005
|
+
return use.parent?.type !== AST_NODE_TYPES22.CallExpression || use.parent.callee !== use;
|
|
2835
3006
|
});
|
|
2836
3007
|
}
|
|
2837
3008
|
function fixtureConstructors(source, declarations, inherited) {
|
|
2838
3009
|
const result = new Map(inherited);
|
|
2839
3010
|
for (const property of declarations.properties) {
|
|
2840
|
-
if (property.type !==
|
|
3011
|
+
if (property.type !== AST_NODE_TYPES22.Property || property.computed || property.value.type === AST_NODE_TYPES22.AssignmentPattern) continue;
|
|
2841
3012
|
const name = ASTUtils13.getPropertyName(property);
|
|
2842
|
-
if (name === null || property.value.type ===
|
|
3013
|
+
if (name === null || property.value.type === AST_NODE_TYPES22.TSEmptyBodyFunctionExpression) continue;
|
|
2843
3014
|
const constructor = fixtureConstructor(source, property.value);
|
|
2844
3015
|
if (constructor === null) result.delete(name);
|
|
2845
3016
|
else result.set(name, constructor);
|
|
@@ -2848,24 +3019,24 @@ function fixtureConstructors(source, declarations, inherited) {
|
|
|
2848
3019
|
}
|
|
2849
3020
|
function fixtureConstructor(source, value) {
|
|
2850
3021
|
value = unwrapExpression(value);
|
|
2851
|
-
if (value.type !==
|
|
3022
|
+
if (value.type !== AST_NODE_TYPES22.ArrowFunctionExpression && value.type !== AST_NODE_TYPES22.FunctionExpression) return newConstructor(source, value);
|
|
2852
3023
|
const use = value.params[1];
|
|
2853
|
-
if (use?.type !==
|
|
3024
|
+
if (use?.type !== AST_NODE_TYPES22.Identifier) return null;
|
|
2854
3025
|
const binding3 = stableBinding(source, use);
|
|
2855
|
-
const calls = scopeNodes(value.body, source).filter((node) => node.type ===
|
|
3026
|
+
const calls = scopeNodes(value.body, source).filter((node) => node.type === AST_NODE_TYPES22.CallExpression && !node.optional && node.arguments.length === 1 && node.callee.type === AST_NODE_TYPES22.Identifier && stableBinding(source, node.callee) === binding3);
|
|
2856
3027
|
if (calls.length !== 1 || binding3 === null) return null;
|
|
2857
3028
|
const argument = calls[0]?.arguments[0];
|
|
2858
|
-
return argument === void 0 || argument.type ===
|
|
3029
|
+
return argument === void 0 || argument.type === AST_NODE_TYPES22.SpreadElement ? null : newConstructor(source, argument);
|
|
2859
3030
|
}
|
|
2860
3031
|
function newConstructor(source, expression) {
|
|
2861
3032
|
const value = unwrapExpression(expression);
|
|
2862
|
-
if (value.type ===
|
|
2863
|
-
if (value.type !==
|
|
3033
|
+
if (value.type === AST_NODE_TYPES22.NewExpression) return constructorBinding(source, value.callee);
|
|
3034
|
+
if (value.type !== AST_NODE_TYPES22.Identifier) return null;
|
|
2864
3035
|
const variable = stableBinding(source, value);
|
|
2865
3036
|
const declaration = variable?.defs[0]?.node;
|
|
2866
|
-
if (declaration?.type !==
|
|
3037
|
+
if (declaration?.type !== AST_NODE_TYPES22.VariableDeclarator || declaration.parent.kind !== "const" || declaration.init === null || declaration.range[1] >= value.range[0]) return null;
|
|
2867
3038
|
const initial = unwrapExpression(declaration.init);
|
|
2868
|
-
return initial.type ===
|
|
3039
|
+
return initial.type === AST_NODE_TYPES22.NewExpression ? constructorBinding(source, initial.callee) : null;
|
|
2869
3040
|
}
|
|
2870
3041
|
function scopeNodes(root, source) {
|
|
2871
3042
|
const result = [];
|
|
@@ -2874,7 +3045,7 @@ function scopeNodes(root, source) {
|
|
|
2874
3045
|
const node = pending.pop();
|
|
2875
3046
|
if (node === void 0) continue;
|
|
2876
3047
|
result.push(node);
|
|
2877
|
-
if (node !== root && (node.type ===
|
|
3048
|
+
if (node !== root && (node.type === AST_NODE_TYPES22.ArrowFunctionExpression || node.type === AST_NODE_TYPES22.FunctionExpression || node.type === AST_NODE_TYPES22.FunctionDeclaration || node.type === AST_NODE_TYPES22.ClassDeclaration || node.type === AST_NODE_TYPES22.ClassExpression)) continue;
|
|
2878
3049
|
for (const key of source.visitorKeys[node.type] ?? []) {
|
|
2879
3050
|
const value = Reflect.get(node, key);
|
|
2880
3051
|
if (Array.isArray(value)) pending.push(...value.filter(isNode2));
|
|
@@ -2888,13 +3059,13 @@ function isNode2(value) {
|
|
|
2888
3059
|
}
|
|
2889
3060
|
function testApiCallee(expression) {
|
|
2890
3061
|
let node = unwrapExpression(expression);
|
|
2891
|
-
while (node.type ===
|
|
3062
|
+
while (node.type === AST_NODE_TYPES22.MemberExpression && !node.optional && TEST_MODIFIERS.has(ASTUtils13.getPropertyName(node) ?? "")) node = unwrapExpression(node.object);
|
|
2892
3063
|
return node;
|
|
2893
3064
|
}
|
|
2894
3065
|
function requestingFunction(node) {
|
|
2895
3066
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
2896
|
-
if (current.type ===
|
|
2897
|
-
if (current.type ===
|
|
3067
|
+
if (current.type === AST_NODE_TYPES22.ArrowFunctionExpression || current.type === AST_NODE_TYPES22.FunctionExpression) return current;
|
|
3068
|
+
if (current.type === AST_NODE_TYPES22.FunctionDeclaration) return null;
|
|
2898
3069
|
}
|
|
2899
3070
|
return null;
|
|
2900
3071
|
}
|
|
@@ -2916,12 +3087,12 @@ var prefer_test_fixture_reuse_default = createRule({
|
|
|
2916
3087
|
const call = functionNode === null ? null : directArgumentCall(functionNode);
|
|
2917
3088
|
if (functionNode === null || call === null) return;
|
|
2918
3089
|
const parameter = functionNode.params[0];
|
|
2919
|
-
if (parameter?.type !==
|
|
3090
|
+
if (parameter?.type !== AST_NODE_TYPES22.ObjectPattern) return;
|
|
2920
3091
|
const entries = fixtureApi(context.sourceCode, testApiCallee(call.callee));
|
|
2921
3092
|
const constructor = constructorBinding(context.sourceCode, node.callee);
|
|
2922
3093
|
if (entries === null || constructor === null) return;
|
|
2923
3094
|
for (const property of parameter.properties) {
|
|
2924
|
-
if (property.type !==
|
|
3095
|
+
if (property.type !== AST_NODE_TYPES22.Property || property.computed) continue;
|
|
2925
3096
|
const name = ASTUtils13.getPropertyName(property);
|
|
2926
3097
|
if (name !== null && entries.get(name) === constructor) {
|
|
2927
3098
|
context.report({ node, messageId: "reuseFixture", data: { fixture: name } });
|
|
@@ -2934,7 +3105,7 @@ var prefer_test_fixture_reuse_default = createRule({
|
|
|
2934
3105
|
});
|
|
2935
3106
|
|
|
2936
3107
|
// src/rules/no-return-disposed-resource.ts
|
|
2937
|
-
import { AST_NODE_TYPES as
|
|
3108
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23, ASTUtils as ASTUtils14 } from "@typescript-eslint/utils";
|
|
2938
3109
|
var NO_RETURN_DISPOSED_RESOURCE_DOCUMENTATION = {
|
|
2939
3110
|
defaultLevel: "warning",
|
|
2940
3111
|
summary: "Do not return a resource whose using declaration disposes it before the caller receives it.",
|
|
@@ -2954,16 +3125,16 @@ var NO_RETURN_DISPOSED_RESOURCE_DOCUMENTATION = {
|
|
|
2954
3125
|
};
|
|
2955
3126
|
function owningFunction(node) {
|
|
2956
3127
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
2957
|
-
if (current.type ===
|
|
3128
|
+
if (current.type === AST_NODE_TYPES23.FunctionDeclaration || current.type === AST_NODE_TYPES23.FunctionExpression || current.type === AST_NODE_TYPES23.ArrowFunctionExpression) return current;
|
|
2958
3129
|
}
|
|
2959
3130
|
return null;
|
|
2960
3131
|
}
|
|
2961
3132
|
function resourceOwner(source, value, seen = /* @__PURE__ */ new Set()) {
|
|
2962
3133
|
const node = unwrapExpression(value);
|
|
2963
|
-
if (node.type !==
|
|
3134
|
+
if (node.type !== AST_NODE_TYPES23.Identifier) return null;
|
|
2964
3135
|
const variable = ASTUtils14.findVariable(source.getScope(node), node.name);
|
|
2965
3136
|
const definition = variable?.defs[0];
|
|
2966
|
-
if (variable === null || variable?.defs.length !== 1 || definition === void 0 || seen.has(variable) || variable.references.some((reference) => reference.isWrite() && !reference.init) || definition.node.type !==
|
|
3137
|
+
if (variable === null || variable?.defs.length !== 1 || definition === void 0 || seen.has(variable) || variable.references.some((reference) => reference.isWrite() && !reference.init) || definition.node.type !== AST_NODE_TYPES23.VariableDeclarator) return null;
|
|
2967
3138
|
const declaration = definition.node;
|
|
2968
3139
|
if (declaration.parent.kind === "using" || declaration.parent.kind === "await using") return declaration;
|
|
2969
3140
|
if (declaration.parent.kind !== "const" || declaration.init === null || declaration.range[1] >= node.range[0]) return null;
|
|
@@ -2992,7 +3163,7 @@ var no_return_disposed_resource_default = createRule({
|
|
|
2992
3163
|
});
|
|
2993
3164
|
|
|
2994
3165
|
// src/rules/require-jwt-lifetime.ts
|
|
2995
|
-
import { AST_NODE_TYPES as
|
|
3166
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
|
|
2996
3167
|
var REQUIRE_JWT_LIFETIME_DOCUMENTATION = {
|
|
2997
3168
|
defaultLevel: "warning",
|
|
2998
3169
|
summary: "Require an expiration claim or a maximum token age when returning a verified JWT.",
|
|
@@ -3020,36 +3191,36 @@ var require_jwt_lifetime_default = createRule({
|
|
|
3020
3191
|
function inspect(input) {
|
|
3021
3192
|
if (input === null) return;
|
|
3022
3193
|
let node = unwrapExpression(input);
|
|
3023
|
-
if (node.type ===
|
|
3024
|
-
if (node.type !==
|
|
3194
|
+
if (node.type === AST_NODE_TYPES24.AwaitExpression) node = unwrapExpression(node.argument);
|
|
3195
|
+
if (node.type !== AST_NODE_TYPES24.CallExpression || !isVerifier(node.callee)) return;
|
|
3025
3196
|
if (!missingLifetime(node.arguments[2])) return;
|
|
3026
3197
|
context.report({ node, messageId: "lifetime" });
|
|
3027
3198
|
}
|
|
3028
3199
|
function isVerifier(node) {
|
|
3029
3200
|
node = unwrapExpression(node);
|
|
3030
|
-
if (node.type ===
|
|
3201
|
+
if (node.type === AST_NODE_TYPES24.Identifier) {
|
|
3031
3202
|
const variable = ASTUtils15.findVariable(sourceCode.getScope(node), node.name);
|
|
3032
3203
|
const declaration = variable?.defs[0]?.node;
|
|
3033
|
-
return variable?.defs.length === 1 && declaration?.type ===
|
|
3204
|
+
return variable?.defs.length === 1 && declaration?.type === AST_NODE_TYPES24.ImportSpecifier && declaration.parent.type === AST_NODE_TYPES24.ImportDeclaration && declaration.importKind !== "type" && declaration.parent.importKind !== "type" && declaration.parent.source.value === "jose" && declaration.imported.type === AST_NODE_TYPES24.Identifier && declaration.imported.name === "jwtVerify";
|
|
3034
3205
|
}
|
|
3035
|
-
if (node.type !==
|
|
3206
|
+
if (node.type !== AST_NODE_TYPES24.MemberExpression || ASTUtils15.getPropertyName(node) !== "jwtVerify" || node.object.type !== AST_NODE_TYPES24.Identifier) return false;
|
|
3036
3207
|
const definition = ASTUtils15.findVariable(sourceCode.getScope(node.object), node.object.name)?.defs[0]?.node;
|
|
3037
|
-
return definition?.type ===
|
|
3208
|
+
return definition?.type === AST_NODE_TYPES24.ImportNamespaceSpecifier && definition.parent.importKind !== "type" && definition.parent.source.value === "jose";
|
|
3038
3209
|
}
|
|
3039
3210
|
function missingLifetime(options) {
|
|
3040
3211
|
if (options === void 0) return true;
|
|
3041
|
-
if (options.type !==
|
|
3042
|
-
return !options.properties.some((property) => property.type ===
|
|
3212
|
+
if (options.type !== AST_NODE_TYPES24.ObjectExpression || options.properties.some((property) => property.type !== AST_NODE_TYPES24.Property || property.computed)) return false;
|
|
3213
|
+
return !options.properties.some((property) => property.type === AST_NODE_TYPES24.Property && lifetimeProperty(property));
|
|
3043
3214
|
}
|
|
3044
3215
|
function lifetimeProperty(property) {
|
|
3045
|
-
const name = property.key.type ===
|
|
3216
|
+
const name = property.key.type === AST_NODE_TYPES24.Identifier ? property.key.name : property.key.type === AST_NODE_TYPES24.Literal ? property.key.value : null;
|
|
3046
3217
|
if (name === "maxTokenAge") {
|
|
3047
|
-
if (property.value.type !==
|
|
3218
|
+
if (property.value.type !== AST_NODE_TYPES24.Literal) return true;
|
|
3048
3219
|
return typeof property.value.value === "number" && Number.isFinite(property.value.value) || typeof property.value.value === "string" && property.value.value.trim() !== "";
|
|
3049
3220
|
}
|
|
3050
3221
|
if (name !== "requiredClaims") return false;
|
|
3051
|
-
if (property.value.type !==
|
|
3052
|
-
return property.value.elements.some((element) => element?.type ===
|
|
3222
|
+
if (property.value.type !== AST_NODE_TYPES24.ArrayExpression || property.value.elements.some((element) => element?.type !== AST_NODE_TYPES24.Literal)) return true;
|
|
3223
|
+
return property.value.elements.some((element) => element?.type === AST_NODE_TYPES24.Literal && element.value === "exp");
|
|
3053
3224
|
}
|
|
3054
3225
|
return {
|
|
3055
3226
|
ReturnStatement(node) {
|
|
@@ -3063,7 +3234,7 @@ var require_jwt_lifetime_default = createRule({
|
|
|
3063
3234
|
});
|
|
3064
3235
|
|
|
3065
3236
|
// src/rules/no-discarded-validation-result.ts
|
|
3066
|
-
import { AST_NODE_TYPES as
|
|
3237
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ASTUtils as ASTUtils16 } from "@typescript-eslint/utils";
|
|
3067
3238
|
|
|
3068
3239
|
// src/rules/_zod.ts
|
|
3069
3240
|
var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
|
|
@@ -3099,51 +3270,51 @@ var no_discarded_validation_result_default = createRule({
|
|
|
3099
3270
|
function schema(node, depth = 0) {
|
|
3100
3271
|
if (depth > 24) return null;
|
|
3101
3272
|
node = unwrapExpression(node);
|
|
3102
|
-
if (node.type ===
|
|
3273
|
+
if (node.type === AST_NODE_TYPES25.Identifier) {
|
|
3103
3274
|
const variable = ASTUtils16.findVariable(sourceCode.getScope(node), node.name);
|
|
3104
3275
|
const definition = variable?.defs[0]?.node;
|
|
3105
3276
|
if (variable?.defs.length !== 1) return null;
|
|
3106
|
-
if (definition?.type ===
|
|
3107
|
-
if (definition?.type ===
|
|
3108
|
-
if (definition?.type ===
|
|
3277
|
+
if (definition?.type === AST_NODE_TYPES25.ImportSpecifier && definition.parent.type === AST_NODE_TYPES25.ImportDeclaration && definition.importKind !== "type" && definition.parent.importKind !== "type" && isZodModule(definition.parent.source.value)) return { changed: false };
|
|
3278
|
+
if (definition?.type === AST_NODE_TYPES25.ImportNamespaceSpecifier && definition.parent.importKind !== "type" && isZodModule(definition.parent.source.value)) return { changed: false };
|
|
3279
|
+
if (definition?.type === AST_NODE_TYPES25.VariableDeclarator && definition.parent.kind === "const" && definition.init !== null && definition.range[1] < node.range[0] && !variable.references.some((reference) => reference.isWrite() && !reference.init)) return schema(definition.init, depth + 1);
|
|
3109
3280
|
return null;
|
|
3110
3281
|
}
|
|
3111
|
-
if (node.type ===
|
|
3282
|
+
if (node.type === AST_NODE_TYPES25.MemberExpression) {
|
|
3112
3283
|
const owner2 = schema(node.object, depth + 1);
|
|
3113
3284
|
return owner2;
|
|
3114
3285
|
}
|
|
3115
|
-
if (node.type !==
|
|
3286
|
+
if (node.type !== AST_NODE_TYPES25.CallExpression) return null;
|
|
3116
3287
|
const owner = schema(node.callee, depth + 1);
|
|
3117
3288
|
if (owner === null) return null;
|
|
3118
|
-
const invokedChange = node.callee.type ===
|
|
3119
|
-
const coerced = node.callee.type ===
|
|
3289
|
+
const invokedChange = node.callee.type === AST_NODE_TYPES25.MemberExpression && CHANGING.has(ASTUtils16.getPropertyName(node.callee) ?? "");
|
|
3290
|
+
const coerced = node.callee.type === AST_NODE_TYPES25.MemberExpression && coercionNamespace(node.callee.object);
|
|
3120
3291
|
const changedArgument = node.arguments.some((argument) => {
|
|
3121
|
-
if (argument.type ===
|
|
3122
|
-
if (argument.type ===
|
|
3292
|
+
if (argument.type === AST_NODE_TYPES25.ArrayExpression) return argument.elements.some((element) => element !== null && schema(element, depth + 1)?.changed === true);
|
|
3293
|
+
if (argument.type === AST_NODE_TYPES25.ObjectExpression) return argument.properties.some((property) => property.type === AST_NODE_TYPES25.Property && schema(property.value, depth + 1)?.changed === true);
|
|
3123
3294
|
return schema(argument, depth + 1)?.changed === true;
|
|
3124
3295
|
});
|
|
3125
3296
|
return { changed: owner.changed || invokedChange || coerced || changedArgument };
|
|
3126
3297
|
}
|
|
3127
3298
|
function coercionNamespace(node) {
|
|
3128
3299
|
let namespace = false;
|
|
3129
|
-
if (node.type ===
|
|
3300
|
+
if (node.type === AST_NODE_TYPES25.MemberExpression && ASTUtils16.getPropertyName(node) === "coerce") {
|
|
3130
3301
|
namespace = true;
|
|
3131
3302
|
node = node.object;
|
|
3132
3303
|
}
|
|
3133
|
-
if (node.type !==
|
|
3304
|
+
if (node.type !== AST_NODE_TYPES25.Identifier) return false;
|
|
3134
3305
|
const variable = ASTUtils16.findVariable(sourceCode.getScope(node), node.name);
|
|
3135
3306
|
const definition = variable?.defs[0]?.node;
|
|
3136
|
-
if (variable?.defs.length !== 1 || definition === void 0 || definition.parent.type !==
|
|
3137
|
-
if (definition.type ===
|
|
3138
|
-
if (definition.type !==
|
|
3139
|
-
const name = definition.imported.type ===
|
|
3307
|
+
if (variable?.defs.length !== 1 || definition === void 0 || definition.parent.type !== AST_NODE_TYPES25.ImportDeclaration || definition.parent.importKind === "type" || !isZodModule(definition.parent.source.value)) return false;
|
|
3308
|
+
if (definition.type === AST_NODE_TYPES25.ImportNamespaceSpecifier) return namespace;
|
|
3309
|
+
if (definition.type !== AST_NODE_TYPES25.ImportSpecifier || definition.importKind === "type") return false;
|
|
3310
|
+
const name = definition.imported.type === AST_NODE_TYPES25.Identifier ? definition.imported.name : definition.imported.value;
|
|
3140
3311
|
return namespace ? name === "z" : name === "coerce";
|
|
3141
3312
|
}
|
|
3142
3313
|
return {
|
|
3143
3314
|
ExpressionStatement(statement) {
|
|
3144
3315
|
let expression = unwrapExpression(statement.expression);
|
|
3145
|
-
if (expression.type ===
|
|
3146
|
-
if (expression.type !==
|
|
3316
|
+
if (expression.type === AST_NODE_TYPES25.AwaitExpression) expression = unwrapExpression(expression.argument);
|
|
3317
|
+
if (expression.type !== AST_NODE_TYPES25.CallExpression || expression.callee.type !== AST_NODE_TYPES25.MemberExpression) return;
|
|
3147
3318
|
const method = ASTUtils16.getPropertyName(expression.callee);
|
|
3148
3319
|
if (!(/* @__PURE__ */ new Set(["parse", "parseAsync", "safeParse", "safeParseAsync"])).has(method ?? "")) return;
|
|
3149
3320
|
const owner = schema(expression.callee.object);
|
|
@@ -3154,7 +3325,7 @@ var no_discarded_validation_result_default = createRule({
|
|
|
3154
3325
|
});
|
|
3155
3326
|
|
|
3156
3327
|
// src/rules/production-derived-test-cases.ts
|
|
3157
|
-
import { AST_NODE_TYPES as
|
|
3328
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ASTUtils as ASTUtils17 } from "@typescript-eslint/utils";
|
|
3158
3329
|
var MEMBERSHIP = /(?:^|_)(?:ALLOWED|ELIGIBLE|REQUIRED|SUPPORTED)(?:_|$)/u;
|
|
3159
3330
|
var SUPPORT_PATH = /(?:^|[/_.-])(?:tests?|fixtures?|fakes?|mocks?|stubs?|__tests__)(?:[/_.-]|$)/u;
|
|
3160
3331
|
var PRODUCTION_DERIVED_TEST_CASES_DOCUMENTATION = {
|
|
@@ -3194,47 +3365,47 @@ var production_derived_test_cases_default = createRule({
|
|
|
3194
3365
|
function importedName7(node, module) {
|
|
3195
3366
|
const variable = binding3(node);
|
|
3196
3367
|
const specifier = variable?.defs[0]?.node;
|
|
3197
|
-
if (variable?.defs.length !== 1 || specifier?.type !==
|
|
3198
|
-
return specifier.imported.type ===
|
|
3368
|
+
if (variable?.defs.length !== 1 || specifier?.type !== AST_NODE_TYPES26.ImportSpecifier || specifier.importKind === "type" || specifier.parent.type !== AST_NODE_TYPES26.ImportDeclaration || specifier.parent.importKind === "type" || specifier.parent.source.value !== module || variable.references.some((reference) => reference.isWrite())) return null;
|
|
3369
|
+
return specifier.imported.type === AST_NODE_TYPES26.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
3199
3370
|
}
|
|
3200
3371
|
function production(node) {
|
|
3201
3372
|
node = unwrapExpression(node);
|
|
3202
|
-
if (node.type !==
|
|
3373
|
+
if (node.type !== AST_NODE_TYPES26.Identifier) return null;
|
|
3203
3374
|
const variable = binding3(node);
|
|
3204
3375
|
const specifier = variable?.defs[0]?.node;
|
|
3205
|
-
if (variable?.defs.length !== 1 || specifier?.type !==
|
|
3206
|
-
const name = specifier.imported.type ===
|
|
3376
|
+
if (variable?.defs.length !== 1 || specifier?.type !== AST_NODE_TYPES26.ImportSpecifier || specifier.importKind === "type" || specifier.parent.type !== AST_NODE_TYPES26.ImportDeclaration || specifier.parent.importKind === "type" || !specifier.parent.source.value.startsWith(".") || SUPPORT_PATH.test(specifier.parent.source.value) || variable.references.some((reference) => reference.isWrite())) return null;
|
|
3377
|
+
const name = specifier.imported.type === AST_NODE_TYPES26.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
3207
3378
|
return MEMBERSHIP.test(name) && !name.endsWith("REGISTRY") ? variable : null;
|
|
3208
3379
|
}
|
|
3209
3380
|
function runner(node) {
|
|
3210
3381
|
node = unwrapExpression(node);
|
|
3211
|
-
while (node.type ===
|
|
3212
|
-
if (node.type !==
|
|
3382
|
+
while (node.type === AST_NODE_TYPES26.MemberExpression && ["only", "skip", "concurrent", "sequential"].includes(ASTUtils17.getPropertyName(node) ?? "")) node = unwrapExpression(node.object);
|
|
3383
|
+
if (node.type !== AST_NODE_TYPES26.Identifier) return false;
|
|
3213
3384
|
const name = importedName7(node, "vitest");
|
|
3214
3385
|
return name === "test" || name === "it" || vitestFixtureTestName(sourceCode, node) !== null;
|
|
3215
3386
|
}
|
|
3216
3387
|
function caseTable(node) {
|
|
3217
|
-
return node.type ===
|
|
3388
|
+
return node.type === AST_NODE_TYPES26.CallExpression && node.callee.type === AST_NODE_TYPES26.MemberExpression && ["each", "for"].includes(ASTUtils17.getPropertyName(node.callee) ?? "") && runner(node.callee.object);
|
|
3218
3389
|
}
|
|
3219
3390
|
function literalTable(node, seen = /* @__PURE__ */ new Set()) {
|
|
3220
3391
|
node = unwrapExpression(node);
|
|
3221
3392
|
if (seen.has(node)) return false;
|
|
3222
3393
|
seen.add(node);
|
|
3223
|
-
if (node.type ===
|
|
3394
|
+
if (node.type === AST_NODE_TYPES26.Identifier) {
|
|
3224
3395
|
const variable = binding3(node);
|
|
3225
3396
|
const definition = variable?.defs[0]?.node;
|
|
3226
|
-
return variable?.defs.length === 1 && definition?.type ===
|
|
3397
|
+
return variable?.defs.length === 1 && definition?.type === AST_NODE_TYPES26.VariableDeclarator && definition.parent.kind === "const" && definition.init !== null && definition.range[1] < node.range[0] && variable.references.every((reference) => reference.init || !reference.isWrite() && reference.identifier.parent.type === AST_NODE_TYPES26.CallExpression && (caseTable(reference.identifier.parent) || reference.identifier.parent.callee.type === AST_NODE_TYPES26.Identifier && importedName7(reference.identifier.parent.callee, "vitest") === "expect" || reference.identifier.parent.callee.type === AST_NODE_TYPES26.MemberExpression && ["toEqual", "toStrictEqual"].includes(ASTUtils17.getPropertyName(reference.identifier.parent.callee) ?? ""))) && literalTable(definition.init, seen);
|
|
3227
3398
|
}
|
|
3228
|
-
return node.type ===
|
|
3399
|
+
return node.type === AST_NODE_TYPES26.ArrayExpression && node.elements.every((element) => element?.type === AST_NODE_TYPES26.Literal && !("regex" in element));
|
|
3229
3400
|
}
|
|
3230
3401
|
function unconditional(node) {
|
|
3231
3402
|
const statement = node.parent;
|
|
3232
|
-
if (statement.type !==
|
|
3233
|
-
if (statement.parent.type ===
|
|
3403
|
+
if (statement.type !== AST_NODE_TYPES26.ExpressionStatement) return false;
|
|
3404
|
+
if (statement.parent.type === AST_NODE_TYPES26.Program) return true;
|
|
3234
3405
|
const block = statement.parent;
|
|
3235
|
-
if (block.type !==
|
|
3406
|
+
if (block.type !== AST_NODE_TYPES26.BlockStatement || block.parent.type !== AST_NODE_TYPES26.ArrowFunctionExpression && block.parent.type !== AST_NODE_TYPES26.FunctionExpression) return false;
|
|
3236
3407
|
const call = block.parent.parent;
|
|
3237
|
-
return call.type ===
|
|
3408
|
+
return call.type === AST_NODE_TYPES26.CallExpression && runner(call.callee);
|
|
3238
3409
|
}
|
|
3239
3410
|
return {
|
|
3240
3411
|
CallExpression(node) {
|
|
@@ -3242,9 +3413,9 @@ var production_derived_test_cases_default = createRule({
|
|
|
3242
3413
|
const variable2 = production(node.arguments[0]);
|
|
3243
3414
|
if (variable2 !== null) tables.push({ node, variable: variable2 });
|
|
3244
3415
|
}
|
|
3245
|
-
if (node.callee.type !==
|
|
3416
|
+
if (node.callee.type !== AST_NODE_TYPES26.MemberExpression || !["toEqual", "toStrictEqual"].includes(ASTUtils17.getPropertyName(node.callee) ?? "") || node.arguments.length !== 1 || node.arguments[0] === void 0 || !literalTable(node.arguments[0]) || !unconditional(node)) return;
|
|
3246
3417
|
const expect = node.callee.object;
|
|
3247
|
-
if (expect.type !==
|
|
3418
|
+
if (expect.type !== AST_NODE_TYPES26.CallExpression || expect.callee.type !== AST_NODE_TYPES26.Identifier || importedName7(expect.callee, "vitest") !== "expect" || expect.arguments.length !== 1 || expect.arguments[0] === void 0) return;
|
|
3248
3419
|
const variable = production(expect.arguments[0]);
|
|
3249
3420
|
if (variable !== null) asserted.add(variable);
|
|
3250
3421
|
},
|
|
@@ -3256,14 +3427,14 @@ var production_derived_test_cases_default = createRule({
|
|
|
3256
3427
|
});
|
|
3257
3428
|
|
|
3258
3429
|
// src/rules/require-constrained-schema-integer.ts
|
|
3259
|
-
import { AST_NODE_TYPES as
|
|
3430
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES27, ASTUtils as ASTUtils18 } from "@typescript-eslint/utils";
|
|
3260
3431
|
var FIELD_MINIMUMS = /* @__PURE__ */ new Map([["limit", 1], ["version", 0]]);
|
|
3261
3432
|
var NUMBER_FACTORIES = /* @__PURE__ */ new Set(["number", "int", "int32", "uint32"]);
|
|
3262
3433
|
var PRESERVING = /* @__PURE__ */ new Set(["optional", "nullable", "nullish", "default", "catch", "readonly", "brand", "describe", "meta", "max", "lte", "lt", "finite", "safe", "multipleOf"]);
|
|
3263
3434
|
function numericLiteral(node) {
|
|
3264
3435
|
node = unwrapExpression(node);
|
|
3265
|
-
if (node.type ===
|
|
3266
|
-
if (node.type ===
|
|
3436
|
+
if (node.type === AST_NODE_TYPES27.Literal && typeof node.value === "number") return node.value;
|
|
3437
|
+
if (node.type === AST_NODE_TYPES27.UnaryExpression && (node.operator === "-" || node.operator === "+")) {
|
|
3267
3438
|
const value = numericLiteral(node.argument);
|
|
3268
3439
|
return value === null ? null : node.operator === "-" ? -value : value;
|
|
3269
3440
|
}
|
|
@@ -3300,34 +3471,34 @@ var require_constrained_schema_integer_default = createRule({
|
|
|
3300
3471
|
const sourceCode = context.sourceCode;
|
|
3301
3472
|
function factory(node) {
|
|
3302
3473
|
node = unwrapExpression(node);
|
|
3303
|
-
if (node.type ===
|
|
3474
|
+
if (node.type === AST_NODE_TYPES27.Identifier) {
|
|
3304
3475
|
const definition2 = imported(node);
|
|
3305
|
-
return definition2?.type ===
|
|
3476
|
+
return definition2?.type === AST_NODE_TYPES27.ImportSpecifier ? definition2.imported.type === AST_NODE_TYPES27.Identifier ? definition2.imported.name : definition2.imported.value : null;
|
|
3306
3477
|
}
|
|
3307
|
-
if (node.type !==
|
|
3478
|
+
if (node.type !== AST_NODE_TYPES27.MemberExpression) return null;
|
|
3308
3479
|
let receiver = unwrapExpression(node.object);
|
|
3309
|
-
if (receiver.type ===
|
|
3310
|
-
if (receiver.type !==
|
|
3480
|
+
if (receiver.type === AST_NODE_TYPES27.MemberExpression && ASTUtils18.getPropertyName(receiver) === "coerce") receiver = unwrapExpression(receiver.object);
|
|
3481
|
+
if (receiver.type !== AST_NODE_TYPES27.Identifier) return null;
|
|
3311
3482
|
const definition = imported(receiver);
|
|
3312
|
-
if (definition === null || definition.type ===
|
|
3483
|
+
if (definition === null || definition.type === AST_NODE_TYPES27.ImportSpecifier && (definition.imported.type === AST_NODE_TYPES27.Identifier ? definition.imported.name : definition.imported.value) !== "z") return null;
|
|
3313
3484
|
return ASTUtils18.getPropertyName(node);
|
|
3314
3485
|
}
|
|
3315
3486
|
function imported(identifier) {
|
|
3316
3487
|
const variable = ASTUtils18.findVariable(sourceCode.getScope(identifier), identifier.name);
|
|
3317
3488
|
const definition = variable?.defs[0]?.node;
|
|
3318
|
-
if (variable?.defs.length !== 1 || definition?.type !==
|
|
3319
|
-
return definition.type ===
|
|
3489
|
+
if (variable?.defs.length !== 1 || definition?.type !== AST_NODE_TYPES27.ImportSpecifier && definition?.type !== AST_NODE_TYPES27.ImportNamespaceSpecifier || definition.parent.type !== AST_NODE_TYPES27.ImportDeclaration || definition.parent.importKind === "type" || !isZodModule(definition.parent.source.value)) return null;
|
|
3490
|
+
return definition.type === AST_NODE_TYPES27.ImportSpecifier && definition.importKind === "type" ? null : definition;
|
|
3320
3491
|
}
|
|
3321
3492
|
function constrained(value, minimum) {
|
|
3322
3493
|
const calls = [];
|
|
3323
3494
|
value = unwrapExpression(value);
|
|
3324
|
-
while (value.type ===
|
|
3495
|
+
while (value.type === AST_NODE_TYPES27.CallExpression) {
|
|
3325
3496
|
const name = factory(value.callee);
|
|
3326
3497
|
if (name !== null) {
|
|
3327
3498
|
return chainContract(name, calls, minimum);
|
|
3328
3499
|
}
|
|
3329
3500
|
const callee = unwrapExpression(value.callee);
|
|
3330
|
-
if (callee.type !==
|
|
3501
|
+
if (callee.type !== AST_NODE_TYPES27.MemberExpression) return null;
|
|
3331
3502
|
const method = ASTUtils18.getPropertyName(callee);
|
|
3332
3503
|
if (method === null) return null;
|
|
3333
3504
|
calls.push({ method, call: value });
|
|
@@ -3353,7 +3524,7 @@ var require_constrained_schema_integer_default = createRule({
|
|
|
3353
3524
|
}
|
|
3354
3525
|
function lowerBound(call, minimum, exclusive) {
|
|
3355
3526
|
const argument = call.arguments[0];
|
|
3356
|
-
if (argument === void 0 || argument.type ===
|
|
3527
|
+
if (argument === void 0 || argument.type === AST_NODE_TYPES27.SpreadElement) return null;
|
|
3357
3528
|
const bound = numericLiteral(argument);
|
|
3358
3529
|
return bound === null || bound >= minimum - (exclusive ? 1 : 0);
|
|
3359
3530
|
}
|
|
@@ -3362,9 +3533,9 @@ var require_constrained_schema_integer_default = createRule({
|
|
|
3362
3533
|
const name = factory(node.callee);
|
|
3363
3534
|
if (name === null || !["object", "strictObject", "looseObject"].includes(name) || node.arguments.length !== 1) return;
|
|
3364
3535
|
const shape = node.arguments[0];
|
|
3365
|
-
if (shape?.type !==
|
|
3536
|
+
if (shape?.type !== AST_NODE_TYPES27.ObjectExpression) return;
|
|
3366
3537
|
for (const property of shape.properties) {
|
|
3367
|
-
if (property.type !==
|
|
3538
|
+
if (property.type !== AST_NODE_TYPES27.Property || property.computed || property.kind !== "init" || property.method) continue;
|
|
3368
3539
|
const field = ASTUtils18.getPropertyName(property);
|
|
3369
3540
|
const minimum = field === null ? void 0 : FIELD_MINIMUMS.get(field);
|
|
3370
3541
|
if (minimum === void 0 || field === null || constrained(property.value, minimum) !== false) continue;
|
|
@@ -3376,7 +3547,7 @@ var require_constrained_schema_integer_default = createRule({
|
|
|
3376
3547
|
});
|
|
3377
3548
|
|
|
3378
3549
|
// src/rules/no-generic-json-parser.ts
|
|
3379
|
-
import { AST_NODE_TYPES as
|
|
3550
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES28, ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
|
|
3380
3551
|
var OPEN_FACTORIES = /* @__PURE__ */ new Set(["any", "unknown", "json", "record", "partialRecord"]);
|
|
3381
3552
|
var WRAPPERS = /* @__PURE__ */ new Set(["optional", "nullable", "nullish", "default", "catch", "readonly", "brand", "describe", "meta"]);
|
|
3382
3553
|
var NO_GENERIC_JSON_PARSER_DOCUMENTATION = {
|
|
@@ -3414,19 +3585,19 @@ var no_generic_json_parser_default = createRule({
|
|
|
3414
3585
|
function initializer(node) {
|
|
3415
3586
|
const variable = binding3(node);
|
|
3416
3587
|
const definition = variable?.defs[0];
|
|
3417
|
-
if (variable?.defs.length !== 1 || definition?.node.type !==
|
|
3588
|
+
if (variable?.defs.length !== 1 || definition?.node.type !== AST_NODE_TYPES28.VariableDeclarator || definition.node.parent.kind !== "const" || definition.node.init === null || definition.node.range[1] >= node.range[0] || variable.references.some((reference) => reference.isWrite() && !reference.init)) return null;
|
|
3418
3589
|
return definition.node.init;
|
|
3419
3590
|
}
|
|
3420
3591
|
function parser(node, seen = /* @__PURE__ */ new Set(), awaited = false) {
|
|
3421
3592
|
node = unwrapExpression(node);
|
|
3422
3593
|
if (seen.has(node)) return null;
|
|
3423
3594
|
seen.add(node);
|
|
3424
|
-
if (node.type ===
|
|
3425
|
-
if (node.type ===
|
|
3595
|
+
if (node.type === AST_NODE_TYPES28.AwaitExpression) return parser(node.argument, seen, true);
|
|
3596
|
+
if (node.type === AST_NODE_TYPES28.Identifier) {
|
|
3426
3597
|
const value = initializer(node);
|
|
3427
3598
|
return value === null ? null : parser(value, seen, awaited);
|
|
3428
3599
|
}
|
|
3429
|
-
if (node.type !==
|
|
3600
|
+
if (node.type !== AST_NODE_TYPES28.CallExpression || node.callee.type !== AST_NODE_TYPES28.MemberExpression || !["parse", "parseAsync"].includes(ASTUtils19.getPropertyName(node.callee) ?? "")) return null;
|
|
3430
3601
|
if (ASTUtils19.getPropertyName(node.callee) === "parseAsync" && !awaited) return null;
|
|
3431
3602
|
return openSchema(node.callee.object) ? node : null;
|
|
3432
3603
|
}
|
|
@@ -3434,29 +3605,29 @@ var no_generic_json_parser_default = createRule({
|
|
|
3434
3605
|
node = unwrapExpression(node);
|
|
3435
3606
|
if (seen.has(node)) return false;
|
|
3436
3607
|
seen.add(node);
|
|
3437
|
-
if (node.type ===
|
|
3608
|
+
if (node.type === AST_NODE_TYPES28.Identifier) {
|
|
3438
3609
|
const value = initializer(node);
|
|
3439
3610
|
return value !== null && openSchema(value, seen);
|
|
3440
3611
|
}
|
|
3441
|
-
if (node.type !==
|
|
3612
|
+
if (node.type !== AST_NODE_TYPES28.CallExpression) return false;
|
|
3442
3613
|
const name = factory(node.callee);
|
|
3443
3614
|
if (name !== null) return OPEN_FACTORIES.has(name);
|
|
3444
3615
|
const callee = unwrapExpression(node.callee);
|
|
3445
|
-
return callee.type ===
|
|
3616
|
+
return callee.type === AST_NODE_TYPES28.MemberExpression && WRAPPERS.has(ASTUtils19.getPropertyName(callee) ?? "") && openSchema(callee.object, seen);
|
|
3446
3617
|
}
|
|
3447
3618
|
function factory(node) {
|
|
3448
3619
|
node = unwrapExpression(node);
|
|
3449
|
-
if (node.type ===
|
|
3620
|
+
if (node.type === AST_NODE_TYPES28.Identifier) {
|
|
3450
3621
|
const definition2 = binding3(node)?.defs[0]?.node;
|
|
3451
|
-
if (definition2?.type !==
|
|
3452
|
-
return definition2.imported.type ===
|
|
3622
|
+
if (definition2?.type !== AST_NODE_TYPES28.ImportSpecifier || definition2.parent.type !== AST_NODE_TYPES28.ImportDeclaration || definition2.importKind === "type" || definition2.parent.importKind === "type" || !isZodModule(definition2.parent.source.value)) return null;
|
|
3623
|
+
return definition2.imported.type === AST_NODE_TYPES28.Identifier ? definition2.imported.name : definition2.imported.value;
|
|
3453
3624
|
}
|
|
3454
|
-
if (node.type !==
|
|
3625
|
+
if (node.type !== AST_NODE_TYPES28.MemberExpression) return null;
|
|
3455
3626
|
const receiver = unwrapExpression(node.object);
|
|
3456
|
-
if (receiver.type !==
|
|
3627
|
+
if (receiver.type !== AST_NODE_TYPES28.Identifier) return null;
|
|
3457
3628
|
const definition = binding3(receiver)?.defs[0]?.node;
|
|
3458
|
-
if (definition === void 0 || definition.type !==
|
|
3459
|
-
if (definition.type ===
|
|
3629
|
+
if (definition === void 0 || definition.type !== AST_NODE_TYPES28.ImportSpecifier && definition.type !== AST_NODE_TYPES28.ImportNamespaceSpecifier || definition.parent.type !== AST_NODE_TYPES28.ImportDeclaration || definition.parent.importKind === "type" || !isZodModule(definition.parent.source.value)) return null;
|
|
3630
|
+
if (definition.type === AST_NODE_TYPES28.ImportSpecifier && (definition.importKind === "type" || (definition.imported.type === AST_NODE_TYPES28.Identifier ? definition.imported.name : definition.imported.value) !== "z")) return null;
|
|
3460
3631
|
return ASTUtils19.getPropertyName(node);
|
|
3461
3632
|
}
|
|
3462
3633
|
const reported = /* @__PURE__ */ new Set();
|
|
@@ -3471,10 +3642,160 @@ var no_generic_json_parser_default = createRule({
|
|
|
3471
3642
|
}
|
|
3472
3643
|
};
|
|
3473
3644
|
}
|
|
3474
|
-
});
|
|
3645
|
+
});
|
|
3646
|
+
|
|
3647
|
+
// src/rules/no-redundant-local-alias.ts
|
|
3648
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES31, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
|
|
3649
|
+
|
|
3650
|
+
// src/rules/_unused-private-binding.ts
|
|
3651
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES30 } from "@typescript-eslint/utils";
|
|
3652
|
+
|
|
3653
|
+
// src/rules/_type-binding.ts
|
|
3654
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29 } from "@typescript-eslint/utils";
|
|
3655
|
+
function typeBinding(source, identifier) {
|
|
3656
|
+
let scope = source.getScope(identifier);
|
|
3657
|
+
while (scope !== null) {
|
|
3658
|
+
const variable = scope.set.get(identifier.name);
|
|
3659
|
+
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
3660
|
+
return variable;
|
|
3661
|
+
}
|
|
3662
|
+
scope = scope.upper;
|
|
3663
|
+
}
|
|
3664
|
+
return null;
|
|
3665
|
+
}
|
|
3666
|
+
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
3667
|
+
function retainsNamedTypeUses(source, removed) {
|
|
3668
|
+
const manager = source.scopeManager;
|
|
3669
|
+
if (manager === null) return false;
|
|
3670
|
+
const index = referenceIndex(source, manager);
|
|
3671
|
+
for (const reference of referencesWithin(index.references, removed)) {
|
|
3672
|
+
if (!reference.isRead()) continue;
|
|
3673
|
+
const binding3 = reference.resolved;
|
|
3674
|
+
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
3675
|
+
if (binding3.defs.length === 0) continue;
|
|
3676
|
+
const reads = publicReadExtents(index, binding3);
|
|
3677
|
+
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
3678
|
+
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
3679
|
+
}
|
|
3680
|
+
return true;
|
|
3681
|
+
}
|
|
3682
|
+
function referenceIndex(source, manager) {
|
|
3683
|
+
const cached = REFERENCE_INDEXES.get(source);
|
|
3684
|
+
if (cached?.manager === manager) return cached;
|
|
3685
|
+
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
3686
|
+
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
3687
|
+
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
3688
|
+
REFERENCE_INDEXES.set(source, index);
|
|
3689
|
+
return index;
|
|
3690
|
+
}
|
|
3691
|
+
function* referencesWithin(references, removed) {
|
|
3692
|
+
let low = 0;
|
|
3693
|
+
let high = references.length;
|
|
3694
|
+
while (low < high) {
|
|
3695
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
3696
|
+
const reference = references[middle];
|
|
3697
|
+
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
3698
|
+
else low = middle + 1;
|
|
3699
|
+
}
|
|
3700
|
+
for (let index = low; index < references.length; index++) {
|
|
3701
|
+
const reference = references[index];
|
|
3702
|
+
if (reference === void 0) continue;
|
|
3703
|
+
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
3704
|
+
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
function publicReadExtents(index, binding3) {
|
|
3708
|
+
const cached = index.publicReads.get(binding3);
|
|
3709
|
+
if (cached !== void 0) return cached;
|
|
3710
|
+
let type = null;
|
|
3711
|
+
let value = null;
|
|
3712
|
+
let both = null;
|
|
3713
|
+
for (const retained of binding3.references) {
|
|
3714
|
+
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
3715
|
+
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
3716
|
+
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
3717
|
+
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
3718
|
+
}
|
|
3719
|
+
const result = { type, value, both };
|
|
3720
|
+
index.publicReads.set(binding3, result);
|
|
3721
|
+
return result;
|
|
3722
|
+
}
|
|
3723
|
+
function extendExtent(extent, identifier) {
|
|
3724
|
+
return {
|
|
3725
|
+
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
3726
|
+
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
3727
|
+
};
|
|
3728
|
+
}
|
|
3729
|
+
function publicTypeUse(identifier) {
|
|
3730
|
+
let node = identifier;
|
|
3731
|
+
while (node.parent) {
|
|
3732
|
+
if (node.type === AST_NODE_TYPES29.TSTypeAnnotation || node.type === AST_NODE_TYPES29.TSTypePredicate || node.type === AST_NODE_TYPES29.TSAsExpression || node.type === AST_NODE_TYPES29.TSTypeAssertion) return false;
|
|
3733
|
+
if (node.type === AST_NODE_TYPES29.TSTypeAliasDeclaration) {
|
|
3734
|
+
return node.parent.type === AST_NODE_TYPES29.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === AST_NODE_TYPES29.Program;
|
|
3735
|
+
}
|
|
3736
|
+
if (node.type === AST_NODE_TYPES29.ExportSpecifier) {
|
|
3737
|
+
return node.parent.type === AST_NODE_TYPES29.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === AST_NODE_TYPES29.Program;
|
|
3738
|
+
}
|
|
3739
|
+
node = node.parent;
|
|
3740
|
+
}
|
|
3741
|
+
return false;
|
|
3742
|
+
}
|
|
3743
|
+
function insideTypeRange(node, range) {
|
|
3744
|
+
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
3745
|
+
}
|
|
3746
|
+
|
|
3747
|
+
// src/rules/_unused-private-binding.ts
|
|
3748
|
+
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
3749
|
+
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
3750
|
+
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
3751
|
+
if (bindings.length === 0 || bindings.some((binding3) => binding3.defs.length !== allowedDeclarations.length || binding3.defs.some((definition) => !allowedDeclarations.includes(definition.node)) || binding3.eslintUsed || binding3.references.some((reference) => reference.isRead() || reference.init !== true))) return false;
|
|
3752
|
+
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
3753
|
+
const statement = declaration.type === AST_NODE_TYPES30.VariableDeclarator ? declaration.parent : declaration;
|
|
3754
|
+
if (statement.parent.type === AST_NODE_TYPES30.ExportNamedDeclaration || statement.parent.type === AST_NODE_TYPES30.ExportDefaultDeclaration) return false;
|
|
3755
|
+
if (statement.parent.type !== AST_NODE_TYPES30.Program) return statement.parent.type === AST_NODE_TYPES30.BlockStatement;
|
|
3756
|
+
return sourceCode.ast.body.some((node) => node.type === AST_NODE_TYPES30.ImportDeclaration || node.type === AST_NODE_TYPES30.ExportNamedDeclaration || node.type === AST_NODE_TYPES30.ExportDefaultDeclaration || node.type === AST_NODE_TYPES30.ExportAllDeclaration);
|
|
3757
|
+
}
|
|
3758
|
+
function hasOnlyDirectFactoryUses(variable) {
|
|
3759
|
+
return variable.references.every((reference) => {
|
|
3760
|
+
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
3761
|
+
const identifier = reference.identifier;
|
|
3762
|
+
const parent = identifier.parent;
|
|
3763
|
+
if (parent.type === AST_NODE_TYPES30.CallExpression && parent.callee === identifier) return true;
|
|
3764
|
+
return parent.type === AST_NODE_TYPES30.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === AST_NODE_TYPES30.CallExpression && parent.parent.callee === parent;
|
|
3765
|
+
});
|
|
3766
|
+
}
|
|
3767
|
+
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
3768
|
+
function hasIdentifierNamed(node, name) {
|
|
3769
|
+
let names = IDENTIFIER_NAMES.get(node);
|
|
3770
|
+
if (names === void 0) {
|
|
3771
|
+
const collected = /* @__PURE__ */ new Set();
|
|
3772
|
+
const pending = [node];
|
|
3773
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
3774
|
+
while (pending.length > 0) {
|
|
3775
|
+
const current = pending.pop();
|
|
3776
|
+
if (current === void 0 || seen.has(current)) continue;
|
|
3777
|
+
seen.add(current);
|
|
3778
|
+
if (current.type === AST_NODE_TYPES30.Identifier || current.type === AST_NODE_TYPES30.JSXIdentifier) collected.add(current.name);
|
|
3779
|
+
forEachOwnAstChild(current, (child) => {
|
|
3780
|
+
pending.push(child);
|
|
3781
|
+
}, (key) => key !== "tokens" && key !== "comments");
|
|
3782
|
+
}
|
|
3783
|
+
names = collected;
|
|
3784
|
+
IDENTIFIER_NAMES.set(node, names);
|
|
3785
|
+
}
|
|
3786
|
+
return names.has(name);
|
|
3787
|
+
}
|
|
3788
|
+
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
3789
|
+
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== AST_NODE_TYPES30.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
3790
|
+
const text = `boolean${sourceCode.getText(annotation).replace(/[^\r\n\u2028\u2029]/gu, "")}`;
|
|
3791
|
+
const neighbor = Math.max(0, annotation.range[0] - 1);
|
|
3792
|
+
const before = sourceCode.text.slice(neighbor, annotation.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
3793
|
+
const after = (sourceCode.text.slice(neighbor, annotation.range[0]) + text + sourceCode.text.slice(annotation.range[1], annotation.range[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
3794
|
+
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
3795
|
+
return (fixer) => fixer.replaceText(annotation, text);
|
|
3796
|
+
}
|
|
3475
3797
|
|
|
3476
3798
|
// src/rules/no-redundant-local-alias.ts
|
|
3477
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES30, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
|
|
3478
3799
|
var NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION = {
|
|
3479
3800
|
defaultLevel: "warning",
|
|
3480
3801
|
summary: "Pass the original local into an object field instead of creating a single-use rename.",
|
|
@@ -3496,24 +3817,24 @@ var NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION = {
|
|
|
3496
3817
|
function stableSource(variable, alias) {
|
|
3497
3818
|
const definition = variable.defs[0];
|
|
3498
3819
|
if (variable.defs.length !== 1 || definition === void 0 || variable.references.some((reference) => reference.isWrite() && !reference.init)) return false;
|
|
3499
|
-
return definition.type === "Parameter" || definition.node.type ===
|
|
3820
|
+
return definition.type === "Parameter" || definition.node.type === AST_NODE_TYPES31.VariableDeclarator && definition.node.parent.kind === "const" && definition.node.init !== null && definition.node.range[1] < alias.range[0];
|
|
3500
3821
|
}
|
|
3501
3822
|
var PRIMITIVE_PARAMETERS = /* @__PURE__ */ new Set([
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3823
|
+
AST_NODE_TYPES31.TSStringKeyword,
|
|
3824
|
+
AST_NODE_TYPES31.TSNumberKeyword,
|
|
3825
|
+
AST_NODE_TYPES31.TSBooleanKeyword,
|
|
3826
|
+
AST_NODE_TYPES31.TSBigIntKeyword,
|
|
3827
|
+
AST_NODE_TYPES31.TSSymbolKeyword
|
|
3507
3828
|
]);
|
|
3508
3829
|
function closedPrimitiveReturnFix(sourceCode, node, property, source, target) {
|
|
3509
3830
|
const statement = node.parent;
|
|
3510
3831
|
const body3 = statement.parent;
|
|
3511
|
-
if (body3.type !==
|
|
3832
|
+
if (body3.type !== AST_NODE_TYPES31.BlockStatement) return null;
|
|
3512
3833
|
const owner = body3.parent;
|
|
3513
|
-
if (owner.type !==
|
|
3834
|
+
if (owner.type !== AST_NODE_TYPES31.FunctionDeclaration || owner.parent.type !== AST_NODE_TYPES31.Program || owner.id === null || owner.async || owner.generator || owner.typeParameters !== void 0 || owner.returnType !== void 0 || owner.params.length !== 1 || body3.body.length !== 2 || body3.body[0] !== statement || node.id.type !== AST_NODE_TYPES31.Identifier || node.id.name === "__proto__" || node.init?.type !== AST_NODE_TYPES31.Identifier || sourceCode.getCommentsInside(owner).length !== 0 || hasIdentifierNamed(sourceCode.ast, "eval")) return null;
|
|
3514
3835
|
const parameter = owner.params[0];
|
|
3515
3836
|
const returned2 = body3.body[1];
|
|
3516
|
-
if (parameter?.type !==
|
|
3837
|
+
if (parameter?.type !== AST_NODE_TYPES31.Identifier || parameter.optional === true || parameter.typeAnnotation === void 0 || !PRIMITIVE_PARAMETERS.has(parameter.typeAnnotation.typeAnnotation.type) || returned2?.type !== AST_NODE_TYPES31.ReturnStatement || returned2.argument !== property.parent || property.parent.type !== AST_NODE_TYPES31.ObjectExpression || property.parent.properties.length !== 1 || ASTUtils20.findVariable(sourceCode.getScope(parameter), parameter.name) !== source || ASTUtils20.findVariable(sourceCode.getScope(property), node.init.name) !== source || source.references.some((reference) => reference.isTypeReference) || target.references.some((reference) => reference.isTypeReference)) return null;
|
|
3517
3838
|
const name = owner.id.name;
|
|
3518
3839
|
const bindings = sourceCode.getDeclaredVariables(owner).filter((binding3) => binding3.name === name);
|
|
3519
3840
|
if (bindings.length !== 1 || bindings[0]?.defs.length !== 1 || bindings[0].defs[0]?.node !== owner || bindings[0].references.some((reference) => reference.isTypeReference)) return null;
|
|
@@ -3540,10 +3861,10 @@ var no_redundant_local_alias_default = createRule({
|
|
|
3540
3861
|
defaultOptions: [],
|
|
3541
3862
|
create(context) {
|
|
3542
3863
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
3543
|
-
const hasModuleSyntax = context.sourceCode.ast.body.some((candidate2) => candidate2.type ===
|
|
3864
|
+
const hasModuleSyntax = context.sourceCode.ast.body.some((candidate2) => candidate2.type === AST_NODE_TYPES31.ImportDeclaration || candidate2.type === AST_NODE_TYPES31.ExportNamedDeclaration || candidate2.type === AST_NODE_TYPES31.ExportDefaultDeclaration || candidate2.type === AST_NODE_TYPES31.ExportAllDeclaration);
|
|
3544
3865
|
return {
|
|
3545
3866
|
VariableDeclarator(node) {
|
|
3546
|
-
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !==
|
|
3867
|
+
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !== AST_NODE_TYPES31.Identifier || node.id.typeAnnotation !== void 0 || node.init?.type !== AST_NODE_TYPES31.Identifier) return;
|
|
3547
3868
|
const scope = context.sourceCode.getScope(node);
|
|
3548
3869
|
if (scope.variableScope.type !== "function") return;
|
|
3549
3870
|
const target = ASTUtils20.findVariable(scope, node.id.name);
|
|
@@ -3554,7 +3875,7 @@ var no_redundant_local_alias_default = createRule({
|
|
|
3554
3875
|
const read = reads[0];
|
|
3555
3876
|
if (read === void 0 || read.from.variableScope !== scope.variableScope) return;
|
|
3556
3877
|
const property = read.identifier.parent;
|
|
3557
|
-
if (property.type !==
|
|
3878
|
+
if (property.type !== AST_NODE_TYPES31.Property || !property.shorthand || property.value !== read.identifier || property.parent.type !== AST_NODE_TYPES31.ObjectExpression || property.computed || property.method || property.kind !== "init") return;
|
|
3558
3879
|
context.report({ node, messageId: "redundantAlias", fix: hasModuleSyntax ? closedPrimitiveReturnFix(context.sourceCode, node, property, source, target) : null, data: { source: node.init.name, target: node.id.name } });
|
|
3559
3880
|
}
|
|
3560
3881
|
};
|
|
@@ -3562,14 +3883,14 @@ var no_redundant_local_alias_default = createRule({
|
|
|
3562
3883
|
});
|
|
3563
3884
|
|
|
3564
3885
|
// src/rules/no-mutating-container-transform.ts
|
|
3565
|
-
import { AST_NODE_TYPES as
|
|
3886
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES32, ASTUtils as ASTUtils21 } from "@typescript-eslint/utils";
|
|
3566
3887
|
var MUTATORS = /* @__PURE__ */ new Set(["copyWithin", "fill", "pop", "push", "reverse", "shift", "sort", "splice", "unshift"]);
|
|
3567
3888
|
var PRIMITIVES = /* @__PURE__ */ new Set([
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3889
|
+
AST_NODE_TYPES32.TSStringKeyword,
|
|
3890
|
+
AST_NODE_TYPES32.TSNumberKeyword,
|
|
3891
|
+
AST_NODE_TYPES32.TSBooleanKeyword,
|
|
3892
|
+
AST_NODE_TYPES32.TSBigIntKeyword,
|
|
3893
|
+
AST_NODE_TYPES32.TSSymbolKeyword
|
|
3573
3894
|
]);
|
|
3574
3895
|
var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
3575
3896
|
defaultLevel: "warning",
|
|
@@ -3588,27 +3909,27 @@ var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
|
3588
3909
|
]
|
|
3589
3910
|
};
|
|
3590
3911
|
function arrayElement(node, sourceCode) {
|
|
3591
|
-
if (node.type ===
|
|
3592
|
-
if (node.type ===
|
|
3912
|
+
if (node.type === AST_NODE_TYPES32.TSArrayType) return node.elementType;
|
|
3913
|
+
if (node.type === AST_NODE_TYPES32.TSTypeReference && node.typeName.type === AST_NODE_TYPES32.Identifier && (node.typeName.name === "Array" || node.typeName.name === "ReadonlyArray") && (ASTUtils21.findVariable(sourceCode.getScope(node.typeName), node.typeName.name)?.defs.length ?? 0) === 0 && node.typeArguments?.params.length === 1) return node.typeArguments.params[0] ?? null;
|
|
3593
3914
|
return null;
|
|
3594
3915
|
}
|
|
3595
3916
|
function returnsArray(node, sourceCode) {
|
|
3596
3917
|
let annotation = node.returnType?.typeAnnotation;
|
|
3597
|
-
if (annotation?.type ===
|
|
3918
|
+
if (annotation?.type === AST_NODE_TYPES32.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES32.Identifier && annotation.typeName.name === "Promise" && (ASTUtils21.findVariable(sourceCode.getScope(annotation.typeName), "Promise")?.defs.length ?? 0) === 0 && annotation.typeArguments?.params.length === 1) annotation = annotation.typeArguments.params[0];
|
|
3598
3919
|
return annotation !== void 0 && arrayElement(annotation, sourceCode) !== null;
|
|
3599
3920
|
}
|
|
3600
3921
|
function supported(statements) {
|
|
3601
3922
|
return statements.every((statement) => {
|
|
3602
3923
|
switch (statement.type) {
|
|
3603
|
-
case
|
|
3604
|
-
case
|
|
3605
|
-
case
|
|
3606
|
-
case
|
|
3607
|
-
case
|
|
3924
|
+
case AST_NODE_TYPES32.ExpressionStatement:
|
|
3925
|
+
case AST_NODE_TYPES32.VariableDeclaration:
|
|
3926
|
+
case AST_NODE_TYPES32.ReturnStatement:
|
|
3927
|
+
case AST_NODE_TYPES32.ThrowStatement:
|
|
3928
|
+
case AST_NODE_TYPES32.EmptyStatement:
|
|
3608
3929
|
return true;
|
|
3609
|
-
case
|
|
3930
|
+
case AST_NODE_TYPES32.BlockStatement:
|
|
3610
3931
|
return supported(statement.body);
|
|
3611
|
-
case
|
|
3932
|
+
case AST_NODE_TYPES32.IfStatement:
|
|
3612
3933
|
return supported([statement.consequent]) && (statement.alternate === null || supported([statement.alternate]));
|
|
3613
3934
|
default:
|
|
3614
3935
|
return false;
|
|
@@ -3629,13 +3950,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3629
3950
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
3630
3951
|
const sourceCode = context.sourceCode;
|
|
3631
3952
|
function binding3(node) {
|
|
3632
|
-
return node.type ===
|
|
3953
|
+
return node.type === AST_NODE_TYPES32.Identifier ? ASTUtils21.findVariable(sourceCode.getScope(node), node.name) : null;
|
|
3633
3954
|
}
|
|
3634
3955
|
function inspect(node) {
|
|
3635
|
-
if (node.body?.type !==
|
|
3956
|
+
if (node.body?.type !== AST_NODE_TYPES32.BlockStatement || !returnsArray(node, sourceCode) || !supported(node.body.body)) return;
|
|
3636
3957
|
const initial = /* @__PURE__ */ new Map();
|
|
3637
3958
|
for (const parameter of node.params) {
|
|
3638
|
-
if (parameter.type !==
|
|
3959
|
+
if (parameter.type !== AST_NODE_TYPES32.Identifier || parameter.typeAnnotation === void 0) continue;
|
|
3639
3960
|
const element = arrayElement(parameter.typeAnnotation.typeAnnotation, sourceCode);
|
|
3640
3961
|
const variable = binding3(parameter);
|
|
3641
3962
|
if (element !== null && PRIMITIVES.has(element.type) && variable !== null) initial.set(variable, parameter.name);
|
|
@@ -3648,26 +3969,26 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3648
3969
|
}
|
|
3649
3970
|
function expression(current, state) {
|
|
3650
3971
|
switch (current.type) {
|
|
3651
|
-
case
|
|
3652
|
-
case
|
|
3653
|
-
case
|
|
3972
|
+
case AST_NODE_TYPES32.FunctionExpression:
|
|
3973
|
+
case AST_NODE_TYPES32.ArrowFunctionExpression:
|
|
3974
|
+
case AST_NODE_TYPES32.ClassExpression:
|
|
3654
3975
|
return;
|
|
3655
|
-
case
|
|
3976
|
+
case AST_NODE_TYPES32.AssignmentExpression:
|
|
3656
3977
|
assignment(current, state);
|
|
3657
3978
|
return;
|
|
3658
|
-
case
|
|
3979
|
+
case AST_NODE_TYPES32.LogicalExpression:
|
|
3659
3980
|
logical(current, state);
|
|
3660
3981
|
return;
|
|
3661
|
-
case
|
|
3982
|
+
case AST_NODE_TYPES32.ConditionalExpression:
|
|
3662
3983
|
conditional(current, state);
|
|
3663
3984
|
return;
|
|
3664
|
-
case
|
|
3985
|
+
case AST_NODE_TYPES32.UpdateExpression:
|
|
3665
3986
|
write(current.argument, state);
|
|
3666
3987
|
break;
|
|
3667
|
-
case
|
|
3988
|
+
case AST_NODE_TYPES32.UnaryExpression:
|
|
3668
3989
|
if (current.operator === "delete") write(current.argument, state);
|
|
3669
3990
|
break;
|
|
3670
|
-
case
|
|
3991
|
+
case AST_NODE_TYPES32.CallExpression:
|
|
3671
3992
|
mutationCall(current, state);
|
|
3672
3993
|
break;
|
|
3673
3994
|
default:
|
|
@@ -3687,13 +4008,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3687
4008
|
function logical(current, state) {
|
|
3688
4009
|
expression(current.left, state);
|
|
3689
4010
|
const left = unwrapExpression(current.left);
|
|
3690
|
-
if (left.type ===
|
|
4011
|
+
if (left.type === AST_NODE_TYPES32.Literal && (current.operator === "&&" && !left.value || current.operator === "||" && !!left.value || current.operator === "??" && left.value !== null)) return;
|
|
3691
4012
|
expression(current.right, state);
|
|
3692
4013
|
}
|
|
3693
4014
|
function conditional(current, state) {
|
|
3694
4015
|
expression(current.test, state);
|
|
3695
4016
|
const test = unwrapExpression(current.test);
|
|
3696
|
-
if (test.type ===
|
|
4017
|
+
if (test.type === AST_NODE_TYPES32.Literal) {
|
|
3697
4018
|
expression(test.value ? current.consequent : current.alternate, state);
|
|
3698
4019
|
return;
|
|
3699
4020
|
}
|
|
@@ -3701,13 +4022,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3701
4022
|
expression(current.alternate, state);
|
|
3702
4023
|
}
|
|
3703
4024
|
function mutationCall(current, state) {
|
|
3704
|
-
if (current.callee.type !==
|
|
4025
|
+
if (current.callee.type !== AST_NODE_TYPES32.MemberExpression || !MUTATORS.has(ASTUtils21.getPropertyName(current.callee) ?? "")) return;
|
|
3705
4026
|
const parameter = origin(current.callee.object, state);
|
|
3706
4027
|
if (parameter !== void 0 && first === null) first = { node: current, parameter };
|
|
3707
4028
|
}
|
|
3708
4029
|
function write(target, state) {
|
|
3709
4030
|
target = unwrapExpression(target);
|
|
3710
|
-
if (target.type !==
|
|
4031
|
+
if (target.type !== AST_NODE_TYPES32.MemberExpression || !target.computed && ASTUtils21.getPropertyName(target) !== "length") return;
|
|
3711
4032
|
const parameter = origin(target.object, state);
|
|
3712
4033
|
if (parameter !== void 0 && first === null) first = { node: target, parameter };
|
|
3713
4034
|
}
|
|
@@ -3717,18 +4038,18 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3717
4038
|
}
|
|
3718
4039
|
function statement(current, state) {
|
|
3719
4040
|
switch (current.type) {
|
|
3720
|
-
case
|
|
4041
|
+
case AST_NODE_TYPES32.BlockStatement:
|
|
3721
4042
|
return statements(current.body, state);
|
|
3722
|
-
case
|
|
4043
|
+
case AST_NODE_TYPES32.IfStatement:
|
|
3723
4044
|
return branch(current, state);
|
|
3724
|
-
case
|
|
4045
|
+
case AST_NODE_TYPES32.VariableDeclaration:
|
|
3725
4046
|
declarations(current, state);
|
|
3726
4047
|
return false;
|
|
3727
|
-
case
|
|
3728
|
-
case
|
|
4048
|
+
case AST_NODE_TYPES32.ReturnStatement:
|
|
4049
|
+
case AST_NODE_TYPES32.ThrowStatement:
|
|
3729
4050
|
if (current.argument !== null) expression(current.argument, state);
|
|
3730
4051
|
return true;
|
|
3731
|
-
case
|
|
4052
|
+
case AST_NODE_TYPES32.ExpressionStatement:
|
|
3732
4053
|
expression(current.expression, state);
|
|
3733
4054
|
return false;
|
|
3734
4055
|
default:
|
|
@@ -3737,7 +4058,7 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3737
4058
|
}
|
|
3738
4059
|
function branch(current, state) {
|
|
3739
4060
|
expression(current.test, state);
|
|
3740
|
-
if (current.test.type ===
|
|
4061
|
+
if (current.test.type === AST_NODE_TYPES32.Literal) return current.test.value ? statements([current.consequent], state) : current.alternate !== null && statements([current.alternate], state);
|
|
3741
4062
|
const left = new Map(state);
|
|
3742
4063
|
const right = new Map(state);
|
|
3743
4064
|
const leftEnds = statements([current.consequent], left);
|
|
@@ -3772,60 +4093,8 @@ var no_mutating_container_transform_default = createRule({
|
|
|
3772
4093
|
import { AST_NODE_TYPES as AST_NODE_TYPES34 } from "@typescript-eslint/utils";
|
|
3773
4094
|
import ts11 from "typescript";
|
|
3774
4095
|
|
|
3775
|
-
// src/rules/_checked-native-source.ts
|
|
3776
|
-
import ts5 from "typescript";
|
|
3777
|
-
var CHECKED = /* @__PURE__ */ new WeakMap();
|
|
3778
|
-
var SINGLE_LINE_DIRECTIVE = /^\/\/\/?\s*@(?:ts-expect-error|ts-ignore)/u;
|
|
3779
|
-
var MULTI_LINE_DIRECTIVE = /^[/*]*\s*@(?:ts-expect-error|ts-ignore)/u;
|
|
3780
|
-
var SINGLE_LINE_PRAGMA = /^\/\/\/?\s*@([^\s:]+)(?:(?:[^\S\r\n]|:).*)?$/mu;
|
|
3781
|
-
function currentNativeSource(sourceCode, services) {
|
|
3782
|
-
const source = services.esTreeNodeToTSNodeMap.get(sourceCode.ast);
|
|
3783
|
-
return ts5.isSourceFile(source) && services.program.getSourceFile(source.fileName) === source && source.text === sourceCode.text ? source : null;
|
|
3784
|
-
}
|
|
3785
|
-
function checkedNativeSource(program, source) {
|
|
3786
|
-
let files = CHECKED.get(program);
|
|
3787
|
-
if (!files) {
|
|
3788
|
-
files = /* @__PURE__ */ new WeakMap();
|
|
3789
|
-
CHECKED.set(program, files);
|
|
3790
|
-
}
|
|
3791
|
-
const known2 = files.get(source);
|
|
3792
|
-
if (known2 !== void 0) return known2;
|
|
3793
|
-
const available = !program.getCompilerOptions().noCheck && !source.isDeclarationFile && (source.flags & (ts5.NodeFlags.JavaScriptFile | ts5.NodeFlags.JsonFile)) === 0 && !program.getProjectReferences()?.length && !program.getResolvedProjectReferences()?.length && program.getSourceFile(source.fileName) === source && !program.isSourceFileFromExternalLibrary(source) && !program.isSourceFileDefaultLibrary(source) && !program.getSyntacticDiagnostics(source).some((diagnostic) => diagnostic.category === ts5.DiagnosticCategory.Error && diagnostic.file === source) && !checkingSuppressed(source) && !program.getSemanticDiagnostics(source).some((diagnostic) => diagnostic.category === ts5.DiagnosticCategory.Error && diagnostic.file === source);
|
|
3794
|
-
files.set(source, available);
|
|
3795
|
-
return available;
|
|
3796
|
-
}
|
|
3797
|
-
function checkingSuppressed(source) {
|
|
3798
|
-
if (!/@ts-/iu.test(source.text)) return false;
|
|
3799
|
-
if (ts5.getLeadingCommentRanges(source.text, 0)?.some((comment) => comment.kind === ts5.SyntaxKind.SingleLineCommentTrivia && SINGLE_LINE_PRAGMA.exec(source.text.slice(comment.pos, comment.end))?.[1]?.toLowerCase() === "ts-nocheck")) return true;
|
|
3800
|
-
const pending = [source];
|
|
3801
|
-
while (pending.length) {
|
|
3802
|
-
const node = pending.pop();
|
|
3803
|
-
if (!node || ts5.isJsxText(node) || ts5.isJSDoc(node) || (node.flags & ts5.NodeFlags.JSDoc) !== 0) continue;
|
|
3804
|
-
if (!ts5.isToken(node)) {
|
|
3805
|
-
for (const child of node.getChildren(source)) pending.push(child);
|
|
3806
|
-
continue;
|
|
3807
|
-
}
|
|
3808
|
-
if (tokenTriviaSuppressesChecking(node, source)) return true;
|
|
3809
|
-
}
|
|
3810
|
-
return false;
|
|
3811
|
-
}
|
|
3812
|
-
function tokenTriviaSuppressesChecking(node, source) {
|
|
3813
|
-
const start = node.getStart(source);
|
|
3814
|
-
for (const comment of [...ts5.getLeadingCommentRanges(source.text, node.pos) ?? [], ...ts5.getTrailingCommentRanges(source.text, node.pos) ?? []]) {
|
|
3815
|
-
if (comment.pos < node.pos || comment.end > start) continue;
|
|
3816
|
-
if (commentSuppressesChecking(source.text.slice(comment.pos, comment.end), comment.kind)) return true;
|
|
3817
|
-
}
|
|
3818
|
-
return false;
|
|
3819
|
-
}
|
|
3820
|
-
function commentSuppressesChecking(text, kind) {
|
|
3821
|
-
if (kind === ts5.SyntaxKind.SingleLineCommentTrivia) return SINGLE_LINE_DIRECTIVE.test(text);
|
|
3822
|
-
let lastLine = text.length;
|
|
3823
|
-
while (lastLine > 0 && !ts5.isLineBreak(text.charCodeAt(lastLine - 1))) lastLine--;
|
|
3824
|
-
return MULTI_LINE_DIRECTIVE.test(text.slice(lastLine).trimStart());
|
|
3825
|
-
}
|
|
3826
|
-
|
|
3827
4096
|
// src/rules/_closed-object-contract.ts
|
|
3828
|
-
import
|
|
4097
|
+
import ts9 from "typescript";
|
|
3829
4098
|
function closedObjectContract(type, checker, singlePropertyOrigins = false) {
|
|
3830
4099
|
return visitContract(type, {
|
|
3831
4100
|
checker,
|
|
@@ -3847,7 +4116,7 @@ function visitContract(type, proof) {
|
|
|
3847
4116
|
function completeObject(type, proof) {
|
|
3848
4117
|
if (!ordinaryObject(type, proof.checker)) return false;
|
|
3849
4118
|
if (proof.origins && !singleOrigins(type, proof.origins)) return false;
|
|
3850
|
-
const declarations = type.getSymbol()?.getDeclarations()?.filter((declaration) =>
|
|
4119
|
+
const declarations = type.getSymbol()?.getDeclarations()?.filter((declaration) => ts9.isInterfaceDeclaration(declaration) || ts9.isTypeLiteralNode(declaration));
|
|
3851
4120
|
if (!declarations?.length) return false;
|
|
3852
4121
|
return declarations.every((declaration) => completeDeclaration(declaration, proof));
|
|
3853
4122
|
}
|
|
@@ -3861,36 +4130,36 @@ function singleOrigins(type, origins) {
|
|
|
3861
4130
|
return true;
|
|
3862
4131
|
}
|
|
3863
4132
|
function ordinaryObject(type, checker) {
|
|
3864
|
-
if ((type.flags &
|
|
4133
|
+
if ((type.flags & ts9.TypeFlags.Object) === 0 || type.isUnion() || checker.getIndexInfosOfType(type).length > 0) return false;
|
|
3865
4134
|
const object = type;
|
|
3866
|
-
if ((object.objectFlags & (
|
|
3867
|
-
if ((object.objectFlags &
|
|
3868
|
-
return checker.getSignaturesOfType(type,
|
|
4135
|
+
if ((object.objectFlags & (ts9.ObjectFlags.Class | ts9.ObjectFlags.Mapped)) !== 0) return false;
|
|
4136
|
+
if ((object.objectFlags & ts9.ObjectFlags.Reference) !== 0 && checker.getTypeArguments(type).some((argument) => (argument.flags & (ts9.TypeFlags.Any | ts9.TypeFlags.Unknown | ts9.TypeFlags.TypeParameter)) !== 0)) return false;
|
|
4137
|
+
return checker.getSignaturesOfType(type, ts9.SignatureKind.Call).length === 0 && checker.getSignaturesOfType(type, ts9.SignatureKind.Construct).length === 0;
|
|
3869
4138
|
}
|
|
3870
4139
|
function completeDeclaration(declaration, proof) {
|
|
3871
4140
|
if (!declaration.members.every((member3) => finiteMember(member3, proof.checker))) return false;
|
|
3872
|
-
if (!
|
|
4141
|
+
if (!ts9.isInterfaceDeclaration(declaration)) return true;
|
|
3873
4142
|
if (declaration.typeParameters?.length) return false;
|
|
3874
4143
|
return (declaration.heritageClauses ?? []).every((heritage) => heritage.types.every((base) => visitContract(proof.checker.getTypeAtLocation(base), proof)));
|
|
3875
4144
|
}
|
|
3876
4145
|
function finiteMember(member3, checker) {
|
|
3877
|
-
if (
|
|
3878
|
-
if (!member3.name || !
|
|
3879
|
-
return (checker.getTypeAtLocation(member3.name.expression).flags & (
|
|
4146
|
+
if (ts9.isIndexSignatureDeclaration(member3)) return false;
|
|
4147
|
+
if (!member3.name || !ts9.isComputedPropertyName(member3.name)) return true;
|
|
4148
|
+
return (checker.getTypeAtLocation(member3.name.expression).flags & (ts9.TypeFlags.StringLiteral | ts9.TypeFlags.NumberLiteral | ts9.TypeFlags.UniqueESSymbol)) !== 0;
|
|
3880
4149
|
}
|
|
3881
4150
|
|
|
3882
4151
|
// src/rules/_private-consumer-fix.ts
|
|
3883
|
-
import { AST_NODE_TYPES as
|
|
3884
|
-
import
|
|
3885
|
-
var UNSAFE =
|
|
4152
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES33 } from "@typescript-eslint/utils";
|
|
4153
|
+
import ts10 from "typescript";
|
|
4154
|
+
var UNSAFE = ts10.TypeFlags.Any | ts10.TypeFlags.Unknown | ts10.TypeFlags.Never | ts10.TypeFlags.TypeParameter | ts10.TypeFlags.Conditional | ts10.TypeFlags.IndexedAccess | ts10.TypeFlags.Substitution;
|
|
3886
4155
|
function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
3887
4156
|
if (sourceCode.getAllComments().some((comment) => /@ts-(?:expect-error|ignore|nocheck)\b/u.test(comment.value))) return false;
|
|
3888
|
-
const owner = node.type ===
|
|
3889
|
-
if (owner.type !==
|
|
4157
|
+
const owner = node.type === AST_NODE_TYPES33.FunctionDeclaration ? node : node.parent;
|
|
4158
|
+
if (owner.type !== AST_NODE_TYPES33.FunctionDeclaration && owner.type !== AST_NODE_TYPES33.VariableDeclarator) return false;
|
|
3890
4159
|
const binding3 = sourceCode.getDeclaredVariables(owner).find((variable) => variable.defs.some((definition) => definition.node === owner && (definition.type === "FunctionName" || definition.type === "Variable")));
|
|
3891
4160
|
if (!binding3) return false;
|
|
3892
4161
|
const declaration = services.esTreeNodeToTSNodeMap.get(node);
|
|
3893
|
-
if (!
|
|
4162
|
+
if (!ts10.isFunctionDeclaration(declaration) && !ts10.isArrowFunction(declaration) || parameter.parent !== declaration || declaration.parameters.some((entry) => ts10.isIdentifier(entry.name) && entry.name.text === "this")) return false;
|
|
3894
4163
|
const selected = declaration.parameters.indexOf(parameter);
|
|
3895
4164
|
if (selected < 0) return false;
|
|
3896
4165
|
const checker = services.program.getTypeChecker();
|
|
@@ -3906,7 +4175,7 @@ function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
|
3906
4175
|
const validArguments = (call) => {
|
|
3907
4176
|
if (declaration.parameters.length > 1) {
|
|
3908
4177
|
const nativeCall = services.esTreeNodeToTSNodeMap.get(call);
|
|
3909
|
-
if (!
|
|
4178
|
+
if (!ts10.isCallExpression(nativeCall) || checker.getResolvedSignature(nativeCall)?.declaration !== declaration) return false;
|
|
3910
4179
|
}
|
|
3911
4180
|
return call.arguments.every((argument, index) => {
|
|
3912
4181
|
const target = originals[index];
|
|
@@ -3922,7 +4191,7 @@ function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
|
3922
4191
|
continue;
|
|
3923
4192
|
}
|
|
3924
4193
|
const call = reference.identifier.parent;
|
|
3925
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !==
|
|
4194
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== AST_NODE_TYPES33.CallExpression || call.callee !== reference.identifier || call.optional || call.typeArguments || call.arguments.length !== declaration.parameters.length || !call.arguments.every((argument) => argument.type === AST_NODE_TYPES33.Identifier) || !validArguments(call)) return false;
|
|
3926
4195
|
calls += 1;
|
|
3927
4196
|
}
|
|
3928
4197
|
return calls > 0;
|
|
@@ -3973,250 +4242,6 @@ function minimalConsumerFix(sourceCode, annotation, removed) {
|
|
|
3973
4242
|
return sameLineTerminators(sourceCode, annotation, text) ? (fixer) => fixer.replaceText(annotation, text) : null;
|
|
3974
4243
|
}
|
|
3975
4244
|
|
|
3976
|
-
// src/rules/_private-scalar-consumer.ts
|
|
3977
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES33 } from "@typescript-eslint/utils";
|
|
3978
|
-
import ts10 from "typescript";
|
|
3979
|
-
|
|
3980
|
-
// src/rules/_scalar-parameter-view.ts
|
|
3981
|
-
import ts9 from "typescript";
|
|
3982
|
-
|
|
3983
|
-
// src/rules/_native-const-value.ts
|
|
3984
|
-
import ts8 from "typescript";
|
|
3985
|
-
function constInitializer(declaration) {
|
|
3986
|
-
if (!declaration || !ts8.isVariableDeclaration(declaration) || !ts8.isVariableDeclarationList(declaration.parent) || (declaration.parent.flags & ts8.NodeFlags.BlockScoped) !== ts8.NodeFlags.Const) return void 0;
|
|
3987
|
-
let initializer = declaration.initializer;
|
|
3988
|
-
while (initializer && ts8.isParenthesizedExpression(initializer)) initializer = initializer.expression;
|
|
3989
|
-
return initializer;
|
|
3990
|
-
}
|
|
3991
|
-
function unassertedValue(node) {
|
|
3992
|
-
let value = node;
|
|
3993
|
-
while (ts8.isParenthesizedExpression(value) || ts8.isAsExpression(value) || ts8.isTypeAssertionExpression(value) || ts8.isNonNullExpression(value) || ts8.isSatisfiesExpression(value)) value = value.expression;
|
|
3994
|
-
return value;
|
|
3995
|
-
}
|
|
3996
|
-
|
|
3997
|
-
// src/rules/_scalar-parameter-view.ts
|
|
3998
|
-
var SCALAR_OPERATORS = /* @__PURE__ */ new Set([
|
|
3999
|
-
ts9.SyntaxKind.PlusToken,
|
|
4000
|
-
ts9.SyntaxKind.MinusToken,
|
|
4001
|
-
ts9.SyntaxKind.AsteriskToken,
|
|
4002
|
-
ts9.SyntaxKind.SlashToken,
|
|
4003
|
-
ts9.SyntaxKind.PercentToken,
|
|
4004
|
-
ts9.SyntaxKind.AsteriskAsteriskToken,
|
|
4005
|
-
ts9.SyntaxKind.LessThanToken,
|
|
4006
|
-
ts9.SyntaxKind.LessThanEqualsToken,
|
|
4007
|
-
ts9.SyntaxKind.GreaterThanToken,
|
|
4008
|
-
ts9.SyntaxKind.GreaterThanEqualsToken,
|
|
4009
|
-
ts9.SyntaxKind.EqualsEqualsEqualsToken,
|
|
4010
|
-
ts9.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
4011
|
-
ts9.SyntaxKind.EqualsEqualsToken,
|
|
4012
|
-
ts9.SyntaxKind.ExclamationEqualsToken,
|
|
4013
|
-
ts9.SyntaxKind.AmpersandAmpersandToken,
|
|
4014
|
-
ts9.SyntaxKind.BarBarToken,
|
|
4015
|
-
ts9.SyntaxKind.QuestionQuestionToken
|
|
4016
|
-
]);
|
|
4017
|
-
var SCALAR_PREFIXES = /* @__PURE__ */ new Set([ts9.SyntaxKind.PlusToken, ts9.SyntaxKind.MinusToken, ts9.SyntaxKind.ExclamationToken, ts9.SyntaxKind.TildeToken]);
|
|
4018
|
-
var RETURNED_OPERANDS = /* @__PURE__ */ new Set([ts9.SyntaxKind.AmpersandAmpersandToken, ts9.SyntaxKind.BarBarToken, ts9.SyntaxKind.QuestionQuestionToken]);
|
|
4019
|
-
function scalarParameterView(parameter, body3, checker) {
|
|
4020
|
-
return parameterReads(parameter, body3, checker, true);
|
|
4021
|
-
}
|
|
4022
|
-
function scalarParameterReads(parameter, body3, checker, callProgram, auxiliaries) {
|
|
4023
|
-
return parameterReads(parameter, body3, checker, false, callProgram, auxiliaries);
|
|
4024
|
-
}
|
|
4025
|
-
function parameterReads(parameter, body3, checker, jsx, callProgram, auxiliaries) {
|
|
4026
|
-
if (parameter.dotDotDotToken || parameter.initializer || ts9.isArrayBindingPattern(parameter.name)) return null;
|
|
4027
|
-
const root = ts9.isIdentifier(parameter.name) ? checker.getSymbolAtLocation(parameter.name) : void 0;
|
|
4028
|
-
if (ts9.isIdentifier(parameter.name) && !root) return null;
|
|
4029
|
-
const reads = /* @__PURE__ */ new Set();
|
|
4030
|
-
const aliases = parameterAliases(parameter.name, checker, reads);
|
|
4031
|
-
if (!aliases) return null;
|
|
4032
|
-
const expression = returnedExpression(body3);
|
|
4033
|
-
const view = { checker, props: checker.getTypeAtLocation(parameter), root, aliases, reads, callProgram, auxiliaries };
|
|
4034
|
-
return expression && scalarView(expression, view, jsx) ? reads : null;
|
|
4035
|
-
}
|
|
4036
|
-
function scalarType(type, allowUndefined = true) {
|
|
4037
|
-
if (type.isUnion()) return type.types.every((part) => scalarType(part, allowUndefined));
|
|
4038
|
-
const flags = ts9.TypeFlags.StringLike | ts9.TypeFlags.NumberLike | ts9.TypeFlags.BooleanLike | ts9.TypeFlags.BigIntLike | ts9.TypeFlags.Null;
|
|
4039
|
-
return (type.flags & (allowUndefined ? flags | ts9.TypeFlags.Undefined : flags)) !== 0;
|
|
4040
|
-
}
|
|
4041
|
-
function parameterAliases(name, checker, reads) {
|
|
4042
|
-
const aliases = /* @__PURE__ */ new Map();
|
|
4043
|
-
if (ts9.isIdentifier(name)) return aliases;
|
|
4044
|
-
for (const element of name.elements) {
|
|
4045
|
-
const key = element.propertyName ?? element.name;
|
|
4046
|
-
if (element.dotDotDotToken || element.initializer || !ts9.isIdentifier(element.name) || !ts9.isIdentifier(key) && !ts9.isStringLiteralLike(key) && !ts9.isNumericLiteral(key)) return null;
|
|
4047
|
-
const binding3 = checker.getSymbolAtLocation(element.name);
|
|
4048
|
-
if (!binding3) return null;
|
|
4049
|
-
reads.add(key.text);
|
|
4050
|
-
aliases.set(binding3, key.text);
|
|
4051
|
-
}
|
|
4052
|
-
return aliases;
|
|
4053
|
-
}
|
|
4054
|
-
function returnedExpression(body3) {
|
|
4055
|
-
if (!ts9.isBlock(body3)) return body3;
|
|
4056
|
-
const statement = body3.statements.length === 1 ? body3.statements[0] : void 0;
|
|
4057
|
-
return statement && ts9.isReturnStatement(statement) ? statement.expression : void 0;
|
|
4058
|
-
}
|
|
4059
|
-
function scalarView(node, view, jsx = false) {
|
|
4060
|
-
if (scalarLiteral(node)) return true;
|
|
4061
|
-
if (ts9.isCallExpression(node)) return !jsx && scalarCall(node, view);
|
|
4062
|
-
if (ts9.isJsxExpression(node)) return !node.dotDotDotToken && (!node.expression || scalarView(node.expression, view, jsx));
|
|
4063
|
-
if (ts9.isIdentifier(node)) {
|
|
4064
|
-
const binding3 = view.checker.getSymbolAtLocation(node);
|
|
4065
|
-
if (binding3 && view.auxiliaries?.has(binding3)) return scalarType(view.checker.getTypeAtLocation(node));
|
|
4066
|
-
const key = binding3 && view.aliases.get(binding3);
|
|
4067
|
-
return key !== void 0 && readField(node, key, view);
|
|
4068
|
-
}
|
|
4069
|
-
if (ts9.isPropertyAccessExpression(node) || ts9.isElementAccessExpression(node)) return memberRead(node, view);
|
|
4070
|
-
return scalarOperation(node, view, jsx);
|
|
4071
|
-
}
|
|
4072
|
-
function scalarOperation(node, view, jsx) {
|
|
4073
|
-
if (ts9.isParenthesizedExpression(node) || ts9.isNonNullExpression(node)) return scalarView(node.expression, view, jsx);
|
|
4074
|
-
if (ts9.isTypeOfExpression(node)) return scalarView(node.expression, view);
|
|
4075
|
-
if (ts9.isConditionalExpression(node)) return scalarView(node.condition, view) && scalarView(node.whenTrue, view, jsx) && scalarView(node.whenFalse, view, jsx);
|
|
4076
|
-
if (ts9.isBinaryExpression(node)) return binaryView(node, view, jsx);
|
|
4077
|
-
if (ts9.isPrefixUnaryExpression(node)) return SCALAR_PREFIXES.has(node.operator) && scalarView(node.operand, view);
|
|
4078
|
-
if (ts9.isTemplateExpression(node)) return node.templateSpans.every((span) => scalarView(span.expression, view));
|
|
4079
|
-
return jsx && jsxView(node, view);
|
|
4080
|
-
}
|
|
4081
|
-
function scalarCall(node, view) {
|
|
4082
|
-
if (!view.callProgram || node.questionDotToken || node.typeArguments?.length || !ts9.isIdentifier(node.expression) || !node.arguments.length || node.arguments.some(ts9.isSpreadElement)) return false;
|
|
4083
|
-
const declarations = view.checker.getSymbolAtLocation(node.expression)?.declarations;
|
|
4084
|
-
const declaration = declarations?.length === 1 ? declarations[0] : void 0;
|
|
4085
|
-
const helper = declaration && localHelper(declaration);
|
|
4086
|
-
if (!helper || helper.getSourceFile() !== node.getSourceFile() || helper.typeParameters?.length || !helper.type || !node.arguments.every((argument) => scalarView(argument, view))) return false;
|
|
4087
|
-
if (!checkedNativeSource(view.callProgram, node.getSourceFile())) return false;
|
|
4088
|
-
const signature = view.checker.getResolvedSignature(node);
|
|
4089
|
-
return signature?.declaration === helper && !view.checker.getTypePredicateOfSignature(signature) && scalarType(view.checker.getTypeAtLocation(node));
|
|
4090
|
-
}
|
|
4091
|
-
function localHelper(node) {
|
|
4092
|
-
if (ts9.isFunctionDeclaration(node)) return node.body && ts9.isSourceFile(node.parent) ? node : void 0;
|
|
4093
|
-
if (!ts9.isVariableDeclaration(node) || node.type || !node.initializer || constInitializer(node) !== node.initializer || !ts9.isArrowFunction(node.initializer) || !ts9.isVariableStatement(node.parent.parent) || !ts9.isSourceFile(node.parent.parent.parent)) return void 0;
|
|
4094
|
-
return node.initializer;
|
|
4095
|
-
}
|
|
4096
|
-
function binaryView(node, view, jsx) {
|
|
4097
|
-
const returned2 = jsx && RETURNED_OPERANDS.has(node.operatorToken.kind);
|
|
4098
|
-
return SCALAR_OPERATORS.has(node.operatorToken.kind) && scalarView(node.left, view, returned2) && scalarView(node.right, view, returned2);
|
|
4099
|
-
}
|
|
4100
|
-
function scalarLiteral(node) {
|
|
4101
|
-
return ts9.isStringLiteralLike(node) || ts9.isNumericLiteral(node) || ts9.isBigIntLiteral(node) || ts9.isJsxText(node) || node.kind === ts9.SyntaxKind.TrueKeyword || node.kind === ts9.SyntaxKind.FalseKeyword || node.kind === ts9.SyntaxKind.NullKeyword;
|
|
4102
|
-
}
|
|
4103
|
-
function memberRead(node, view) {
|
|
4104
|
-
if (!view.root || !ts9.isIdentifier(node.expression) || view.checker.getSymbolAtLocation(node.expression) !== view.root) return false;
|
|
4105
|
-
const key = ts9.isPropertyAccessExpression(node) ? node.name.text : node.argumentExpression && (ts9.isStringLiteralLike(node.argumentExpression) || ts9.isNumericLiteral(node.argumentExpression)) ? node.argumentExpression.text : void 0;
|
|
4106
|
-
return key !== void 0 && readField(node, key, view);
|
|
4107
|
-
}
|
|
4108
|
-
function readField(node, key, view) {
|
|
4109
|
-
if (!view.checker.getPropertyOfType(view.props, key) || !scalarType(view.checker.getTypeAtLocation(node))) return false;
|
|
4110
|
-
view.reads.add(key);
|
|
4111
|
-
return true;
|
|
4112
|
-
}
|
|
4113
|
-
function jsxView(node, view) {
|
|
4114
|
-
if (ts9.isJsxFragment(node)) return node.children.every((child) => scalarView(child, view, true));
|
|
4115
|
-
if (ts9.isJsxElement(node)) return jsxView(node.openingElement, view) && node.children.every((child) => scalarView(child, view, true));
|
|
4116
|
-
if (!ts9.isJsxOpeningElement(node) && !ts9.isJsxSelfClosingElement(node)) return false;
|
|
4117
|
-
if (!ts9.isIdentifier(node.tagName) || !/^[a-z][A-Za-z0-9]*$/u.test(node.tagName.text)) return false;
|
|
4118
|
-
return node.attributes.properties.every((attribute) => intrinsicAttribute(attribute, view));
|
|
4119
|
-
}
|
|
4120
|
-
function intrinsicAttribute(attribute, view) {
|
|
4121
|
-
return ts9.isJsxAttribute(attribute) && ts9.isIdentifier(attribute.name) && attribute.name.text !== "is" && (!attribute.initializer || scalarView(attribute.initializer, view));
|
|
4122
|
-
}
|
|
4123
|
-
|
|
4124
|
-
// src/rules/_private-scalar-consumer.ts
|
|
4125
|
-
function directEval(node) {
|
|
4126
|
-
let callee = unwrapExpression(node.callee);
|
|
4127
|
-
while (callee.type === AST_NODE_TYPES33.TSInstantiationExpression) callee = unwrapExpression(callee.expression);
|
|
4128
|
-
return callee.type === AST_NODE_TYPES33.Identifier && callee.name === "eval";
|
|
4129
|
-
}
|
|
4130
|
-
function primitiveKeyword(node) {
|
|
4131
|
-
return node !== void 0 && (node.kind === ts10.SyntaxKind.StringKeyword || node.kind === ts10.SyntaxKind.NumberKeyword || node.kind === ts10.SyntaxKind.BooleanKeyword || node.kind === ts10.SyntaxKind.BigIntKeyword);
|
|
4132
|
-
}
|
|
4133
|
-
function nullishPrimitiveUnion(node) {
|
|
4134
|
-
return node !== void 0 && ts10.isUnionTypeNode(node) && node.types.length === 2 && node.types.some(primitiveKeyword) && node.types.some((part) => part.kind === ts10.SyntaxKind.UndefinedKeyword || ts10.isLiteralTypeNode(part) && part.literal.kind === ts10.SyntaxKind.NullKeyword);
|
|
4135
|
-
}
|
|
4136
|
-
function consumerAnnotation(node, auxiliaryScalars = false) {
|
|
4137
|
-
if (node.params.length !== 1) {
|
|
4138
|
-
if (!auxiliaryScalars) return void 0;
|
|
4139
|
-
let annotation;
|
|
4140
|
-
for (const parameter2 of node.params) {
|
|
4141
|
-
if (parameter2.type !== AST_NODE_TYPES33.Identifier && parameter2.type !== AST_NODE_TYPES33.ObjectPattern) continue;
|
|
4142
|
-
const current = parameter2.typeAnnotation?.typeAnnotation;
|
|
4143
|
-
if (current?.type !== AST_NODE_TYPES33.TSTypeLiteral) continue;
|
|
4144
|
-
if (annotation) return void 0;
|
|
4145
|
-
annotation = current;
|
|
4146
|
-
}
|
|
4147
|
-
return annotation;
|
|
4148
|
-
}
|
|
4149
|
-
const parameter = node.params[0];
|
|
4150
|
-
return parameter?.type === AST_NODE_TYPES33.Identifier || parameter?.type === AST_NODE_TYPES33.ObjectPattern ? parameter.typeAnnotation?.typeAnnotation : void 0;
|
|
4151
|
-
}
|
|
4152
|
-
function exportedSymbols(source, checker) {
|
|
4153
|
-
const symbol = checker.getSymbolAtLocation(source);
|
|
4154
|
-
return new Set(symbol ? checker.getExportsOfModule(symbol).map((entry) => (entry.flags & ts10.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(entry) : entry) : []);
|
|
4155
|
-
}
|
|
4156
|
-
function privateScalarConsumer(node, sourceCode, services, exports, options = {}) {
|
|
4157
|
-
const native = services.esTreeNodeToTSNodeMap.get(node);
|
|
4158
|
-
if (!ts10.isFunctionDeclaration(native) && !ts10.isArrowFunction(native) || !native.body) return null;
|
|
4159
|
-
let parameter = native.parameters[0];
|
|
4160
|
-
if (native.parameters.length !== 1) {
|
|
4161
|
-
const annotation = consumerAnnotation(node, options.auxiliaryScalars);
|
|
4162
|
-
const selected = annotation && services.esTreeNodeToTSNodeMap.get(annotation);
|
|
4163
|
-
parameter = native.parameters.find((entry) => entry.type === selected);
|
|
4164
|
-
}
|
|
4165
|
-
if (!parameter || !independentSignature(native, parameter, options.auxiliaryScalars === true)) return null;
|
|
4166
|
-
const checker = services.program.getTypeChecker();
|
|
4167
|
-
if (!ts10.isExternalModule(native.getSourceFile()) || !services.program.getCompilerOptions().strict) return null;
|
|
4168
|
-
if (!privateDirectCallable(node, native, sourceCode, checker, exports)) return null;
|
|
4169
|
-
const signature = checker.getSignatureFromDeclaration(native);
|
|
4170
|
-
if (!signature || signature.typeParameters?.length || checker.getTypePredicateOfSignature(signature)) return null;
|
|
4171
|
-
const expression = returnedExpression(native.body);
|
|
4172
|
-
if (!expression || !checker.isTypeAssignableTo(checker.getTypeAtLocation(expression), checker.getReturnTypeOfSignature(signature))) return null;
|
|
4173
|
-
const auxiliaries = native.parameters.length > 1 ? auxiliaryBindings(native, parameter, checker) : void 0;
|
|
4174
|
-
if (auxiliaries === null) return null;
|
|
4175
|
-
const reads = scalarParameterReads(parameter, native.body, checker, options.scalarCalls ? services.program : void 0, auxiliaries);
|
|
4176
|
-
return reads?.size ? { parameter, reads } : null;
|
|
4177
|
-
}
|
|
4178
|
-
function privateDirectCallable(node, native, sourceCode, checker, exports) {
|
|
4179
|
-
const binding3 = callableBinding(node, sourceCode);
|
|
4180
|
-
if (!binding3 || binding3.defs.length !== 1) return false;
|
|
4181
|
-
const name = ts10.isFunctionDeclaration(native) ? native.name : ts10.isVariableDeclaration(native.parent) ? native.parent.name : void 0;
|
|
4182
|
-
const symbol = name && checker.getSymbolAtLocation(name);
|
|
4183
|
-
return symbol !== void 0 && symbol.declarations?.length === 1 && !exports.has(symbol) && directCalls(binding3, native.parameters.length);
|
|
4184
|
-
}
|
|
4185
|
-
function independentSignature(native, selected, auxiliaryScalars) {
|
|
4186
|
-
if (!auxiliaryScalars && native.parameters.length !== 1 || native.typeParameters?.length || native.asteriskToken || native.modifiers?.length || !primitiveKeyword(native.type)) return false;
|
|
4187
|
-
return native.parameters.every((parameter) => parameter.type !== void 0 && !parameter.modifiers?.length && !parameter.questionToken && !parameter.initializer && !parameter.dotDotDotToken && (!ts10.isIdentifier(parameter.name) || parameter.name.text !== "this") && (parameter === selected || ts10.isIdentifier(parameter.name) && primitiveKeyword(parameter.type)));
|
|
4188
|
-
}
|
|
4189
|
-
function auxiliaryBindings(native, selected, checker) {
|
|
4190
|
-
const bindings = /* @__PURE__ */ new Set();
|
|
4191
|
-
for (const parameter of native.parameters) {
|
|
4192
|
-
if (parameter === selected) continue;
|
|
4193
|
-
const symbol = ts10.isIdentifier(parameter.name) ? checker.getSymbolAtLocation(parameter.name) : void 0;
|
|
4194
|
-
if (!symbol || symbol.declarations?.length !== 1 || symbol.declarations[0] !== parameter || bindings.has(symbol)) return null;
|
|
4195
|
-
bindings.add(symbol);
|
|
4196
|
-
}
|
|
4197
|
-
return bindings;
|
|
4198
|
-
}
|
|
4199
|
-
function callableBinding(node, sourceCode) {
|
|
4200
|
-
if (node.type === AST_NODE_TYPES33.FunctionDeclaration) {
|
|
4201
|
-
if (node.parent.type !== AST_NODE_TYPES33.Program) return void 0;
|
|
4202
|
-
return sourceCode.getDeclaredVariables(node).find((variable) => variable.defs.some((definition) => definition.type === "FunctionName" && definition.node === node));
|
|
4203
|
-
}
|
|
4204
|
-
const declaration = node.parent;
|
|
4205
|
-
if (declaration.type !== AST_NODE_TYPES33.VariableDeclarator || declaration.init !== node || declaration.id.type !== AST_NODE_TYPES33.Identifier || declaration.id.typeAnnotation || declaration.parent.kind !== "const" || declaration.parent.parent.type !== AST_NODE_TYPES33.Program) return void 0;
|
|
4206
|
-
return sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
4207
|
-
}
|
|
4208
|
-
function directCalls(binding3, arity) {
|
|
4209
|
-
let calls = 0;
|
|
4210
|
-
const stable2 = stableValueBinding(binding3, (reference) => {
|
|
4211
|
-
const identifier = reference.identifier;
|
|
4212
|
-
const call = identifier.parent;
|
|
4213
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== AST_NODE_TYPES33.CallExpression || call.callee !== identifier || call.optional || call.typeArguments || call.arguments.length !== arity || !call.arguments.every((argument) => argument.type === AST_NODE_TYPES33.Identifier)) return false;
|
|
4214
|
-
calls += 1;
|
|
4215
|
-
return true;
|
|
4216
|
-
});
|
|
4217
|
-
return stable2 && calls > 0;
|
|
4218
|
-
}
|
|
4219
|
-
|
|
4220
4245
|
// src/rules/no-redundant-consumer-union.ts
|
|
4221
4246
|
var CONFIG3 = { path: "tsconfig.json", source: '{"compilerOptions":{"strict":true,"target":"ESNext","module":"ESNext","moduleResolution":"Bundler"}}' };
|
|
4222
4247
|
var EXAMPLE = 'export {}; interface Animal {readonly name: string} interface Dog extends Animal {readonly breed: string} export type KeptDog = Dog; const dog: Dog = {name: "Ada", breed: "Collie"}; function label(value: Dog | Animal): string {return value.name;} label(dog);';
|
|
@@ -5544,7 +5569,7 @@ function isSearchParamReceiver(call, services) {
|
|
|
5544
5569
|
// package.json
|
|
5545
5570
|
var package_default = {
|
|
5546
5571
|
name: "@sarj/eslint-plugin",
|
|
5547
|
-
version: "18.0.
|
|
5572
|
+
version: "18.0.5",
|
|
5548
5573
|
packageManager: "npm@12.2.1",
|
|
5549
5574
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
5550
5575
|
type: "module",
|