@sarj/eslint-plugin 15.15.0 → 15.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +797 -363
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +812 -378
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4010,8 +4010,8 @@ function privateMemberFixes(context, services, owner, members, removePrivateKeyw
|
|
|
4010
4010
|
return;
|
|
4011
4011
|
}
|
|
4012
4012
|
if (node.type !== AST_NODE_TYPES14.MemberExpression) return;
|
|
4013
|
-
const
|
|
4014
|
-
if (
|
|
4013
|
+
const propertyName7 = node.property.type === AST_NODE_TYPES14.Identifier || node.property.type === AST_NODE_TYPES14.PrivateIdentifier ? node.property.name : node.property.type === AST_NODE_TYPES14.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
4014
|
+
if (propertyName7 !== name) return;
|
|
4015
4015
|
const propertySymbol = symbolAt(services, checker, node.property);
|
|
4016
4016
|
if (node.computed || node.property.type !== AST_NODE_TYPES14.Identifier || node.object.type !== AST_NODE_TYPES14.ThisExpression || enclosingClass(node) !== owner || !symbols.some((symbol) => sameSymbol(symbol, propertySymbol))) {
|
|
4017
4017
|
unsafe = true;
|
|
@@ -5420,9 +5420,9 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5420
5420
|
TSMethodSignature(node) {
|
|
5421
5421
|
const owner = owningInterface(node);
|
|
5422
5422
|
const alias = owningTypeAlias(node);
|
|
5423
|
-
const
|
|
5424
|
-
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 ||
|
|
5425
|
-
report2(node.returnType.typeAnnotation, `${owner?.id.name ?? alias?.id.name ?? "type"}.${
|
|
5423
|
+
const memberName6 = staticMemberName3(node.key);
|
|
5424
|
+
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 || memberName6 === null) return;
|
|
5425
|
+
report2(node.returnType.typeAnnotation, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName6}`);
|
|
5426
5426
|
},
|
|
5427
5427
|
TSTypeAliasDeclaration(node) {
|
|
5428
5428
|
if (!typeExports.has(node.id.name)) return;
|
|
@@ -5433,11 +5433,11 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5433
5433
|
const owner = owningInterface(node);
|
|
5434
5434
|
const alias = owningTypeAlias(node);
|
|
5435
5435
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
5436
|
-
const
|
|
5437
|
-
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) ||
|
|
5436
|
+
const memberName6 = staticMemberName3(node.key);
|
|
5437
|
+
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || memberName6 === null || annotation === void 0) return;
|
|
5438
5438
|
const returnType = callableReturnType(annotation, aliases);
|
|
5439
5439
|
if (returnType !== null) {
|
|
5440
|
-
report2(returnType, `${owner?.id.name ?? alias?.id.name ?? "type"}.${
|
|
5440
|
+
report2(returnType, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName6}`);
|
|
5441
5441
|
}
|
|
5442
5442
|
},
|
|
5443
5443
|
PropertyDefinition(node) {
|
|
@@ -11823,14 +11823,14 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
11823
11823
|
});
|
|
11824
11824
|
|
|
11825
11825
|
// src/rules/prefer-node-crypto-hash.ts
|
|
11826
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES52 } from "@typescript-eslint/utils";
|
|
11826
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES52, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
|
|
11827
11827
|
var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
|
|
11828
11828
|
summary: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
|
|
11829
11829
|
rationale: "A createHash-update-digest chain allocates mutable streaming state for a single in-memory value; Node's built-in hash function expresses the one-shot operation directly and can use its optimized fast path.",
|
|
11830
11830
|
remediation: "Import hash from node:crypto and replace a single-update chain with hash(algorithm, value, encoding). Keep createHash for streams or multiple incremental updates.",
|
|
11831
11831
|
category: "performance",
|
|
11832
11832
|
limitations: [
|
|
11833
|
-
"Only
|
|
11833
|
+
"Only bindings and inline calls with statically proven provenance from crypto or node:crypto are analyzed; arbitrary assignments and dynamic module specifiers are excluded.",
|
|
11834
11834
|
"Only a literal algorithm with exactly one update call is reported; streaming and incremental hashes remain valid."
|
|
11835
11835
|
],
|
|
11836
11836
|
examples: [
|
|
@@ -11838,22 +11838,79 @@ var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
|
|
|
11838
11838
|
{ id: "mutable-one-shot-chain", title: "Avoid mutable state for one value", outcome: "match", files: [{ path: "case.ts", source: "import { createHash } from 'node:crypto'; export const digest = createHash('sha256').update('value').digest('hex');" }], focusPath: "case.ts", expectedCount: 1, public: true }
|
|
11839
11839
|
]
|
|
11840
11840
|
};
|
|
11841
|
+
function memberName3(node) {
|
|
11842
|
+
if (!node.computed && node.property.type === AST_NODE_TYPES52.Identifier) return node.property.name;
|
|
11843
|
+
if (node.computed && node.property.type === AST_NODE_TYPES52.Literal && typeof node.property.value === "string") {
|
|
11844
|
+
return node.property.value;
|
|
11845
|
+
}
|
|
11846
|
+
return null;
|
|
11847
|
+
}
|
|
11848
|
+
function isCryptoLoader(node, resolve) {
|
|
11849
|
+
if (node.type !== AST_NODE_TYPES52.CallExpression || node.arguments.length !== 1) return false;
|
|
11850
|
+
const [argument] = node.arguments;
|
|
11851
|
+
if (argument === void 0 || argument.type === AST_NODE_TYPES52.SpreadElement || !isCryptoSpecifier(argument)) {
|
|
11852
|
+
return false;
|
|
11853
|
+
}
|
|
11854
|
+
if (node.callee.type === AST_NODE_TYPES52.Identifier) {
|
|
11855
|
+
return node.callee.name === "require" && isUnshadowedBuiltinIdentifier(node.callee, resolve);
|
|
11856
|
+
}
|
|
11857
|
+
return node.callee.type === AST_NODE_TYPES52.MemberExpression && node.callee.object.type === AST_NODE_TYPES52.Identifier && node.callee.object.name === "process" && isUnshadowedBuiltinIdentifier(node.callee.object, resolve) && memberName3(node.callee) === "getBuiltinModule";
|
|
11858
|
+
}
|
|
11859
|
+
function isCryptoSpecifier(node) {
|
|
11860
|
+
return node.type === AST_NODE_TYPES52.Literal && (node.value === "crypto" || node.value === "node:crypto");
|
|
11861
|
+
}
|
|
11862
|
+
function isUnshadowedBuiltinIdentifier(identifier, resolve) {
|
|
11863
|
+
const variable = resolve(identifier);
|
|
11864
|
+
return variable === null || variable.defs.length === 0;
|
|
11865
|
+
}
|
|
11866
|
+
function propertyName3(node) {
|
|
11867
|
+
if (!node.computed && node.key.type === AST_NODE_TYPES52.Identifier) return node.key.name;
|
|
11868
|
+
if (node.key.type === AST_NODE_TYPES52.Literal && typeof node.key.value === "string") {
|
|
11869
|
+
return node.key.value;
|
|
11870
|
+
}
|
|
11871
|
+
return null;
|
|
11872
|
+
}
|
|
11841
11873
|
var prefer_node_crypto_hash_default = createRule({
|
|
11842
11874
|
name: "prefer-node-crypto-hash",
|
|
11843
11875
|
documentation: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION,
|
|
11844
11876
|
meta: { type: "problem", docs: { description: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION.summary }, schema: [], messages: { preferNodeCryptoHash: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary." } },
|
|
11845
11877
|
defaultOptions: [],
|
|
11846
11878
|
create(context) {
|
|
11847
|
-
const
|
|
11848
|
-
const
|
|
11879
|
+
const directBindings = /* @__PURE__ */ new Set();
|
|
11880
|
+
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
11881
|
+
function resolve(identifier) {
|
|
11882
|
+
return ASTUtils15.findVariable(
|
|
11883
|
+
context.sourceCode.getScope(identifier),
|
|
11884
|
+
identifier.name
|
|
11885
|
+
);
|
|
11886
|
+
}
|
|
11887
|
+
function record(identifier, destination) {
|
|
11888
|
+
const variable = resolve(identifier);
|
|
11889
|
+
if (variable !== null) destination.add(variable);
|
|
11890
|
+
}
|
|
11849
11891
|
return {
|
|
11850
11892
|
ImportDeclaration(node) {
|
|
11851
|
-
if (node.source.value !== "node:crypto") return;
|
|
11893
|
+
if (node.source.value !== "crypto" && node.source.value !== "node:crypto") return;
|
|
11852
11894
|
for (const specifier of node.specifiers) {
|
|
11853
|
-
if (specifier.type === AST_NODE_TYPES52.ImportNamespaceSpecifier) {
|
|
11854
|
-
|
|
11895
|
+
if (specifier.type === AST_NODE_TYPES52.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES52.ImportDefaultSpecifier) {
|
|
11896
|
+
record(specifier.local, namespaceBindings);
|
|
11855
11897
|
} else if (specifier.type === AST_NODE_TYPES52.ImportSpecifier && importedName5(specifier.imported) === "createHash") {
|
|
11856
|
-
|
|
11898
|
+
record(specifier.local, directBindings);
|
|
11899
|
+
}
|
|
11900
|
+
}
|
|
11901
|
+
},
|
|
11902
|
+
VariableDeclarator(node) {
|
|
11903
|
+
if (node.parent.kind !== "const" || node.init === null || !isCryptoLoader(node.init, resolve)) {
|
|
11904
|
+
return;
|
|
11905
|
+
}
|
|
11906
|
+
if (node.id.type === AST_NODE_TYPES52.Identifier) {
|
|
11907
|
+
record(node.id, namespaceBindings);
|
|
11908
|
+
return;
|
|
11909
|
+
}
|
|
11910
|
+
if (node.id.type !== AST_NODE_TYPES52.ObjectPattern) return;
|
|
11911
|
+
for (const property of node.id.properties) {
|
|
11912
|
+
if (property.type === AST_NODE_TYPES52.Property && propertyName3(property) === "createHash" && property.value.type === AST_NODE_TYPES52.Identifier) {
|
|
11913
|
+
record(property.value, directBindings);
|
|
11857
11914
|
}
|
|
11858
11915
|
}
|
|
11859
11916
|
},
|
|
@@ -11863,7 +11920,12 @@ var prefer_node_crypto_hash_default = createRule({
|
|
|
11863
11920
|
if (update.type !== AST_NODE_TYPES52.CallExpression || update.arguments.length !== 1 || !isMemberCall(update, "update"))
|
|
11864
11921
|
return;
|
|
11865
11922
|
const create = update.callee.object;
|
|
11866
|
-
if (create.type !== AST_NODE_TYPES52.CallExpression || create.arguments.length !== 1 || create.arguments[0]?.type !== AST_NODE_TYPES52.Literal || typeof create.arguments[0].value !== "string" || !isCreateHashCall(
|
|
11923
|
+
if (create.type !== AST_NODE_TYPES52.CallExpression || create.arguments.length !== 1 || create.arguments[0]?.type !== AST_NODE_TYPES52.Literal || typeof create.arguments[0].value !== "string" || !isCreateHashCall(
|
|
11924
|
+
create,
|
|
11925
|
+
directBindings,
|
|
11926
|
+
namespaceBindings,
|
|
11927
|
+
resolve
|
|
11928
|
+
))
|
|
11867
11929
|
return;
|
|
11868
11930
|
context.report({ node, messageId: "preferNodeCryptoHash" });
|
|
11869
11931
|
}
|
|
@@ -11874,12 +11936,20 @@ function importedName5(node) {
|
|
|
11874
11936
|
return node.type === AST_NODE_TYPES52.Identifier ? node.name : node.value;
|
|
11875
11937
|
}
|
|
11876
11938
|
function isMemberCall(node, name) {
|
|
11877
|
-
return node.callee.type === AST_NODE_TYPES52.MemberExpression &&
|
|
11939
|
+
return node.callee.type === AST_NODE_TYPES52.MemberExpression && memberName3(node.callee) === name;
|
|
11878
11940
|
}
|
|
11879
|
-
function isCreateHashCall(node,
|
|
11880
|
-
if (node.callee.type === AST_NODE_TYPES52.Identifier)
|
|
11881
|
-
|
|
11882
|
-
|
|
11941
|
+
function isCreateHashCall(node, directBindings, namespaceBindings, resolve) {
|
|
11942
|
+
if (node.callee.type === AST_NODE_TYPES52.Identifier) {
|
|
11943
|
+
const variable2 = resolve(node.callee);
|
|
11944
|
+
return variable2 !== null && directBindings.has(variable2);
|
|
11945
|
+
}
|
|
11946
|
+
if (node.callee.type !== AST_NODE_TYPES52.MemberExpression || memberName3(node.callee) !== "createHash") {
|
|
11947
|
+
return false;
|
|
11948
|
+
}
|
|
11949
|
+
if (isCryptoLoader(node.callee.object, resolve)) return true;
|
|
11950
|
+
if (node.callee.object.type !== AST_NODE_TYPES52.Identifier) return false;
|
|
11951
|
+
const variable = resolve(node.callee.object);
|
|
11952
|
+
return variable !== null && namespaceBindings.has(variable);
|
|
11883
11953
|
}
|
|
11884
11954
|
|
|
11885
11955
|
// src/rules/prefer-node-fs-promises.ts
|
|
@@ -11892,20 +11962,40 @@ var PREFER_NODE_FS_PROMISES_DOCUMENTATION = {
|
|
|
11892
11962
|
limitations: [
|
|
11893
11963
|
"Tests and generated files are excluded.",
|
|
11894
11964
|
"ESLint rule implementations under src/rules are excluded because visitor creation and execution are synchronous by contract.",
|
|
11895
|
-
"
|
|
11965
|
+
"Only statically identifiable node:fs loads are inspected; filesystem objects passed through arbitrary functions or assignments require type-aware analysis."
|
|
11896
11966
|
],
|
|
11897
11967
|
examples: [
|
|
11898
11968
|
{ id: "async-read", title: "Use the promise API", outcome: "no-match", files: [{ path: "src/store.ts", source: "import { readFile } from 'node:fs/promises'; export async function load(path: string) { return readFile(path, 'utf8'); }" }], focusPath: "src/store.ts", expectedCount: 0, public: true },
|
|
11899
11969
|
{ id: "sync-read", title: "Do not block on a synchronous read", outcome: "match", files: [{ path: "src/store.ts", source: "import { readFileSync } from 'node:fs'; export function load(path: string) { return readFileSync(path, 'utf8'); }" }], focusPath: "src/store.ts", expectedCount: 1, public: true }
|
|
11900
11970
|
]
|
|
11901
11971
|
};
|
|
11902
|
-
function
|
|
11972
|
+
function memberName4(node) {
|
|
11903
11973
|
if (!node.computed && node.property.type === AST_NODE_TYPES53.Identifier) return node.property.name;
|
|
11904
11974
|
if (node.computed && node.property.type === AST_NODE_TYPES53.Literal && typeof node.property.value === "string") {
|
|
11905
11975
|
return node.property.value;
|
|
11906
11976
|
}
|
|
11907
11977
|
return null;
|
|
11908
11978
|
}
|
|
11979
|
+
function unwrapAwait2(node) {
|
|
11980
|
+
return node.type === AST_NODE_TYPES53.AwaitExpression ? node.argument : node;
|
|
11981
|
+
}
|
|
11982
|
+
function isFsLoader(node) {
|
|
11983
|
+
const expression = unwrapAwait2(node);
|
|
11984
|
+
if (expression.type === AST_NODE_TYPES53.ImportExpression) return isFsSpecifier(expression.source);
|
|
11985
|
+
if (expression.type !== AST_NODE_TYPES53.CallExpression || expression.arguments.length !== 1) return false;
|
|
11986
|
+
const [argument] = expression.arguments;
|
|
11987
|
+
if (argument === void 0 || argument.type === AST_NODE_TYPES53.SpreadElement || !isFsSpecifier(argument)) return false;
|
|
11988
|
+
if (expression.callee.type === AST_NODE_TYPES53.Identifier) return expression.callee.name === "require";
|
|
11989
|
+
return expression.callee.type === AST_NODE_TYPES53.MemberExpression && expression.callee.object.type === AST_NODE_TYPES53.Identifier && expression.callee.object.name === "process" && memberName4(expression.callee) === "getBuiltinModule";
|
|
11990
|
+
}
|
|
11991
|
+
function isFsSpecifier(node) {
|
|
11992
|
+
return node.type === AST_NODE_TYPES53.Literal && (node.value === "node:fs" || node.value === "fs");
|
|
11993
|
+
}
|
|
11994
|
+
function propertyName4(node) {
|
|
11995
|
+
if (!node.computed && node.key.type === AST_NODE_TYPES53.Identifier) return node.key.name;
|
|
11996
|
+
if (node.key.type === AST_NODE_TYPES53.Literal && typeof node.key.value === "string") return node.key.value;
|
|
11997
|
+
return null;
|
|
11998
|
+
}
|
|
11909
11999
|
var prefer_node_fs_promises_default = createRule({
|
|
11910
12000
|
name: "prefer-node-fs-promises",
|
|
11911
12001
|
documentation: PREFER_NODE_FS_PROMISES_DOCUMENTATION,
|
|
@@ -11942,10 +12032,32 @@ var prefer_node_fs_promises_default = createRule({
|
|
|
11942
12032
|
});
|
|
11943
12033
|
}
|
|
11944
12034
|
},
|
|
12035
|
+
VariableDeclarator(node) {
|
|
12036
|
+
if (node.init === null || !isFsLoader(node.init) && (node.init.type !== AST_NODE_TYPES53.Identifier || !namespaces.has(node.init.name)))
|
|
12037
|
+
return;
|
|
12038
|
+
if (node.id.type === AST_NODE_TYPES53.Identifier) {
|
|
12039
|
+
namespaces.add(node.id.name);
|
|
12040
|
+
return;
|
|
12041
|
+
}
|
|
12042
|
+
if (node.id.type !== AST_NODE_TYPES53.ObjectPattern) return;
|
|
12043
|
+
const synchronousImports = node.id.properties.flatMap((property) => {
|
|
12044
|
+
if (property.type !== AST_NODE_TYPES53.Property) return [];
|
|
12045
|
+
const name = propertyName4(property);
|
|
12046
|
+
return name?.endsWith("Sync") === true ? [name] : [];
|
|
12047
|
+
});
|
|
12048
|
+
if (synchronousImports.length > 0) {
|
|
12049
|
+
context.report({
|
|
12050
|
+
node,
|
|
12051
|
+
messageId: "preferAsyncFs",
|
|
12052
|
+
data: { name: synchronousImports.join(", ") }
|
|
12053
|
+
});
|
|
12054
|
+
}
|
|
12055
|
+
},
|
|
11945
12056
|
MemberExpression(node) {
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
12057
|
+
const name = memberName4(node);
|
|
12058
|
+
if (name?.endsWith("Sync") !== true) return;
|
|
12059
|
+
const object = unwrapAwait2(node.object);
|
|
12060
|
+
if (object.type === AST_NODE_TYPES53.Identifier && namespaces.has(object.name) || isFsLoader(object)) {
|
|
11949
12061
|
context.report({ node, messageId: "preferAsyncFs", data: { name } });
|
|
11950
12062
|
}
|
|
11951
12063
|
}
|
|
@@ -11954,7 +12066,7 @@ var prefer_node_fs_promises_default = createRule({
|
|
|
11954
12066
|
});
|
|
11955
12067
|
|
|
11956
12068
|
// src/rules/prefer-non-nullable-collection.ts
|
|
11957
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES54, ASTUtils as
|
|
12069
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES54, ASTUtils as ASTUtils16 } from "@typescript-eslint/utils";
|
|
11958
12070
|
var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
11959
12071
|
summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
|
|
11960
12072
|
rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
|
|
@@ -11967,7 +12079,7 @@ var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
|
11967
12079
|
]
|
|
11968
12080
|
};
|
|
11969
12081
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
11970
|
-
function
|
|
12082
|
+
function propertyName5(node) {
|
|
11971
12083
|
const key = node.key;
|
|
11972
12084
|
if (node.computed) return null;
|
|
11973
12085
|
if (key.type === AST_NODE_TYPES54.Identifier) return key.name;
|
|
@@ -11980,7 +12092,7 @@ function isArrayType(node) {
|
|
|
11980
12092
|
}
|
|
11981
12093
|
function nullableProperty(node) {
|
|
11982
12094
|
if (node.optional) return null;
|
|
11983
|
-
const name =
|
|
12095
|
+
const name = propertyName5(node);
|
|
11984
12096
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
11985
12097
|
if (name === null || annotation?.type !== AST_NODE_TYPES54.TSUnionType) return null;
|
|
11986
12098
|
const concrete = annotation.types.filter(
|
|
@@ -12084,14 +12196,14 @@ function directlyCoalesced(node) {
|
|
|
12084
12196
|
return parent?.type === AST_NODE_TYPES54.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
|
|
12085
12197
|
}
|
|
12086
12198
|
function identifierIsOnlyCoalesced(context, binding, fn) {
|
|
12087
|
-
const variable =
|
|
12199
|
+
const variable = ASTUtils16.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
12088
12200
|
if (variable === null || variable.references.length === 0) return false;
|
|
12089
12201
|
return variable.references.every(
|
|
12090
12202
|
(reference) => belongsToFunction(reference.identifier, fn) && directlyCoalesced(reference.identifier)
|
|
12091
12203
|
);
|
|
12092
12204
|
}
|
|
12093
12205
|
function memberIsOnlyCoalesced(context, object, property, fn) {
|
|
12094
|
-
const variable =
|
|
12206
|
+
const variable = ASTUtils16.findVariable(context.sourceCode.getScope(object), object.name);
|
|
12095
12207
|
if (variable === null) return false;
|
|
12096
12208
|
const accesses = variable.references.flatMap((reference) => {
|
|
12097
12209
|
if (!belongsToFunction(reference.identifier, fn)) return [null];
|
|
@@ -12190,7 +12302,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12190
12302
|
context.report({
|
|
12191
12303
|
node,
|
|
12192
12304
|
messageId: "preferNonNullableCollection",
|
|
12193
|
-
data: { name:
|
|
12305
|
+
data: { name: propertyName5(node) ?? "collection" }
|
|
12194
12306
|
});
|
|
12195
12307
|
}
|
|
12196
12308
|
}
|
|
@@ -12201,7 +12313,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12201
12313
|
// src/rules/prefer-nullish-filter-predicate.ts
|
|
12202
12314
|
import {
|
|
12203
12315
|
AST_NODE_TYPES as AST_NODE_TYPES55,
|
|
12204
|
-
ASTUtils as
|
|
12316
|
+
ASTUtils as ASTUtils17,
|
|
12205
12317
|
ESLintUtils as ESLintUtils5
|
|
12206
12318
|
} from "@typescript-eslint/utils";
|
|
12207
12319
|
import ts3 from "typescript";
|
|
@@ -12247,7 +12359,7 @@ var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
|
12247
12359
|
]
|
|
12248
12360
|
};
|
|
12249
12361
|
function isUnshadowedBoolean(node, context) {
|
|
12250
|
-
const variable =
|
|
12362
|
+
const variable = ASTUtils17.findVariable(context.sourceCode.getScope(node), node.name);
|
|
12251
12363
|
return variable === null || variable.defs.length === 0;
|
|
12252
12364
|
}
|
|
12253
12365
|
function isBuiltinArrayFilter(node, services) {
|
|
@@ -12306,7 +12418,7 @@ function isProvablyTruthy(type, checker) {
|
|
|
12306
12418
|
}
|
|
12307
12419
|
function availableParameterName(node, context) {
|
|
12308
12420
|
for (const name of ["value", "item", "element", "candidate"]) {
|
|
12309
|
-
if (
|
|
12421
|
+
if (ASTUtils17.findVariable(context.sourceCode.getScope(node), name) === null) return name;
|
|
12310
12422
|
}
|
|
12311
12423
|
return null;
|
|
12312
12424
|
}
|
|
@@ -12360,7 +12472,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
12360
12472
|
|
|
12361
12473
|
// src/rules/prefer-await-in-async-return.ts
|
|
12362
12474
|
import {
|
|
12363
|
-
ASTUtils as
|
|
12475
|
+
ASTUtils as ASTUtils18,
|
|
12364
12476
|
ESLintUtils as ESLintUtils6,
|
|
12365
12477
|
AST_NODE_TYPES as AST_NODE_TYPES56
|
|
12366
12478
|
} from "@typescript-eslint/utils";
|
|
@@ -12474,13 +12586,13 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12474
12586
|
if (services === null) return {};
|
|
12475
12587
|
const frameworkLoaders = /* @__PURE__ */ new Set();
|
|
12476
12588
|
const rememberFrameworkLoader = (identifier) => {
|
|
12477
|
-
const variable =
|
|
12589
|
+
const variable = ASTUtils18.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
12478
12590
|
if (variable !== null) frameworkLoaders.add(variable);
|
|
12479
12591
|
};
|
|
12480
12592
|
const isFrameworkLoaderCallback = (owner) => {
|
|
12481
12593
|
const parent = owner.parent;
|
|
12482
12594
|
if (parent.type !== AST_NODE_TYPES56.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== AST_NODE_TYPES56.Identifier) return false;
|
|
12483
|
-
const variable =
|
|
12595
|
+
const variable = ASTUtils18.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
|
|
12484
12596
|
return variable !== null && frameworkLoaders.has(variable);
|
|
12485
12597
|
};
|
|
12486
12598
|
return {
|
|
@@ -13029,14 +13141,14 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
13029
13141
|
// src/rules/prefer-shared-zod-enum.ts
|
|
13030
13142
|
import { AST_NODE_TYPES as AST_NODE_TYPES58 } from "@typescript-eslint/utils";
|
|
13031
13143
|
var PREFER_SHARED_ZOD_ENUM_DOCUMENTATION = {
|
|
13032
|
-
summary: "
|
|
13033
|
-
rationale: "
|
|
13034
|
-
remediation: "Declare
|
|
13144
|
+
summary: "Give literal Zod enum domains one reusable module-level schema.",
|
|
13145
|
+
rationale: "Inline or repeated literal domains hide a reusable contract and allow equivalent fields to drift independently.",
|
|
13146
|
+
remediation: "Declare a module-level named Zod enum schema and reuse it at each field or contract site.",
|
|
13035
13147
|
category: "maintainability",
|
|
13036
|
-
limitations: ["Only direct z.enum calls with
|
|
13148
|
+
limitations: ["Only direct z.enum calls with string-literal arrays are inspected; computed domains require review."],
|
|
13037
13149
|
examples: [
|
|
13038
13150
|
{ id: "shared-provider", title: "Reuse a named enum schema", outcome: "no-match", files: [{ path: "src/provider.ts", source: "import { z } from 'zod'; const ProviderSchema = z.enum(['agy', 'claude', 'sol']); const JobSchema = z.object({ provider: ProviderSchema }); const StatusSchema = z.object({ provider: ProviderSchema.optional() });" }], focusPath: "src/provider.ts", expectedCount: 0, public: true },
|
|
13039
|
-
{ id: "
|
|
13151
|
+
{ id: "inline-provider", title: "Do not inline enum domains in object fields", outcome: "match", files: [{ path: "src/provider.ts", source: "import { z } from 'zod'; const JobSchema = z.object({ provider: z.enum(['agy', 'claude', 'sol']) });" }], focusPath: "src/provider.ts", expectedCount: 1, public: true }
|
|
13040
13152
|
]
|
|
13041
13153
|
};
|
|
13042
13154
|
function literalDomain(node) {
|
|
@@ -13049,15 +13161,26 @@ function literalDomain(node) {
|
|
|
13049
13161
|
}
|
|
13050
13162
|
return values;
|
|
13051
13163
|
}
|
|
13164
|
+
function isModuleLevelNamedSchema(node) {
|
|
13165
|
+
let current = node;
|
|
13166
|
+
while (current.parent?.type === AST_NODE_TYPES58.MemberExpression && current.parent.object === current) {
|
|
13167
|
+
current = current.parent;
|
|
13168
|
+
if (current.parent?.type === AST_NODE_TYPES58.CallExpression && current.parent.callee === current) current = current.parent;
|
|
13169
|
+
}
|
|
13170
|
+
const declarator = current.parent;
|
|
13171
|
+
if (declarator?.type !== AST_NODE_TYPES58.VariableDeclarator || declarator.init !== current || declarator.id.type !== AST_NODE_TYPES58.Identifier || declarator.parent.type !== AST_NODE_TYPES58.VariableDeclaration) return false;
|
|
13172
|
+
const declarationParent = declarator.parent.parent;
|
|
13173
|
+
return declarationParent.type === AST_NODE_TYPES58.Program || declarationParent.type === AST_NODE_TYPES58.ExportNamedDeclaration && declarationParent.parent.type === AST_NODE_TYPES58.Program;
|
|
13174
|
+
}
|
|
13052
13175
|
var prefer_shared_zod_enum_default = createRule({
|
|
13053
13176
|
name: "prefer-shared-zod-enum",
|
|
13054
13177
|
documentation: PREFER_SHARED_ZOD_ENUM_DOCUMENTATION,
|
|
13055
13178
|
meta: {
|
|
13056
13179
|
type: "suggestion",
|
|
13057
|
-
docs: { description: "
|
|
13180
|
+
docs: { description: "Give literal Zod enum domains one reusable module-level schema." },
|
|
13058
13181
|
schema: [],
|
|
13059
13182
|
messages: {
|
|
13060
|
-
shareEnumDomain: "
|
|
13183
|
+
shareEnumDomain: "Extract this literal Zod enum to one module-level named schema and reuse it."
|
|
13061
13184
|
}
|
|
13062
13185
|
},
|
|
13063
13186
|
defaultOptions: [],
|
|
@@ -13077,7 +13200,9 @@ var prefer_shared_zod_enum_default = createRule({
|
|
|
13077
13200
|
const domain = literalDomain(node);
|
|
13078
13201
|
if (domain === null) return;
|
|
13079
13202
|
const key = JSON.stringify(domain);
|
|
13080
|
-
|
|
13203
|
+
const inline = !isModuleLevelNamedSchema(node);
|
|
13204
|
+
if (inline || seen.has(key))
|
|
13205
|
+
context.report({ node, messageId: "shareEnumDomain" });
|
|
13081
13206
|
else seen.add(key);
|
|
13082
13207
|
}
|
|
13083
13208
|
};
|
|
@@ -13093,6 +13218,7 @@ var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
|
|
|
13093
13218
|
category: "maintainability",
|
|
13094
13219
|
limitations: [
|
|
13095
13220
|
"Only direct if/else-if chains with at least three strict-equality tests are reported.",
|
|
13221
|
+
"Case values may be literals, enum-like member references, or upper-case named constants; dynamic expressions are excluded.",
|
|
13096
13222
|
"The rule deliberately ignores compound predicates, loose equality, ranges, and chains that compare different discriminants."
|
|
13097
13223
|
],
|
|
13098
13224
|
examples: [
|
|
@@ -13102,11 +13228,17 @@ var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
|
|
|
13102
13228
|
};
|
|
13103
13229
|
function discriminantText(sourceCode, test) {
|
|
13104
13230
|
if (test.type !== AST_NODE_TYPES59.BinaryExpression || test.operator !== "===") return null;
|
|
13105
|
-
const leftIsCase = test.left
|
|
13106
|
-
const rightIsCase = test.right
|
|
13231
|
+
const leftIsCase = isCaseValue(test.left);
|
|
13232
|
+
const rightIsCase = isCaseValue(test.right);
|
|
13107
13233
|
if (leftIsCase === rightIsCase) return null;
|
|
13108
13234
|
return sourceCode.getText(leftIsCase ? test.right : test.left);
|
|
13109
13235
|
}
|
|
13236
|
+
function isCaseValue(node) {
|
|
13237
|
+
if (node.type === AST_NODE_TYPES59.Literal) return true;
|
|
13238
|
+
if (node.type === AST_NODE_TYPES59.Identifier) return /^[A-Z][A-Z0-9_]*$/u.test(node.name);
|
|
13239
|
+
if (node.type !== AST_NODE_TYPES59.MemberExpression || node.computed) return false;
|
|
13240
|
+
return node.property.type === AST_NODE_TYPES59.Identifier && (node.object.type === AST_NODE_TYPES59.Identifier || isCaseValue(node.object));
|
|
13241
|
+
}
|
|
13110
13242
|
var prefer_switch_for_repeated_equality_default = createRule({
|
|
13111
13243
|
name: "prefer-switch-for-repeated-equality",
|
|
13112
13244
|
documentation: PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION,
|
|
@@ -14040,7 +14172,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
14040
14172
|
});
|
|
14041
14173
|
|
|
14042
14174
|
// src/rules/repeated-static-call-cases.ts
|
|
14043
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES62, ASTUtils as
|
|
14175
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES62, ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
|
|
14044
14176
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
14045
14177
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
14046
14178
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
@@ -14066,7 +14198,7 @@ function staticMemberName5(node) {
|
|
|
14066
14198
|
return null;
|
|
14067
14199
|
}
|
|
14068
14200
|
function importedName6(identifier, context, modules) {
|
|
14069
|
-
const variable =
|
|
14201
|
+
const variable = ASTUtils19.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
14070
14202
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
14071
14203
|
for (const definition of variable.defs) {
|
|
14072
14204
|
if (definition.node.type !== AST_NODE_TYPES62.ImportSpecifier) continue;
|
|
@@ -14644,11 +14776,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
14644
14776
|
continue;
|
|
14645
14777
|
}
|
|
14646
14778
|
const key = member.key;
|
|
14647
|
-
const
|
|
14648
|
-
if (
|
|
14779
|
+
const propertyName7 = key.type === AST_NODE_TYPES63.Identifier ? key.name : key.type === AST_NODE_TYPES63.Literal && typeof key.value === "string" ? key.value : null;
|
|
14780
|
+
if (propertyName7 === null) {
|
|
14649
14781
|
continue;
|
|
14650
14782
|
}
|
|
14651
|
-
const propertyTokens = nameTokens(
|
|
14783
|
+
const propertyTokens = nameTokens(propertyName7);
|
|
14652
14784
|
if (propertyTokens.length < 2) {
|
|
14653
14785
|
continue;
|
|
14654
14786
|
}
|
|
@@ -14663,7 +14795,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14663
14795
|
node: annotation,
|
|
14664
14796
|
owner,
|
|
14665
14797
|
ownerName,
|
|
14666
|
-
propertyName:
|
|
14798
|
+
propertyName: propertyName7,
|
|
14667
14799
|
propertyTokens
|
|
14668
14800
|
});
|
|
14669
14801
|
}
|
|
@@ -15067,7 +15199,7 @@ var require_assert_never_default = createRule({
|
|
|
15067
15199
|
});
|
|
15068
15200
|
|
|
15069
15201
|
// src/rules/require-fetch-timeout.ts
|
|
15070
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES65, ASTUtils as
|
|
15202
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES65, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
|
|
15071
15203
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
15072
15204
|
summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
|
|
15073
15205
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -15148,7 +15280,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
15148
15280
|
}
|
|
15149
15281
|
function resolvesToGlobal(identifier) {
|
|
15150
15282
|
const scope = context.sourceCode.getScope(identifier);
|
|
15151
|
-
const variable =
|
|
15283
|
+
const variable = ASTUtils20.findVariable(scope, identifier.name);
|
|
15152
15284
|
return variable === null || variable.defs.length === 0;
|
|
15153
15285
|
}
|
|
15154
15286
|
function isGlobalFetchCall2(callee) {
|
|
@@ -15158,7 +15290,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
15158
15290
|
return callee.type === AST_NODE_TYPES65.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES65.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES65.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
15159
15291
|
}
|
|
15160
15292
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
15161
|
-
const variable =
|
|
15293
|
+
const variable = ASTUtils20.findVariable(
|
|
15162
15294
|
context.sourceCode.getScope(identifier),
|
|
15163
15295
|
identifier.name
|
|
15164
15296
|
);
|
|
@@ -15194,8 +15326,141 @@ var require_fetch_timeout_default = createRule({
|
|
|
15194
15326
|
}
|
|
15195
15327
|
});
|
|
15196
15328
|
|
|
15197
|
-
// src/rules/require-
|
|
15329
|
+
// src/rules/require-interface-for-exported-class.ts
|
|
15198
15330
|
import { AST_NODE_TYPES as AST_NODE_TYPES66 } from "@typescript-eslint/utils";
|
|
15331
|
+
var REQUIRE_INTERFACE_FOR_EXPORTED_CLASS_DOCUMENTATION = {
|
|
15332
|
+
summary: "Require exported concrete classes with public behavior to declare a contract.",
|
|
15333
|
+
rationale: "Consumers coupled only to a concrete class cannot substitute implementations or state the supported public capability independently of implementation details.",
|
|
15334
|
+
remediation: "Declare a focused interface and add an implements clause, or inherit from an intentional base contract.",
|
|
15335
|
+
category: "architecture",
|
|
15336
|
+
limitations: [
|
|
15337
|
+
"The warning-stage rule checks module-level class declarations and direct class-expression values exported directly, through local export specifiers, or through a default identifier; re-exports and expressions wrapped in other calls require review.",
|
|
15338
|
+
"An extends clause satisfies the contract only when its target is a locally declared abstract class; imported base-class contracts require an explicit implements clause.",
|
|
15339
|
+
"Static factories and data-only classes without public instance methods are outside the contract requirement."
|
|
15340
|
+
],
|
|
15341
|
+
examples: [
|
|
15342
|
+
{
|
|
15343
|
+
id: "implemented-store-contract",
|
|
15344
|
+
title: "Export behavior through a focused contract",
|
|
15345
|
+
outcome: "no-match",
|
|
15346
|
+
files: [
|
|
15347
|
+
{
|
|
15348
|
+
path: "src/artifact-store.ts",
|
|
15349
|
+
source: "export interface ArtifactStorage { read(id: string): Promise<Uint8Array>; } export class ArtifactStore implements ArtifactStorage { async read(id: string) { return new Uint8Array(); } }"
|
|
15350
|
+
}
|
|
15351
|
+
],
|
|
15352
|
+
focusPath: "src/artifact-store.ts",
|
|
15353
|
+
expectedCount: 0,
|
|
15354
|
+
public: true
|
|
15355
|
+
},
|
|
15356
|
+
{
|
|
15357
|
+
id: "concrete-only-store",
|
|
15358
|
+
title: "Do not export behavior only through a concrete class",
|
|
15359
|
+
outcome: "match",
|
|
15360
|
+
files: [
|
|
15361
|
+
{
|
|
15362
|
+
path: "src/artifact-store.ts",
|
|
15363
|
+
source: "export class ArtifactStore { async read(id: string) { return new Uint8Array(); } }"
|
|
15364
|
+
}
|
|
15365
|
+
],
|
|
15366
|
+
focusPath: "src/artifact-store.ts",
|
|
15367
|
+
expectedCount: 1,
|
|
15368
|
+
public: true
|
|
15369
|
+
}
|
|
15370
|
+
]
|
|
15371
|
+
};
|
|
15372
|
+
function hasPublicInstanceBehavior(node) {
|
|
15373
|
+
return node.body.body.some((member) => {
|
|
15374
|
+
if (member.type === AST_NODE_TYPES66.MethodDefinition) {
|
|
15375
|
+
return member.kind !== "constructor" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.key.type !== AST_NODE_TYPES66.PrivateIdentifier;
|
|
15376
|
+
}
|
|
15377
|
+
if (member.type !== AST_NODE_TYPES66.PropertyDefinition || member.static)
|
|
15378
|
+
return false;
|
|
15379
|
+
if (member.accessibility === "private" || member.accessibility === "protected" || member.key.type === AST_NODE_TYPES66.PrivateIdentifier) return false;
|
|
15380
|
+
return member.value?.type === AST_NODE_TYPES66.ArrowFunctionExpression || member.value?.type === AST_NODE_TYPES66.FunctionExpression || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES66.TSFunctionType;
|
|
15381
|
+
});
|
|
15382
|
+
}
|
|
15383
|
+
function classBindings(statement) {
|
|
15384
|
+
const declaration = statement.type === AST_NODE_TYPES66.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15385
|
+
if (declaration?.type === AST_NODE_TYPES66.ClassDeclaration) {
|
|
15386
|
+
return declaration.id === null ? [] : [{ declaration, name: declaration.id.name }];
|
|
15387
|
+
}
|
|
15388
|
+
if (declaration?.type !== AST_NODE_TYPES66.VariableDeclaration) return [];
|
|
15389
|
+
return declaration.declarations.flatMap(
|
|
15390
|
+
(item) => item.id.type === AST_NODE_TYPES66.Identifier && item.init?.type === AST_NODE_TYPES66.ClassExpression ? [{ declaration: item.init, name: item.id.name }] : []
|
|
15391
|
+
);
|
|
15392
|
+
}
|
|
15393
|
+
var require_interface_for_exported_class_default = createRule({
|
|
15394
|
+
name: "require-interface-for-exported-class",
|
|
15395
|
+
documentation: REQUIRE_INTERFACE_FOR_EXPORTED_CLASS_DOCUMENTATION,
|
|
15396
|
+
meta: {
|
|
15397
|
+
type: "suggestion",
|
|
15398
|
+
docs: {
|
|
15399
|
+
description: "Require exported concrete classes with public behavior to declare a contract."
|
|
15400
|
+
},
|
|
15401
|
+
schema: [],
|
|
15402
|
+
messages: {
|
|
15403
|
+
requireContract: "Exported class `{{name}}` has public behavior but no declared interface or base contract; add a focused contract and implement it."
|
|
15404
|
+
}
|
|
15405
|
+
},
|
|
15406
|
+
defaultOptions: [],
|
|
15407
|
+
create(context) {
|
|
15408
|
+
if (isTestFile(context.filename) || isStoryFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
15409
|
+
return {
|
|
15410
|
+
"Program:exit"(program) {
|
|
15411
|
+
const classes = /* @__PURE__ */ new Map();
|
|
15412
|
+
const abstractBases = /* @__PURE__ */ new Set();
|
|
15413
|
+
for (const statement of program.body) {
|
|
15414
|
+
for (const binding of classBindings(statement)) {
|
|
15415
|
+
classes.set(binding.name, binding.declaration);
|
|
15416
|
+
if (binding.declaration.abstract) abstractBases.add(binding.name);
|
|
15417
|
+
}
|
|
15418
|
+
}
|
|
15419
|
+
const exported = /* @__PURE__ */ new Map();
|
|
15420
|
+
for (const statement of program.body) {
|
|
15421
|
+
if (statement.type === AST_NODE_TYPES66.ExportNamedDeclaration) {
|
|
15422
|
+
for (const binding of classBindings(statement)) {
|
|
15423
|
+
exported.set(binding.declaration, binding.name);
|
|
15424
|
+
}
|
|
15425
|
+
if (statement.source !== null || statement.exportKind === "type") continue;
|
|
15426
|
+
for (const specifier of statement.specifiers) {
|
|
15427
|
+
if (specifier.exportKind === "type") continue;
|
|
15428
|
+
const candidate2 = classes.get(specifier.local.name);
|
|
15429
|
+
if (candidate2 === void 0) continue;
|
|
15430
|
+
const exportedName = specifier.exported.type === AST_NODE_TYPES66.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
15431
|
+
exported.set(candidate2, exportedName);
|
|
15432
|
+
}
|
|
15433
|
+
continue;
|
|
15434
|
+
}
|
|
15435
|
+
if (statement.type !== AST_NODE_TYPES66.ExportDefaultDeclaration) continue;
|
|
15436
|
+
if (statement.declaration.type === AST_NODE_TYPES66.ClassDeclaration || statement.declaration.type === AST_NODE_TYPES66.ClassExpression) {
|
|
15437
|
+
exported.set(
|
|
15438
|
+
statement.declaration,
|
|
15439
|
+
statement.declaration.id?.name ?? "default"
|
|
15440
|
+
);
|
|
15441
|
+
} else if (statement.declaration.type === AST_NODE_TYPES66.Identifier) {
|
|
15442
|
+
const candidate2 = classes.get(statement.declaration.name);
|
|
15443
|
+
if (candidate2 !== void 0) {
|
|
15444
|
+
exported.set(candidate2, statement.declaration.name);
|
|
15445
|
+
}
|
|
15446
|
+
}
|
|
15447
|
+
}
|
|
15448
|
+
for (const [declaration, exportedName] of exported) {
|
|
15449
|
+
const extendsLocalAbstractBase = declaration.superClass?.type === AST_NODE_TYPES66.Identifier && abstractBases.has(declaration.superClass.name);
|
|
15450
|
+
if (declaration.abstract || declaration.implements.length > 0 || extendsLocalAbstractBase || !hasPublicInstanceBehavior(declaration)) continue;
|
|
15451
|
+
context.report({
|
|
15452
|
+
node: declaration.id ?? declaration,
|
|
15453
|
+
messageId: "requireContract",
|
|
15454
|
+
data: { name: exportedName }
|
|
15455
|
+
});
|
|
15456
|
+
}
|
|
15457
|
+
}
|
|
15458
|
+
};
|
|
15459
|
+
}
|
|
15460
|
+
});
|
|
15461
|
+
|
|
15462
|
+
// src/rules/require-port-for-service.ts
|
|
15463
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES67 } from "@typescript-eslint/utils";
|
|
15199
15464
|
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
15200
15465
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
15201
15466
|
rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
|
|
@@ -15220,45 +15485,45 @@ var ROUTER_FACTORY_NAME = "Router";
|
|
|
15220
15485
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
15221
15486
|
var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set(["=", "&&=", "??=", "||="]);
|
|
15222
15487
|
var staticMemberName6 = (member) => {
|
|
15223
|
-
if (member.property.type ===
|
|
15224
|
-
if (!member.computed && member.property.type ===
|
|
15225
|
-
return member.computed && member.property.type ===
|
|
15488
|
+
if (member.property.type === AST_NODE_TYPES67.PrivateIdentifier) return `#${member.property.name}`;
|
|
15489
|
+
if (!member.computed && member.property.type === AST_NODE_TYPES67.Identifier) return member.property.name;
|
|
15490
|
+
return member.computed && member.property.type === AST_NODE_TYPES67.Literal && typeof member.property.value === "string" ? member.property.value : null;
|
|
15226
15491
|
};
|
|
15227
15492
|
var detachedValueExports = (program) => {
|
|
15228
15493
|
const names = /* @__PURE__ */ new Set();
|
|
15229
15494
|
for (const statement of program.body) {
|
|
15230
|
-
if (statement.type ===
|
|
15495
|
+
if (statement.type === AST_NODE_TYPES67.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
|
|
15231
15496
|
for (const specifier of statement.specifiers) {
|
|
15232
15497
|
if (specifier.exportKind !== "type") names.add(specifier.local.name);
|
|
15233
15498
|
}
|
|
15234
|
-
} else if (statement.type ===
|
|
15499
|
+
} else if (statement.type === AST_NODE_TYPES67.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES67.Identifier) {
|
|
15235
15500
|
names.add(statement.declaration.name);
|
|
15236
|
-
} else if (statement.type ===
|
|
15501
|
+
} else if (statement.type === AST_NODE_TYPES67.TSExportAssignment && statement.expression.type === AST_NODE_TYPES67.Identifier) {
|
|
15237
15502
|
names.add(statement.expression.name);
|
|
15238
15503
|
}
|
|
15239
15504
|
}
|
|
15240
15505
|
return names;
|
|
15241
15506
|
};
|
|
15242
|
-
var isExportedClass2 = (node, detached) => node.parent.type ===
|
|
15507
|
+
var isExportedClass2 = (node, detached) => node.parent.type === AST_NODE_TYPES67.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES67.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
|
|
15243
15508
|
var readTypeReference = (annotation) => {
|
|
15244
|
-
if (annotation?.type ===
|
|
15509
|
+
if (annotation?.type === AST_NODE_TYPES67.TSUnionType) {
|
|
15245
15510
|
const members = annotation.types.filter(
|
|
15246
|
-
(member) => member.type !==
|
|
15511
|
+
(member) => member.type !== AST_NODE_TYPES67.TSUndefinedKeyword && member.type !== AST_NODE_TYPES67.TSNullKeyword
|
|
15247
15512
|
);
|
|
15248
15513
|
annotation = members.length === 1 ? members[0] : void 0;
|
|
15249
15514
|
}
|
|
15250
|
-
if (annotation === void 0 || annotation.type !==
|
|
15515
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES67.TSTypeReference) return null;
|
|
15251
15516
|
const { typeName } = annotation;
|
|
15252
|
-
const rightmost = typeName.type ===
|
|
15517
|
+
const rightmost = typeName.type === AST_NODE_TYPES67.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES67.TSQualifiedName ? typeName.right.name : null;
|
|
15253
15518
|
if (rightmost === null) return null;
|
|
15254
15519
|
return { typeName: rightmost, display: qualifiedName(typeName) };
|
|
15255
15520
|
};
|
|
15256
|
-
var qualifiedName = (name) => name.type ===
|
|
15521
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES67.Identifier ? name.name : name.type === AST_NODE_TYPES67.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
15257
15522
|
var propertySignatureTypes = (members) => {
|
|
15258
15523
|
const types = /* @__PURE__ */ new Map();
|
|
15259
15524
|
for (const member of members) {
|
|
15260
|
-
if (member.type !==
|
|
15261
|
-
if (member.computed || member.key.type !==
|
|
15525
|
+
if (member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
|
|
15526
|
+
if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
|
|
15262
15527
|
const reference = readTypeReference(member.typeAnnotation?.typeAnnotation);
|
|
15263
15528
|
if (reference === null) continue;
|
|
15264
15529
|
types.set(member.key.name, reference);
|
|
@@ -15269,18 +15534,18 @@ var fileTypeIndex = (program) => {
|
|
|
15269
15534
|
const objects = /* @__PURE__ */ new Map();
|
|
15270
15535
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
15271
15536
|
for (const statement of program.body) {
|
|
15272
|
-
const declaration = statement.type ===
|
|
15273
|
-
if (declaration?.type ===
|
|
15537
|
+
const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15538
|
+
if (declaration?.type === AST_NODE_TYPES67.TSInterfaceDeclaration) {
|
|
15274
15539
|
objects.set(declaration.id.name, propertySignatureTypes(declaration.body.body));
|
|
15275
15540
|
continue;
|
|
15276
15541
|
}
|
|
15277
|
-
if (declaration?.type !==
|
|
15542
|
+
if (declaration?.type !== AST_NODE_TYPES67.TSTypeAliasDeclaration) continue;
|
|
15278
15543
|
const aliased = declaration.typeAnnotation;
|
|
15279
|
-
if (aliased.type ===
|
|
15544
|
+
if (aliased.type === AST_NODE_TYPES67.TSFunctionType || aliased.type === AST_NODE_TYPES67.TSConstructorType) {
|
|
15280
15545
|
functionAliases.add(declaration.id.name);
|
|
15281
15546
|
continue;
|
|
15282
15547
|
}
|
|
15283
|
-
const literals = aliased.type ===
|
|
15548
|
+
const literals = aliased.type === AST_NODE_TYPES67.TSTypeLiteral ? [aliased] : aliased.type === AST_NODE_TYPES67.TSIntersectionType ? aliased.types.filter((part) => part.type === AST_NODE_TYPES67.TSTypeLiteral) : [];
|
|
15284
15549
|
if (literals.length === 0) continue;
|
|
15285
15550
|
const merged = /* @__PURE__ */ new Map();
|
|
15286
15551
|
for (const literal of literals) {
|
|
@@ -15309,10 +15574,10 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15309
15574
|
while (pending.length > 0) {
|
|
15310
15575
|
const current = pending.pop();
|
|
15311
15576
|
if (current === void 0) break;
|
|
15312
|
-
if (current.type ===
|
|
15313
|
-
const expression = current.type ===
|
|
15314
|
-
const storedField = expression?.type ===
|
|
15315
|
-
if (expression?.type !==
|
|
15577
|
+
if (current.type === AST_NODE_TYPES67.ArrowFunctionExpression || current.type === AST_NODE_TYPES67.FunctionExpression || current.type === AST_NODE_TYPES67.FunctionDeclaration || current.type === AST_NODE_TYPES67.ClassExpression || current.type === AST_NODE_TYPES67.ClassDeclaration) continue;
|
|
15578
|
+
const expression = current.type === AST_NODE_TYPES67.ExpressionStatement ? current.expression : null;
|
|
15579
|
+
const storedField = expression?.type === AST_NODE_TYPES67.AssignmentExpression && expression.left.type === AST_NODE_TYPES67.MemberExpression && expression.left.object.type === AST_NODE_TYPES67.ThisExpression ? staticMemberName6(expression.left) : null;
|
|
15580
|
+
if (expression?.type !== AST_NODE_TYPES67.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== AST_NODE_TYPES67.MemberExpression || expression.left.object.type !== AST_NODE_TYPES67.ThisExpression || storedField === null) {
|
|
15316
15581
|
for (const key of Object.keys(current)) {
|
|
15317
15582
|
if (key === "parent") continue;
|
|
15318
15583
|
const value = current[key];
|
|
@@ -15325,14 +15590,14 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15325
15590
|
continue;
|
|
15326
15591
|
}
|
|
15327
15592
|
let source = expression.right;
|
|
15328
|
-
while (source.type ===
|
|
15329
|
-
if (source.type ===
|
|
15593
|
+
while (source.type === AST_NODE_TYPES67.TSNonNullExpression || source.type === AST_NODE_TYPES67.TSAsExpression || source.type === AST_NODE_TYPES67.TSSatisfiesExpression || source.type === AST_NODE_TYPES67.TSTypeAssertion) source = source.expression;
|
|
15594
|
+
if (source.type === AST_NODE_TYPES67.NewExpression) {
|
|
15330
15595
|
constructedFields += 1;
|
|
15331
|
-
} else if (source.type ===
|
|
15596
|
+
} else if (source.type === AST_NODE_TYPES67.Identifier) {
|
|
15332
15597
|
const fields = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
|
|
15333
15598
|
fields.add(storedField);
|
|
15334
15599
|
storedFieldsFrom.set(source.name, fields);
|
|
15335
|
-
} else if (source.type ===
|
|
15600
|
+
} else if (source.type === AST_NODE_TYPES67.MemberExpression && source.object.type === AST_NODE_TYPES67.Identifier) {
|
|
15336
15601
|
const fields = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
|
|
15337
15602
|
fields.add(storedField);
|
|
15338
15603
|
storedFieldsFrom.set(source.object.name, fields);
|
|
@@ -15350,7 +15615,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15350
15615
|
const collaborators = [];
|
|
15351
15616
|
for (const parameter of ctor.value.params) {
|
|
15352
15617
|
for (const reference of parameterCollaborators(parameter, declared, storedMemberFieldsFrom)) {
|
|
15353
|
-
const fields = parameter.type ===
|
|
15618
|
+
const fields = parameter.type === AST_NODE_TYPES67.TSParameterProperty ? [reference.name] : reference.fields.length > 0 ? reference.fields : [...storedFieldsFrom.get(reference.name) ?? []];
|
|
15354
15619
|
if (fields.length === 0) continue;
|
|
15355
15620
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
15356
15621
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -15365,8 +15630,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15365
15630
|
};
|
|
15366
15631
|
var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
15367
15632
|
let target = parameter;
|
|
15368
|
-
if (target.type ===
|
|
15369
|
-
if (target.type ===
|
|
15633
|
+
if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
|
|
15634
|
+
if (target.type === AST_NODE_TYPES67.ObjectPattern) {
|
|
15370
15635
|
return objectPatternCollaborators(target, declared);
|
|
15371
15636
|
}
|
|
15372
15637
|
const named2 = namedParameterCollaborator(parameter);
|
|
@@ -15375,9 +15640,9 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
|
15375
15640
|
};
|
|
15376
15641
|
var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
15377
15642
|
let target = annotated;
|
|
15378
|
-
if (target.type ===
|
|
15379
|
-
if (target.type ===
|
|
15380
|
-
if (target.type !==
|
|
15643
|
+
if (target.type === AST_NODE_TYPES67.TSParameterProperty) target = target.parameter;
|
|
15644
|
+
if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
|
|
15645
|
+
if (target.type !== AST_NODE_TYPES67.Identifier) return [];
|
|
15381
15646
|
const members = bagMemberTypes(target.typeAnnotation?.typeAnnotation, declared);
|
|
15382
15647
|
if (members === null) return [];
|
|
15383
15648
|
const storedMembers = storedMemberFieldsFrom.get(target.name);
|
|
@@ -15393,9 +15658,9 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
|
15393
15658
|
};
|
|
15394
15659
|
var namedParameterCollaborator = (annotated) => {
|
|
15395
15660
|
let target = annotated;
|
|
15396
|
-
if (target.type ===
|
|
15397
|
-
if (target.type ===
|
|
15398
|
-
if (target.type !==
|
|
15661
|
+
if (target.type === AST_NODE_TYPES67.TSParameterProperty) target = target.parameter;
|
|
15662
|
+
if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
|
|
15663
|
+
if (target.type !== AST_NODE_TYPES67.Identifier) return null;
|
|
15399
15664
|
const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
|
|
15400
15665
|
if (reference === null) return null;
|
|
15401
15666
|
return { name: target.name, ...reference, fields: [] };
|
|
@@ -15407,11 +15672,11 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
15407
15672
|
if (members === null) return [];
|
|
15408
15673
|
const collaborators = [];
|
|
15409
15674
|
for (const property of pattern.properties) {
|
|
15410
|
-
if (property.type !==
|
|
15411
|
-
if (property.key.type !==
|
|
15675
|
+
if (property.type !== AST_NODE_TYPES67.Property || property.computed) continue;
|
|
15676
|
+
if (property.key.type !== AST_NODE_TYPES67.Identifier) continue;
|
|
15412
15677
|
const key = property.key.name;
|
|
15413
|
-
const bound = property.value.type ===
|
|
15414
|
-
if (bound.type !==
|
|
15678
|
+
const bound = property.value.type === AST_NODE_TYPES67.AssignmentPattern ? property.value.left : property.value;
|
|
15679
|
+
if (bound.type !== AST_NODE_TYPES67.Identifier) continue;
|
|
15415
15680
|
if (CONFIGISH_NAME_RE.test(key)) continue;
|
|
15416
15681
|
const reference = members.get(key);
|
|
15417
15682
|
if (reference === void 0) continue;
|
|
@@ -15421,21 +15686,21 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
15421
15686
|
};
|
|
15422
15687
|
var bagMemberTypes = (annotation, declared) => {
|
|
15423
15688
|
if (annotation === void 0) return null;
|
|
15424
|
-
if (annotation.type ===
|
|
15689
|
+
if (annotation.type === AST_NODE_TYPES67.TSTypeLiteral) {
|
|
15425
15690
|
return propertySignatureTypes(annotation.members);
|
|
15426
15691
|
}
|
|
15427
|
-
if (annotation.type !==
|
|
15692
|
+
if (annotation.type !== AST_NODE_TYPES67.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES67.Identifier) {
|
|
15428
15693
|
return null;
|
|
15429
15694
|
}
|
|
15430
15695
|
return declared().objects.get(annotation.typeName.name) ?? null;
|
|
15431
15696
|
};
|
|
15432
15697
|
var isFrameworkWiring = (body2) => subtreeHas(body2, (node) => {
|
|
15433
|
-
if (node.type ===
|
|
15698
|
+
if (node.type === AST_NODE_TYPES67.CallExpression) {
|
|
15434
15699
|
const { callee } = node;
|
|
15435
|
-
if (callee.type ===
|
|
15436
|
-
return callee.type ===
|
|
15700
|
+
if (callee.type === AST_NODE_TYPES67.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
15701
|
+
return callee.type === AST_NODE_TYPES67.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES67.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
15437
15702
|
}
|
|
15438
|
-
return node.type ===
|
|
15703
|
+
return node.type === AST_NODE_TYPES67.TSTypeReference && node.typeName.type === AST_NODE_TYPES67.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
15439
15704
|
});
|
|
15440
15705
|
var subtreeHas = (root, found) => {
|
|
15441
15706
|
let hit = false;
|
|
@@ -15462,19 +15727,19 @@ var invokedInstanceField = (call) => {
|
|
|
15462
15727
|
const direct = instanceField(call.callee);
|
|
15463
15728
|
if (direct !== null) return direct;
|
|
15464
15729
|
let callee = call.callee;
|
|
15465
|
-
while (callee.type ===
|
|
15466
|
-
return callee.type ===
|
|
15730
|
+
while (callee.type === AST_NODE_TYPES67.ChainExpression || callee.type === AST_NODE_TYPES67.TSAsExpression || callee.type === AST_NODE_TYPES67.TSNonNullExpression || callee.type === AST_NODE_TYPES67.TSSatisfiesExpression || callee.type === AST_NODE_TYPES67.TSTypeAssertion) callee = callee.expression;
|
|
15731
|
+
return callee.type === AST_NODE_TYPES67.MemberExpression ? instanceField(callee.object) : null;
|
|
15467
15732
|
};
|
|
15468
15733
|
var instanceField = (candidate2) => {
|
|
15469
15734
|
let node = candidate2;
|
|
15470
|
-
while (node.type ===
|
|
15471
|
-
return node.type ===
|
|
15735
|
+
while (node.type === AST_NODE_TYPES67.ChainExpression || node.type === AST_NODE_TYPES67.TSAsExpression || node.type === AST_NODE_TYPES67.TSNonNullExpression || node.type === AST_NODE_TYPES67.TSSatisfiesExpression || node.type === AST_NODE_TYPES67.TSTypeAssertion) node = node.expression;
|
|
15736
|
+
return node.type === AST_NODE_TYPES67.MemberExpression && node.object.type === AST_NODE_TYPES67.ThisExpression ? staticMemberName6(node) : null;
|
|
15472
15737
|
};
|
|
15473
15738
|
var behaviorallyInvokedFields = (body2) => {
|
|
15474
15739
|
const invoked = /* @__PURE__ */ new Set();
|
|
15475
15740
|
const visit = (current) => {
|
|
15476
|
-
if (current.type ===
|
|
15477
|
-
if (current.type ===
|
|
15741
|
+
if (current.type === AST_NODE_TYPES67.ClassDeclaration || current.type === AST_NODE_TYPES67.ClassExpression || current.type === AST_NODE_TYPES67.FunctionDeclaration || current.type === AST_NODE_TYPES67.FunctionExpression) return;
|
|
15742
|
+
if (current.type === AST_NODE_TYPES67.CallExpression) {
|
|
15478
15743
|
const field = invokedInstanceField(current);
|
|
15479
15744
|
if (field !== null) invoked.add(field);
|
|
15480
15745
|
}
|
|
@@ -15487,14 +15752,14 @@ var behaviorallyInvokedFields = (body2) => {
|
|
|
15487
15752
|
}
|
|
15488
15753
|
};
|
|
15489
15754
|
for (const member of body2.body) {
|
|
15490
|
-
if (member.type ===
|
|
15491
|
-
if (member.type ===
|
|
15755
|
+
if (member.type === AST_NODE_TYPES67.StaticBlock || member.static) continue;
|
|
15756
|
+
if (member.type === AST_NODE_TYPES67.MethodDefinition) {
|
|
15492
15757
|
if (member.value.body !== null && member.value.body !== void 0) visit(member.value.body);
|
|
15493
15758
|
continue;
|
|
15494
15759
|
}
|
|
15495
|
-
if (member.type !==
|
|
15760
|
+
if (member.type !== AST_NODE_TYPES67.PropertyDefinition || member.value === null) continue;
|
|
15496
15761
|
visit(
|
|
15497
|
-
member.value.type ===
|
|
15762
|
+
member.value.type === AST_NODE_TYPES67.ArrowFunctionExpression ? member.value.body : member.value
|
|
15498
15763
|
);
|
|
15499
15764
|
}
|
|
15500
15765
|
return invoked;
|
|
@@ -15514,26 +15779,26 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
15514
15779
|
var fileInterfaceNames = (program) => {
|
|
15515
15780
|
const names = [];
|
|
15516
15781
|
for (const statement of program.body) {
|
|
15517
|
-
const declaration = statement.type ===
|
|
15518
|
-
if (declaration?.type ===
|
|
15782
|
+
const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15783
|
+
if (declaration?.type === AST_NODE_TYPES67.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
15519
15784
|
}
|
|
15520
15785
|
return names;
|
|
15521
15786
|
};
|
|
15522
15787
|
var publicMethodNames = (body2, functionAliases) => {
|
|
15523
15788
|
const names = [];
|
|
15524
15789
|
for (const member of body2.body) {
|
|
15525
|
-
if (member.type ===
|
|
15790
|
+
if (member.type === AST_NODE_TYPES67.PropertyDefinition) {
|
|
15526
15791
|
if (member.static || member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15527
|
-
if (member.key.type ===
|
|
15528
|
-
if (member.value?.type !==
|
|
15529
|
-
names.push(member.key.type ===
|
|
15792
|
+
if (member.key.type === AST_NODE_TYPES67.PrivateIdentifier) continue;
|
|
15793
|
+
if (member.value?.type !== AST_NODE_TYPES67.ArrowFunctionExpression && member.value?.type !== AST_NODE_TYPES67.FunctionExpression && member.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES67.TSFunctionType && !(member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name))) continue;
|
|
15794
|
+
names.push(member.key.type === AST_NODE_TYPES67.Identifier ? member.key.name : "\u2026");
|
|
15530
15795
|
continue;
|
|
15531
15796
|
}
|
|
15532
|
-
if (member.type !==
|
|
15797
|
+
if (member.type !== AST_NODE_TYPES67.MethodDefinition) continue;
|
|
15533
15798
|
if (member.kind !== "method" || member.static) continue;
|
|
15534
15799
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15535
|
-
if (member.key.type ===
|
|
15536
|
-
if (member.key.type ===
|
|
15800
|
+
if (member.key.type === AST_NODE_TYPES67.PrivateIdentifier) continue;
|
|
15801
|
+
if (member.key.type === AST_NODE_TYPES67.Identifier) names.push(member.key.name);
|
|
15537
15802
|
else names.push("\u2026");
|
|
15538
15803
|
}
|
|
15539
15804
|
return names;
|
|
@@ -15541,13 +15806,13 @@ var publicMethodNames = (body2, functionAliases) => {
|
|
|
15541
15806
|
var isFluentConstructionObject = (node, getText) => {
|
|
15542
15807
|
if (node.id === null) return false;
|
|
15543
15808
|
const methods = node.body.body.filter(
|
|
15544
|
-
(member) => member.type ===
|
|
15809
|
+
(member) => member.type === AST_NODE_TYPES67.MethodDefinition && member.kind === "method" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.value.body !== null
|
|
15545
15810
|
);
|
|
15546
15811
|
if (methods.length === 0) return false;
|
|
15547
15812
|
return methods.every((member) => {
|
|
15548
15813
|
const result = member.value.returnType?.typeAnnotation;
|
|
15549
15814
|
if (result === void 0) return false;
|
|
15550
|
-
const returnsOwnType = result.type ===
|
|
15815
|
+
const returnsOwnType = result.type === AST_NODE_TYPES67.TSTypeReference && result.typeName.type === AST_NODE_TYPES67.Identifier && result.typeName.name === node.id?.name;
|
|
15551
15816
|
return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
|
|
15552
15817
|
});
|
|
15553
15818
|
};
|
|
@@ -15555,10 +15820,10 @@ function localClassAbstractness(program) {
|
|
|
15555
15820
|
const classes = /* @__PURE__ */ new Map();
|
|
15556
15821
|
const parents = /* @__PURE__ */ new Map();
|
|
15557
15822
|
for (const statement of program.body) {
|
|
15558
|
-
const declaration = statement.type ===
|
|
15559
|
-
if (declaration?.type ===
|
|
15823
|
+
const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration || statement.type === AST_NODE_TYPES67.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
15824
|
+
if (declaration?.type === AST_NODE_TYPES67.ClassDeclaration && declaration.id !== null) {
|
|
15560
15825
|
classes.set(declaration.id.name, declaration.abstract === true);
|
|
15561
|
-
if (declaration.superClass?.type ===
|
|
15826
|
+
if (declaration.superClass?.type === AST_NODE_TYPES67.Identifier) {
|
|
15562
15827
|
parents.set(declaration.id.name, declaration.superClass.name);
|
|
15563
15828
|
}
|
|
15564
15829
|
}
|
|
@@ -15580,43 +15845,43 @@ function localInterfaceSurfaces(program) {
|
|
|
15580
15845
|
const parents = /* @__PURE__ */ new Map();
|
|
15581
15846
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
15582
15847
|
for (const statement of program.body) {
|
|
15583
|
-
const declaration = statement.type ===
|
|
15584
|
-
if (declaration?.type ===
|
|
15848
|
+
const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15849
|
+
if (declaration?.type === AST_NODE_TYPES67.TSTypeAliasDeclaration && (declaration.typeAnnotation.type === AST_NODE_TYPES67.TSFunctionType || declaration.typeAnnotation.type === AST_NODE_TYPES67.TSConstructorType)) functionAliases.add(declaration.id.name);
|
|
15585
15850
|
}
|
|
15586
15851
|
for (const statement of program.body) {
|
|
15587
|
-
const declaration = statement.type ===
|
|
15588
|
-
if (declaration?.type ===
|
|
15852
|
+
const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15853
|
+
if (declaration?.type === AST_NODE_TYPES67.TSTypeAliasDeclaration) {
|
|
15589
15854
|
const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15590
|
-
const parts = declaration.typeAnnotation.type ===
|
|
15855
|
+
const parts = declaration.typeAnnotation.type === AST_NODE_TYPES67.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
|
|
15591
15856
|
const inherited = parents.get(declaration.id.name) ?? [];
|
|
15592
15857
|
for (const part of parts) {
|
|
15593
|
-
if (part.type ===
|
|
15858
|
+
if (part.type === AST_NODE_TYPES67.TSTypeReference && part.typeName.type === AST_NODE_TYPES67.Identifier) {
|
|
15594
15859
|
inherited.push(part.typeName.name);
|
|
15595
15860
|
continue;
|
|
15596
15861
|
}
|
|
15597
|
-
if (part.type !==
|
|
15862
|
+
if (part.type !== AST_NODE_TYPES67.TSTypeLiteral) continue;
|
|
15598
15863
|
for (const member of part.members) {
|
|
15599
|
-
if (member.type !==
|
|
15600
|
-
if (member.computed || member.key.type !==
|
|
15601
|
-
if (member.type ===
|
|
15864
|
+
if (member.type !== AST_NODE_TYPES67.TSMethodSignature && member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
|
|
15865
|
+
if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
|
|
15866
|
+
if (member.type === AST_NODE_TYPES67.TSMethodSignature) {
|
|
15602
15867
|
callables2.add(member.key.name);
|
|
15603
15868
|
continue;
|
|
15604
15869
|
}
|
|
15605
|
-
if (member.type !==
|
|
15870
|
+
if (member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
|
|
15606
15871
|
const annotation = member.typeAnnotation?.typeAnnotation;
|
|
15607
|
-
if (annotation?.type ===
|
|
15872
|
+
if (annotation?.type === AST_NODE_TYPES67.TSFunctionType || annotation?.type === AST_NODE_TYPES67.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(member.key.name);
|
|
15608
15873
|
}
|
|
15609
15874
|
}
|
|
15610
15875
|
interfaces.set(declaration.id.name, callables2);
|
|
15611
15876
|
parents.set(declaration.id.name, inherited);
|
|
15612
15877
|
continue;
|
|
15613
15878
|
}
|
|
15614
|
-
if (declaration?.type !==
|
|
15879
|
+
if (declaration?.type !== AST_NODE_TYPES67.TSInterfaceDeclaration) continue;
|
|
15615
15880
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15616
15881
|
for (const member of declaration.body.body) {
|
|
15617
|
-
if (member.type !==
|
|
15618
|
-
if (member.computed || member.key.type !==
|
|
15619
|
-
if (member.type ===
|
|
15882
|
+
if (member.type !== AST_NODE_TYPES67.TSMethodSignature && member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
|
|
15883
|
+
if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
|
|
15884
|
+
if (member.type === AST_NODE_TYPES67.TSMethodSignature || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSFunctionType || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name)) callables.add(member.key.name);
|
|
15620
15885
|
}
|
|
15621
15886
|
interfaces.set(declaration.id.name, callables);
|
|
15622
15887
|
parents.set(
|
|
@@ -15624,7 +15889,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15624
15889
|
[
|
|
15625
15890
|
...parents.get(declaration.id.name) ?? [],
|
|
15626
15891
|
...declaration.extends.flatMap(
|
|
15627
|
-
(heritage) => heritage.expression.type ===
|
|
15892
|
+
(heritage) => heritage.expression.type === AST_NODE_TYPES67.Identifier ? [heritage.expression.name] : ["*"]
|
|
15628
15893
|
)
|
|
15629
15894
|
]
|
|
15630
15895
|
);
|
|
@@ -15651,7 +15916,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15651
15916
|
}
|
|
15652
15917
|
function hasServicePort(node, methods, classes, interfaces) {
|
|
15653
15918
|
if (node.superClass !== null) {
|
|
15654
|
-
if (node.superClass.type !==
|
|
15919
|
+
if (node.superClass.type !== AST_NODE_TYPES67.Identifier) return true;
|
|
15655
15920
|
const localAbstract = classes.get(node.superClass.name);
|
|
15656
15921
|
if (localAbstract === void 0 || localAbstract) return true;
|
|
15657
15922
|
}
|
|
@@ -15663,7 +15928,7 @@ function hasServicePort(node, methods, classes, interfaces) {
|
|
|
15663
15928
|
if (node.implements.length === 0) return false;
|
|
15664
15929
|
const combined = /* @__PURE__ */ new Set();
|
|
15665
15930
|
for (const implementation of node.implements) {
|
|
15666
|
-
if (implementation.expression.type !==
|
|
15931
|
+
if (implementation.expression.type !== AST_NODE_TYPES67.Identifier) return true;
|
|
15667
15932
|
const name = implementation.expression.name;
|
|
15668
15933
|
const localAbstract = classes.get(name);
|
|
15669
15934
|
if (localAbstract === true) return true;
|
|
@@ -15706,7 +15971,7 @@ var require_port_for_service_default = createRule({
|
|
|
15706
15971
|
if (node.abstract === true) return;
|
|
15707
15972
|
if (node.decorators.length > 0) return;
|
|
15708
15973
|
const ctor = node.body.body.find(
|
|
15709
|
-
(member) => member.type ===
|
|
15974
|
+
(member) => member.type === AST_NODE_TYPES67.MethodDefinition && member.kind === "constructor" && member.value.body !== null && member.value.body !== void 0
|
|
15710
15975
|
);
|
|
15711
15976
|
if (ctor === void 0) return;
|
|
15712
15977
|
const constructorFacts = readConstructor(
|
|
@@ -15741,32 +16006,67 @@ var require_port_for_service_default = createRule({
|
|
|
15741
16006
|
});
|
|
15742
16007
|
|
|
15743
16008
|
// src/rules/require-sql-access-class.ts
|
|
15744
|
-
import { AST_NODE_TYPES as
|
|
15745
|
-
var
|
|
16009
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES68 } from "@typescript-eslint/utils";
|
|
16010
|
+
var DIRECT_EXECUTION_METHODS = /* @__PURE__ */ new Set([
|
|
15746
16011
|
"all",
|
|
15747
16012
|
"batch",
|
|
15748
|
-
"delete",
|
|
15749
16013
|
"dump",
|
|
15750
16014
|
"exec",
|
|
15751
16015
|
"execute",
|
|
15752
16016
|
"get",
|
|
15753
|
-
"insert",
|
|
15754
16017
|
"pragma",
|
|
15755
16018
|
"prepare",
|
|
16019
|
+
"query",
|
|
15756
16020
|
"run",
|
|
16021
|
+
"transaction"
|
|
16022
|
+
]);
|
|
16023
|
+
var BUILDER_TERMINAL_METHODS = /* @__PURE__ */ new Set([
|
|
16024
|
+
"execute",
|
|
16025
|
+
"executeQuery",
|
|
16026
|
+
"executeTakeFirst",
|
|
16027
|
+
"executeTakeFirstOrThrow",
|
|
16028
|
+
"stream"
|
|
16029
|
+
]);
|
|
16030
|
+
var BUILDER_METHODS = /* @__PURE__ */ new Set([
|
|
16031
|
+
"delete",
|
|
16032
|
+
"insert",
|
|
15757
16033
|
"select",
|
|
15758
|
-
"transaction",
|
|
15759
16034
|
"update"
|
|
15760
16035
|
]);
|
|
15761
|
-
var
|
|
16036
|
+
var BUILDER_SHORT_TERMINALS = /* @__PURE__ */ new Set([
|
|
16037
|
+
"all",
|
|
16038
|
+
"get",
|
|
16039
|
+
"run"
|
|
16040
|
+
]);
|
|
16041
|
+
var MODEL_EXECUTION_METHODS = /* @__PURE__ */ new Set([
|
|
16042
|
+
"aggregate",
|
|
16043
|
+
"count",
|
|
16044
|
+
"create",
|
|
16045
|
+
"createMany",
|
|
16046
|
+
"createManyAndReturn",
|
|
16047
|
+
"delete",
|
|
16048
|
+
"deleteMany",
|
|
16049
|
+
"findFirst",
|
|
16050
|
+
"findFirstOrThrow",
|
|
16051
|
+
"findMany",
|
|
16052
|
+
"findUnique",
|
|
16053
|
+
"findUniqueOrThrow",
|
|
16054
|
+
"groupBy",
|
|
16055
|
+
"update",
|
|
16056
|
+
"updateMany",
|
|
16057
|
+
"updateManyAndReturn",
|
|
16058
|
+
"upsert"
|
|
16059
|
+
]);
|
|
16060
|
+
var DATABASE_NAMES = /^(?:db|database|connection|pool|prisma|query|transaction|tx)$/iu;
|
|
15762
16061
|
var REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION = {
|
|
15763
16062
|
summary: "Keep SQL reads and writes inside a class that receives its database dependency.",
|
|
15764
16063
|
rationale: "Free-function database access hides connection ownership and makes transaction, retry, observability, and test boundaries inconsistent.",
|
|
15765
16064
|
remediation: "Move the query into a repository or store class and inject the pool, connection, transaction, or typed database binding through its constructor.",
|
|
15766
16065
|
category: "architecture",
|
|
15767
16066
|
limitations: [
|
|
15768
|
-
"The rule recognizes conventional database receiver names
|
|
15769
|
-
"Query construction without execution is not reported."
|
|
16067
|
+
"The rule recognizes conventional database receiver names, Cloudflare DB bindings, direct pool.query calls, explicit query-builder terminals, and Prisma-style model delegates; unusually named or heavily aliased clients require architectural review.",
|
|
16068
|
+
"Query construction without a recognized execution terminal is intentionally not reported.",
|
|
16069
|
+
"Constructor injection inherited from a base class or transformed through a wrapper is not inferred by this syntax-only rule."
|
|
15770
16070
|
],
|
|
15771
16071
|
examples: [
|
|
15772
16072
|
{
|
|
@@ -15799,28 +16099,160 @@ var REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION = {
|
|
|
15799
16099
|
}
|
|
15800
16100
|
]
|
|
15801
16101
|
};
|
|
15802
|
-
function
|
|
15803
|
-
if (!node.computed && node.property.type ===
|
|
16102
|
+
function memberName5(node) {
|
|
16103
|
+
if (!node.computed && node.property.type === AST_NODE_TYPES68.Identifier)
|
|
15804
16104
|
return node.property.name;
|
|
15805
|
-
if (node.computed && node.property.type ===
|
|
16105
|
+
if (node.computed && node.property.type === AST_NODE_TYPES68.Literal && typeof node.property.value === "string")
|
|
15806
16106
|
return node.property.value;
|
|
15807
16107
|
return null;
|
|
15808
16108
|
}
|
|
16109
|
+
function isDatabaseOperation(method, receiver) {
|
|
16110
|
+
if (DIRECT_EXECUTION_METHODS.has(method) && databaseReceiver(receiver))
|
|
16111
|
+
return true;
|
|
16112
|
+
if (!expressionHasDatabaseMarker(receiver)) return false;
|
|
16113
|
+
if (BUILDER_TERMINAL_METHODS.has(method) || MODEL_EXECUTION_METHODS.has(method)) return true;
|
|
16114
|
+
return BUILDER_SHORT_TERMINALS.has(method) && expressionCallsBuilder(receiver);
|
|
16115
|
+
}
|
|
15809
16116
|
function databaseReceiver(node) {
|
|
15810
|
-
if (node.type ===
|
|
16117
|
+
if (node.type === AST_NODE_TYPES68.Identifier)
|
|
15811
16118
|
return DATABASE_NAMES.test(node.name);
|
|
15812
|
-
if (node.type !==
|
|
15813
|
-
const name =
|
|
16119
|
+
if (node.type !== AST_NODE_TYPES68.MemberExpression) return false;
|
|
16120
|
+
const name = memberName5(node);
|
|
15814
16121
|
return name === "DB" || name !== null && DATABASE_NAMES.test(name);
|
|
15815
16122
|
}
|
|
15816
|
-
function
|
|
16123
|
+
function databaseRootMember(node) {
|
|
16124
|
+
let current = node;
|
|
16125
|
+
for (; ; ) {
|
|
16126
|
+
if (current.type === AST_NODE_TYPES68.ChainExpression) {
|
|
16127
|
+
current = current.expression;
|
|
16128
|
+
continue;
|
|
16129
|
+
}
|
|
16130
|
+
if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
|
|
16131
|
+
current = current.expression;
|
|
16132
|
+
continue;
|
|
16133
|
+
}
|
|
16134
|
+
if (current.type === AST_NODE_TYPES68.CallExpression) {
|
|
16135
|
+
if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return null;
|
|
16136
|
+
current = current.callee.object;
|
|
16137
|
+
continue;
|
|
16138
|
+
}
|
|
16139
|
+
if (current.type === AST_NODE_TYPES68.MemberExpression) {
|
|
16140
|
+
if (current.object.type === AST_NODE_TYPES68.ThisExpression)
|
|
16141
|
+
return memberName5(current);
|
|
16142
|
+
current = current.object;
|
|
16143
|
+
continue;
|
|
16144
|
+
}
|
|
16145
|
+
return current.type === AST_NODE_TYPES68.Identifier ? current.name : null;
|
|
16146
|
+
}
|
|
16147
|
+
}
|
|
16148
|
+
function expressionHasDatabaseMarker(node) {
|
|
16149
|
+
let current = node;
|
|
16150
|
+
for (; ; ) {
|
|
16151
|
+
if (current.type === AST_NODE_TYPES68.ChainExpression) {
|
|
16152
|
+
current = current.expression;
|
|
16153
|
+
continue;
|
|
16154
|
+
}
|
|
16155
|
+
if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
|
|
16156
|
+
current = current.expression;
|
|
16157
|
+
continue;
|
|
16158
|
+
}
|
|
16159
|
+
if (current.type === AST_NODE_TYPES68.CallExpression) {
|
|
16160
|
+
if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return false;
|
|
16161
|
+
current = current.callee.object;
|
|
16162
|
+
continue;
|
|
16163
|
+
}
|
|
16164
|
+
if (current.type === AST_NODE_TYPES68.MemberExpression) {
|
|
16165
|
+
const name = memberName5(current);
|
|
16166
|
+
if (name === "DB" || name !== null && DATABASE_NAMES.test(name))
|
|
16167
|
+
return true;
|
|
16168
|
+
current = current.object;
|
|
16169
|
+
continue;
|
|
16170
|
+
}
|
|
16171
|
+
return current.type === AST_NODE_TYPES68.Identifier && DATABASE_NAMES.test(current.name);
|
|
16172
|
+
}
|
|
16173
|
+
}
|
|
16174
|
+
function expressionCallsBuilder(node) {
|
|
16175
|
+
let current = node;
|
|
16176
|
+
for (; ; ) {
|
|
16177
|
+
if (current.type === AST_NODE_TYPES68.ChainExpression) {
|
|
16178
|
+
current = current.expression;
|
|
16179
|
+
continue;
|
|
16180
|
+
}
|
|
16181
|
+
if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
|
|
16182
|
+
current = current.expression;
|
|
16183
|
+
continue;
|
|
16184
|
+
}
|
|
16185
|
+
if (current.type === AST_NODE_TYPES68.CallExpression) {
|
|
16186
|
+
if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return false;
|
|
16187
|
+
const name = memberName5(current.callee);
|
|
16188
|
+
if (name !== null && BUILDER_METHODS.has(name)) return true;
|
|
16189
|
+
current = current.callee.object;
|
|
16190
|
+
continue;
|
|
16191
|
+
}
|
|
16192
|
+
if (current.type !== AST_NODE_TYPES68.MemberExpression) return false;
|
|
16193
|
+
current = current.object;
|
|
16194
|
+
}
|
|
16195
|
+
}
|
|
16196
|
+
function owningClass2(node) {
|
|
15817
16197
|
let current = node.parent;
|
|
15818
16198
|
while (current != null) {
|
|
15819
|
-
if (current.type ===
|
|
15820
|
-
return
|
|
16199
|
+
if (current.type === AST_NODE_TYPES68.ClassDeclaration || current.type === AST_NODE_TYPES68.ClassExpression)
|
|
16200
|
+
return current;
|
|
15821
16201
|
current = current.parent;
|
|
15822
16202
|
}
|
|
15823
|
-
return
|
|
16203
|
+
return null;
|
|
16204
|
+
}
|
|
16205
|
+
function injectedMembers(owner) {
|
|
16206
|
+
const injected = /* @__PURE__ */ new Set();
|
|
16207
|
+
const constructor = owner.body.body.find(
|
|
16208
|
+
(member) => member.type === AST_NODE_TYPES68.MethodDefinition && member.kind === "constructor"
|
|
16209
|
+
);
|
|
16210
|
+
if (constructor === void 0) return injected;
|
|
16211
|
+
const parameters = /* @__PURE__ */ new Set();
|
|
16212
|
+
for (const parameter of constructor.value.params) {
|
|
16213
|
+
for (const name of parameterNames(parameter)) parameters.add(name);
|
|
16214
|
+
if (parameter.type !== AST_NODE_TYPES68.TSParameterProperty) continue;
|
|
16215
|
+
const value = parameter.parameter.type === AST_NODE_TYPES68.AssignmentPattern ? parameter.parameter.left : parameter.parameter;
|
|
16216
|
+
if (value.type === AST_NODE_TYPES68.Identifier) injected.add(value.name);
|
|
16217
|
+
}
|
|
16218
|
+
const body2 = constructor.value.body;
|
|
16219
|
+
if (body2 === null) return injected;
|
|
16220
|
+
for (const statement of body2.body) {
|
|
16221
|
+
if (statement.type !== AST_NODE_TYPES68.ExpressionStatement || statement.expression.type !== AST_NODE_TYPES68.AssignmentExpression || statement.expression.operator !== "=") continue;
|
|
16222
|
+
const { left, right } = statement.expression;
|
|
16223
|
+
if (left.type !== AST_NODE_TYPES68.MemberExpression) continue;
|
|
16224
|
+
const target = thisRootMember(left);
|
|
16225
|
+
if (target === null) continue;
|
|
16226
|
+
const source = right.type === AST_NODE_TYPES68.Identifier ? right.name : right.type === AST_NODE_TYPES68.MemberExpression && right.object.type === AST_NODE_TYPES68.Identifier ? right.object.name : null;
|
|
16227
|
+
if (source !== null && parameters.has(source)) injected.add(target);
|
|
16228
|
+
}
|
|
16229
|
+
return injected;
|
|
16230
|
+
}
|
|
16231
|
+
function thisRootMember(node) {
|
|
16232
|
+
let current = node;
|
|
16233
|
+
let root = null;
|
|
16234
|
+
while (current.type === AST_NODE_TYPES68.MemberExpression) {
|
|
16235
|
+
const name = memberName5(current);
|
|
16236
|
+
if (name === null) return null;
|
|
16237
|
+
root = name;
|
|
16238
|
+
current = current.object;
|
|
16239
|
+
}
|
|
16240
|
+
return current.type === AST_NODE_TYPES68.ThisExpression ? root : null;
|
|
16241
|
+
}
|
|
16242
|
+
function parameterNames(parameter) {
|
|
16243
|
+
let value = parameter;
|
|
16244
|
+
if (value.type === AST_NODE_TYPES68.TSParameterProperty) value = value.parameter;
|
|
16245
|
+
if (value.type === AST_NODE_TYPES68.AssignmentPattern) value = value.left;
|
|
16246
|
+
if (value.type === AST_NODE_TYPES68.Identifier) return /* @__PURE__ */ new Set([value.name]);
|
|
16247
|
+
if (value.type !== AST_NODE_TYPES68.ObjectPattern) return /* @__PURE__ */ new Set();
|
|
16248
|
+
return new Set(
|
|
16249
|
+
value.properties.flatMap((property) => {
|
|
16250
|
+
if (property.type === AST_NODE_TYPES68.RestElement)
|
|
16251
|
+
return property.argument.type === AST_NODE_TYPES68.Identifier ? [property.argument.name] : [];
|
|
16252
|
+
const target = property.value.type === AST_NODE_TYPES68.AssignmentPattern ? property.value.left : property.value;
|
|
16253
|
+
return target.type === AST_NODE_TYPES68.Identifier ? [target.name] : [];
|
|
16254
|
+
})
|
|
16255
|
+
);
|
|
15824
16256
|
}
|
|
15825
16257
|
var require_sql_access_class_default = createRule({
|
|
15826
16258
|
name: "require-sql-access-class",
|
|
@@ -15841,11 +16273,16 @@ var require_sql_access_class_default = createRule({
|
|
|
15841
16273
|
return {};
|
|
15842
16274
|
return {
|
|
15843
16275
|
CallExpression(node) {
|
|
15844
|
-
if (
|
|
16276
|
+
if (node.callee.type !== AST_NODE_TYPES68.MemberExpression)
|
|
15845
16277
|
return;
|
|
15846
|
-
const method =
|
|
15847
|
-
if (method === null || !
|
|
16278
|
+
const method = memberName5(node.callee);
|
|
16279
|
+
if (method === null || !isDatabaseOperation(method, node.callee.object))
|
|
15848
16280
|
return;
|
|
16281
|
+
const owner = owningClass2(node);
|
|
16282
|
+
if (owner !== null) {
|
|
16283
|
+
const root = databaseRootMember(node.callee.object);
|
|
16284
|
+
if (root !== null && injectedMembers(owner).has(root)) return;
|
|
16285
|
+
}
|
|
15849
16286
|
context.report({ node, messageId: "moveSqlIntoClass" });
|
|
15850
16287
|
}
|
|
15851
16288
|
};
|
|
@@ -15853,7 +16290,7 @@ var require_sql_access_class_default = createRule({
|
|
|
15853
16290
|
});
|
|
15854
16291
|
|
|
15855
16292
|
// src/rules/require-static-next-matcher.ts
|
|
15856
|
-
import { AST_NODE_TYPES as
|
|
16293
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES69 } from "@typescript-eslint/utils";
|
|
15857
16294
|
var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
15858
16295
|
summary: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
|
|
15859
16296
|
rationale: "Next.js must statically analyze matcher values at build time; computed values are ignored.",
|
|
@@ -15866,34 +16303,34 @@ var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
|
15866
16303
|
};
|
|
15867
16304
|
var NEXT_ENTRY_FILE = /(?:^|[/\\])(?:middleware|proxy)\.[cm]?[jt]sx?$/u;
|
|
15868
16305
|
function unwrapExpression3(node) {
|
|
15869
|
-
if (node.type ===
|
|
16306
|
+
if (node.type === AST_NODE_TYPES69.TSAsExpression || node.type === AST_NODE_TYPES69.TSSatisfiesExpression || node.type === AST_NODE_TYPES69.TSNonNullExpression || node.type === AST_NODE_TYPES69.TSTypeAssertion) {
|
|
15870
16307
|
return unwrapExpression3(node.expression);
|
|
15871
16308
|
}
|
|
15872
16309
|
return node;
|
|
15873
16310
|
}
|
|
15874
16311
|
function isStaticValue(node) {
|
|
15875
16312
|
const value = unwrapExpression3(node);
|
|
15876
|
-
if (value.type ===
|
|
16313
|
+
if (value.type === AST_NODE_TYPES69.Literal) {
|
|
15877
16314
|
return true;
|
|
15878
16315
|
}
|
|
15879
|
-
if (value.type ===
|
|
16316
|
+
if (value.type === AST_NODE_TYPES69.TemplateLiteral) {
|
|
15880
16317
|
return value.expressions.length === 0;
|
|
15881
16318
|
}
|
|
15882
|
-
if (value.type ===
|
|
16319
|
+
if (value.type === AST_NODE_TYPES69.ArrayExpression) {
|
|
15883
16320
|
return value.elements.every(
|
|
15884
|
-
(element) => element !== null && element.type !==
|
|
16321
|
+
(element) => element !== null && element.type !== AST_NODE_TYPES69.SpreadElement && isStaticValue(element)
|
|
15885
16322
|
);
|
|
15886
16323
|
}
|
|
15887
|
-
if (value.type ===
|
|
16324
|
+
if (value.type === AST_NODE_TYPES69.ObjectExpression) {
|
|
15888
16325
|
return value.properties.every(
|
|
15889
|
-
(property) => property.type ===
|
|
16326
|
+
(property) => property.type === AST_NODE_TYPES69.Property && property.kind === "init" && !property.computed && property.value.type !== AST_NODE_TYPES69.AssignmentPattern && isStaticValue(property.value)
|
|
15890
16327
|
);
|
|
15891
16328
|
}
|
|
15892
16329
|
return false;
|
|
15893
16330
|
}
|
|
15894
|
-
function
|
|
16331
|
+
function propertyName6(property) {
|
|
15895
16332
|
if (property.computed) return null;
|
|
15896
|
-
if (property.key.type ===
|
|
16333
|
+
if (property.key.type === AST_NODE_TYPES69.Identifier) return property.key.name;
|
|
15897
16334
|
return typeof property.key.value === "string" ? property.key.value : null;
|
|
15898
16335
|
}
|
|
15899
16336
|
var require_static_next_matcher_default = createRule({
|
|
@@ -15916,19 +16353,19 @@ var require_static_next_matcher_default = createRule({
|
|
|
15916
16353
|
}
|
|
15917
16354
|
return {
|
|
15918
16355
|
ExportNamedDeclaration(node) {
|
|
15919
|
-
if (node.declaration?.type !==
|
|
16356
|
+
if (node.declaration?.type !== AST_NODE_TYPES69.VariableDeclaration) {
|
|
15920
16357
|
return;
|
|
15921
16358
|
}
|
|
15922
16359
|
for (const declaration of node.declaration.declarations) {
|
|
15923
|
-
if (declaration.id.type !==
|
|
16360
|
+
if (declaration.id.type !== AST_NODE_TYPES69.Identifier || declaration.id.name !== "config" || declaration.init === null) {
|
|
15924
16361
|
continue;
|
|
15925
16362
|
}
|
|
15926
16363
|
const config = unwrapExpression3(declaration.init);
|
|
15927
|
-
if (config.type !==
|
|
16364
|
+
if (config.type !== AST_NODE_TYPES69.ObjectExpression) {
|
|
15928
16365
|
continue;
|
|
15929
16366
|
}
|
|
15930
16367
|
for (const property of config.properties) {
|
|
15931
|
-
if (property.type !==
|
|
16368
|
+
if (property.type !== AST_NODE_TYPES69.Property || propertyName6(property) !== "matcher" || property.value.type === AST_NODE_TYPES69.AssignmentPattern) {
|
|
15932
16369
|
continue;
|
|
15933
16370
|
}
|
|
15934
16371
|
if (!isStaticValue(property.value)) {
|
|
@@ -15942,7 +16379,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
15942
16379
|
});
|
|
15943
16380
|
|
|
15944
16381
|
// src/rules/require-use-form-default-values.ts
|
|
15945
|
-
import { ASTUtils as
|
|
16382
|
+
import { ASTUtils as ASTUtils21 } from "@typescript-eslint/utils";
|
|
15946
16383
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
15947
16384
|
summary: "react-hook-form useForm call without defaultValues",
|
|
15948
16385
|
rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
|
|
@@ -15996,13 +16433,13 @@ var require_use_form_default_values_default = createRule({
|
|
|
15996
16433
|
if (node.source.value !== "react-hook-form") return;
|
|
15997
16434
|
for (const specifier of node.specifiers) {
|
|
15998
16435
|
if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
|
|
15999
|
-
const variable =
|
|
16436
|
+
const variable = ASTUtils21.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
16000
16437
|
if (variable) importedHooks.add(variable);
|
|
16001
16438
|
}
|
|
16002
16439
|
},
|
|
16003
16440
|
CallExpression(node) {
|
|
16004
16441
|
if (node.callee.type !== "Identifier") return;
|
|
16005
|
-
const variable =
|
|
16442
|
+
const variable = ASTUtils21.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
|
|
16006
16443
|
const options = node.arguments[0];
|
|
16007
16444
|
if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
|
|
16008
16445
|
context.report({ node, messageId: "requireUseFormDefaultValues" });
|
|
@@ -16079,8 +16516,8 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
16079
16516
|
|
|
16080
16517
|
// src/rules/require-zod-form-validation.ts
|
|
16081
16518
|
import {
|
|
16082
|
-
AST_NODE_TYPES as
|
|
16083
|
-
ASTUtils as
|
|
16519
|
+
AST_NODE_TYPES as AST_NODE_TYPES70,
|
|
16520
|
+
ASTUtils as ASTUtils22
|
|
16084
16521
|
} from "@typescript-eslint/utils";
|
|
16085
16522
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
16086
16523
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
@@ -16106,14 +16543,14 @@ var FORM_VALUE_METHODS = /* @__PURE__ */ new Set(["get", "getAll"]);
|
|
|
16106
16543
|
var zodReceiverRoot = (node) => {
|
|
16107
16544
|
let current = node;
|
|
16108
16545
|
while (true) {
|
|
16109
|
-
if (current.type ===
|
|
16546
|
+
if (current.type === AST_NODE_TYPES70.Identifier) {
|
|
16110
16547
|
return current;
|
|
16111
16548
|
}
|
|
16112
|
-
if (current.type ===
|
|
16549
|
+
if (current.type === AST_NODE_TYPES70.CallExpression) {
|
|
16113
16550
|
current = current.callee;
|
|
16114
16551
|
continue;
|
|
16115
16552
|
}
|
|
16116
|
-
if (current.type ===
|
|
16553
|
+
if (current.type === AST_NODE_TYPES70.MemberExpression) {
|
|
16117
16554
|
current = current.object;
|
|
16118
16555
|
continue;
|
|
16119
16556
|
}
|
|
@@ -16122,12 +16559,12 @@ var zodReceiverRoot = (node) => {
|
|
|
16122
16559
|
};
|
|
16123
16560
|
var isFormDataMethodCall = (node) => {
|
|
16124
16561
|
let current = node;
|
|
16125
|
-
if (current.type ===
|
|
16562
|
+
if (current.type === AST_NODE_TYPES70.AwaitExpression) {
|
|
16126
16563
|
current = current.argument;
|
|
16127
16564
|
}
|
|
16128
|
-
if (current.type !==
|
|
16565
|
+
if (current.type !== AST_NODE_TYPES70.CallExpression) return false;
|
|
16129
16566
|
const callee = current.callee;
|
|
16130
|
-
return callee.type ===
|
|
16567
|
+
return callee.type === AST_NODE_TYPES70.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES70.Identifier && callee.property.name === "formData";
|
|
16131
16568
|
};
|
|
16132
16569
|
var require_zod_form_validation_default = createRule({
|
|
16133
16570
|
name: "require-zod-form-validation",
|
|
@@ -16148,7 +16585,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16148
16585
|
return {};
|
|
16149
16586
|
}
|
|
16150
16587
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
16151
|
-
const resolvedBinding = (identifier) =>
|
|
16588
|
+
const resolvedBinding = (identifier) => ASTUtils22.findVariable(
|
|
16152
16589
|
context.sourceCode.getScope(identifier),
|
|
16153
16590
|
identifier.name
|
|
16154
16591
|
);
|
|
@@ -16158,16 +16595,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
16158
16595
|
return false;
|
|
16159
16596
|
}
|
|
16160
16597
|
const definition = binding.defs[0];
|
|
16161
|
-
if (definition?.type !== "Variable" || definition.node.type !==
|
|
16598
|
+
if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES70.VariableDeclarator) {
|
|
16162
16599
|
return false;
|
|
16163
16600
|
}
|
|
16164
16601
|
const init = definition.node.init;
|
|
16165
|
-
return init?.type ===
|
|
16602
|
+
return init?.type === AST_NODE_TYPES70.ObjectExpression || init?.type === AST_NODE_TYPES70.ArrayExpression || init?.type === AST_NODE_TYPES70.Literal || init?.type === AST_NODE_TYPES70.ArrowFunctionExpression || init?.type === AST_NODE_TYPES70.FunctionExpression;
|
|
16166
16603
|
};
|
|
16167
16604
|
const isZodParseCall = (node) => {
|
|
16168
|
-
if (node.type !==
|
|
16605
|
+
if (node.type !== AST_NODE_TYPES70.CallExpression) return false;
|
|
16169
16606
|
const callee = node.callee;
|
|
16170
|
-
if (callee.type !==
|
|
16607
|
+
if (callee.type !== AST_NODE_TYPES70.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES70.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
|
|
16171
16608
|
return false;
|
|
16172
16609
|
}
|
|
16173
16610
|
const root = zodReceiverRoot(callee.object);
|
|
@@ -16176,14 +16613,14 @@ var require_zod_form_validation_default = createRule({
|
|
|
16176
16613
|
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
16177
16614
|
};
|
|
16178
16615
|
const isFormSourceIdentifier = (node) => {
|
|
16179
|
-
if (node.type !==
|
|
16616
|
+
if (node.type !== AST_NODE_TYPES70.Identifier) return false;
|
|
16180
16617
|
const conventionalName = /formdata/i.test(node.name);
|
|
16181
16618
|
let scope = context.sourceCode.getScope(node);
|
|
16182
16619
|
while (scope !== null) {
|
|
16183
16620
|
const variable = scope.set.get(node.name);
|
|
16184
16621
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
16185
16622
|
const def = variable.defs[0];
|
|
16186
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
16623
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES70.VariableDeclarator && def.node.init !== null) {
|
|
16187
16624
|
return isFormDataMethodCall(def.node.init);
|
|
16188
16625
|
}
|
|
16189
16626
|
return def?.type === "Parameter" && conventionalName;
|
|
@@ -16194,8 +16631,8 @@ var require_zod_form_validation_default = createRule({
|
|
|
16194
16631
|
};
|
|
16195
16632
|
const isFormDataGetCall = (node) => {
|
|
16196
16633
|
const callee = node.callee;
|
|
16197
|
-
if (callee.type !==
|
|
16198
|
-
if (callee.property.type !==
|
|
16634
|
+
if (callee.type !== AST_NODE_TYPES70.MemberExpression) return false;
|
|
16635
|
+
if (callee.property.type !== AST_NODE_TYPES70.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
16199
16636
|
return false;
|
|
16200
16637
|
}
|
|
16201
16638
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -16211,16 +16648,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
16211
16648
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
16212
16649
|
const isInstanceofNarrowing = (node) => {
|
|
16213
16650
|
const parent = node.parent;
|
|
16214
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
16651
|
+
return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES70.BinaryExpression && parent.operator === "instanceof" && parent.left === node && parent.right.type === AST_NODE_TYPES70.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
|
|
16215
16652
|
};
|
|
16216
16653
|
const boundDeclarator = (node) => {
|
|
16217
16654
|
let current = node;
|
|
16218
16655
|
let parent = current.parent;
|
|
16219
|
-
while ((parent.type ===
|
|
16656
|
+
while ((parent.type === AST_NODE_TYPES70.TSAsExpression || parent.type === AST_NODE_TYPES70.TSSatisfiesExpression || parent.type === AST_NODE_TYPES70.TSNonNullExpression || parent.type === AST_NODE_TYPES70.ChainExpression) && parent.expression === current) {
|
|
16220
16657
|
current = parent;
|
|
16221
16658
|
parent = current.parent;
|
|
16222
16659
|
}
|
|
16223
|
-
if (parent.type ===
|
|
16660
|
+
if (parent.type === AST_NODE_TYPES70.VariableDeclarator && parent.init === current && parent.id.type === AST_NODE_TYPES70.Identifier) {
|
|
16224
16661
|
return parent;
|
|
16225
16662
|
}
|
|
16226
16663
|
return null;
|
|
@@ -16229,7 +16666,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16229
16666
|
let current = node;
|
|
16230
16667
|
while (current.parent !== void 0) {
|
|
16231
16668
|
const parent = current.parent;
|
|
16232
|
-
if (parent.type ===
|
|
16669
|
+
if (parent.type === AST_NODE_TYPES70.BlockStatement || parent.type === AST_NODE_TYPES70.Program) {
|
|
16233
16670
|
return current;
|
|
16234
16671
|
}
|
|
16235
16672
|
current = parent;
|
|
@@ -16238,12 +16675,12 @@ var require_zod_form_validation_default = createRule({
|
|
|
16238
16675
|
};
|
|
16239
16676
|
const zodParseMethod = (call) => {
|
|
16240
16677
|
const callee = call.callee;
|
|
16241
|
-
return callee.type ===
|
|
16678
|
+
return callee.type === AST_NODE_TYPES70.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES70.Identifier ? callee.property.name : null;
|
|
16242
16679
|
};
|
|
16243
16680
|
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
16244
16681
|
let current = node.parent;
|
|
16245
16682
|
while (current !== void 0 && current !== statement) {
|
|
16246
|
-
if (current.type ===
|
|
16683
|
+
if (current.type === AST_NODE_TYPES70.LogicalExpression || current.type === AST_NODE_TYPES70.ConditionalExpression) {
|
|
16247
16684
|
return true;
|
|
16248
16685
|
}
|
|
16249
16686
|
current = current.parent;
|
|
@@ -16253,7 +16690,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16253
16690
|
const isAwaitedBeforeStatement = (node, statement) => {
|
|
16254
16691
|
let current = node.parent;
|
|
16255
16692
|
while (current !== void 0 && current !== statement) {
|
|
16256
|
-
if (current.type ===
|
|
16693
|
+
if (current.type === AST_NODE_TYPES70.AwaitExpression) return true;
|
|
16257
16694
|
current = current.parent;
|
|
16258
16695
|
}
|
|
16259
16696
|
return false;
|
|
@@ -16266,7 +16703,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16266
16703
|
if (declarationStatement === null || validationStatement === null || declarationStatement.parent !== validationStatement.parent || validationStatement.range[0] <= declarationStatement.range[1] || hasConditionalAncestorBeforeStatement(parse2, validationStatement)) {
|
|
16267
16704
|
return null;
|
|
16268
16705
|
}
|
|
16269
|
-
if (validationStatement.type !==
|
|
16706
|
+
if (validationStatement.type !== AST_NODE_TYPES70.VariableDeclaration && validationStatement.type !== AST_NODE_TYPES70.ExpressionStatement) {
|
|
16270
16707
|
return null;
|
|
16271
16708
|
}
|
|
16272
16709
|
const method = zodParseMethod(parse2);
|
|
@@ -16278,16 +16715,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
16278
16715
|
};
|
|
16279
16716
|
const isSafePrevalidationInspection = (identifier) => {
|
|
16280
16717
|
const parent = identifier.parent;
|
|
16281
|
-
if (parent.type ===
|
|
16718
|
+
if (parent.type === AST_NODE_TYPES70.UnaryExpression && parent.operator === "typeof") {
|
|
16282
16719
|
return true;
|
|
16283
16720
|
}
|
|
16284
|
-
if (parent.type !==
|
|
16721
|
+
if (parent.type !== AST_NODE_TYPES70.BinaryExpression || parent.left !== identifier) {
|
|
16285
16722
|
return false;
|
|
16286
16723
|
}
|
|
16287
16724
|
if (parent.operator === "instanceof") {
|
|
16288
|
-
return parent.right.type ===
|
|
16725
|
+
return parent.right.type === AST_NODE_TYPES70.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
|
|
16289
16726
|
}
|
|
16290
|
-
return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type ===
|
|
16727
|
+
return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type === AST_NODE_TYPES70.Literal && parent.right.value === null || parent.right.type === AST_NODE_TYPES70.Identifier && parent.right.name === "undefined");
|
|
16291
16728
|
};
|
|
16292
16729
|
const isDescendantOf = (node, ancestor) => {
|
|
16293
16730
|
let current = node;
|
|
@@ -16298,23 +16735,23 @@ var require_zod_form_validation_default = createRule({
|
|
|
16298
16735
|
return false;
|
|
16299
16736
|
};
|
|
16300
16737
|
const blockTerminates = (node) => {
|
|
16301
|
-
if (node.type ===
|
|
16738
|
+
if (node.type === AST_NODE_TYPES70.ReturnStatement || node.type === AST_NODE_TYPES70.ThrowStatement) {
|
|
16302
16739
|
return true;
|
|
16303
16740
|
}
|
|
16304
|
-
if (node.type !==
|
|
16741
|
+
if (node.type !== AST_NODE_TYPES70.BlockStatement || node.body.length === 0) return false;
|
|
16305
16742
|
const last = node.body.at(-1);
|
|
16306
16743
|
return last !== void 0 && blockTerminates(last);
|
|
16307
16744
|
};
|
|
16308
16745
|
const narrowingIf = (identifier) => {
|
|
16309
16746
|
const comparison = identifier.parent;
|
|
16310
|
-
if (comparison?.type !==
|
|
16747
|
+
if (comparison?.type !== AST_NODE_TYPES70.BinaryExpression || comparison.operator !== "instanceof" || comparison.left !== identifier || comparison.right.type !== AST_NODE_TYPES70.Identifier || comparison.right.name !== "File" && comparison.right.name !== "Blob") {
|
|
16311
16748
|
return null;
|
|
16312
16749
|
}
|
|
16313
16750
|
const maybeNegation = comparison.parent;
|
|
16314
|
-
const negated = maybeNegation?.type ===
|
|
16751
|
+
const negated = maybeNegation?.type === AST_NODE_TYPES70.UnaryExpression && maybeNegation.operator === "!";
|
|
16315
16752
|
const test = negated ? maybeNegation : comparison;
|
|
16316
16753
|
const branch = test.parent;
|
|
16317
|
-
return branch?.type ===
|
|
16754
|
+
return branch?.type === AST_NODE_TYPES70.IfStatement && branch.test === test ? { branch, positive: !negated } : null;
|
|
16318
16755
|
};
|
|
16319
16756
|
const useDominatedByNarrowing = (use, narrowings) => narrowings.some(({ branch, positive }) => {
|
|
16320
16757
|
if (positive) return isDescendantOf(use, branch.consequent);
|
|
@@ -16334,7 +16771,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16334
16771
|
const variable = context.sourceCode.getDeclaredVariables(declarator)[0];
|
|
16335
16772
|
if (variable === void 0) return false;
|
|
16336
16773
|
const references = variable.references.filter((reference) => !reference.isWriteOnly()).map((reference) => reference.identifier).filter(
|
|
16337
|
-
(identifier) => identifier.type ===
|
|
16774
|
+
(identifier) => identifier.type === AST_NODE_TYPES70.Identifier
|
|
16338
16775
|
);
|
|
16339
16776
|
if (references.length === 0) return false;
|
|
16340
16777
|
const narrowings = references.map(narrowingIf).filter(
|
|
@@ -16360,7 +16797,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
16360
16797
|
ImportDeclaration(node) {
|
|
16361
16798
|
if (!isZodModule(node.source.value)) return;
|
|
16362
16799
|
for (const specifier of node.specifiers) {
|
|
16363
|
-
if (specifier.type ===
|
|
16800
|
+
if (specifier.type === AST_NODE_TYPES70.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES70.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES70.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES70.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
|
|
16364
16801
|
const binding = resolvedBinding(specifier.local);
|
|
16365
16802
|
if (binding !== null) zodBindings.add(binding);
|
|
16366
16803
|
}
|
|
@@ -16445,7 +16882,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
16445
16882
|
});
|
|
16446
16883
|
|
|
16447
16884
|
// src/rules/stepdown.ts
|
|
16448
|
-
import { AST_NODE_TYPES as
|
|
16885
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as ASTUtils23 } from "@typescript-eslint/utils";
|
|
16449
16886
|
var STEPDOWN_DOCUMENTATION = {
|
|
16450
16887
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
16451
16888
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -16465,7 +16902,7 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
16465
16902
|
]
|
|
16466
16903
|
};
|
|
16467
16904
|
function isFunction(node) {
|
|
16468
|
-
return node.type ===
|
|
16905
|
+
return node.type === AST_NODE_TYPES71.ArrowFunctionExpression || node.type === AST_NODE_TYPES71.FunctionDeclaration || node.type === AST_NODE_TYPES71.FunctionExpression;
|
|
16469
16906
|
}
|
|
16470
16907
|
function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true, makeFix) {
|
|
16471
16908
|
const byName = new Map(scopeDefinitions.map((definition) => [definition.name, definition]));
|
|
@@ -16562,8 +16999,8 @@ function moduleScope(context, program) {
|
|
|
16562
16999
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
16563
17000
|
const overloadNames = new Set(
|
|
16564
17001
|
program.body.flatMap((statement) => {
|
|
16565
|
-
const node = statement.type ===
|
|
16566
|
-
return node?.type ===
|
|
17002
|
+
const node = statement.type === AST_NODE_TYPES71.ExportNamedDeclaration ? statement.declaration : statement;
|
|
17003
|
+
return node?.type === AST_NODE_TYPES71.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
|
|
16567
17004
|
})
|
|
16568
17005
|
);
|
|
16569
17006
|
const exported = exportedNames(program);
|
|
@@ -16587,7 +17024,7 @@ function moduleScope(context, program) {
|
|
|
16587
17024
|
const nearestFunction2 = [...ancestors].reverse().find(isFunction);
|
|
16588
17025
|
const parent = identifier.parent;
|
|
16589
17026
|
const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
|
|
16590
|
-
if (callerDefinition === void 0 || parent.type !==
|
|
17027
|
+
if (callerDefinition === void 0 || parent.type !== AST_NODE_TYPES71.CallExpression || parent.callee !== identifier) {
|
|
16591
17028
|
pinned.add(definition.name);
|
|
16592
17029
|
continue;
|
|
16593
17030
|
}
|
|
@@ -16602,38 +17039,38 @@ function moduleScope(context, program) {
|
|
|
16602
17039
|
function exportedNames(program) {
|
|
16603
17040
|
const names = /* @__PURE__ */ new Set();
|
|
16604
17041
|
for (const statement of program.body) {
|
|
16605
|
-
if (statement.type !==
|
|
16606
|
-
if (statement.declaration?.type ===
|
|
17042
|
+
if (statement.type !== AST_NODE_TYPES71.ExportNamedDeclaration || statement.exportKind === "type" || statement.source !== null) continue;
|
|
17043
|
+
if (statement.declaration?.type === AST_NODE_TYPES71.FunctionDeclaration && statement.declaration.id !== null) {
|
|
16607
17044
|
names.add(statement.declaration.id.name);
|
|
16608
17045
|
}
|
|
16609
|
-
if (statement.declaration?.type ===
|
|
17046
|
+
if (statement.declaration?.type === AST_NODE_TYPES71.VariableDeclaration) {
|
|
16610
17047
|
for (const declarator of statement.declaration.declarations) {
|
|
16611
|
-
if (declarator.id.type ===
|
|
17048
|
+
if (declarator.id.type === AST_NODE_TYPES71.Identifier) names.add(declarator.id.name);
|
|
16612
17049
|
}
|
|
16613
17050
|
}
|
|
16614
17051
|
for (const specifier of statement.specifiers) {
|
|
16615
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
17052
|
+
if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES71.Identifier) {
|
|
16616
17053
|
names.add(specifier.local.name);
|
|
16617
17054
|
}
|
|
16618
17055
|
}
|
|
16619
17056
|
}
|
|
16620
17057
|
for (const statement of program.body) {
|
|
16621
|
-
if (statement.type ===
|
|
16622
|
-
if (statement.type ===
|
|
17058
|
+
if (statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES71.Identifier) names.add(statement.declaration.name);
|
|
17059
|
+
if (statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES71.FunctionDeclaration && statement.declaration.id !== null) names.add(statement.declaration.id.name);
|
|
16623
17060
|
}
|
|
16624
17061
|
return names;
|
|
16625
17062
|
}
|
|
16626
17063
|
function moduleDefinitions(program) {
|
|
16627
17064
|
const definitions = [];
|
|
16628
17065
|
for (const statement of program.body) {
|
|
16629
|
-
const node = statement.type ===
|
|
16630
|
-
if (node?.type ===
|
|
17066
|
+
const node = statement.type === AST_NODE_TYPES71.ExportNamedDeclaration || statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
17067
|
+
if (node?.type === AST_NODE_TYPES71.FunctionDeclaration && node.id !== null && node.body !== null) {
|
|
16631
17068
|
definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
16632
17069
|
continue;
|
|
16633
17070
|
}
|
|
16634
|
-
if (node?.type !==
|
|
17071
|
+
if (node?.type !== AST_NODE_TYPES71.VariableDeclaration || node.kind !== "const") continue;
|
|
16635
17072
|
for (const declarator of node.declarations) {
|
|
16636
|
-
if (declarator.id.type ===
|
|
17073
|
+
if (declarator.id.type === AST_NODE_TYPES71.Identifier && declarator.init !== null && isFunction(declarator.init)) {
|
|
16637
17074
|
definitions.push({
|
|
16638
17075
|
name: declarator.id.name,
|
|
16639
17076
|
node: declarator,
|
|
@@ -16646,21 +17083,21 @@ function moduleDefinitions(program) {
|
|
|
16646
17083
|
return definitions;
|
|
16647
17084
|
}
|
|
16648
17085
|
function methodName(node) {
|
|
16649
|
-
if (node.key.type ===
|
|
16650
|
-
return !node.computed && node.key.type ===
|
|
17086
|
+
if (node.key.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.key.name}`;
|
|
17087
|
+
return !node.computed && node.key.type === AST_NODE_TYPES71.Identifier ? node.key.name : null;
|
|
16651
17088
|
}
|
|
16652
17089
|
function referencedMethod(context, node, classVariables) {
|
|
16653
|
-
const objectVariable = node.object.type ===
|
|
17090
|
+
const objectVariable = node.object.type === AST_NODE_TYPES71.Identifier ? ASTUtils23.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
|
|
16654
17091
|
const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
|
|
16655
|
-
if (node.object.type !==
|
|
16656
|
-
if (node.property.type ===
|
|
16657
|
-
if (!node.computed && node.property.type ===
|
|
16658
|
-
return node.computed && node.property.type ===
|
|
17092
|
+
if (node.object.type !== AST_NODE_TYPES71.ThisExpression && !isClassReference) return null;
|
|
17093
|
+
if (node.property.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.property.name}`;
|
|
17094
|
+
if (!node.computed && node.property.type === AST_NODE_TYPES71.Identifier) return node.property.name;
|
|
17095
|
+
return node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
16659
17096
|
}
|
|
16660
17097
|
function referencedPropertyName(node) {
|
|
16661
|
-
if (node.property.type ===
|
|
16662
|
-
if (!node.computed && node.property.type ===
|
|
16663
|
-
return node.computed && node.property.type ===
|
|
17098
|
+
if (node.property.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.property.name}`;
|
|
17099
|
+
if (!node.computed && node.property.type === AST_NODE_TYPES71.Identifier) return node.property.name;
|
|
17100
|
+
return node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
16664
17101
|
}
|
|
16665
17102
|
function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
16666
17103
|
visit(node, nestedFunction);
|
|
@@ -16676,7 +17113,7 @@ function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
|
16676
17113
|
}
|
|
16677
17114
|
function classScope(context, node, computedReferenceNames) {
|
|
16678
17115
|
const methods = node.body.body.filter(
|
|
16679
|
-
(member) => member.type ===
|
|
17116
|
+
(member) => member.type === AST_NODE_TYPES71.MethodDefinition
|
|
16680
17117
|
);
|
|
16681
17118
|
const counts = /* @__PURE__ */ new Map();
|
|
16682
17119
|
for (const method of methods) {
|
|
@@ -16684,8 +17121,8 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16684
17121
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16685
17122
|
}
|
|
16686
17123
|
for (const member of node.body.body) {
|
|
16687
|
-
if (member.type !==
|
|
16688
|
-
const name = !member.computed && member.key.type ===
|
|
17124
|
+
if (member.type !== AST_NODE_TYPES71.TSAbstractMethodDefinition) continue;
|
|
17125
|
+
const name = !member.computed && member.key.type === AST_NODE_TYPES71.Identifier ? member.key.name : null;
|
|
16689
17126
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16690
17127
|
}
|
|
16691
17128
|
const scopeDefinitions = methods.flatMap((method) => {
|
|
@@ -16694,7 +17131,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16694
17131
|
});
|
|
16695
17132
|
const definitions = methods.flatMap((method) => {
|
|
16696
17133
|
const name = methodName(method);
|
|
16697
|
-
const isPrivate = method.accessibility === "private" || method.key.type ===
|
|
17134
|
+
const isPrivate = method.accessibility === "private" || method.key.type === AST_NODE_TYPES71.PrivateIdentifier;
|
|
16698
17135
|
return name !== null && isPrivate && counts.get(name) === 1 && method.decorators.length === 0 ? [{ name, node: method }] : [];
|
|
16699
17136
|
});
|
|
16700
17137
|
if (definitions.length === 0) return;
|
|
@@ -16703,11 +17140,11 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16703
17140
|
const pinned = /* @__PURE__ */ new Set();
|
|
16704
17141
|
const classVariables = /* @__PURE__ */ new Set();
|
|
16705
17142
|
if (node.id !== null) {
|
|
16706
|
-
const internal =
|
|
17143
|
+
const internal = ASTUtils23.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
16707
17144
|
if (internal !== null) classVariables.add(internal);
|
|
16708
17145
|
}
|
|
16709
|
-
if (node.type ===
|
|
16710
|
-
const outer =
|
|
17146
|
+
if (node.type === AST_NODE_TYPES71.ClassExpression && node.parent.type === AST_NODE_TYPES71.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES71.Identifier) {
|
|
17147
|
+
const outer = ASTUtils23.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
16711
17148
|
if (outer !== null) classVariables.add(outer);
|
|
16712
17149
|
}
|
|
16713
17150
|
for (const method of methods) {
|
|
@@ -16723,27 +17160,27 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16723
17160
|
}
|
|
16724
17161
|
const thisValue = (value) => {
|
|
16725
17162
|
let current = value;
|
|
16726
|
-
while (current?.type ===
|
|
16727
|
-
return current?.type ===
|
|
17163
|
+
while (current?.type === AST_NODE_TYPES71.TSAsExpression || current?.type === AST_NODE_TYPES71.TSSatisfiesExpression || current?.type === AST_NODE_TYPES71.TSNonNullExpression) current = current.expression;
|
|
17164
|
+
return current?.type === AST_NODE_TYPES71.ThisExpression;
|
|
16728
17165
|
};
|
|
16729
17166
|
const collectAlias = (current, nestedFunction) => {
|
|
16730
|
-
if (nestedFunction || current.type !==
|
|
16731
|
-
if (current.type ===
|
|
16732
|
-
const binding = current.type ===
|
|
16733
|
-
const value = current.type ===
|
|
17167
|
+
if (nestedFunction || current.type !== AST_NODE_TYPES71.VariableDeclarator && current.type !== AST_NODE_TYPES71.AssignmentPattern) return;
|
|
17168
|
+
if (current.type === AST_NODE_TYPES71.VariableDeclarator && (current.parent.type !== AST_NODE_TYPES71.VariableDeclaration || current.parent.kind !== "const")) return;
|
|
17169
|
+
const binding = current.type === AST_NODE_TYPES71.VariableDeclarator ? current.id : current.left;
|
|
17170
|
+
const value = current.type === AST_NODE_TYPES71.VariableDeclarator ? current.init : current.right;
|
|
16734
17171
|
if (!thisValue(value)) return;
|
|
16735
|
-
if (binding.type ===
|
|
17172
|
+
if (binding.type === AST_NODE_TYPES71.ObjectPattern) {
|
|
16736
17173
|
for (const property of binding.properties) {
|
|
16737
|
-
if (property.type ===
|
|
17174
|
+
if (property.type === AST_NODE_TYPES71.RestElement) {
|
|
16738
17175
|
for (const name of privateNames) pinned.add(name);
|
|
16739
|
-
} else if (property.key.type ===
|
|
17176
|
+
} else if (property.key.type === AST_NODE_TYPES71.Identifier && privateNames.has(property.key.name)) {
|
|
16740
17177
|
pinned.add(property.key.name);
|
|
16741
17178
|
}
|
|
16742
17179
|
}
|
|
16743
17180
|
return;
|
|
16744
17181
|
}
|
|
16745
|
-
if (binding.type !==
|
|
16746
|
-
const variable =
|
|
17182
|
+
if (binding.type !== AST_NODE_TYPES71.Identifier) return;
|
|
17183
|
+
const variable = ASTUtils23.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
16747
17184
|
if (variable !== null) {
|
|
16748
17185
|
methodClassVariables.add(variable);
|
|
16749
17186
|
methodAliases.add(variable);
|
|
@@ -16756,16 +17193,16 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16756
17193
|
walk2(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
16757
17194
|
}
|
|
16758
17195
|
const visitCall = (current, nestedFunction) => {
|
|
16759
|
-
if (current.type ===
|
|
17196
|
+
if (current.type === AST_NODE_TYPES71.VariableDeclarator && current.id.type === AST_NODE_TYPES71.ObjectPattern && thisValue(current.init)) {
|
|
16760
17197
|
for (const property of current.id.properties) {
|
|
16761
|
-
if (property.type ===
|
|
17198
|
+
if (property.type === AST_NODE_TYPES71.RestElement) {
|
|
16762
17199
|
for (const name of privateNames) pinned.add(name);
|
|
16763
17200
|
continue;
|
|
16764
17201
|
}
|
|
16765
|
-
if (property.type ===
|
|
17202
|
+
if (property.type === AST_NODE_TYPES71.Property && property.key.type === AST_NODE_TYPES71.Identifier && privateNames.has(property.key.name)) pinned.add(property.key.name);
|
|
16766
17203
|
}
|
|
16767
17204
|
}
|
|
16768
|
-
if (current.type !==
|
|
17205
|
+
if (current.type !== AST_NODE_TYPES71.MemberExpression) return;
|
|
16769
17206
|
const target = referencedMethod(context, current, methodClassVariables);
|
|
16770
17207
|
if (target === null) {
|
|
16771
17208
|
const possibleTarget = referencedPropertyName(current);
|
|
@@ -16773,12 +17210,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16773
17210
|
return;
|
|
16774
17211
|
}
|
|
16775
17212
|
if (!privateNames.has(target)) return;
|
|
16776
|
-
const objectVariable = current.object.type ===
|
|
17213
|
+
const objectVariable = current.object.type === AST_NODE_TYPES71.Identifier ? ASTUtils23.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
|
|
16777
17214
|
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
16778
17215
|
pinned.add(target);
|
|
16779
17216
|
return;
|
|
16780
17217
|
}
|
|
16781
|
-
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !==
|
|
17218
|
+
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !== AST_NODE_TYPES71.CallExpression || current.parent.callee !== current) {
|
|
16782
17219
|
pinned.add(target);
|
|
16783
17220
|
return;
|
|
16784
17221
|
}
|
|
@@ -16798,9 +17235,9 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16798
17235
|
}
|
|
16799
17236
|
}
|
|
16800
17237
|
for (const member of node.body.body) {
|
|
16801
|
-
if (member.type ===
|
|
17238
|
+
if (member.type === AST_NODE_TYPES71.MethodDefinition || member.type === AST_NODE_TYPES71.TSAbstractMethodDefinition) continue;
|
|
16802
17239
|
walk2(member, context.sourceCode.visitorKeys, (current) => {
|
|
16803
|
-
if (current.type !==
|
|
17240
|
+
if (current.type !== AST_NODE_TYPES71.MemberExpression) return;
|
|
16804
17241
|
const target = referencedMethod(context, current, classVariables);
|
|
16805
17242
|
const possibleTarget = target ?? referencedPropertyName(current);
|
|
16806
17243
|
if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
|
|
@@ -16852,12 +17289,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16852
17289
|
}
|
|
16853
17290
|
function isClassRuntimeBarrier(member) {
|
|
16854
17291
|
switch (member.type) {
|
|
16855
|
-
case
|
|
17292
|
+
case AST_NODE_TYPES71.StaticBlock:
|
|
16856
17293
|
return true;
|
|
16857
|
-
case
|
|
16858
|
-
case
|
|
17294
|
+
case AST_NODE_TYPES71.PropertyDefinition:
|
|
17295
|
+
case AST_NODE_TYPES71.AccessorProperty:
|
|
16859
17296
|
return member.static || member.computed || member.decorators.length > 0 || member.value !== null;
|
|
16860
|
-
case
|
|
17297
|
+
case AST_NODE_TYPES71.MethodDefinition:
|
|
16861
17298
|
return member.computed || member.decorators.length > 0;
|
|
16862
17299
|
default:
|
|
16863
17300
|
return false;
|
|
@@ -16890,7 +17327,7 @@ var stepdown_default = createRule({
|
|
|
16890
17327
|
moduleScope(context, program);
|
|
16891
17328
|
const computedReferenceNames = /* @__PURE__ */ new Set();
|
|
16892
17329
|
walk2(program, context.sourceCode.visitorKeys, (node) => {
|
|
16893
|
-
if (node.type ===
|
|
17330
|
+
if (node.type === AST_NODE_TYPES71.MemberExpression && node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string") computedReferenceNames.add(node.property.value);
|
|
16894
17331
|
});
|
|
16895
17332
|
for (const node of classes) classScope(context, node, computedReferenceNames);
|
|
16896
17333
|
}
|
|
@@ -16899,7 +17336,7 @@ var stepdown_default = createRule({
|
|
|
16899
17336
|
});
|
|
16900
17337
|
|
|
16901
17338
|
// src/rules/source-coupled-test.ts
|
|
16902
|
-
import { AST_NODE_TYPES as
|
|
17339
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES72 } from "@typescript-eslint/utils";
|
|
16903
17340
|
var GENERAL_SOURCE_SUFFIX_RE = /\.(?:bash|sh|ya?ml|jsonc|py|[cm]?[jt]s)$/iu;
|
|
16904
17341
|
var FS_MODULES = /* @__PURE__ */ new Set(["fs", "node:fs", "fs/promises", "node:fs/promises"]);
|
|
16905
17342
|
var FS_READERS = /* @__PURE__ */ new Set(["readFile", "readFileSync"]);
|
|
@@ -16968,20 +17405,20 @@ var SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
|
16968
17405
|
]
|
|
16969
17406
|
};
|
|
16970
17407
|
function staticMemberName7(node) {
|
|
16971
|
-
if (!node.computed && node.property.type ===
|
|
16972
|
-
if (node.computed && node.property.type ===
|
|
17408
|
+
if (!node.computed && node.property.type === AST_NODE_TYPES72.Identifier) return node.property.name;
|
|
17409
|
+
if (node.computed && node.property.type === AST_NODE_TYPES72.Literal && typeof node.property.value === "string") return node.property.value;
|
|
16973
17410
|
return null;
|
|
16974
17411
|
}
|
|
16975
17412
|
function unwrap6(node) {
|
|
16976
|
-
if (node.type ===
|
|
16977
|
-
if (node.type ===
|
|
16978
|
-
if (node.type ===
|
|
17413
|
+
if (node.type === AST_NODE_TYPES72.AwaitExpression) return unwrap6(node.argument);
|
|
17414
|
+
if (node.type === AST_NODE_TYPES72.ChainExpression) return unwrap6(node.expression);
|
|
17415
|
+
if (node.type === AST_NODE_TYPES72.TSAsExpression || node.type === AST_NODE_TYPES72.TSNonNullExpression || node.type === AST_NODE_TYPES72.TSTypeAssertion) return unwrap6(node.expression);
|
|
16979
17416
|
return node;
|
|
16980
17417
|
}
|
|
16981
17418
|
function stringValue(node) {
|
|
16982
17419
|
const current = unwrap6(node);
|
|
16983
|
-
if (current.type ===
|
|
16984
|
-
if (current.type ===
|
|
17420
|
+
if (current.type === AST_NODE_TYPES72.Literal && typeof current.value === "string") return current.value;
|
|
17421
|
+
if (current.type === AST_NODE_TYPES72.TemplateLiteral && current.expressions.length === 0) return current.quasis[0]?.value.cooked ?? null;
|
|
16985
17422
|
return null;
|
|
16986
17423
|
}
|
|
16987
17424
|
function importSource(node) {
|
|
@@ -16989,7 +17426,7 @@ function importSource(node) {
|
|
|
16989
17426
|
}
|
|
16990
17427
|
function requireSource(node) {
|
|
16991
17428
|
const current = unwrap6(node);
|
|
16992
|
-
if (current.type !==
|
|
17429
|
+
if (current.type !== AST_NODE_TYPES72.CallExpression || current.callee.type !== AST_NODE_TYPES72.Identifier || current.callee.name !== "require" || current.arguments.length !== 1 || current.arguments[0]?.type === AST_NODE_TYPES72.SpreadElement) return null;
|
|
16993
17430
|
return stringValue(current.arguments[0]);
|
|
16994
17431
|
}
|
|
16995
17432
|
function newScope() {
|
|
@@ -17029,38 +17466,38 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
17029
17466
|
const current = unwrap6(node);
|
|
17030
17467
|
const value = stringValue(current);
|
|
17031
17468
|
if (value !== null) return sourceSuffixRe.test(value);
|
|
17032
|
-
if (current.type ===
|
|
17033
|
-
if (current.type ===
|
|
17469
|
+
if (current.type === AST_NODE_TYPES72.Identifier) return visible("paths", current.name);
|
|
17470
|
+
if (current.type === AST_NODE_TYPES72.BinaryExpression && current.operator === "+") {
|
|
17034
17471
|
return sourcePath(current.left) || sourcePath(current.right);
|
|
17035
17472
|
}
|
|
17036
|
-
if (current.type ===
|
|
17037
|
-
if (current.type ===
|
|
17038
|
-
return current.arguments.some((argument) => argument.type !==
|
|
17473
|
+
if (current.type === AST_NODE_TYPES72.TemplateLiteral) return current.expressions.some(sourcePath);
|
|
17474
|
+
if (current.type === AST_NODE_TYPES72.CallExpression || current.type === AST_NODE_TYPES72.NewExpression) {
|
|
17475
|
+
return current.arguments.some((argument) => argument.type !== AST_NODE_TYPES72.SpreadElement && sourcePath(argument));
|
|
17039
17476
|
}
|
|
17040
|
-
if (current.type ===
|
|
17477
|
+
if (current.type === AST_NODE_TYPES72.MemberExpression) return sourcePath(current.object);
|
|
17041
17478
|
return false;
|
|
17042
17479
|
};
|
|
17043
17480
|
const rawRead = (node) => {
|
|
17044
17481
|
const current = unwrap6(node);
|
|
17045
|
-
if (current.type !==
|
|
17482
|
+
if (current.type !== AST_NODE_TYPES72.CallExpression || current.arguments.length === 0) return false;
|
|
17046
17483
|
const callee = unwrap6(current.callee);
|
|
17047
|
-
if (callee.type ===
|
|
17484
|
+
if (callee.type === AST_NODE_TYPES72.Identifier) {
|
|
17048
17485
|
return visible("fsReaders", callee.name) && sourcePath(current.arguments[0]);
|
|
17049
17486
|
}
|
|
17050
|
-
if (callee.type !==
|
|
17487
|
+
if (callee.type !== AST_NODE_TYPES72.MemberExpression) return false;
|
|
17051
17488
|
const name2 = staticMemberName7(callee);
|
|
17052
17489
|
const object = unwrap6(callee.object);
|
|
17053
|
-
return name2 !== null && FS_READERS.has(name2) && object.type ===
|
|
17490
|
+
return name2 !== null && FS_READERS.has(name2) && object.type === AST_NODE_TYPES72.Identifier && visible("fsObjects", object.name) && sourcePath(current.arguments[0]);
|
|
17054
17491
|
};
|
|
17055
17492
|
const rawOrigins = (node) => {
|
|
17056
17493
|
const current = unwrap6(node);
|
|
17057
|
-
if (current.type ===
|
|
17494
|
+
if (current.type === AST_NODE_TYPES72.Identifier) return visibleRawOrigins(current.name);
|
|
17058
17495
|
if (rawRead(current)) return /* @__PURE__ */ new Set([`${current.range[0]}:${current.range[1]}`]);
|
|
17059
|
-
if (current.type ===
|
|
17060
|
-
if (current.type ===
|
|
17061
|
-
if (current.type !==
|
|
17496
|
+
if (current.type === AST_NODE_TYPES72.BinaryExpression && current.operator === "+") return /* @__PURE__ */ new Set([...rawOrigins(current.left), ...rawOrigins(current.right)]);
|
|
17497
|
+
if (current.type === AST_NODE_TYPES72.MemberExpression && staticMemberName7(current) === "length") return rawOrigins(current.object);
|
|
17498
|
+
if (current.type !== AST_NODE_TYPES72.CallExpression) return /* @__PURE__ */ new Set();
|
|
17062
17499
|
const callee = unwrap6(current.callee);
|
|
17063
|
-
if (callee.type !==
|
|
17500
|
+
if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
|
|
17064
17501
|
const name2 = staticMemberName7(callee);
|
|
17065
17502
|
return name2 !== null && TEXT_TRANSFORMS.has(name2) ? rawOrigins(callee.object) : /* @__PURE__ */ new Set();
|
|
17066
17503
|
};
|
|
@@ -17068,38 +17505,38 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
17068
17505
|
const current = unwrap6(node);
|
|
17069
17506
|
const direct = rawOrigins(current);
|
|
17070
17507
|
if (direct.size > 0) return direct;
|
|
17071
|
-
if (current.type ===
|
|
17072
|
-
if (current.type ===
|
|
17073
|
-
if (current.type !==
|
|
17508
|
+
if (current.type === AST_NODE_TYPES72.BinaryExpression || current.type === AST_NODE_TYPES72.LogicalExpression) return /* @__PURE__ */ new Set([...evidenceOrigins(current.left), ...evidenceOrigins(current.right)]);
|
|
17509
|
+
if (current.type === AST_NODE_TYPES72.UnaryExpression) return evidenceOrigins(current.argument);
|
|
17510
|
+
if (current.type !== AST_NODE_TYPES72.CallExpression) return /* @__PURE__ */ new Set();
|
|
17074
17511
|
const callee = unwrap6(current.callee);
|
|
17075
|
-
if (callee.type !==
|
|
17512
|
+
if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
|
|
17076
17513
|
const name2 = staticMemberName7(callee);
|
|
17077
17514
|
if (name2 !== null && TEXT_PREDICATES.has(name2)) return rawOrigins(callee.object);
|
|
17078
|
-
if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type ===
|
|
17515
|
+
if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...rawOrigins(argument)]));
|
|
17079
17516
|
return /* @__PURE__ */ new Set();
|
|
17080
17517
|
};
|
|
17081
17518
|
const rawAssertionOrigins = (node) => {
|
|
17082
17519
|
const callee = unwrap6(node.callee);
|
|
17083
|
-
if (callee.type ===
|
|
17084
|
-
return new Set(node.arguments.flatMap((argument) => argument.type ===
|
|
17520
|
+
if (callee.type === AST_NODE_TYPES72.Identifier && callee.name === "assert") {
|
|
17521
|
+
return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
17085
17522
|
}
|
|
17086
|
-
if (callee.type !==
|
|
17523
|
+
if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
|
|
17087
17524
|
const matcher = staticMemberName7(callee);
|
|
17088
17525
|
if (matcher === null) return /* @__PURE__ */ new Set();
|
|
17089
17526
|
let receiver = unwrap6(callee.object);
|
|
17090
|
-
while (receiver.type ===
|
|
17091
|
-
if (receiver.type ===
|
|
17527
|
+
while (receiver.type === AST_NODE_TYPES72.MemberExpression && EXPECT_MODIFIERS2.has(staticMemberName7(receiver) ?? "")) receiver = unwrap6(receiver.object);
|
|
17528
|
+
if (receiver.type === AST_NODE_TYPES72.CallExpression && receiver.callee.type === AST_NODE_TYPES72.Identifier && receiver.callee.name === "expect") {
|
|
17092
17529
|
if (!EXPECT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
17093
|
-
return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type ===
|
|
17530
|
+
return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
17094
17531
|
}
|
|
17095
|
-
if (receiver.type !==
|
|
17096
|
-
return new Set(node.arguments.flatMap((argument) => argument.type ===
|
|
17532
|
+
if (receiver.type !== AST_NODE_TYPES72.Identifier || receiver.name !== "assert" || !ASSERT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
17533
|
+
return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
17097
17534
|
};
|
|
17098
17535
|
const rawRegexExtractionOrigins = (node) => {
|
|
17099
17536
|
const callee = unwrap6(node.callee);
|
|
17100
|
-
if (callee.type !==
|
|
17537
|
+
if (callee.type !== AST_NODE_TYPES72.MemberExpression || staticMemberName7(callee) !== "matchAll" || node.arguments.length !== 1) return /* @__PURE__ */ new Set();
|
|
17101
17538
|
const argument = node.arguments[0];
|
|
17102
|
-
if (argument?.type !==
|
|
17539
|
+
if (argument?.type !== AST_NODE_TYPES72.Literal || !(argument.value instanceof RegExp)) return /* @__PURE__ */ new Set();
|
|
17103
17540
|
return rawOrigins(callee.object);
|
|
17104
17541
|
};
|
|
17105
17542
|
const declare = (name2, state) => {
|
|
@@ -17120,15 +17557,15 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
17120
17557
|
};
|
|
17121
17558
|
const sourceCollection = (node) => {
|
|
17122
17559
|
const current = unwrap6(node);
|
|
17123
|
-
return current.type ===
|
|
17560
|
+
return current.type === AST_NODE_TYPES72.ArrayExpression && current.elements.length > 0 && current.elements.every((element) => element !== null && element.type !== AST_NODE_TYPES72.SpreadElement && sourcePath(element));
|
|
17124
17561
|
};
|
|
17125
17562
|
const declaredNames2 = (node) => {
|
|
17126
17563
|
const current = unwrap6(node);
|
|
17127
|
-
if (current.type ===
|
|
17128
|
-
if (current.type ===
|
|
17129
|
-
if (current.type ===
|
|
17130
|
-
if (current.type ===
|
|
17131
|
-
if (current.type ===
|
|
17564
|
+
if (current.type === AST_NODE_TYPES72.Identifier) return [current.name];
|
|
17565
|
+
if (current.type === AST_NODE_TYPES72.AssignmentPattern) return declaredNames2(current.left);
|
|
17566
|
+
if (current.type === AST_NODE_TYPES72.RestElement) return declaredNames2(current.argument);
|
|
17567
|
+
if (current.type === AST_NODE_TYPES72.ArrayPattern) return current.elements.flatMap((element) => element === null ? [] : declaredNames2(element));
|
|
17568
|
+
if (current.type === AST_NODE_TYPES72.ObjectPattern) return current.properties.flatMap((property) => property.type === AST_NODE_TYPES72.RestElement ? declaredNames2(property.argument) : declaredNames2(property.value));
|
|
17132
17569
|
return [];
|
|
17133
17570
|
};
|
|
17134
17571
|
const enterFunction = (node) => {
|
|
@@ -17143,8 +17580,8 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
17143
17580
|
const source = importSource(node);
|
|
17144
17581
|
if (source === null || !FS_MODULES.has(source)) return;
|
|
17145
17582
|
for (const specifier of node.specifiers) {
|
|
17146
|
-
if (specifier.type ===
|
|
17147
|
-
const imported = specifier.imported.type ===
|
|
17583
|
+
if (specifier.type === AST_NODE_TYPES72.ImportSpecifier) {
|
|
17584
|
+
const imported = specifier.imported.type === AST_NODE_TYPES72.Identifier ? specifier.imported.name : String(specifier.imported.value);
|
|
17148
17585
|
if (FS_READERS.has(imported)) declare(specifier.local.name, { fsReader: true });
|
|
17149
17586
|
} else {
|
|
17150
17587
|
declare(specifier.local.name, { fsObject: true });
|
|
@@ -17156,29 +17593,29 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
17156
17593
|
VariableDeclarator(node) {
|
|
17157
17594
|
if (node.init === null) return;
|
|
17158
17595
|
const required = requireSource(node.init);
|
|
17159
|
-
if (required !== null && FS_MODULES.has(required) && node.id.type ===
|
|
17596
|
+
if (required !== null && FS_MODULES.has(required) && node.id.type === AST_NODE_TYPES72.Identifier) {
|
|
17160
17597
|
declare(node.id.name, { fsObject: true });
|
|
17161
17598
|
return;
|
|
17162
17599
|
}
|
|
17163
|
-
if (node.id.type ===
|
|
17600
|
+
if (node.id.type === AST_NODE_TYPES72.ObjectPattern && required !== null && FS_MODULES.has(required)) {
|
|
17164
17601
|
for (const property of node.id.properties) {
|
|
17165
|
-
if (property.type !==
|
|
17166
|
-
const key = property.key.type ===
|
|
17602
|
+
if (property.type !== AST_NODE_TYPES72.Property || property.value.type !== AST_NODE_TYPES72.Identifier) continue;
|
|
17603
|
+
const key = property.key.type === AST_NODE_TYPES72.Identifier ? property.key.name : property.key.type === AST_NODE_TYPES72.Literal ? String(property.key.value) : "";
|
|
17167
17604
|
if (FS_READERS.has(key)) declare(property.value.name, { fsReader: true });
|
|
17168
17605
|
}
|
|
17169
17606
|
return;
|
|
17170
17607
|
}
|
|
17171
|
-
if (node.id.type !==
|
|
17608
|
+
if (node.id.type !== AST_NODE_TYPES72.Identifier) return;
|
|
17172
17609
|
declare(node.id.name, { collection: sourceCollection(node.init), path: sourcePath(node.init), rawOrigins: rawOrigins(node.init) });
|
|
17173
17610
|
},
|
|
17174
17611
|
AssignmentExpression(node) {
|
|
17175
|
-
if (node.left.type ===
|
|
17612
|
+
if (node.left.type === AST_NODE_TYPES72.Identifier) declare(node.left.name, { path: sourcePath(node.right), rawOrigins: rawOrigins(node.right) });
|
|
17176
17613
|
},
|
|
17177
17614
|
ForOfStatement(node) {
|
|
17178
17615
|
const right = unwrap6(node.right);
|
|
17179
|
-
const collection = right.type ===
|
|
17180
|
-
const left = node.left.type ===
|
|
17181
|
-
if (collection && left?.type ===
|
|
17616
|
+
const collection = right.type === AST_NODE_TYPES72.Identifier && visible("collections", right.name);
|
|
17617
|
+
const left = node.left.type === AST_NODE_TYPES72.VariableDeclaration ? node.left.declarations[0]?.id : node.left;
|
|
17618
|
+
if (collection && left?.type === AST_NODE_TYPES72.Identifier) declare(left.name, { path: true });
|
|
17182
17619
|
},
|
|
17183
17620
|
CallExpression(node) {
|
|
17184
17621
|
const origins = /* @__PURE__ */ new Set([
|
|
@@ -17200,7 +17637,7 @@ var source_coupled_test_default = createSourceCoupledRule(
|
|
|
17200
17637
|
);
|
|
17201
17638
|
|
|
17202
17639
|
// src/rules/sole-export-matches-filename.ts
|
|
17203
|
-
import { AST_NODE_TYPES as
|
|
17640
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES73 } from "@typescript-eslint/utils";
|
|
17204
17641
|
var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
17205
17642
|
summary: "Match a module filename to its sole named public runtime export.",
|
|
17206
17643
|
rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
|
|
@@ -17217,29 +17654,21 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
|
17217
17654
|
};
|
|
17218
17655
|
var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
|
|
17219
17656
|
"common",
|
|
17220
|
-
"config",
|
|
17221
|
-
"constants",
|
|
17222
|
-
"error",
|
|
17223
|
-
"errors",
|
|
17224
17657
|
"global",
|
|
17225
|
-
"handler",
|
|
17226
17658
|
"helpers",
|
|
17227
17659
|
"index",
|
|
17228
17660
|
"layout",
|
|
17229
17661
|
"loading",
|
|
17230
17662
|
"middleware",
|
|
17231
17663
|
"misc",
|
|
17232
|
-
"models",
|
|
17233
17664
|
"not-found",
|
|
17234
17665
|
"page",
|
|
17235
17666
|
"route",
|
|
17236
|
-
"schema",
|
|
17237
17667
|
"shared",
|
|
17238
17668
|
"template",
|
|
17239
17669
|
"types",
|
|
17240
17670
|
"util",
|
|
17241
|
-
"utils"
|
|
17242
|
-
"worker"
|
|
17671
|
+
"utils"
|
|
17243
17672
|
]);
|
|
17244
17673
|
function stem3(filename) {
|
|
17245
17674
|
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
@@ -17251,10 +17680,10 @@ function kebabCase(name) {
|
|
|
17251
17680
|
function declarationExport(statement) {
|
|
17252
17681
|
const declaration = statement.declaration;
|
|
17253
17682
|
if (declaration === null || declaration.declare === true) return [];
|
|
17254
|
-
if (declaration.type ===
|
|
17255
|
-
if (declaration.type !==
|
|
17683
|
+
if (declaration.type === AST_NODE_TYPES73.ClassDeclaration || declaration.type === AST_NODE_TYPES73.FunctionDeclaration || declaration.type === AST_NODE_TYPES73.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
|
|
17684
|
+
if (declaration.type !== AST_NODE_TYPES73.VariableDeclaration) return [];
|
|
17256
17685
|
return declaration.declarations.flatMap(
|
|
17257
|
-
(item) => item.id.type ===
|
|
17686
|
+
(item) => item.id.type === AST_NODE_TYPES73.Identifier ? [{ name: item.id.name, node: item }] : []
|
|
17258
17687
|
);
|
|
17259
17688
|
}
|
|
17260
17689
|
var sole_export_matches_filename_default = createRule({
|
|
@@ -17278,31 +17707,31 @@ var sole_export_matches_filename_default = createRule({
|
|
|
17278
17707
|
const exports = [];
|
|
17279
17708
|
const publicExports = /* @__PURE__ */ new Set();
|
|
17280
17709
|
for (const statement of program.body) {
|
|
17281
|
-
if (statement.type ===
|
|
17282
|
-
if (statement.type ===
|
|
17710
|
+
if (statement.type === AST_NODE_TYPES73.ExportAllDeclaration || statement.type === AST_NODE_TYPES73.ExportNamedDeclaration && statement.source !== null) return;
|
|
17711
|
+
if (statement.type === AST_NODE_TYPES73.ExportDefaultDeclaration) {
|
|
17283
17712
|
publicExports.add("default");
|
|
17284
17713
|
const declaration2 = statement.declaration;
|
|
17285
|
-
if ((declaration2.type ===
|
|
17714
|
+
if ((declaration2.type === AST_NODE_TYPES73.ClassDeclaration || declaration2.type === AST_NODE_TYPES73.FunctionDeclaration) && declaration2.id !== null) exports.push({ name: declaration2.id.name, node: declaration2 });
|
|
17286
17715
|
else return;
|
|
17287
17716
|
}
|
|
17288
|
-
if (statement.type !==
|
|
17717
|
+
if (statement.type !== AST_NODE_TYPES73.ExportNamedDeclaration) continue;
|
|
17289
17718
|
const declaration = statement.declaration;
|
|
17290
|
-
if (declaration !== null && "id" in declaration && declaration.id?.type ===
|
|
17719
|
+
if (declaration !== null && "id" in declaration && declaration.id?.type === AST_NODE_TYPES73.Identifier) {
|
|
17291
17720
|
publicExports.add(declaration.id.name);
|
|
17292
17721
|
}
|
|
17293
|
-
if (declaration?.type ===
|
|
17722
|
+
if (declaration?.type === AST_NODE_TYPES73.VariableDeclaration) {
|
|
17294
17723
|
for (const item of declaration.declarations) {
|
|
17295
|
-
if (item.id.type ===
|
|
17724
|
+
if (item.id.type === AST_NODE_TYPES73.Identifier) publicExports.add(item.id.name);
|
|
17296
17725
|
}
|
|
17297
17726
|
}
|
|
17298
17727
|
for (const specifier of statement.specifiers) {
|
|
17299
|
-
const exported = specifier.exported.type ===
|
|
17728
|
+
const exported = specifier.exported.type === AST_NODE_TYPES73.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
17300
17729
|
publicExports.add(String(exported));
|
|
17301
17730
|
}
|
|
17302
17731
|
if (statement.exportKind === "type") continue;
|
|
17303
17732
|
exports.push(...declarationExport(statement));
|
|
17304
17733
|
for (const specifier of statement.specifiers) {
|
|
17305
|
-
const exported = specifier.exported.type ===
|
|
17734
|
+
const exported = specifier.exported.type === AST_NODE_TYPES73.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
17306
17735
|
publicExports.add(String(exported));
|
|
17307
17736
|
if (specifier.exportKind === "type") continue;
|
|
17308
17737
|
if (exported === "default") exports.push({ name: specifier.local.name, node: specifier });
|
|
@@ -17361,8 +17790,8 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
17361
17790
|
|
|
17362
17791
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
17363
17792
|
import {
|
|
17364
|
-
AST_NODE_TYPES as
|
|
17365
|
-
ASTUtils as
|
|
17793
|
+
AST_NODE_TYPES as AST_NODE_TYPES74,
|
|
17794
|
+
ASTUtils as ASTUtils24
|
|
17366
17795
|
} from "@typescript-eslint/utils";
|
|
17367
17796
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
17368
17797
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
@@ -17495,18 +17924,18 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
|
17495
17924
|
"superRefine",
|
|
17496
17925
|
"transform"
|
|
17497
17926
|
]);
|
|
17498
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
17927
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES74.Identifier ? callee.property.name : null;
|
|
17499
17928
|
var calleeChainRoot = (node) => {
|
|
17500
17929
|
let current = node;
|
|
17501
17930
|
for (; ; ) {
|
|
17502
|
-
if (current.type ===
|
|
17931
|
+
if (current.type === AST_NODE_TYPES74.Identifier) {
|
|
17503
17932
|
return current;
|
|
17504
17933
|
}
|
|
17505
|
-
if (current.type ===
|
|
17934
|
+
if (current.type === AST_NODE_TYPES74.MemberExpression) {
|
|
17506
17935
|
current = current.object;
|
|
17507
17936
|
continue;
|
|
17508
17937
|
}
|
|
17509
|
-
if (current.type ===
|
|
17938
|
+
if (current.type === AST_NODE_TYPES74.CallExpression) {
|
|
17510
17939
|
current = current.callee;
|
|
17511
17940
|
continue;
|
|
17512
17941
|
}
|
|
@@ -17517,13 +17946,13 @@ var chainMemberNames = (node) => {
|
|
|
17517
17946
|
const names = [];
|
|
17518
17947
|
let current = node;
|
|
17519
17948
|
for (; ; ) {
|
|
17520
|
-
if (current.type ===
|
|
17521
|
-
if (current.computed || current.property.type !==
|
|
17949
|
+
if (current.type === AST_NODE_TYPES74.MemberExpression) {
|
|
17950
|
+
if (current.computed || current.property.type !== AST_NODE_TYPES74.Identifier) return [];
|
|
17522
17951
|
names.push(current.property.name);
|
|
17523
17952
|
current = current.object;
|
|
17524
17953
|
continue;
|
|
17525
17954
|
}
|
|
17526
|
-
if (current.type ===
|
|
17955
|
+
if (current.type === AST_NODE_TYPES74.CallExpression) {
|
|
17527
17956
|
current = current.callee;
|
|
17528
17957
|
continue;
|
|
17529
17958
|
}
|
|
@@ -17534,16 +17963,16 @@ var chainMemberNames = (node) => {
|
|
|
17534
17963
|
};
|
|
17535
17964
|
var unwrapExpression4 = (node) => {
|
|
17536
17965
|
let current = node;
|
|
17537
|
-
while (current.type ===
|
|
17966
|
+
while (current.type === AST_NODE_TYPES74.TSAsExpression || current.type === AST_NODE_TYPES74.TSSatisfiesExpression || current.type === AST_NODE_TYPES74.TSNonNullExpression || current.type === AST_NODE_TYPES74.TSTypeAssertion) {
|
|
17538
17967
|
current = current.expression;
|
|
17539
17968
|
}
|
|
17540
17969
|
return current;
|
|
17541
17970
|
};
|
|
17542
17971
|
var isModuleDeclarator = (node) => {
|
|
17543
17972
|
const declaration = node.parent;
|
|
17544
|
-
if (declaration.type !==
|
|
17973
|
+
if (declaration.type !== AST_NODE_TYPES74.VariableDeclaration) return false;
|
|
17545
17974
|
const owner = declaration.parent;
|
|
17546
|
-
return owner.type ===
|
|
17975
|
+
return owner.type === AST_NODE_TYPES74.Program || owner.type === AST_NODE_TYPES74.ExportNamedDeclaration && owner.parent.type === AST_NODE_TYPES74.Program;
|
|
17547
17976
|
};
|
|
17548
17977
|
var require_pascal_case_zod_schema_name_default = createRule({
|
|
17549
17978
|
name: "require-pascal-case-zod-schema-name",
|
|
@@ -17563,7 +17992,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17563
17992
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
17564
17993
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
17565
17994
|
function resolvedBinding(identifier) {
|
|
17566
|
-
return
|
|
17995
|
+
return ASTUtils24.findVariable(
|
|
17567
17996
|
context.sourceCode.getScope(identifier),
|
|
17568
17997
|
identifier.name
|
|
17569
17998
|
);
|
|
@@ -17584,8 +18013,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17584
18013
|
}
|
|
17585
18014
|
function isConfirmedSchema(expression) {
|
|
17586
18015
|
const init = unwrapExpression4(expression);
|
|
17587
|
-
if (init.type ===
|
|
17588
|
-
if (init.type !==
|
|
18016
|
+
if (init.type === AST_NODE_TYPES74.Identifier) return isSchemaBinding(init);
|
|
18017
|
+
if (init.type !== AST_NODE_TYPES74.CallExpression || init.callee.type !== AST_NODE_TYPES74.MemberExpression) {
|
|
17589
18018
|
return false;
|
|
17590
18019
|
}
|
|
17591
18020
|
const terminal = terminalMethodName(init.callee);
|
|
@@ -17605,7 +18034,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17605
18034
|
ImportDeclaration(node) {
|
|
17606
18035
|
if (!isZodModule(node.source.value)) return;
|
|
17607
18036
|
for (const specifier of node.specifiers) {
|
|
17608
|
-
if (specifier.type ===
|
|
18037
|
+
if (specifier.type === AST_NODE_TYPES74.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES74.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES74.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES74.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
|
|
17609
18038
|
recordZodBinding(specifier.local);
|
|
17610
18039
|
}
|
|
17611
18040
|
}
|
|
@@ -17614,7 +18043,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17614
18043
|
if (!isModuleDeclarator(node)) return;
|
|
17615
18044
|
const init = node.init;
|
|
17616
18045
|
if (init === null || init === void 0) return;
|
|
17617
|
-
if (node.id.type !==
|
|
18046
|
+
if (node.id.type !== AST_NODE_TYPES74.Identifier) return;
|
|
17618
18047
|
if (!isConfirmedSchema(init)) return;
|
|
17619
18048
|
const binding = resolvedBinding(node.id);
|
|
17620
18049
|
if (binding !== null) schemaBindings.add(binding);
|
|
@@ -17789,6 +18218,7 @@ var RULES = {
|
|
|
17789
18218
|
"prefer-zod-infer": prefer_zod_infer_default,
|
|
17790
18219
|
"require-assert-never": require_assert_never_default,
|
|
17791
18220
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
18221
|
+
"require-interface-for-exported-class": require_interface_for_exported_class_default,
|
|
17792
18222
|
"require-port-for-service": require_port_for_service_default,
|
|
17793
18223
|
"require-sql-access-class": require_sql_access_class_default,
|
|
17794
18224
|
"require-static-next-matcher": require_static_next_matcher_default,
|
|
@@ -17801,7 +18231,7 @@ var RULES = {
|
|
|
17801
18231
|
};
|
|
17802
18232
|
var meta = {
|
|
17803
18233
|
name: "@sarj/eslint-plugin",
|
|
17804
|
-
version: "15.
|
|
18234
|
+
version: "15.16.0"
|
|
17805
18235
|
};
|
|
17806
18236
|
var APPLICATION_ONLY_RULES = [
|
|
17807
18237
|
"no-restricted-library-load",
|
|
@@ -17811,8 +18241,10 @@ var APPLICATION_ONLY_RULES = [
|
|
|
17811
18241
|
var ADVISORY_RULES = [
|
|
17812
18242
|
"@sarj/prefer-named-complex-return-type",
|
|
17813
18243
|
"@sarj/prefer-node-crypto-hash",
|
|
18244
|
+
"@sarj/prefer-node-fs-promises",
|
|
17814
18245
|
"@sarj/prefer-shared-zod-enum",
|
|
17815
18246
|
"@sarj/prefer-switch-for-repeated-equality",
|
|
18247
|
+
"@sarj/require-interface-for-exported-class",
|
|
17816
18248
|
"@sarj/require-pascal-case-zod-schema-name",
|
|
17817
18249
|
"@sarj/require-sql-access-class",
|
|
17818
18250
|
"@sarj/sole-export-matches-filename"
|
|
@@ -17872,7 +18304,7 @@ var RECOMMENDED_RULES = {
|
|
|
17872
18304
|
"@sarj/prefer-module-level-schema": "error",
|
|
17873
18305
|
"@sarj/prefer-named-complex-return-type": "warn",
|
|
17874
18306
|
"@sarj/prefer-node-crypto-hash": "warn",
|
|
17875
|
-
"@sarj/prefer-node-fs-promises": "
|
|
18307
|
+
"@sarj/prefer-node-fs-promises": "warn",
|
|
17876
18308
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17877
18309
|
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17878
18310
|
"@sarj/prefer-await-in-async-return": "error",
|
|
@@ -17886,6 +18318,7 @@ var RECOMMENDED_RULES = {
|
|
|
17886
18318
|
"@sarj/prefer-zod-infer": "error",
|
|
17887
18319
|
"@sarj/require-assert-never": "error",
|
|
17888
18320
|
"@sarj/require-fetch-timeout": "error",
|
|
18321
|
+
"@sarj/require-interface-for-exported-class": "warn",
|
|
17889
18322
|
"@sarj/require-port-for-service": "error",
|
|
17890
18323
|
"@sarj/require-sql-access-class": "warn",
|
|
17891
18324
|
"@sarj/require-static-next-matcher": "error",
|
|
@@ -17958,7 +18391,7 @@ var STRICT_RULES = {
|
|
|
17958
18391
|
"@sarj/prefer-module-level-schema": "error",
|
|
17959
18392
|
"@sarj/prefer-named-complex-return-type": "warn",
|
|
17960
18393
|
"@sarj/prefer-node-crypto-hash": "warn",
|
|
17961
|
-
"@sarj/prefer-node-fs-promises": "
|
|
18394
|
+
"@sarj/prefer-node-fs-promises": "warn",
|
|
17962
18395
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17963
18396
|
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17964
18397
|
"@sarj/prefer-await-in-async-return": "error",
|
|
@@ -17972,6 +18405,7 @@ var STRICT_RULES = {
|
|
|
17972
18405
|
"@sarj/prefer-zod-infer": "error",
|
|
17973
18406
|
"@sarj/require-assert-never": "error",
|
|
17974
18407
|
"@sarj/require-fetch-timeout": "error",
|
|
18408
|
+
"@sarj/require-interface-for-exported-class": "warn",
|
|
17975
18409
|
"@sarj/require-port-for-service": "error",
|
|
17976
18410
|
"@sarj/require-sql-access-class": "warn",
|
|
17977
18411
|
"@sarj/require-static-next-matcher": "error",
|