@sarj/eslint-plugin 15.13.3 → 15.15.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 +1395 -668
- package/dist/index.d.cts +35 -3
- package/dist/index.d.ts +35 -3
- package/dist/index.js +1398 -667
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1274,8 +1274,8 @@ function testCallMatrixStems(comments) {
|
|
|
1274
1274
|
const stems = /* @__PURE__ */ new Set();
|
|
1275
1275
|
for (const comment of comments) {
|
|
1276
1276
|
const body2 = stripCommentMarker(comment.value);
|
|
1277
|
-
const
|
|
1278
|
-
if (
|
|
1277
|
+
const stem4 = CALL_LABEL_RE.exec(body2)?.[1];
|
|
1278
|
+
if (stem4 !== void 0 && MULTIPLIER_PSEUDOCODE_RE.test(body2)) stems.add(stem4);
|
|
1279
1279
|
}
|
|
1280
1280
|
return stems;
|
|
1281
1281
|
}
|
|
@@ -4924,8 +4924,8 @@ var CJS_OBJECT_EXPORT_METHODS = /* @__PURE__ */ new Set(["assign", "defineProper
|
|
|
4924
4924
|
function fileParts(filename) {
|
|
4925
4925
|
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
4926
4926
|
const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
|
|
4927
|
-
const [
|
|
4928
|
-
return { stem:
|
|
4927
|
+
const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
|
|
4928
|
+
return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
|
|
4929
4929
|
}
|
|
4930
4930
|
function declaredNames(declaration) {
|
|
4931
4931
|
if (declaration.declare === true) return [];
|
|
@@ -5049,8 +5049,8 @@ var no_generic_single_export_module_default = createRule({
|
|
|
5049
5049
|
defaultOptions: [],
|
|
5050
5050
|
create(context) {
|
|
5051
5051
|
const file = fileParts(context.filename);
|
|
5052
|
-
const { stem:
|
|
5053
|
-
if (!GENERIC_STEMS.has(
|
|
5052
|
+
const { stem: stem4 } = file;
|
|
5053
|
+
if (!GENERIC_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
5054
5054
|
let hasCommonJsExport = false;
|
|
5055
5055
|
return {
|
|
5056
5056
|
CallExpression(node) {
|
|
@@ -5070,12 +5070,12 @@ var no_generic_single_export_module_default = createRule({
|
|
|
5070
5070
|
const { name: exported, node } = onlyExport;
|
|
5071
5071
|
if (isConventionalFrameworkUtility(context.filename, exported)) return;
|
|
5072
5072
|
const exportedRole = exported.replaceAll(/[^a-z0-9]/giu, "").toLowerCase();
|
|
5073
|
-
const pathRole = [
|
|
5073
|
+
const pathRole = [stem4, ...file.suffixes].join("").replaceAll(/[^a-z0-9]/giu, "");
|
|
5074
5074
|
if (exportedRole === pathRole && file.suffixes.length > 0) return;
|
|
5075
5075
|
context.report({
|
|
5076
5076
|
node,
|
|
5077
5077
|
messageId: "genericSingleExport",
|
|
5078
|
-
data: { stem:
|
|
5078
|
+
data: { stem: stem4, exported }
|
|
5079
5079
|
});
|
|
5080
5080
|
}
|
|
5081
5081
|
};
|
|
@@ -5392,7 +5392,7 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5392
5392
|
const aliases = typeAliases(context.sourceCode.ast);
|
|
5393
5393
|
const reportedFunctions = /* @__PURE__ */ new WeakSet();
|
|
5394
5394
|
const functionStack = [];
|
|
5395
|
-
const
|
|
5395
|
+
const report2 = (annotation, name) => {
|
|
5396
5396
|
const tuple = tupleReturnType(annotation, aliases);
|
|
5397
5397
|
if (tuple === null || tuple.elementTypes.length < MIN_ELEMENTS) return;
|
|
5398
5398
|
context.report({
|
|
@@ -5426,7 +5426,7 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5426
5426
|
if (name === null) {
|
|
5427
5427
|
return;
|
|
5428
5428
|
}
|
|
5429
|
-
|
|
5429
|
+
report2(annotation, name);
|
|
5430
5430
|
};
|
|
5431
5431
|
const enterFunction = (node) => {
|
|
5432
5432
|
functionStack.push(node);
|
|
@@ -5451,34 +5451,34 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5451
5451
|
},
|
|
5452
5452
|
TSDeclareFunction(node) {
|
|
5453
5453
|
if (node.id === null || node.returnType === void 0 || node.parent.type !== import_utils28.AST_NODE_TYPES.ExportNamedDeclaration && node.parent.type !== import_utils28.AST_NODE_TYPES.ExportDefaultDeclaration && !specifierExports.has(node.id.name)) return;
|
|
5454
|
-
|
|
5454
|
+
report2(node.returnType.typeAnnotation, node.id.name);
|
|
5455
5455
|
},
|
|
5456
5456
|
TSCallSignatureDeclaration(node) {
|
|
5457
5457
|
const owner = owningInterface(node);
|
|
5458
5458
|
if (owner === null || !isExportedInterface(owner, typeExports) || node.returnType === void 0) return;
|
|
5459
|
-
|
|
5459
|
+
report2(node.returnType.typeAnnotation, `${owner.id.name}.call`);
|
|
5460
5460
|
},
|
|
5461
5461
|
TSMethodSignature(node) {
|
|
5462
5462
|
const owner = owningInterface(node);
|
|
5463
5463
|
const alias = owningTypeAlias(node);
|
|
5464
|
-
const
|
|
5465
|
-
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 ||
|
|
5466
|
-
|
|
5464
|
+
const memberName5 = staticMemberName3(node.key);
|
|
5465
|
+
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 || memberName5 === null) return;
|
|
5466
|
+
report2(node.returnType.typeAnnotation, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName5}`);
|
|
5467
5467
|
},
|
|
5468
5468
|
TSTypeAliasDeclaration(node) {
|
|
5469
5469
|
if (!typeExports.has(node.id.name)) return;
|
|
5470
5470
|
const returnType = callableReturnType(node.typeAnnotation, aliases);
|
|
5471
|
-
if (returnType !== null)
|
|
5471
|
+
if (returnType !== null) report2(returnType, node.id.name);
|
|
5472
5472
|
},
|
|
5473
5473
|
TSPropertySignature(node) {
|
|
5474
5474
|
const owner = owningInterface(node);
|
|
5475
5475
|
const alias = owningTypeAlias(node);
|
|
5476
5476
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
5477
|
-
const
|
|
5478
|
-
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) ||
|
|
5477
|
+
const memberName5 = staticMemberName3(node.key);
|
|
5478
|
+
if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || memberName5 === null || annotation === void 0) return;
|
|
5479
5479
|
const returnType = callableReturnType(annotation, aliases);
|
|
5480
5480
|
if (returnType !== null) {
|
|
5481
|
-
|
|
5481
|
+
report2(returnType, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName5}`);
|
|
5482
5482
|
}
|
|
5483
5483
|
},
|
|
5484
5484
|
PropertyDefinition(node) {
|
|
@@ -5489,7 +5489,7 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5489
5489
|
const returnType = callableReturnType(annotation, aliases);
|
|
5490
5490
|
if (returnType !== null) {
|
|
5491
5491
|
const name = node.key.type === import_utils28.AST_NODE_TYPES.Identifier ? node.key.name : "property";
|
|
5492
|
-
|
|
5492
|
+
report2(returnType, name);
|
|
5493
5493
|
}
|
|
5494
5494
|
}
|
|
5495
5495
|
};
|
|
@@ -5965,7 +5965,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
5965
5965
|
defaultOptions: [{ libraries: [] }],
|
|
5966
5966
|
create(context, [options]) {
|
|
5967
5967
|
const restrictions = options.libraries;
|
|
5968
|
-
function
|
|
5968
|
+
function report2(node, source) {
|
|
5969
5969
|
const restriction = restrictions.find(
|
|
5970
5970
|
(entry) => matchesModule(source, entry.module)
|
|
5971
5971
|
);
|
|
@@ -5991,7 +5991,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
5991
5991
|
return {
|
|
5992
5992
|
ImportExpression(node) {
|
|
5993
5993
|
const source = literalModule(node.source);
|
|
5994
|
-
if (source !== null)
|
|
5994
|
+
if (source !== null) report2(node.source, source);
|
|
5995
5995
|
},
|
|
5996
5996
|
CallExpression(node) {
|
|
5997
5997
|
let requireIdentifier = null;
|
|
@@ -6002,12 +6002,12 @@ var no_restricted_library_load_default = createRule({
|
|
|
6002
6002
|
}
|
|
6003
6003
|
if (requireIdentifier === null || !isUnshadowedRequire(requireIdentifier)) return;
|
|
6004
6004
|
const source = literalModule(node.arguments[0]);
|
|
6005
|
-
if (source !== null)
|
|
6005
|
+
if (source !== null) report2(node.arguments[0], source);
|
|
6006
6006
|
},
|
|
6007
6007
|
TSImportEqualsDeclaration(node) {
|
|
6008
6008
|
if (node.moduleReference.type !== import_utils32.AST_NODE_TYPES.TSExternalModuleReference) return;
|
|
6009
6009
|
const source = literalModule(node.moduleReference.expression);
|
|
6010
|
-
if (source !== null)
|
|
6010
|
+
if (source !== null) report2(node.moduleReference.expression, source);
|
|
6011
6011
|
}
|
|
6012
6012
|
};
|
|
6013
6013
|
}
|
|
@@ -7823,7 +7823,7 @@ var no_sleep_in_test_body_default = createRule({
|
|
|
7823
7823
|
if (!isTestFile(context.filename)) {
|
|
7824
7824
|
return {};
|
|
7825
7825
|
}
|
|
7826
|
-
const
|
|
7826
|
+
const report2 = (node) => {
|
|
7827
7827
|
if (!isImmediatelyConsumedSleep(node)) {
|
|
7828
7828
|
return;
|
|
7829
7829
|
}
|
|
@@ -7836,12 +7836,12 @@ var no_sleep_in_test_body_default = createRule({
|
|
|
7836
7836
|
return {
|
|
7837
7837
|
NewExpression(node) {
|
|
7838
7838
|
if (isPromiseSleep(node)) {
|
|
7839
|
-
|
|
7839
|
+
report2(node);
|
|
7840
7840
|
}
|
|
7841
7841
|
},
|
|
7842
7842
|
CallExpression(node) {
|
|
7843
7843
|
if (isHelperSleep(node)) {
|
|
7844
|
-
|
|
7844
|
+
report2(node);
|
|
7845
7845
|
}
|
|
7846
7846
|
}
|
|
7847
7847
|
};
|
|
@@ -10282,7 +10282,7 @@ function reportClass2(context, services, owner) {
|
|
|
10282
10282
|
}
|
|
10283
10283
|
function isConvertible(member) {
|
|
10284
10284
|
if (member.type !== import_utils58.AST_NODE_TYPES.MethodDefinition && member.type !== import_utils58.AST_NODE_TYPES.PropertyDefinition && member.type !== import_utils58.AST_NODE_TYPES.AccessorProperty) return false;
|
|
10285
|
-
return member.accessibility === "private" && !member.computed && member.key.type === import_utils58.AST_NODE_TYPES.Identifier && member.decorators.length === 0 && !("declare" in member && member.declare) && !member.override && !(member.type === import_utils58.AST_NODE_TYPES.MethodDefinition && member.value.body === null);
|
|
10285
|
+
return member.accessibility === "private" && !(member.type === import_utils58.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor") && !member.computed && member.key.type === import_utils58.AST_NODE_TYPES.Identifier && member.decorators.length === 0 && !("declare" in member && member.declare) && !member.override && !(member.type === import_utils58.AST_NODE_TYPES.MethodDefinition && member.value.body === null);
|
|
10286
10286
|
}
|
|
10287
10287
|
var prefer_ecmascript_private_members_default = createRule({
|
|
10288
10288
|
name: "prefer-ecmascript-private-members",
|
|
@@ -10480,9 +10480,9 @@ var INPUT_MODULE = /(?:^|\/)components\/ui\/input$/u;
|
|
|
10480
10480
|
var INPUT_GROUP_MODULE = /(?:^|\/)components\/ui\/input-group$/u;
|
|
10481
10481
|
var MAX_JSX_DISTANCE = 2;
|
|
10482
10482
|
var SEARCH_EXPORTS = ["Search", "SearchIcon", "LucideSearch"];
|
|
10483
|
-
function localNamedImports(node,
|
|
10483
|
+
function localNamedImports(node, importedName7) {
|
|
10484
10484
|
return node.specifiers.filter(
|
|
10485
|
-
(specifier) => specifier.type === import_utils61.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils61.AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value) ===
|
|
10485
|
+
(specifier) => specifier.type === import_utils61.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils61.AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value) === importedName7
|
|
10486
10486
|
).map((specifier) => specifier.local.name);
|
|
10487
10487
|
}
|
|
10488
10488
|
function elementName(node) {
|
|
@@ -11695,8 +11695,67 @@ var prefer_module_level_schema_default = createRule({
|
|
|
11695
11695
|
}
|
|
11696
11696
|
});
|
|
11697
11697
|
|
|
11698
|
-
// src/rules/prefer-
|
|
11698
|
+
// src/rules/prefer-named-complex-return-type.ts
|
|
11699
11699
|
var import_utils66 = require("@typescript-eslint/utils");
|
|
11700
|
+
var PREFER_NAMED_COMPLEX_RETURN_TYPE_DOCUMENTATION = {
|
|
11701
|
+
summary: "Prefer a named contract for structurally complex function return types.",
|
|
11702
|
+
rationale: "A large inline return annotation hides a reusable domain concept and makes signatures difficult to scan.",
|
|
11703
|
+
remediation: "Extract the return annotation to a named type or interface and reference that contract from the signature.",
|
|
11704
|
+
category: "maintainability",
|
|
11705
|
+
limitations: [
|
|
11706
|
+
"Only explicit object types with at least three members and unions with at least three object variants are reported.",
|
|
11707
|
+
"Generic wrappers such as Promise and Readonly are unwrapped one level at a time; inferred return types are outside this rule."
|
|
11708
|
+
],
|
|
11709
|
+
examples: [
|
|
11710
|
+
{ id: "named-result", title: "Name a multi-state result", outcome: "no-match", files: [{ path: "src/queue.ts", source: "type ClaimResult = { state: 'idle' } | { state: 'waiting'; retryAt: number } | { state: 'claimed'; id: string }; export function claim(): ClaimResult { return { state: 'idle' }; }" }], focusPath: "src/queue.ts", expectedCount: 0, public: true },
|
|
11711
|
+
{ id: "inline-result", title: "Do not inline a multi-state result", outcome: "match", files: [{ path: "src/queue.ts", source: "export function claim(): { state: 'idle' } | { state: 'waiting'; retryAt: number } | { state: 'claimed'; id: string } { return { state: 'idle' }; }" }], focusPath: "src/queue.ts", expectedCount: 1, public: true }
|
|
11712
|
+
]
|
|
11713
|
+
};
|
|
11714
|
+
function unwrap4(node) {
|
|
11715
|
+
if (node.type === import_utils66.AST_NODE_TYPES.TSTypeReference && node.typeArguments?.params.length === 1) {
|
|
11716
|
+
const [inner] = node.typeArguments.params;
|
|
11717
|
+
if (inner !== void 0) return unwrap4(inner);
|
|
11718
|
+
}
|
|
11719
|
+
return node;
|
|
11720
|
+
}
|
|
11721
|
+
function report(context, node) {
|
|
11722
|
+
const annotation = node.returnType?.typeAnnotation;
|
|
11723
|
+
if (annotation !== void 0 && isComplex(annotation)) {
|
|
11724
|
+
context.report({ node: annotation, messageId: "nameComplexReturnType" });
|
|
11725
|
+
}
|
|
11726
|
+
}
|
|
11727
|
+
function isComplex(node) {
|
|
11728
|
+
const type = unwrap4(node);
|
|
11729
|
+
if (type.type === import_utils66.AST_NODE_TYPES.TSTypeLiteral) return type.members.length >= 3;
|
|
11730
|
+
if (type.type !== import_utils66.AST_NODE_TYPES.TSUnionType || type.types.length < 3) return false;
|
|
11731
|
+
return type.types.every((member) => unwrap4(member).type === import_utils66.AST_NODE_TYPES.TSTypeLiteral);
|
|
11732
|
+
}
|
|
11733
|
+
var prefer_named_complex_return_type_default = createRule({
|
|
11734
|
+
name: "prefer-named-complex-return-type",
|
|
11735
|
+
documentation: PREFER_NAMED_COMPLEX_RETURN_TYPE_DOCUMENTATION,
|
|
11736
|
+
meta: {
|
|
11737
|
+
type: "suggestion",
|
|
11738
|
+
docs: { description: "Prefer a named contract for structurally complex function return types." },
|
|
11739
|
+
schema: [],
|
|
11740
|
+
messages: {
|
|
11741
|
+
nameComplexReturnType: "Extract this structurally complex return annotation to a named type or interface."
|
|
11742
|
+
}
|
|
11743
|
+
},
|
|
11744
|
+
defaultOptions: [],
|
|
11745
|
+
create(context) {
|
|
11746
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
11747
|
+
return {
|
|
11748
|
+
ArrowFunctionExpression: (node) => report(context, node),
|
|
11749
|
+
FunctionDeclaration: (node) => report(context, node),
|
|
11750
|
+
FunctionExpression: (node) => report(context, node),
|
|
11751
|
+
TSDeclareFunction: (node) => report(context, node),
|
|
11752
|
+
TSMethodSignature: (node) => report(context, node)
|
|
11753
|
+
};
|
|
11754
|
+
}
|
|
11755
|
+
});
|
|
11756
|
+
|
|
11757
|
+
// src/rules/prefer-native-random-uuid.ts
|
|
11758
|
+
var import_utils67 = require("@typescript-eslint/utils");
|
|
11700
11759
|
var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
|
|
11701
11760
|
summary: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
|
|
11702
11761
|
rationale: "The platform implementation avoids an unnecessary dependency for standard random UUID generation.",
|
|
@@ -11710,7 +11769,7 @@ var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
|
|
|
11710
11769
|
]
|
|
11711
11770
|
};
|
|
11712
11771
|
function requireUuid(node) {
|
|
11713
|
-
return node?.type ===
|
|
11772
|
+
return node?.type === import_utils67.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils67.AST_NODE_TYPES.Identifier && node.callee.name === "require" && node.arguments.length === 1 && node.arguments[0]?.type === import_utils67.AST_NODE_TYPES.Literal && node.arguments[0].value === "uuid";
|
|
11714
11773
|
}
|
|
11715
11774
|
var prefer_native_random_uuid_default = createRule({
|
|
11716
11775
|
name: "prefer-native-random-uuid",
|
|
@@ -11732,13 +11791,13 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
11732
11791
|
const directBindings = /* @__PURE__ */ new Set();
|
|
11733
11792
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
11734
11793
|
function resolve(identifier) {
|
|
11735
|
-
return
|
|
11794
|
+
return import_utils67.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
11736
11795
|
}
|
|
11737
11796
|
function record(identifier, destination) {
|
|
11738
11797
|
const variable = resolve(identifier);
|
|
11739
11798
|
if (variable !== null) destination.add(variable);
|
|
11740
11799
|
}
|
|
11741
|
-
function
|
|
11800
|
+
function report2(node) {
|
|
11742
11801
|
context.report({
|
|
11743
11802
|
node,
|
|
11744
11803
|
messageId: "preferNative",
|
|
@@ -11754,48 +11813,179 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
11754
11813
|
ImportDeclaration(node) {
|
|
11755
11814
|
if (node.source.value !== "uuid") return;
|
|
11756
11815
|
for (const specifier of node.specifiers) {
|
|
11757
|
-
if (specifier.type ===
|
|
11816
|
+
if (specifier.type === import_utils67.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils67.AST_NODE_TYPES.Identifier ? specifier.imported.name === "v4" : specifier.imported.value === "v4")) {
|
|
11758
11817
|
record(specifier.local, directBindings);
|
|
11759
|
-
} else if (specifier.type ===
|
|
11818
|
+
} else if (specifier.type === import_utils67.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
11760
11819
|
record(specifier.local, namespaceBindings);
|
|
11761
11820
|
}
|
|
11762
11821
|
}
|
|
11763
11822
|
},
|
|
11764
11823
|
VariableDeclarator(node) {
|
|
11765
11824
|
if (node.parent.kind !== "const" || !requireUuid(node.init)) return;
|
|
11766
|
-
if (node.init?.type !==
|
|
11825
|
+
if (node.init?.type !== import_utils67.AST_NODE_TYPES.CallExpression || node.init.callee.type !== import_utils67.AST_NODE_TYPES.Identifier || (resolve(node.init.callee)?.defs.length ?? 0) > 0) {
|
|
11767
11826
|
return;
|
|
11768
11827
|
}
|
|
11769
|
-
if (node.id.type ===
|
|
11828
|
+
if (node.id.type === import_utils67.AST_NODE_TYPES.Identifier) {
|
|
11770
11829
|
record(node.id, namespaceBindings);
|
|
11771
11830
|
return;
|
|
11772
11831
|
}
|
|
11773
|
-
if (node.id.type !==
|
|
11832
|
+
if (node.id.type !== import_utils67.AST_NODE_TYPES.ObjectPattern) return;
|
|
11774
11833
|
for (const property of node.id.properties) {
|
|
11775
|
-
if (property.type ===
|
|
11834
|
+
if (property.type === import_utils67.AST_NODE_TYPES.Property && !property.computed && (property.key.type === import_utils67.AST_NODE_TYPES.Identifier && property.key.name === "v4" || property.key.type === import_utils67.AST_NODE_TYPES.Literal && property.key.value === "v4") && property.value.type === import_utils67.AST_NODE_TYPES.Identifier) {
|
|
11776
11835
|
record(property.value, directBindings);
|
|
11777
11836
|
}
|
|
11778
11837
|
}
|
|
11779
11838
|
},
|
|
11780
11839
|
"CallExpression:exit"(node) {
|
|
11781
11840
|
if (node.arguments.length !== 0) return;
|
|
11782
|
-
if (node.callee.type ===
|
|
11841
|
+
if (node.callee.type === import_utils67.AST_NODE_TYPES.Identifier) {
|
|
11783
11842
|
const variable2 = resolve(node.callee);
|
|
11784
|
-
if (variable2 !== null && directBindings.has(variable2))
|
|
11843
|
+
if (variable2 !== null && directBindings.has(variable2)) report2(node);
|
|
11785
11844
|
return;
|
|
11786
11845
|
}
|
|
11787
|
-
if (node.callee.type !==
|
|
11846
|
+
if (node.callee.type !== import_utils67.AST_NODE_TYPES.MemberExpression || node.callee.computed || node.callee.object.type !== import_utils67.AST_NODE_TYPES.Identifier || node.callee.property.type !== import_utils67.AST_NODE_TYPES.Identifier || node.callee.property.name !== "v4") {
|
|
11788
11847
|
return;
|
|
11789
11848
|
}
|
|
11790
11849
|
const variable = resolve(node.callee.object);
|
|
11791
|
-
if (variable !== null && namespaceBindings.has(variable))
|
|
11850
|
+
if (variable !== null && namespaceBindings.has(variable)) report2(node);
|
|
11851
|
+
}
|
|
11852
|
+
};
|
|
11853
|
+
}
|
|
11854
|
+
});
|
|
11855
|
+
|
|
11856
|
+
// src/rules/prefer-node-crypto-hash.ts
|
|
11857
|
+
var import_utils68 = require("@typescript-eslint/utils");
|
|
11858
|
+
var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
|
|
11859
|
+
summary: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
|
|
11860
|
+
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.",
|
|
11861
|
+
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.",
|
|
11862
|
+
category: "performance",
|
|
11863
|
+
limitations: [
|
|
11864
|
+
"Only direct ESM imports and namespace imports from node:crypto are analyzed.",
|
|
11865
|
+
"Only a literal algorithm with exactly one update call is reported; streaming and incremental hashes remain valid."
|
|
11866
|
+
],
|
|
11867
|
+
examples: [
|
|
11868
|
+
{ id: "one-shot-hash", title: "Use Node's one-shot hash API", outcome: "no-match", files: [{ path: "case.ts", source: "import { hash } from 'node:crypto'; export const digest = hash('sha256', 'value', 'hex');" }], focusPath: "case.ts", expectedCount: 0, public: true },
|
|
11869
|
+
{ 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 }
|
|
11870
|
+
]
|
|
11871
|
+
};
|
|
11872
|
+
var prefer_node_crypto_hash_default = createRule({
|
|
11873
|
+
name: "prefer-node-crypto-hash",
|
|
11874
|
+
documentation: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION,
|
|
11875
|
+
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." } },
|
|
11876
|
+
defaultOptions: [],
|
|
11877
|
+
create(context) {
|
|
11878
|
+
const directImports = /* @__PURE__ */ new Set();
|
|
11879
|
+
const namespaceImports = /* @__PURE__ */ new Set();
|
|
11880
|
+
return {
|
|
11881
|
+
ImportDeclaration(node) {
|
|
11882
|
+
if (node.source.value !== "node:crypto") return;
|
|
11883
|
+
for (const specifier of node.specifiers) {
|
|
11884
|
+
if (specifier.type === import_utils68.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
11885
|
+
namespaceImports.add(specifier.local.name);
|
|
11886
|
+
} else if (specifier.type === import_utils68.AST_NODE_TYPES.ImportSpecifier && importedName5(specifier.imported) === "createHash") {
|
|
11887
|
+
directImports.add(specifier.local.name);
|
|
11888
|
+
}
|
|
11889
|
+
}
|
|
11890
|
+
},
|
|
11891
|
+
CallExpression(node) {
|
|
11892
|
+
if (!isMemberCall(node, "digest")) return;
|
|
11893
|
+
const update = node.callee.object;
|
|
11894
|
+
if (update.type !== import_utils68.AST_NODE_TYPES.CallExpression || update.arguments.length !== 1 || !isMemberCall(update, "update"))
|
|
11895
|
+
return;
|
|
11896
|
+
const create = update.callee.object;
|
|
11897
|
+
if (create.type !== import_utils68.AST_NODE_TYPES.CallExpression || create.arguments.length !== 1 || create.arguments[0]?.type !== import_utils68.AST_NODE_TYPES.Literal || typeof create.arguments[0].value !== "string" || !isCreateHashCall(create, directImports, namespaceImports))
|
|
11898
|
+
return;
|
|
11899
|
+
context.report({ node, messageId: "preferNodeCryptoHash" });
|
|
11900
|
+
}
|
|
11901
|
+
};
|
|
11902
|
+
}
|
|
11903
|
+
});
|
|
11904
|
+
function importedName5(node) {
|
|
11905
|
+
return node.type === import_utils68.AST_NODE_TYPES.Identifier ? node.name : node.value;
|
|
11906
|
+
}
|
|
11907
|
+
function isMemberCall(node, name) {
|
|
11908
|
+
return node.callee.type === import_utils68.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils68.AST_NODE_TYPES.Identifier && node.callee.property.name === name;
|
|
11909
|
+
}
|
|
11910
|
+
function isCreateHashCall(node, directImports, namespaceImports) {
|
|
11911
|
+
if (node.callee.type === import_utils68.AST_NODE_TYPES.Identifier)
|
|
11912
|
+
return directImports.has(node.callee.name);
|
|
11913
|
+
return node.callee.type === import_utils68.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.object.type === import_utils68.AST_NODE_TYPES.Identifier && namespaceImports.has(node.callee.object.name) && node.callee.property.type === import_utils68.AST_NODE_TYPES.Identifier && node.callee.property.name === "createHash";
|
|
11914
|
+
}
|
|
11915
|
+
|
|
11916
|
+
// src/rules/prefer-node-fs-promises.ts
|
|
11917
|
+
var import_utils69 = require("@typescript-eslint/utils");
|
|
11918
|
+
var PREFER_NODE_FS_PROMISES_DOCUMENTATION = {
|
|
11919
|
+
summary: "Prefer promise-based Node.js filesystem APIs over synchronous calls in production modules.",
|
|
11920
|
+
rationale: "Synchronous filesystem work blocks the event loop and can stall unrelated daemon, server, and worker tasks.",
|
|
11921
|
+
remediation: "Import the promise API from node:fs/promises and await it; use FileHandle.sync only where a documented durability boundary requires it.",
|
|
11922
|
+
category: "performance",
|
|
11923
|
+
limitations: [
|
|
11924
|
+
"Tests and generated files are excluded.",
|
|
11925
|
+
"ESLint rule implementations under src/rules are excluded because visitor creation and execution are synchronous by contract.",
|
|
11926
|
+
"The rule covers static ESM imports and member calls through namespace/default imports from node:fs; CommonJS require flows are not inferred."
|
|
11927
|
+
],
|
|
11928
|
+
examples: [
|
|
11929
|
+
{ 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 },
|
|
11930
|
+
{ 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 }
|
|
11931
|
+
]
|
|
11932
|
+
};
|
|
11933
|
+
function memberName3(node) {
|
|
11934
|
+
if (!node.computed && node.property.type === import_utils69.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
11935
|
+
if (node.computed && node.property.type === import_utils69.AST_NODE_TYPES.Literal && typeof node.property.value === "string") {
|
|
11936
|
+
return node.property.value;
|
|
11937
|
+
}
|
|
11938
|
+
return null;
|
|
11939
|
+
}
|
|
11940
|
+
var prefer_node_fs_promises_default = createRule({
|
|
11941
|
+
name: "prefer-node-fs-promises",
|
|
11942
|
+
documentation: PREFER_NODE_FS_PROMISES_DOCUMENTATION,
|
|
11943
|
+
meta: {
|
|
11944
|
+
type: "suggestion",
|
|
11945
|
+
docs: { description: "Prefer promise-based Node.js filesystem APIs over synchronous calls in production modules." },
|
|
11946
|
+
schema: [],
|
|
11947
|
+
messages: {
|
|
11948
|
+
preferAsyncFs: "Node filesystem API `{{name}}` is synchronous; use the promise API and await it."
|
|
11949
|
+
}
|
|
11950
|
+
},
|
|
11951
|
+
defaultOptions: [],
|
|
11952
|
+
create(context) {
|
|
11953
|
+
const normalizedFilename = context.filename.replaceAll("\\", "/");
|
|
11954
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text) || normalizedFilename.includes("src/rules/"))
|
|
11955
|
+
return {};
|
|
11956
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
11957
|
+
return {
|
|
11958
|
+
ImportDeclaration(node) {
|
|
11959
|
+
if (node.source.value !== "node:fs" && node.source.value !== "fs") return;
|
|
11960
|
+
const synchronousImports = [];
|
|
11961
|
+
for (const specifier of node.specifiers) {
|
|
11962
|
+
if (specifier.type === import_utils69.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils69.AST_NODE_TYPES.ImportDefaultSpecifier) {
|
|
11963
|
+
namespaces.add(specifier.local.name);
|
|
11964
|
+
continue;
|
|
11965
|
+
}
|
|
11966
|
+
if (specifier.type === import_utils69.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === import_utils69.AST_NODE_TYPES.Identifier && specifier.imported.name.endsWith("Sync")) synchronousImports.push(specifier.imported.name);
|
|
11967
|
+
}
|
|
11968
|
+
if (synchronousImports.length > 0) {
|
|
11969
|
+
context.report({
|
|
11970
|
+
node,
|
|
11971
|
+
messageId: "preferAsyncFs",
|
|
11972
|
+
data: { name: synchronousImports.join(", ") }
|
|
11973
|
+
});
|
|
11974
|
+
}
|
|
11975
|
+
},
|
|
11976
|
+
MemberExpression(node) {
|
|
11977
|
+
if (node.object.type !== import_utils69.AST_NODE_TYPES.Identifier || !namespaces.has(node.object.name)) return;
|
|
11978
|
+
const name = memberName3(node);
|
|
11979
|
+
if (name?.endsWith("Sync") === true) {
|
|
11980
|
+
context.report({ node, messageId: "preferAsyncFs", data: { name } });
|
|
11981
|
+
}
|
|
11792
11982
|
}
|
|
11793
11983
|
};
|
|
11794
11984
|
}
|
|
11795
11985
|
});
|
|
11796
11986
|
|
|
11797
11987
|
// src/rules/prefer-non-nullable-collection.ts
|
|
11798
|
-
var
|
|
11988
|
+
var import_utils70 = require("@typescript-eslint/utils");
|
|
11799
11989
|
var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
11800
11990
|
summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
|
|
11801
11991
|
rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
|
|
@@ -11811,33 +12001,33 @@ var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
|
11811
12001
|
function propertyName3(node) {
|
|
11812
12002
|
const key = node.key;
|
|
11813
12003
|
if (node.computed) return null;
|
|
11814
|
-
if (key.type ===
|
|
11815
|
-
if (key.type ===
|
|
12004
|
+
if (key.type === import_utils70.AST_NODE_TYPES.Identifier) return key.name;
|
|
12005
|
+
if (key.type === import_utils70.AST_NODE_TYPES.Literal && typeof key.value === "string") return key.value;
|
|
11816
12006
|
return null;
|
|
11817
12007
|
}
|
|
11818
12008
|
function isArrayType(node) {
|
|
11819
|
-
if (node.type ===
|
|
11820
|
-
return node.type ===
|
|
12009
|
+
if (node.type === import_utils70.AST_NODE_TYPES.TSArrayType) return true;
|
|
12010
|
+
return node.type === import_utils70.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils70.AST_NODE_TYPES.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
11821
12011
|
}
|
|
11822
12012
|
function nullableProperty(node) {
|
|
11823
12013
|
if (node.optional) return null;
|
|
11824
12014
|
const name = propertyName3(node);
|
|
11825
12015
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
11826
|
-
if (name === null || annotation?.type !==
|
|
12016
|
+
if (name === null || annotation?.type !== import_utils70.AST_NODE_TYPES.TSUnionType) return null;
|
|
11827
12017
|
const concrete = annotation.types.filter(
|
|
11828
|
-
(member) => member.type !==
|
|
12018
|
+
(member) => member.type !== import_utils70.AST_NODE_TYPES.TSNullKeyword && member.type !== import_utils70.AST_NODE_TYPES.TSUndefinedKeyword
|
|
11829
12019
|
);
|
|
11830
12020
|
if (concrete.length === 0 || !concrete.every(isArrayType)) return null;
|
|
11831
|
-
const acceptsNull = annotation.types.some((member) => member.type ===
|
|
12021
|
+
const acceptsNull = annotation.types.some((member) => member.type === import_utils70.AST_NODE_TYPES.TSNullKeyword);
|
|
11832
12022
|
const acceptsUndefined = annotation.types.some(
|
|
11833
|
-
(member) => member.type ===
|
|
12023
|
+
(member) => member.type === import_utils70.AST_NODE_TYPES.TSUndefinedKeyword
|
|
11834
12024
|
);
|
|
11835
12025
|
if (!acceptsNull && !acceptsUndefined) return null;
|
|
11836
12026
|
return { name, node, acceptsNull, acceptsUndefined };
|
|
11837
12027
|
}
|
|
11838
12028
|
function shapeProperties(members) {
|
|
11839
12029
|
return members.flatMap((member) => {
|
|
11840
|
-
if (member.type !==
|
|
12030
|
+
if (member.type !== import_utils70.AST_NODE_TYPES.TSPropertySignature) return [];
|
|
11841
12031
|
const property = nullableProperty(member);
|
|
11842
12032
|
return property === null ? [] : [property];
|
|
11843
12033
|
});
|
|
@@ -11845,14 +12035,14 @@ function shapeProperties(members) {
|
|
|
11845
12035
|
function typeIndex(program) {
|
|
11846
12036
|
const index = /* @__PURE__ */ new Map();
|
|
11847
12037
|
for (const statement of program.body) {
|
|
11848
|
-
const exported = statement.type ===
|
|
12038
|
+
const exported = statement.type === import_utils70.AST_NODE_TYPES.ExportNamedDeclaration;
|
|
11849
12039
|
const declaration = exported ? statement.declaration : statement;
|
|
11850
|
-
if (declaration?.type ===
|
|
12040
|
+
if (declaration?.type === import_utils70.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
11851
12041
|
index.set(declaration.id.name, {
|
|
11852
12042
|
exported,
|
|
11853
12043
|
properties: shapeProperties(declaration.body.body)
|
|
11854
12044
|
});
|
|
11855
|
-
} else if (declaration?.type ===
|
|
12045
|
+
} else if (declaration?.type === import_utils70.AST_NODE_TYPES.TSTypeAliasDeclaration && declaration.typeAnnotation.type === import_utils70.AST_NODE_TYPES.TSTypeLiteral) {
|
|
11856
12046
|
index.set(declaration.id.name, {
|
|
11857
12047
|
exported,
|
|
11858
12048
|
properties: shapeProperties(declaration.typeAnnotation.members)
|
|
@@ -11862,42 +12052,42 @@ function typeIndex(program) {
|
|
|
11862
12052
|
return index;
|
|
11863
12053
|
}
|
|
11864
12054
|
function emptyArray(node) {
|
|
11865
|
-
return node.type ===
|
|
12055
|
+
return node.type === import_utils70.AST_NODE_TYPES.ArrayExpression && node.elements.length === 0;
|
|
11866
12056
|
}
|
|
11867
12057
|
function sameAccess(node, access) {
|
|
11868
12058
|
if (access.kind === "identifier") {
|
|
11869
|
-
return node.type ===
|
|
12059
|
+
return node.type === import_utils70.AST_NODE_TYPES.Identifier && node.name === access.name;
|
|
11870
12060
|
}
|
|
11871
|
-
return node.type ===
|
|
12061
|
+
return node.type === import_utils70.AST_NODE_TYPES.MemberExpression && !node.computed && node.object.type === import_utils70.AST_NODE_TYPES.Identifier && node.object.name === access.object && node.property.type === import_utils70.AST_NODE_TYPES.Identifier && node.property.name === access.property;
|
|
11872
12062
|
}
|
|
11873
12063
|
function isNullGuard(node, access) {
|
|
11874
|
-
if (node.type ===
|
|
11875
|
-
if (node.type !==
|
|
12064
|
+
if (node.type === import_utils70.AST_NODE_TYPES.UnaryExpression && node.operator === "!" && (sameAccess(node.argument, access) || optionalMemberLengthOf(node.argument, access))) return true;
|
|
12065
|
+
if (node.type !== import_utils70.AST_NODE_TYPES.BinaryExpression || !["==", "==="].includes(node.operator)) {
|
|
11876
12066
|
return false;
|
|
11877
12067
|
}
|
|
11878
|
-
const nullish = (value) => value.type ===
|
|
12068
|
+
const nullish = (value) => value.type === import_utils70.AST_NODE_TYPES.Literal && value.value === null || value.type === import_utils70.AST_NODE_TYPES.Identifier && value.name === "undefined";
|
|
11879
12069
|
return sameAccess(node.left, access) && nullish(node.right) || sameAccess(node.right, access) && nullish(node.left);
|
|
11880
12070
|
}
|
|
11881
12071
|
function isEmptyGuard(node, access) {
|
|
11882
|
-
if (node.type ===
|
|
11883
|
-
if (node.type !==
|
|
12072
|
+
if (node.type === import_utils70.AST_NODE_TYPES.UnaryExpression && node.operator === "!" && memberLengthOf(node.argument, access)) return true;
|
|
12073
|
+
if (node.type !== import_utils70.AST_NODE_TYPES.BinaryExpression || !["==", "===", "<="].includes(node.operator)) {
|
|
11884
12074
|
return false;
|
|
11885
12075
|
}
|
|
11886
|
-
const zero = (value) => value.type ===
|
|
12076
|
+
const zero = (value) => value.type === import_utils70.AST_NODE_TYPES.Literal && value.value === 0;
|
|
11887
12077
|
return memberLengthOf(node.left, access) && zero(node.right) || memberLengthOf(node.right, access) && zero(node.left);
|
|
11888
12078
|
}
|
|
11889
12079
|
function memberLengthOf(node, access) {
|
|
11890
|
-
const target = node.type ===
|
|
11891
|
-
return target.type ===
|
|
12080
|
+
const target = node.type === import_utils70.AST_NODE_TYPES.ChainExpression ? node.expression : node;
|
|
12081
|
+
return target.type === import_utils70.AST_NODE_TYPES.MemberExpression && !target.computed && target.property.type === import_utils70.AST_NODE_TYPES.Identifier && target.property.name === "length" && sameAccess(target.object, access);
|
|
11892
12082
|
}
|
|
11893
12083
|
function optionalMemberLengthOf(node, access) {
|
|
11894
|
-
return node.type ===
|
|
12084
|
+
return node.type === import_utils70.AST_NODE_TYPES.ChainExpression && node.expression.type === import_utils70.AST_NODE_TYPES.MemberExpression && node.expression.optional && memberLengthOf(node, access);
|
|
11895
12085
|
}
|
|
11896
12086
|
function hasEquivalentLeadingGuard(fn, access, visitorKeys) {
|
|
11897
|
-
if (fn.body.type !==
|
|
12087
|
+
if (fn.body.type !== import_utils70.AST_NODE_TYPES.BlockStatement) return false;
|
|
11898
12088
|
const first = fn.body.body[0];
|
|
11899
|
-
if (first?.type !==
|
|
11900
|
-
const terminating = first.consequent.type ===
|
|
12089
|
+
if (first?.type !== import_utils70.AST_NODE_TYPES.IfStatement) return false;
|
|
12090
|
+
const terminating = first.consequent.type === import_utils70.AST_NODE_TYPES.ReturnStatement || first.consequent.type === import_utils70.AST_NODE_TYPES.ThrowStatement || first.consequent.type === import_utils70.AST_NODE_TYPES.BlockStatement && first.consequent.body.length === 1 && (first.consequent.body[0]?.type === import_utils70.AST_NODE_TYPES.ReturnStatement || first.consequent.body[0]?.type === import_utils70.AST_NODE_TYPES.ThrowStatement);
|
|
11901
12091
|
if (!terminating) return false;
|
|
11902
12092
|
if (contains(first.consequent, visitorKeys, (node) => sameAccess(node, access))) return false;
|
|
11903
12093
|
return contains(first.test, visitorKeys, (node) => isNullGuard(node, access)) && contains(first.test, visitorKeys, (node) => isEmptyGuard(node, access));
|
|
@@ -11915,29 +12105,29 @@ function contains(node, visitorKeys, predicate) {
|
|
|
11915
12105
|
function belongsToFunction(node, fn) {
|
|
11916
12106
|
let current = node;
|
|
11917
12107
|
while (current !== void 0 && current !== fn) {
|
|
11918
|
-
if (current !== node && (current.type ===
|
|
12108
|
+
if (current !== node && (current.type === import_utils70.AST_NODE_TYPES.ArrowFunctionExpression || current.type === import_utils70.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils70.AST_NODE_TYPES.FunctionExpression)) return false;
|
|
11919
12109
|
current = current.parent;
|
|
11920
12110
|
}
|
|
11921
12111
|
return current === fn;
|
|
11922
12112
|
}
|
|
11923
12113
|
function directlyCoalesced(node) {
|
|
11924
12114
|
const parent = node.parent;
|
|
11925
|
-
return parent?.type ===
|
|
12115
|
+
return parent?.type === import_utils70.AST_NODE_TYPES.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
|
|
11926
12116
|
}
|
|
11927
12117
|
function identifierIsOnlyCoalesced(context, binding, fn) {
|
|
11928
|
-
const variable =
|
|
12118
|
+
const variable = import_utils70.ASTUtils.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
11929
12119
|
if (variable === null || variable.references.length === 0) return false;
|
|
11930
12120
|
return variable.references.every(
|
|
11931
12121
|
(reference) => belongsToFunction(reference.identifier, fn) && directlyCoalesced(reference.identifier)
|
|
11932
12122
|
);
|
|
11933
12123
|
}
|
|
11934
12124
|
function memberIsOnlyCoalesced(context, object, property, fn) {
|
|
11935
|
-
const variable =
|
|
12125
|
+
const variable = import_utils70.ASTUtils.findVariable(context.sourceCode.getScope(object), object.name);
|
|
11936
12126
|
if (variable === null) return false;
|
|
11937
12127
|
const accesses = variable.references.flatMap((reference) => {
|
|
11938
12128
|
if (!belongsToFunction(reference.identifier, fn)) return [null];
|
|
11939
12129
|
const parent = reference.identifier.parent;
|
|
11940
|
-
if (parent?.type ===
|
|
12130
|
+
if (parent?.type === import_utils70.AST_NODE_TYPES.MemberExpression && !parent.computed && parent.object === reference.identifier && parent.property.type === import_utils70.AST_NODE_TYPES.Identifier && parent.property.name === property) return [parent];
|
|
11941
12131
|
return [];
|
|
11942
12132
|
});
|
|
11943
12133
|
return accesses.length > 0 && accesses.every((access) => access !== null && directlyCoalesced(access));
|
|
@@ -11963,8 +12153,8 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
11963
12153
|
let shapes = /* @__PURE__ */ new Map();
|
|
11964
12154
|
const evidence = /* @__PURE__ */ new Map();
|
|
11965
12155
|
function propertiesFor(annotation) {
|
|
11966
|
-
if (annotation?.type ===
|
|
11967
|
-
if (annotation?.type ===
|
|
12156
|
+
if (annotation?.type === import_utils70.AST_NODE_TYPES.TSTypeLiteral) return shapeProperties(annotation.members);
|
|
12157
|
+
if (annotation?.type === import_utils70.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils70.AST_NODE_TYPES.Identifier) {
|
|
11968
12158
|
const shape = shapes.get(annotation.typeName.name);
|
|
11969
12159
|
return shape?.exported === false ? shape.properties : [];
|
|
11970
12160
|
}
|
|
@@ -11977,21 +12167,21 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
11977
12167
|
}
|
|
11978
12168
|
function checkFunction(fn) {
|
|
11979
12169
|
for (const rawParameter of fn.params) {
|
|
11980
|
-
const parameter = rawParameter.type ===
|
|
11981
|
-
if (parameter.type ===
|
|
12170
|
+
const parameter = rawParameter.type === import_utils70.AST_NODE_TYPES.AssignmentPattern ? rawParameter.left : rawParameter;
|
|
12171
|
+
if (parameter.type === import_utils70.AST_NODE_TYPES.ObjectPattern) {
|
|
11982
12172
|
const properties2 = propertiesFor(parameter.typeAnnotation?.typeAnnotation);
|
|
11983
12173
|
for (const property of properties2) {
|
|
11984
12174
|
const bindingProperty = parameter.properties.find(
|
|
11985
|
-
(entry) => entry.type ===
|
|
12175
|
+
(entry) => entry.type === import_utils70.AST_NODE_TYPES.Property && !entry.computed && entry.key.type === import_utils70.AST_NODE_TYPES.Identifier && entry.key.name === property.name
|
|
11986
12176
|
);
|
|
11987
12177
|
if (bindingProperty === void 0) continue;
|
|
11988
12178
|
const value = bindingProperty.value;
|
|
11989
|
-
const binding = value.type ===
|
|
11990
|
-
if (binding.type !==
|
|
12179
|
+
const binding = value.type === import_utils70.AST_NODE_TYPES.AssignmentPattern ? value.left : value;
|
|
12180
|
+
if (binding.type !== import_utils70.AST_NODE_TYPES.Identifier) {
|
|
11991
12181
|
record(property, false);
|
|
11992
12182
|
continue;
|
|
11993
12183
|
}
|
|
11994
|
-
if (value.type ===
|
|
12184
|
+
if (value.type === import_utils70.AST_NODE_TYPES.AssignmentPattern && emptyArray(value.right) && property.acceptsUndefined && !property.acceptsNull) {
|
|
11995
12185
|
record(property, true);
|
|
11996
12186
|
continue;
|
|
11997
12187
|
}
|
|
@@ -12003,7 +12193,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12003
12193
|
}
|
|
12004
12194
|
continue;
|
|
12005
12195
|
}
|
|
12006
|
-
if (parameter.type !==
|
|
12196
|
+
if (parameter.type !== import_utils70.AST_NODE_TYPES.Identifier) continue;
|
|
12007
12197
|
const properties = propertiesFor(parameter.typeAnnotation?.typeAnnotation);
|
|
12008
12198
|
for (const property of properties) {
|
|
12009
12199
|
const access = {
|
|
@@ -12039,9 +12229,165 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12039
12229
|
}
|
|
12040
12230
|
});
|
|
12041
12231
|
|
|
12232
|
+
// src/rules/prefer-nullish-filter-predicate.ts
|
|
12233
|
+
var import_utils71 = require("@typescript-eslint/utils");
|
|
12234
|
+
var import_typescript = __toESM(require("typescript"), 1);
|
|
12235
|
+
var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
12236
|
+
summary: "Prefer an explicit nullish predicate when `filter(Boolean)` removes only nullish values but does not narrow the result type.",
|
|
12237
|
+
rationale: "An explicit nullish predicate preserves the same runtime elements while letting TypeScript remove `null` and `undefined` from the result.",
|
|
12238
|
+
remediation: "Replace `filter(Boolean)` with `filter((value) => value !== null && value !== undefined)`.",
|
|
12239
|
+
category: "correctness",
|
|
12240
|
+
autofix: "suggestion",
|
|
12241
|
+
limitations: [
|
|
12242
|
+
"The receiver must resolve to the built-in Array or ReadonlyArray filter method.",
|
|
12243
|
+
"Broad primitive types, falsy literals, any, unknown, generics, intersections, custom filters, and shadowed Boolean bindings are excluded."
|
|
12244
|
+
],
|
|
12245
|
+
examples: [
|
|
12246
|
+
{
|
|
12247
|
+
id: "explicit-nullish-predicate",
|
|
12248
|
+
title: "Nullish filtering narrows the result",
|
|
12249
|
+
outcome: "no-match",
|
|
12250
|
+
files: [
|
|
12251
|
+
{
|
|
12252
|
+
path: "src/users.ts",
|
|
12253
|
+
source: "declare const users: readonly ({ id: string } | null)[];\nconst present = users.filter((user) => user !== null && user !== undefined);"
|
|
12254
|
+
}
|
|
12255
|
+
],
|
|
12256
|
+
focusPath: "src/users.ts",
|
|
12257
|
+
expectedCount: 0,
|
|
12258
|
+
public: true
|
|
12259
|
+
},
|
|
12260
|
+
{
|
|
12261
|
+
id: "boolean-nullish-filter",
|
|
12262
|
+
title: "Boolean filtering loses nullish narrowing",
|
|
12263
|
+
outcome: "match",
|
|
12264
|
+
files: [
|
|
12265
|
+
{
|
|
12266
|
+
path: "src/users.ts",
|
|
12267
|
+
source: "declare const users: readonly ({ id: string } | null)[];\nconst present = users.filter(Boolean);"
|
|
12268
|
+
}
|
|
12269
|
+
],
|
|
12270
|
+
focusPath: "src/users.ts",
|
|
12271
|
+
expectedCount: 1,
|
|
12272
|
+
public: true
|
|
12273
|
+
}
|
|
12274
|
+
]
|
|
12275
|
+
};
|
|
12276
|
+
function isUnshadowedBoolean(node, context) {
|
|
12277
|
+
const variable = import_utils71.ASTUtils.findVariable(context.sourceCode.getScope(node), node.name);
|
|
12278
|
+
return variable === null || variable.defs.length === 0;
|
|
12279
|
+
}
|
|
12280
|
+
function isBuiltinArrayFilter(node, services) {
|
|
12281
|
+
const checker = services.program.getTypeChecker();
|
|
12282
|
+
const property = services.esTreeNodeToTSNodeMap.get(node.property);
|
|
12283
|
+
const symbol = checker.getSymbolAtLocation(property);
|
|
12284
|
+
return symbol?.declarations?.some((declaration) => {
|
|
12285
|
+
const owner = declaration.parent;
|
|
12286
|
+
return import_typescript.default.isInterfaceDeclaration(owner) && (owner.name.text === "Array" || owner.name.text === "ReadonlyArray") && services.program.isSourceFileDefaultLibrary(owner.getSourceFile());
|
|
12287
|
+
}) ?? false;
|
|
12288
|
+
}
|
|
12289
|
+
function arrayElementType(node, services) {
|
|
12290
|
+
const checker = services.program.getTypeChecker();
|
|
12291
|
+
const receiver = services.esTreeNodeToTSNodeMap.get(node);
|
|
12292
|
+
return checker.getIndexTypeOfType(checker.getTypeAtLocation(receiver), import_typescript.default.IndexKind.Number) ?? null;
|
|
12293
|
+
}
|
|
12294
|
+
var NULLISH_FLAGS = import_typescript.default.TypeFlags.Null | import_typescript.default.TypeFlags.Undefined;
|
|
12295
|
+
var UNKNOWN_FLAGS = import_typescript.default.TypeFlags.Any | import_typescript.default.TypeFlags.Unknown | import_typescript.default.TypeFlags.TypeParameter | import_typescript.default.TypeFlags.Intersection | import_typescript.default.TypeFlags.Enum | import_typescript.default.TypeFlags.EnumLiteral;
|
|
12296
|
+
function isNullishPlusTruthy(type, checker) {
|
|
12297
|
+
const members = type.isUnion() ? type.types : [type];
|
|
12298
|
+
let sawNullish = false;
|
|
12299
|
+
for (const member of members) {
|
|
12300
|
+
if ((member.flags & NULLISH_FLAGS) !== 0) {
|
|
12301
|
+
sawNullish = true;
|
|
12302
|
+
} else if ((member.flags & import_typescript.default.TypeFlags.Never) === 0 && !isProvablyTruthy(member, checker)) {
|
|
12303
|
+
return false;
|
|
12304
|
+
}
|
|
12305
|
+
}
|
|
12306
|
+
return sawNullish;
|
|
12307
|
+
}
|
|
12308
|
+
function isProvablyTruthy(type, checker) {
|
|
12309
|
+
if ((type.flags & UNKNOWN_FLAGS) !== 0) return false;
|
|
12310
|
+
if ((type.flags & import_typescript.default.TypeFlags.Object) !== 0) {
|
|
12311
|
+
return ![
|
|
12312
|
+
checker.getStringType(),
|
|
12313
|
+
checker.getNumberType(),
|
|
12314
|
+
checker.getBigIntType(),
|
|
12315
|
+
checker.getBooleanType()
|
|
12316
|
+
].some((primitive) => checker.isTypeAssignableTo(primitive, type));
|
|
12317
|
+
}
|
|
12318
|
+
if ((type.flags & (import_typescript.default.TypeFlags.ESSymbol | import_typescript.default.TypeFlags.UniqueESSymbol)) !== 0) return true;
|
|
12319
|
+
if ((type.flags & import_typescript.default.TypeFlags.BooleanLiteral) !== 0) {
|
|
12320
|
+
return type.intrinsicName === "true";
|
|
12321
|
+
}
|
|
12322
|
+
if ((type.flags & import_typescript.default.TypeFlags.StringLiteral) !== 0) {
|
|
12323
|
+
return type.value.length > 0;
|
|
12324
|
+
}
|
|
12325
|
+
if ((type.flags & import_typescript.default.TypeFlags.NumberLiteral) !== 0) {
|
|
12326
|
+
const value = type.value;
|
|
12327
|
+
return value !== 0 && !Number.isNaN(value);
|
|
12328
|
+
}
|
|
12329
|
+
if ((type.flags & import_typescript.default.TypeFlags.BigIntLiteral) !== 0) {
|
|
12330
|
+
return type.value.base10Value !== "0";
|
|
12331
|
+
}
|
|
12332
|
+
return false;
|
|
12333
|
+
}
|
|
12334
|
+
function availableParameterName(node, context) {
|
|
12335
|
+
for (const name of ["value", "item", "element", "candidate"]) {
|
|
12336
|
+
if (import_utils71.ASTUtils.findVariable(context.sourceCode.getScope(node), name) === null) return name;
|
|
12337
|
+
}
|
|
12338
|
+
return null;
|
|
12339
|
+
}
|
|
12340
|
+
var prefer_nullish_filter_predicate_default = createRule({
|
|
12341
|
+
name: "prefer-nullish-filter-predicate",
|
|
12342
|
+
documentation: PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION,
|
|
12343
|
+
meta: {
|
|
12344
|
+
type: "suggestion",
|
|
12345
|
+
docs: { description: PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION.summary },
|
|
12346
|
+
hasSuggestions: true,
|
|
12347
|
+
schema: [],
|
|
12348
|
+
messages: {
|
|
12349
|
+
preferNullishPredicate: "This built-in array contains only nullish or provably truthy values, so `filter(Boolean)` preserves runtime values but loses nullish narrowing. Use an explicit nullish predicate.",
|
|
12350
|
+
replaceBoolean: "Replace `Boolean` with an explicit nullish predicate."
|
|
12351
|
+
}
|
|
12352
|
+
},
|
|
12353
|
+
defaultOptions: [],
|
|
12354
|
+
create(context) {
|
|
12355
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
12356
|
+
let services;
|
|
12357
|
+
try {
|
|
12358
|
+
services = import_utils71.ESLintUtils.getParserServices(context);
|
|
12359
|
+
} catch {
|
|
12360
|
+
services = null;
|
|
12361
|
+
}
|
|
12362
|
+
if (services === null) return {};
|
|
12363
|
+
return {
|
|
12364
|
+
CallExpression(node) {
|
|
12365
|
+
const callee = node.callee;
|
|
12366
|
+
const callback = node.arguments[0];
|
|
12367
|
+
if (node.arguments.length !== 1 || callback?.type !== import_utils71.AST_NODE_TYPES.Identifier || callback.name !== "Boolean" || callee.type !== import_utils71.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils71.AST_NODE_TYPES.Identifier || callee.property.name !== "filter" || !isUnshadowedBoolean(callback, context) || !isBuiltinArrayFilter(callee, services)) return;
|
|
12368
|
+
const elementType = arrayElementType(callee.object, services);
|
|
12369
|
+
const checker = services.program.getTypeChecker();
|
|
12370
|
+
if (elementType === null || !isNullishPlusTruthy(elementType, checker)) return;
|
|
12371
|
+
const parameter = availableParameterName(node, context);
|
|
12372
|
+
context.report({
|
|
12373
|
+
node: callback,
|
|
12374
|
+
messageId: "preferNullishPredicate",
|
|
12375
|
+
suggest: parameter === null ? null : [{
|
|
12376
|
+
messageId: "replaceBoolean",
|
|
12377
|
+
fix: (fixer) => fixer.replaceText(
|
|
12378
|
+
callback,
|
|
12379
|
+
`(${parameter}) => ${parameter} !== null && ${parameter} !== undefined`
|
|
12380
|
+
)
|
|
12381
|
+
}]
|
|
12382
|
+
});
|
|
12383
|
+
}
|
|
12384
|
+
};
|
|
12385
|
+
}
|
|
12386
|
+
});
|
|
12387
|
+
|
|
12042
12388
|
// src/rules/prefer-await-in-async-return.ts
|
|
12043
|
-
var
|
|
12044
|
-
var
|
|
12389
|
+
var import_utils72 = require("@typescript-eslint/utils");
|
|
12390
|
+
var ts4 = __toESM(require("typescript"), 1);
|
|
12045
12391
|
var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
|
|
12046
12392
|
summary: "Prefer explicit `await` when an async function directly returns one typed Promise `.then` transform.",
|
|
12047
12393
|
rationale: "Mixing a directly returned Promise callback into otherwise async control flow makes sequencing and failures harder to read.",
|
|
@@ -12082,10 +12428,10 @@ var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
|
|
|
12082
12428
|
};
|
|
12083
12429
|
function directAsyncReturnOwner(node) {
|
|
12084
12430
|
const parent = node.parent;
|
|
12085
|
-
if (parent.type ===
|
|
12431
|
+
if (parent.type === import_utils72.AST_NODE_TYPES.ArrowFunctionExpression && parent.body === node) {
|
|
12086
12432
|
return parent.async && !parent.generator ? parent : null;
|
|
12087
12433
|
}
|
|
12088
|
-
if (parent.type !==
|
|
12434
|
+
if (parent.type !== import_utils72.AST_NODE_TYPES.ReturnStatement || parent.argument !== node) {
|
|
12089
12435
|
return null;
|
|
12090
12436
|
}
|
|
12091
12437
|
let owner = parent.parent;
|
|
@@ -12095,15 +12441,15 @@ function directAsyncReturnOwner(node) {
|
|
|
12095
12441
|
return owner !== void 0 && owner.async && !owner.generator ? owner : null;
|
|
12096
12442
|
}
|
|
12097
12443
|
function isRuntimeFunction(node) {
|
|
12098
|
-
return node.type ===
|
|
12444
|
+
return node.type === import_utils72.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils72.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils72.AST_NODE_TYPES.FunctionExpression;
|
|
12099
12445
|
}
|
|
12100
12446
|
function promiseThenReceiver(node) {
|
|
12101
12447
|
const callee = node.callee;
|
|
12102
|
-
if (callee.type !==
|
|
12448
|
+
if (callee.type !== import_utils72.AST_NODE_TYPES.MemberExpression || callee.computed || callee.optional || callee.property.type !== import_utils72.AST_NODE_TYPES.Identifier || callee.property.name !== "then" || node.optional || node.arguments.length !== 1) {
|
|
12103
12449
|
return null;
|
|
12104
12450
|
}
|
|
12105
12451
|
const callback = node.arguments[0];
|
|
12106
|
-
if (callback === void 0 || callback.type !==
|
|
12452
|
+
if (callback === void 0 || callback.type !== import_utils72.AST_NODE_TYPES.ArrowFunctionExpression && callback.type !== import_utils72.AST_NODE_TYPES.FunctionExpression) {
|
|
12107
12453
|
return null;
|
|
12108
12454
|
}
|
|
12109
12455
|
return callee.object;
|
|
@@ -12112,14 +12458,14 @@ function isProvenPromiseLike(node, services) {
|
|
|
12112
12458
|
const checker = services.program.getTypeChecker();
|
|
12113
12459
|
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
|
12114
12460
|
const receiverType = checker.getTypeAtLocation(tsNode);
|
|
12115
|
-
if ((receiverType.flags & (
|
|
12461
|
+
if ((receiverType.flags & (ts4.TypeFlags.Any | ts4.TypeFlags.Unknown | ts4.TypeFlags.Never)) !== 0) {
|
|
12116
12462
|
return false;
|
|
12117
12463
|
}
|
|
12118
12464
|
const thenSymbol = checker.getPropertyOfType(receiverType, "then");
|
|
12119
12465
|
const hasBuiltInPromiseDeclaration = thenSymbol?.declarations?.some(
|
|
12120
12466
|
(declaration) => {
|
|
12121
12467
|
let owner = declaration.parent;
|
|
12122
|
-
while (owner !== void 0 && !
|
|
12468
|
+
while (owner !== void 0 && !ts4.isInterfaceDeclaration(owner)) {
|
|
12123
12469
|
owner = owner.parent;
|
|
12124
12470
|
}
|
|
12125
12471
|
return owner !== void 0 && (owner.name.text === "Promise" || owner.name.text === "PromiseLike") && services.program.isSourceFileDefaultLibrary(owner.getSourceFile());
|
|
@@ -12144,32 +12490,32 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12144
12490
|
create(context) {
|
|
12145
12491
|
let services;
|
|
12146
12492
|
try {
|
|
12147
|
-
services =
|
|
12493
|
+
services = import_utils72.ESLintUtils.getParserServices(context);
|
|
12148
12494
|
} catch {
|
|
12149
12495
|
services = null;
|
|
12150
12496
|
}
|
|
12151
12497
|
if (services === null) return {};
|
|
12152
12498
|
const frameworkLoaders = /* @__PURE__ */ new Set();
|
|
12153
12499
|
const rememberFrameworkLoader = (identifier) => {
|
|
12154
|
-
const variable =
|
|
12500
|
+
const variable = import_utils72.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
12155
12501
|
if (variable !== null) frameworkLoaders.add(variable);
|
|
12156
12502
|
};
|
|
12157
12503
|
const isFrameworkLoaderCallback = (owner) => {
|
|
12158
12504
|
const parent = owner.parent;
|
|
12159
|
-
if (parent.type !==
|
|
12160
|
-
const variable =
|
|
12505
|
+
if (parent.type !== import_utils72.AST_NODE_TYPES.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== import_utils72.AST_NODE_TYPES.Identifier) return false;
|
|
12506
|
+
const variable = import_utils72.ASTUtils.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
|
|
12161
12507
|
return variable !== null && frameworkLoaders.has(variable);
|
|
12162
12508
|
};
|
|
12163
12509
|
return {
|
|
12164
12510
|
ImportDeclaration(node) {
|
|
12165
12511
|
if (node.source.value === "react") {
|
|
12166
12512
|
for (const specifier of node.specifiers) {
|
|
12167
|
-
if (specifier.type ===
|
|
12513
|
+
if (specifier.type === import_utils72.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils72.AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value) === "lazy") rememberFrameworkLoader(specifier.local);
|
|
12168
12514
|
}
|
|
12169
12515
|
}
|
|
12170
12516
|
if (node.source.value === "next/dynamic") {
|
|
12171
12517
|
for (const specifier of node.specifiers) {
|
|
12172
|
-
if (specifier.type ===
|
|
12518
|
+
if (specifier.type === import_utils72.AST_NODE_TYPES.ImportDefaultSpecifier) rememberFrameworkLoader(specifier.local);
|
|
12173
12519
|
}
|
|
12174
12520
|
}
|
|
12175
12521
|
},
|
|
@@ -12187,7 +12533,7 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12187
12533
|
});
|
|
12188
12534
|
|
|
12189
12535
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
12190
|
-
var
|
|
12536
|
+
var import_utils73 = require("@typescript-eslint/utils");
|
|
12191
12537
|
var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
|
|
12192
12538
|
summary: "Require Zod (or similar) schema validation on `response.json()` / `JSON.parse()` results before property access.",
|
|
12193
12539
|
rationale: "External JSON is untrusted at runtime even when its expected TypeScript shape is known statically.",
|
|
@@ -12199,12 +12545,12 @@ var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
|
|
|
12199
12545
|
{ id: "unvalidated-payload", title: "Do not trust response JSON directly", outcome: "match", files: [{ path: "src/client.ts", source: "async function load(response) { const body = await response.json(); return body.id; }" }], focusPath: "src/client.ts", expectedCount: 1, public: true }
|
|
12200
12546
|
]
|
|
12201
12547
|
};
|
|
12202
|
-
var
|
|
12548
|
+
var unwrap5 = (node) => {
|
|
12203
12549
|
let current = node;
|
|
12204
12550
|
while (current !== null && current !== void 0) {
|
|
12205
|
-
if (current.type ===
|
|
12551
|
+
if (current.type === import_utils73.AST_NODE_TYPES.TSAsExpression || current.type === import_utils73.AST_NODE_TYPES.TSTypeAssertion || current.type === import_utils73.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils73.AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
12206
12552
|
current = current.expression;
|
|
12207
|
-
} else if (current.type ===
|
|
12553
|
+
} else if (current.type === import_utils73.AST_NODE_TYPES.ChainExpression) {
|
|
12208
12554
|
current = current.expression;
|
|
12209
12555
|
} else {
|
|
12210
12556
|
break;
|
|
@@ -12218,24 +12564,24 @@ var PROMISE_CHAIN_METHODS = /* @__PURE__ */ new Set([
|
|
|
12218
12564
|
"finally"
|
|
12219
12565
|
]);
|
|
12220
12566
|
var isSchemaParseReference = (node) => {
|
|
12221
|
-
const inner =
|
|
12222
|
-
return inner !== null && inner.type ===
|
|
12567
|
+
const inner = unwrap5(node);
|
|
12568
|
+
return inner !== null && inner.type === import_utils73.AST_NODE_TYPES.MemberExpression && !inner.computed && inner.property.type === import_utils73.AST_NODE_TYPES.Identifier && (inner.property.name === "parse" || inner.property.name === "safeParse");
|
|
12223
12569
|
};
|
|
12224
12570
|
var isRawPayloadSource = (node, isKnownLocalText) => {
|
|
12225
|
-
let current =
|
|
12571
|
+
let current = unwrap5(node);
|
|
12226
12572
|
if (current === null) return false;
|
|
12227
|
-
if (current.type ===
|
|
12228
|
-
current =
|
|
12573
|
+
if (current.type === import_utils73.AST_NODE_TYPES.AwaitExpression) {
|
|
12574
|
+
current = unwrap5(current.argument);
|
|
12229
12575
|
}
|
|
12230
|
-
if (current === null || current.type !==
|
|
12576
|
+
if (current === null || current.type !== import_utils73.AST_NODE_TYPES.CallExpression) {
|
|
12231
12577
|
return false;
|
|
12232
12578
|
}
|
|
12233
|
-
const callee =
|
|
12234
|
-
if (callee === null || callee.type !==
|
|
12579
|
+
const callee = unwrap5(current.callee);
|
|
12580
|
+
if (callee === null || callee.type !== import_utils73.AST_NODE_TYPES.MemberExpression) {
|
|
12235
12581
|
return false;
|
|
12236
12582
|
}
|
|
12237
|
-
const property =
|
|
12238
|
-
if (property === null || property.type !==
|
|
12583
|
+
const property = unwrap5(callee.property);
|
|
12584
|
+
if (property === null || property.type !== import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12239
12585
|
return false;
|
|
12240
12586
|
}
|
|
12241
12587
|
if (property.name === "json") {
|
|
@@ -12244,18 +12590,18 @@ var isRawPayloadSource = (node, isKnownLocalText) => {
|
|
|
12244
12590
|
if (PROMISE_CHAIN_METHODS.has(property.name)) {
|
|
12245
12591
|
return !current.arguments.some(isSchemaParseReference) && isRawPayloadSource(callee.object);
|
|
12246
12592
|
}
|
|
12247
|
-
const object =
|
|
12248
|
-
return property.name === "parse" && object !== null && object.type ===
|
|
12593
|
+
const object = unwrap5(callee.object);
|
|
12594
|
+
return property.name === "parse" && object !== null && object.type === import_utils73.AST_NODE_TYPES.Identifier && object.name === "JSON" && !isLocalFileRead(current.arguments[0]) && isKnownLocalText?.(current.arguments[0]) !== true;
|
|
12249
12595
|
};
|
|
12250
12596
|
var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
|
|
12251
12597
|
var isDirectLocalFileRead = (node) => {
|
|
12252
|
-
let current =
|
|
12253
|
-
if (current?.type ===
|
|
12254
|
-
current =
|
|
12598
|
+
let current = unwrap5(node);
|
|
12599
|
+
if (current?.type === import_utils73.AST_NODE_TYPES.AwaitExpression) {
|
|
12600
|
+
current = unwrap5(current.argument);
|
|
12255
12601
|
}
|
|
12256
|
-
if (current?.type !==
|
|
12257
|
-
const callee =
|
|
12258
|
-
const name = callee?.type ===
|
|
12602
|
+
if (current?.type !== import_utils73.AST_NODE_TYPES.CallExpression) return false;
|
|
12603
|
+
const callee = unwrap5(current.callee);
|
|
12604
|
+
const name = callee?.type === import_utils73.AST_NODE_TYPES.Identifier ? callee.name : callee?.type === import_utils73.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils73.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
12259
12605
|
return name !== null && FILE_READ_RE.test(name);
|
|
12260
12606
|
};
|
|
12261
12607
|
var isLocalFileRead = (node) => {
|
|
@@ -12282,15 +12628,15 @@ var isLocalFileRead = (node) => {
|
|
|
12282
12628
|
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
12283
12629
|
var isInsideAssertion = (node) => {
|
|
12284
12630
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12285
|
-
if (current.type !==
|
|
12631
|
+
if (current.type !== import_utils73.AST_NODE_TYPES.CallExpression) continue;
|
|
12286
12632
|
let callee = current.callee;
|
|
12287
|
-
while (callee.type ===
|
|
12633
|
+
while (callee.type === import_utils73.AST_NODE_TYPES.MemberExpression) {
|
|
12288
12634
|
callee = callee.object;
|
|
12289
12635
|
}
|
|
12290
|
-
if (callee.type ===
|
|
12636
|
+
if (callee.type === import_utils73.AST_NODE_TYPES.CallExpression) {
|
|
12291
12637
|
callee = callee.callee;
|
|
12292
12638
|
}
|
|
12293
|
-
if (callee.type ===
|
|
12639
|
+
if (callee.type === import_utils73.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
12294
12640
|
return true;
|
|
12295
12641
|
}
|
|
12296
12642
|
}
|
|
@@ -12309,22 +12655,22 @@ var GUARD_NAME_RE = /^(?:is|validate|parse|assert|decode|coerce)[A-Z]/;
|
|
|
12309
12655
|
var isValidationRead = (node) => {
|
|
12310
12656
|
let current = node;
|
|
12311
12657
|
let parent = current.parent;
|
|
12312
|
-
while (parent !== null && parent !== void 0 && (parent.type ===
|
|
12658
|
+
while (parent !== null && parent !== void 0 && (parent.type === import_utils73.AST_NODE_TYPES.TSAsExpression || parent.type === import_utils73.AST_NODE_TYPES.TSTypeAssertion || parent.type === import_utils73.AST_NODE_TYPES.TSNonNullExpression || parent.type === import_utils73.AST_NODE_TYPES.TSSatisfiesExpression || parent.type === import_utils73.AST_NODE_TYPES.ChainExpression)) {
|
|
12313
12659
|
current = parent;
|
|
12314
12660
|
parent = parent.parent;
|
|
12315
12661
|
}
|
|
12316
12662
|
if (parent === null || parent === void 0) return false;
|
|
12317
|
-
if (parent.type ===
|
|
12663
|
+
if (parent.type === import_utils73.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
|
|
12318
12664
|
return true;
|
|
12319
12665
|
}
|
|
12320
|
-
if (parent.type !==
|
|
12666
|
+
if (parent.type !== import_utils73.AST_NODE_TYPES.CallExpression || !parent.arguments.some((arg) => arg === current)) {
|
|
12321
12667
|
return false;
|
|
12322
12668
|
}
|
|
12323
12669
|
const callee = parent.callee;
|
|
12324
|
-
if (callee.type ===
|
|
12670
|
+
if (callee.type === import_utils73.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils73.AST_NODE_TYPES.Identifier && callee.object.name === "Array" && callee.property.type === import_utils73.AST_NODE_TYPES.Identifier && callee.property.name === "isArray") {
|
|
12325
12671
|
return parent.arguments.length === 1;
|
|
12326
12672
|
}
|
|
12327
|
-
return callee.type ===
|
|
12673
|
+
return callee.type === import_utils73.AST_NODE_TYPES.Identifier && GUARD_NAME_RE.test(callee.name);
|
|
12328
12674
|
};
|
|
12329
12675
|
var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
|
|
12330
12676
|
"bigint",
|
|
@@ -12335,13 +12681,13 @@ var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
|
|
|
12335
12681
|
"undefined"
|
|
12336
12682
|
]);
|
|
12337
12683
|
var bindingValidationPolarity = (test, bindingName) => {
|
|
12338
|
-
if (test.type ===
|
|
12684
|
+
if (test.type === import_utils73.AST_NODE_TYPES.UnaryExpression && test.operator === "!") {
|
|
12339
12685
|
const inner = bindingValidationPolarity(test.argument, bindingName);
|
|
12340
12686
|
return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
|
|
12341
12687
|
}
|
|
12342
|
-
if (test.type ===
|
|
12343
|
-
const typeofName = (node) => node.type ===
|
|
12344
|
-
const literalType = (node) => node.type ===
|
|
12688
|
+
if (test.type === import_utils73.AST_NODE_TYPES.BinaryExpression) {
|
|
12689
|
+
const typeofName = (node) => node.type === import_utils73.AST_NODE_TYPES.UnaryExpression && node.operator === "typeof" && node.argument.type === import_utils73.AST_NODE_TYPES.Identifier ? node.argument.name : null;
|
|
12690
|
+
const literalType = (node) => node.type === import_utils73.AST_NODE_TYPES.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value) ? node.value : null;
|
|
12345
12691
|
const matches = typeofName(test.left) === bindingName && literalType(test.right) !== null || typeofName(test.right) === bindingName && literalType(test.left) !== null;
|
|
12346
12692
|
if (!matches) return null;
|
|
12347
12693
|
if (test.operator === "===" || test.operator === "==") {
|
|
@@ -12349,9 +12695,9 @@ var bindingValidationPolarity = (test, bindingName) => {
|
|
|
12349
12695
|
}
|
|
12350
12696
|
return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
|
|
12351
12697
|
}
|
|
12352
|
-
return test.type ===
|
|
12698
|
+
return test.type === import_utils73.AST_NODE_TYPES.CallExpression && test.arguments.length === 1 && test.arguments[0]?.type === import_utils73.AST_NODE_TYPES.Identifier && test.arguments[0].name === bindingName && test.callee.type === import_utils73.AST_NODE_TYPES.MemberExpression && !test.callee.computed && test.callee.object.type === import_utils73.AST_NODE_TYPES.Identifier && test.callee.object.name === "Array" && test.callee.property.type === import_utils73.AST_NODE_TYPES.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
|
|
12353
12699
|
};
|
|
12354
|
-
var plainMemberAccess = (node) => node.type ===
|
|
12700
|
+
var plainMemberAccess = (node) => node.type === import_utils73.AST_NODE_TYPES.MemberExpression && !node.computed && node.object.type === import_utils73.AST_NODE_TYPES.Identifier && node.property.type === import_utils73.AST_NODE_TYPES.Identifier ? { object: node.object.name, property: node.property.name } : null;
|
|
12355
12701
|
var isSamePlainMember = (node, access) => {
|
|
12356
12702
|
const candidate2 = plainMemberAccess(node);
|
|
12357
12703
|
return candidate2 !== null && candidate2.object === access.object && candidate2.property === access.property;
|
|
@@ -12359,19 +12705,19 @@ var isSamePlainMember = (node, access) => {
|
|
|
12359
12705
|
var nodeWithin2 = (node, container) => node.range[0] >= container.range[0] && node.range[1] <= container.range[1];
|
|
12360
12706
|
var isUseWithinValidatedBranch = (node, bindingName) => {
|
|
12361
12707
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12362
|
-
if (current.type ===
|
|
12708
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12363
12709
|
const polarity = bindingValidationPolarity(current.test, bindingName);
|
|
12364
12710
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
|
|
12365
12711
|
return true;
|
|
12366
12712
|
}
|
|
12367
12713
|
}
|
|
12368
|
-
if (current.type ===
|
|
12714
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12369
12715
|
const polarity = bindingValidationPolarity(current.test, bindingName);
|
|
12370
12716
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
|
|
12371
12717
|
return true;
|
|
12372
12718
|
}
|
|
12373
12719
|
}
|
|
12374
|
-
if (current.type ===
|
|
12720
|
+
if (current.type === import_utils73.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils73.AST_NODE_TYPES.FunctionExpression || current.type === import_utils73.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
12375
12721
|
return false;
|
|
12376
12722
|
}
|
|
12377
12723
|
}
|
|
@@ -12379,32 +12725,32 @@ var isUseWithinValidatedBranch = (node, bindingName) => {
|
|
|
12379
12725
|
};
|
|
12380
12726
|
var isMemberUseWithinValidatedBranch = (node, access) => {
|
|
12381
12727
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12382
|
-
if (current.type ===
|
|
12728
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12383
12729
|
const polarity = memberValidationPolarity(current.test, access);
|
|
12384
12730
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
|
|
12385
12731
|
return true;
|
|
12386
12732
|
}
|
|
12387
12733
|
}
|
|
12388
|
-
if (current.type ===
|
|
12734
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12389
12735
|
const polarity = memberValidationPolarity(current.test, access);
|
|
12390
12736
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
|
|
12391
12737
|
return true;
|
|
12392
12738
|
}
|
|
12393
12739
|
}
|
|
12394
|
-
if (current.type ===
|
|
12740
|
+
if (current.type === import_utils73.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils73.AST_NODE_TYPES.FunctionExpression || current.type === import_utils73.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
12395
12741
|
return false;
|
|
12396
12742
|
}
|
|
12397
12743
|
}
|
|
12398
12744
|
return false;
|
|
12399
12745
|
};
|
|
12400
12746
|
var memberValidationPolarity = (test, access) => {
|
|
12401
|
-
if (test.type ===
|
|
12747
|
+
if (test.type === import_utils73.AST_NODE_TYPES.UnaryExpression && test.operator === "!") {
|
|
12402
12748
|
const inner = memberValidationPolarity(test.argument, access);
|
|
12403
12749
|
return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
|
|
12404
12750
|
}
|
|
12405
|
-
if (test.type ===
|
|
12406
|
-
const isMatchingTypeof = (node) => node.type ===
|
|
12407
|
-
const isPrimitiveType = (node) => node.type ===
|
|
12751
|
+
if (test.type === import_utils73.AST_NODE_TYPES.BinaryExpression) {
|
|
12752
|
+
const isMatchingTypeof = (node) => node.type === import_utils73.AST_NODE_TYPES.UnaryExpression && node.operator === "typeof" && isSamePlainMember(node.argument, access);
|
|
12753
|
+
const isPrimitiveType = (node) => node.type === import_utils73.AST_NODE_TYPES.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value);
|
|
12408
12754
|
if (!(isMatchingTypeof(test.left) && isPrimitiveType(test.right) || isMatchingTypeof(test.right) && isPrimitiveType(test.left))) {
|
|
12409
12755
|
return null;
|
|
12410
12756
|
}
|
|
@@ -12413,15 +12759,15 @@ var memberValidationPolarity = (test, access) => {
|
|
|
12413
12759
|
}
|
|
12414
12760
|
return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
|
|
12415
12761
|
}
|
|
12416
|
-
return test.type ===
|
|
12762
|
+
return test.type === import_utils73.AST_NODE_TYPES.CallExpression && test.arguments.length === 1 && test.arguments[0] !== void 0 && test.arguments[0].type !== import_utils73.AST_NODE_TYPES.SpreadElement && isSamePlainMember(test.arguments[0], access) && test.callee.type === import_utils73.AST_NODE_TYPES.MemberExpression && !test.callee.computed && test.callee.object.type === import_utils73.AST_NODE_TYPES.Identifier && test.callee.object.name === "Array" && test.callee.property.type === import_utils73.AST_NODE_TYPES.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
|
|
12417
12763
|
};
|
|
12418
12764
|
var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
12419
12765
|
const isValidationReference = (identifier) => {
|
|
12420
12766
|
for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12421
|
-
if ((current.type ===
|
|
12767
|
+
if ((current.type === import_utils73.AST_NODE_TYPES.BinaryExpression || current.type === import_utils73.AST_NODE_TYPES.CallExpression || current.type === import_utils73.AST_NODE_TYPES.UnaryExpression) && bindingValidationPolarity(current, identifier.name) !== null) {
|
|
12422
12768
|
return true;
|
|
12423
12769
|
}
|
|
12424
|
-
if (current.type !==
|
|
12770
|
+
if (current.type !== import_utils73.AST_NODE_TYPES.UnaryExpression && current.type !== import_utils73.AST_NODE_TYPES.MemberExpression && current.type !== import_utils73.AST_NODE_TYPES.CallExpression) {
|
|
12425
12771
|
return false;
|
|
12426
12772
|
}
|
|
12427
12773
|
}
|
|
@@ -12429,7 +12775,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12429
12775
|
};
|
|
12430
12776
|
const isGuardedUse = (identifier) => {
|
|
12431
12777
|
for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12432
|
-
if (current.type ===
|
|
12778
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12433
12779
|
const polarity = bindingValidationPolarity(current.test, identifier.name);
|
|
12434
12780
|
if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
|
|
12435
12781
|
return true;
|
|
@@ -12438,7 +12784,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12438
12784
|
return true;
|
|
12439
12785
|
}
|
|
12440
12786
|
}
|
|
12441
|
-
if (current.type ===
|
|
12787
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12442
12788
|
const polarity = bindingValidationPolarity(current.test, identifier.name);
|
|
12443
12789
|
if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
|
|
12444
12790
|
return true;
|
|
@@ -12447,14 +12793,14 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12447
12793
|
return true;
|
|
12448
12794
|
}
|
|
12449
12795
|
}
|
|
12450
|
-
if (current.type ===
|
|
12796
|
+
if (current.type === import_utils73.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils73.AST_NODE_TYPES.FunctionExpression || current.type === import_utils73.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
12451
12797
|
return false;
|
|
12452
12798
|
}
|
|
12453
12799
|
}
|
|
12454
12800
|
return false;
|
|
12455
12801
|
};
|
|
12456
12802
|
const declarator = member.parent;
|
|
12457
|
-
if (declarator.type !==
|
|
12803
|
+
if (declarator.type !== import_utils73.AST_NODE_TYPES.VariableDeclarator || declarator.init !== member || declarator.id.type !== import_utils73.AST_NODE_TYPES.Identifier || declarator.parent.type !== import_utils73.AST_NODE_TYPES.VariableDeclaration || declarator.parent.kind !== "const") {
|
|
12458
12804
|
return false;
|
|
12459
12805
|
}
|
|
12460
12806
|
const extracted = context.sourceCode.getDeclaredVariables(declarator)[0];
|
|
@@ -12462,7 +12808,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12462
12808
|
let hasValueUse = false;
|
|
12463
12809
|
for (const reference of extracted.references) {
|
|
12464
12810
|
const identifier = reference.identifier;
|
|
12465
|
-
if (identifier.type !==
|
|
12811
|
+
if (identifier.type !== import_utils73.AST_NODE_TYPES.Identifier) return false;
|
|
12466
12812
|
if (nodeWithin2(identifier, declarator)) continue;
|
|
12467
12813
|
if (isValidationReference(identifier)) continue;
|
|
12468
12814
|
hasValueUse = true;
|
|
@@ -12475,17 +12821,17 @@ var isGuardTestPosition = (node) => {
|
|
|
12475
12821
|
let parent = current.parent;
|
|
12476
12822
|
while (parent !== void 0 && parent !== null) {
|
|
12477
12823
|
switch (parent.type) {
|
|
12478
|
-
case
|
|
12479
|
-
case
|
|
12480
|
-
case
|
|
12824
|
+
case import_utils73.AST_NODE_TYPES.UnaryExpression:
|
|
12825
|
+
case import_utils73.AST_NODE_TYPES.LogicalExpression:
|
|
12826
|
+
case import_utils73.AST_NODE_TYPES.ChainExpression:
|
|
12481
12827
|
current = parent;
|
|
12482
12828
|
parent = parent.parent;
|
|
12483
12829
|
continue;
|
|
12484
|
-
case
|
|
12485
|
-
case
|
|
12486
|
-
case
|
|
12487
|
-
case
|
|
12488
|
-
case
|
|
12830
|
+
case import_utils73.AST_NODE_TYPES.IfStatement:
|
|
12831
|
+
case import_utils73.AST_NODE_TYPES.ConditionalExpression:
|
|
12832
|
+
case import_utils73.AST_NODE_TYPES.WhileStatement:
|
|
12833
|
+
case import_utils73.AST_NODE_TYPES.DoWhileStatement:
|
|
12834
|
+
case import_utils73.AST_NODE_TYPES.ForStatement:
|
|
12489
12835
|
return parent.test === current;
|
|
12490
12836
|
default:
|
|
12491
12837
|
return false;
|
|
@@ -12494,8 +12840,8 @@ var isGuardTestPosition = (node) => {
|
|
|
12494
12840
|
return false;
|
|
12495
12841
|
};
|
|
12496
12842
|
var unvalidatedVariableRef = (node, scope, tracked) => {
|
|
12497
|
-
const unwrapped =
|
|
12498
|
-
if (unwrapped === null || unwrapped.type !==
|
|
12843
|
+
const unwrapped = unwrap5(node);
|
|
12844
|
+
if (unwrapped === null || unwrapped.type !== import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12499
12845
|
return null;
|
|
12500
12846
|
}
|
|
12501
12847
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -12523,8 +12869,8 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12523
12869
|
const aliasGroups = /* @__PURE__ */ new Map();
|
|
12524
12870
|
const localFileTextVariables = /* @__PURE__ */ new Set();
|
|
12525
12871
|
const localFileTextRef = (node, scope) => {
|
|
12526
|
-
const unwrapped =
|
|
12527
|
-
if (unwrapped?.type !==
|
|
12872
|
+
const unwrapped = unwrap5(node);
|
|
12873
|
+
if (unwrapped?.type !== import_utils73.AST_NODE_TYPES.Identifier) return null;
|
|
12528
12874
|
const variable = findVariable2(scope, unwrapped.name);
|
|
12529
12875
|
return variable !== null && localFileTextVariables.has(variable) ? variable : null;
|
|
12530
12876
|
};
|
|
@@ -12593,7 +12939,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12593
12939
|
return {
|
|
12594
12940
|
VariableDeclarator(node) {
|
|
12595
12941
|
const scope = context.sourceCode.getScope(node);
|
|
12596
|
-
if (node.id.type ===
|
|
12942
|
+
if (node.id.type === import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12597
12943
|
const variable = context.sourceCode.getDeclaredVariables(node)[0];
|
|
12598
12944
|
if (variable !== void 0) {
|
|
12599
12945
|
updateLocalFileText(variable, node.init, scope);
|
|
@@ -12601,7 +12947,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12601
12947
|
trackInitializer(node, scope);
|
|
12602
12948
|
return;
|
|
12603
12949
|
}
|
|
12604
|
-
if (node.id.type ===
|
|
12950
|
+
if (node.id.type === import_utils73.AST_NODE_TYPES.ObjectPattern || node.id.type === import_utils73.AST_NODE_TYPES.ArrayPattern) {
|
|
12605
12951
|
if (isRawPayloadSource(
|
|
12606
12952
|
node.init,
|
|
12607
12953
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
@@ -12618,7 +12964,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12618
12964
|
},
|
|
12619
12965
|
AssignmentExpression(node) {
|
|
12620
12966
|
const scope = context.sourceCode.getScope(node);
|
|
12621
|
-
if (node.left.type ===
|
|
12967
|
+
if (node.left.type === import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12622
12968
|
const variable = findVariable2(scope, node.left.name);
|
|
12623
12969
|
if (variable === null) return;
|
|
12624
12970
|
const isLocalText = (candidate2) => localFileTextRef(candidate2, scope) !== null;
|
|
@@ -12632,7 +12978,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12632
12978
|
}
|
|
12633
12979
|
return;
|
|
12634
12980
|
}
|
|
12635
|
-
if (node.left.type ===
|
|
12981
|
+
if (node.left.type === import_utils73.AST_NODE_TYPES.ObjectPattern || node.left.type === import_utils73.AST_NODE_TYPES.ArrayPattern) {
|
|
12636
12982
|
if (isRawPayloadSource(
|
|
12637
12983
|
node.right,
|
|
12638
12984
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
@@ -12652,15 +12998,15 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12652
12998
|
}
|
|
12653
12999
|
},
|
|
12654
13000
|
CallExpression(node) {
|
|
12655
|
-
if (node.callee.type !==
|
|
13001
|
+
if (node.callee.type !== import_utils73.AST_NODE_TYPES.Identifier) return;
|
|
12656
13002
|
if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
|
|
12657
13003
|
return;
|
|
12658
13004
|
}
|
|
12659
13005
|
const scope = context.sourceCode.getScope(node);
|
|
12660
13006
|
for (const arg of node.arguments) {
|
|
12661
|
-
if (arg.type ===
|
|
12662
|
-
const unwrapped =
|
|
12663
|
-
if (unwrapped === null || unwrapped.type !==
|
|
13007
|
+
if (arg.type === import_utils73.AST_NODE_TYPES.SpreadElement) continue;
|
|
13008
|
+
const unwrapped = unwrap5(arg);
|
|
13009
|
+
if (unwrapped === null || unwrapped.type !== import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12664
13010
|
continue;
|
|
12665
13011
|
}
|
|
12666
13012
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -12671,20 +13017,20 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12671
13017
|
if (isInsideAssertion(node)) return;
|
|
12672
13018
|
if (isValidationRead(node)) return;
|
|
12673
13019
|
const scope = context.sourceCode.getScope(node);
|
|
12674
|
-
const obj =
|
|
13020
|
+
const obj = unwrap5(node.object);
|
|
12675
13021
|
if (isRawPayloadSource(
|
|
12676
13022
|
obj,
|
|
12677
13023
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
12678
13024
|
)) {
|
|
12679
13025
|
const parent = node.parent;
|
|
12680
|
-
if (parent.type ===
|
|
13026
|
+
if (parent.type === import_utils73.AST_NODE_TYPES.CallExpression && parent.callee === node && node.property.type === import_utils73.AST_NODE_TYPES.Identifier && (node.property.name === "parse" || node.property.name === "safeParse" || PROMISE_CHAIN_METHODS.has(node.property.name))) {
|
|
12681
13027
|
return;
|
|
12682
13028
|
}
|
|
12683
13029
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
12684
13030
|
return;
|
|
12685
13031
|
}
|
|
12686
|
-
const variable = obj?.type ===
|
|
12687
|
-
if (variable !== null && obj?.type ===
|
|
13032
|
+
const variable = obj?.type === import_utils73.AST_NODE_TYPES.Identifier ? unvalidatedVariableRef(obj, scope, unvalidatedVariables) : null;
|
|
13033
|
+
if (variable !== null && obj?.type === import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12688
13034
|
if (isUseWithinValidatedBranch(node, obj.name)) {
|
|
12689
13035
|
return;
|
|
12690
13036
|
}
|
|
@@ -12703,8 +13049,122 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12703
13049
|
}
|
|
12704
13050
|
});
|
|
12705
13051
|
|
|
13052
|
+
// src/rules/prefer-shared-zod-enum.ts
|
|
13053
|
+
var import_utils74 = require("@typescript-eslint/utils");
|
|
13054
|
+
var PREFER_SHARED_ZOD_ENUM_DOCUMENTATION = {
|
|
13055
|
+
summary: "Reuse identical literal Zod enum domains within a module.",
|
|
13056
|
+
rationale: "Repeating the same literal domain creates parallel contracts that can drift independently.",
|
|
13057
|
+
remediation: "Declare one module-level named Zod enum schema and reuse it at each field or contract site.",
|
|
13058
|
+
category: "maintainability",
|
|
13059
|
+
limitations: ["Only direct z.enum calls with ordered string-literal arrays in the same module are compared."],
|
|
13060
|
+
examples: [
|
|
13061
|
+
{ 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 },
|
|
13062
|
+
{ id: "duplicate-provider", title: "Do not repeat one enum domain", outcome: "match", files: [{ path: "src/provider.ts", source: "import { z } from 'zod'; const JobSchema = z.object({ provider: z.enum(['agy', 'claude', 'sol']) }); const StatusSchema = z.object({ provider: z.enum(['agy', 'claude', 'sol']).optional() });" }], focusPath: "src/provider.ts", expectedCount: 1, public: true }
|
|
13063
|
+
]
|
|
13064
|
+
};
|
|
13065
|
+
function literalDomain(node) {
|
|
13066
|
+
const [argument] = node.arguments;
|
|
13067
|
+
if (argument?.type !== import_utils74.AST_NODE_TYPES.ArrayExpression || argument.elements.length < 2) return null;
|
|
13068
|
+
const values = [];
|
|
13069
|
+
for (const element of argument.elements) {
|
|
13070
|
+
if (element?.type !== import_utils74.AST_NODE_TYPES.Literal || typeof element.value !== "string") return null;
|
|
13071
|
+
values.push(element.value);
|
|
13072
|
+
}
|
|
13073
|
+
return values;
|
|
13074
|
+
}
|
|
13075
|
+
var prefer_shared_zod_enum_default = createRule({
|
|
13076
|
+
name: "prefer-shared-zod-enum",
|
|
13077
|
+
documentation: PREFER_SHARED_ZOD_ENUM_DOCUMENTATION,
|
|
13078
|
+
meta: {
|
|
13079
|
+
type: "suggestion",
|
|
13080
|
+
docs: { description: "Reuse identical literal Zod enum domains within a module." },
|
|
13081
|
+
schema: [],
|
|
13082
|
+
messages: {
|
|
13083
|
+
shareEnumDomain: "This Zod enum repeats an earlier identical domain; extract and reuse one module-level named schema."
|
|
13084
|
+
}
|
|
13085
|
+
},
|
|
13086
|
+
defaultOptions: [],
|
|
13087
|
+
create(context) {
|
|
13088
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
13089
|
+
const zodBindings = /* @__PURE__ */ new Set();
|
|
13090
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13091
|
+
return {
|
|
13092
|
+
ImportDeclaration(node) {
|
|
13093
|
+
if (!isZodModule(node.source.value)) return;
|
|
13094
|
+
for (const specifier of node.specifiers) {
|
|
13095
|
+
if (specifier.type === import_utils74.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils74.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils74.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === import_utils74.AST_NODE_TYPES.Identifier && specifier.imported.name === "z") zodBindings.add(specifier.local.name);
|
|
13096
|
+
}
|
|
13097
|
+
},
|
|
13098
|
+
CallExpression(node) {
|
|
13099
|
+
if (node.callee.type !== import_utils74.AST_NODE_TYPES.MemberExpression || node.callee.computed || node.callee.object.type !== import_utils74.AST_NODE_TYPES.Identifier || !zodBindings.has(node.callee.object.name) || node.callee.property.type !== import_utils74.AST_NODE_TYPES.Identifier || node.callee.property.name !== "enum") return;
|
|
13100
|
+
const domain = literalDomain(node);
|
|
13101
|
+
if (domain === null) return;
|
|
13102
|
+
const key = JSON.stringify(domain);
|
|
13103
|
+
if (seen.has(key)) context.report({ node, messageId: "shareEnumDomain" });
|
|
13104
|
+
else seen.add(key);
|
|
13105
|
+
}
|
|
13106
|
+
};
|
|
13107
|
+
}
|
|
13108
|
+
});
|
|
13109
|
+
|
|
13110
|
+
// src/rules/prefer-switch-for-repeated-equality.ts
|
|
13111
|
+
var import_utils75 = require("@typescript-eslint/utils");
|
|
13112
|
+
var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
|
|
13113
|
+
summary: "Prefer switch over long if/else-if chains that compare one value for strict equality.",
|
|
13114
|
+
rationale: "A switch makes finite dispatch cases visually uniform and easier to extend without duplicating the discriminant.",
|
|
13115
|
+
remediation: "Replace three or more strict-equality branches over the same discriminant with a switch; keep if statements for ranges, guards, and heterogeneous predicates.",
|
|
13116
|
+
category: "maintainability",
|
|
13117
|
+
limitations: [
|
|
13118
|
+
"Only direct if/else-if chains with at least three strict-equality tests are reported.",
|
|
13119
|
+
"The rule deliberately ignores compound predicates, loose equality, ranges, and chains that compare different discriminants."
|
|
13120
|
+
],
|
|
13121
|
+
examples: [
|
|
13122
|
+
{ id: "switch-dispatch", title: "Make finite dispatch explicit", outcome: "no-match", files: [{ path: "src/render.ts", source: "switch (kind) { case 'a': return a(); case 'b': return b(); case 'c': return c(); default: return fallback(); }" }], focusPath: "src/render.ts", expectedCount: 0, public: true },
|
|
13123
|
+
{ id: "repeated-equality", title: "Avoid repeating the discriminant", outcome: "match", files: [{ path: "src/render.ts", source: "if (kind === 'a') return a(); else if (kind === 'b') return b(); else if (kind === 'c') return c();" }], focusPath: "src/render.ts", expectedCount: 1, public: true }
|
|
13124
|
+
]
|
|
13125
|
+
};
|
|
13126
|
+
function discriminantText(sourceCode, test) {
|
|
13127
|
+
if (test.type !== import_utils75.AST_NODE_TYPES.BinaryExpression || test.operator !== "===") return null;
|
|
13128
|
+
const leftIsCase = test.left.type === import_utils75.AST_NODE_TYPES.Literal;
|
|
13129
|
+
const rightIsCase = test.right.type === import_utils75.AST_NODE_TYPES.Literal;
|
|
13130
|
+
if (leftIsCase === rightIsCase) return null;
|
|
13131
|
+
return sourceCode.getText(leftIsCase ? test.right : test.left);
|
|
13132
|
+
}
|
|
13133
|
+
var prefer_switch_for_repeated_equality_default = createRule({
|
|
13134
|
+
name: "prefer-switch-for-repeated-equality",
|
|
13135
|
+
documentation: PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION,
|
|
13136
|
+
meta: {
|
|
13137
|
+
type: "suggestion",
|
|
13138
|
+
docs: { description: "Prefer switch over long if/else-if chains that compare one value for strict equality." },
|
|
13139
|
+
schema: [],
|
|
13140
|
+
messages: {
|
|
13141
|
+
preferSwitch: "This if/else-if chain repeatedly compares `{{discriminant}}`; use a switch for the finite cases."
|
|
13142
|
+
}
|
|
13143
|
+
},
|
|
13144
|
+
defaultOptions: [],
|
|
13145
|
+
create(context) {
|
|
13146
|
+
return {
|
|
13147
|
+
IfStatement(node) {
|
|
13148
|
+
if (node.parent.type === import_utils75.AST_NODE_TYPES.IfStatement && node.parent.alternate === node) return;
|
|
13149
|
+
const first = discriminantText(context.sourceCode, node.test);
|
|
13150
|
+
if (first === null) return;
|
|
13151
|
+
let count = 1;
|
|
13152
|
+
let current = node.alternate;
|
|
13153
|
+
while (current?.type === import_utils75.AST_NODE_TYPES.IfStatement) {
|
|
13154
|
+
if (discriminantText(context.sourceCode, current.test) !== first) return;
|
|
13155
|
+
count += 1;
|
|
13156
|
+
current = current.alternate;
|
|
13157
|
+
}
|
|
13158
|
+
if (count >= 3) {
|
|
13159
|
+
context.report({ node, messageId: "preferSwitch", data: { discriminant: first } });
|
|
13160
|
+
}
|
|
13161
|
+
}
|
|
13162
|
+
};
|
|
13163
|
+
}
|
|
13164
|
+
});
|
|
13165
|
+
|
|
12706
13166
|
// src/rules/prefer-semantic-colors.ts
|
|
12707
|
-
var
|
|
13167
|
+
var import_utils76 = require("@typescript-eslint/utils");
|
|
12708
13168
|
var import_fs = require("fs");
|
|
12709
13169
|
var import_path = require("path");
|
|
12710
13170
|
|
|
@@ -12816,7 +13276,7 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
12816
13276
|
var isInsideSvg = (node) => {
|
|
12817
13277
|
let current = node.parent;
|
|
12818
13278
|
while (current !== void 0 && current !== null) {
|
|
12819
|
-
if (current.type ===
|
|
13279
|
+
if (current.type === import_utils76.AST_NODE_TYPES.JSXElement) {
|
|
12820
13280
|
const name = jsxElementName(current);
|
|
12821
13281
|
if (name !== null && isSvgLikeElementName(name)) return true;
|
|
12822
13282
|
}
|
|
@@ -12826,8 +13286,8 @@ var isInsideSvg = (node) => {
|
|
|
12826
13286
|
};
|
|
12827
13287
|
function jsxElementName(node) {
|
|
12828
13288
|
const name = node.openingElement.name;
|
|
12829
|
-
if (name.type ===
|
|
12830
|
-
if (name.type ===
|
|
13289
|
+
if (name.type === import_utils76.AST_NODE_TYPES.JSXIdentifier) return name.name;
|
|
13290
|
+
if (name.type === import_utils76.AST_NODE_TYPES.JSXMemberExpression && name.property.type === import_utils76.AST_NODE_TYPES.JSXIdentifier) {
|
|
12831
13291
|
return name.property.name;
|
|
12832
13292
|
}
|
|
12833
13293
|
return null;
|
|
@@ -12853,7 +13313,7 @@ function isSvgLikeElementName(name) {
|
|
|
12853
13313
|
var isInsideIconFactoryPath = (node) => {
|
|
12854
13314
|
let current = node.parent;
|
|
12855
13315
|
while (current !== void 0 && current !== null) {
|
|
12856
|
-
if (current.type ===
|
|
13316
|
+
if (current.type === import_utils76.AST_NODE_TYPES.Property && propName(current.key) === "path" && current.parent.type === import_utils76.AST_NODE_TYPES.ObjectExpression && current.parent.parent.type === import_utils76.AST_NODE_TYPES.CallExpression && current.parent.parent.callee.type === import_utils76.AST_NODE_TYPES.Identifier && current.parent.parent.callee.name === "createIcon") {
|
|
12857
13317
|
return true;
|
|
12858
13318
|
}
|
|
12859
13319
|
current = current.parent;
|
|
@@ -12987,12 +13447,12 @@ var expandWorkspaceGlob = (root, glob) => {
|
|
|
12987
13447
|
return (0, import_fs.readdirSync)(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => (0, import_path.join)(parent, entry.name));
|
|
12988
13448
|
};
|
|
12989
13449
|
var propName = (key) => {
|
|
12990
|
-
if (key.type ===
|
|
12991
|
-
if (key.type ===
|
|
13450
|
+
if (key.type === import_utils76.AST_NODE_TYPES.Identifier) return key.name;
|
|
13451
|
+
if (key.type === import_utils76.AST_NODE_TYPES.Literal && typeof key.value === "string") return key.value;
|
|
12992
13452
|
return null;
|
|
12993
13453
|
};
|
|
12994
13454
|
var staticallyImportsEmailOrPdfRenderer = (program) => program.body.some((statement) => {
|
|
12995
|
-
if (statement.type !==
|
|
13455
|
+
if (statement.type !== import_utils76.AST_NODE_TYPES.ImportDeclaration && statement.type !== import_utils76.AST_NODE_TYPES.ExportNamedDeclaration && statement.type !== import_utils76.AST_NODE_TYPES.ExportAllDeclaration) {
|
|
12996
13456
|
return false;
|
|
12997
13457
|
}
|
|
12998
13458
|
return statement.source !== null && typeof statement.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(statement.source.value);
|
|
@@ -13029,43 +13489,43 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13029
13489
|
}
|
|
13030
13490
|
let importsEmailOrPdfRenderer = false;
|
|
13031
13491
|
const pendingReports = [];
|
|
13032
|
-
const
|
|
13492
|
+
const report2 = (node, messageId, data) => {
|
|
13033
13493
|
pendingReports.push({ node, messageId, data });
|
|
13034
13494
|
};
|
|
13035
13495
|
const reportClasses = (value, node) => {
|
|
13036
13496
|
for (const token of classTokens(value)) {
|
|
13037
13497
|
const base = tailwindBase(token);
|
|
13038
13498
|
if (RAW_PALETTE_RE.test(base)) {
|
|
13039
|
-
|
|
13499
|
+
report2(node, "rawPalette", { class: token });
|
|
13040
13500
|
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
13041
|
-
|
|
13501
|
+
report2(node, "arbitraryColor", { class: token });
|
|
13042
13502
|
}
|
|
13043
13503
|
}
|
|
13044
13504
|
};
|
|
13045
13505
|
const checkClassNode = (node) => {
|
|
13046
13506
|
if (node === null) return;
|
|
13047
13507
|
switch (node.type) {
|
|
13048
|
-
case
|
|
13508
|
+
case import_utils76.AST_NODE_TYPES.Literal:
|
|
13049
13509
|
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
13050
13510
|
break;
|
|
13051
|
-
case
|
|
13511
|
+
case import_utils76.AST_NODE_TYPES.TemplateLiteral:
|
|
13052
13512
|
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
13053
13513
|
break;
|
|
13054
|
-
case
|
|
13514
|
+
case import_utils76.AST_NODE_TYPES.ArrayExpression:
|
|
13055
13515
|
for (const element of node.elements) {
|
|
13056
|
-
if (element !== null && element.type !==
|
|
13516
|
+
if (element !== null && element.type !== import_utils76.AST_NODE_TYPES.SpreadElement) checkClassNode(element);
|
|
13057
13517
|
}
|
|
13058
13518
|
break;
|
|
13059
|
-
case
|
|
13519
|
+
case import_utils76.AST_NODE_TYPES.ObjectExpression:
|
|
13060
13520
|
for (const property of node.properties) {
|
|
13061
|
-
if (property.type ===
|
|
13521
|
+
if (property.type === import_utils76.AST_NODE_TYPES.Property) checkClassNode(property.value);
|
|
13062
13522
|
}
|
|
13063
13523
|
break;
|
|
13064
|
-
case
|
|
13524
|
+
case import_utils76.AST_NODE_TYPES.ConditionalExpression:
|
|
13065
13525
|
checkClassNode(node.consequent);
|
|
13066
13526
|
checkClassNode(node.alternate);
|
|
13067
13527
|
break;
|
|
13068
|
-
case
|
|
13528
|
+
case import_utils76.AST_NODE_TYPES.LogicalExpression:
|
|
13069
13529
|
checkClassNode(node.right);
|
|
13070
13530
|
break;
|
|
13071
13531
|
default:
|
|
@@ -13073,32 +13533,32 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13073
13533
|
}
|
|
13074
13534
|
};
|
|
13075
13535
|
const checkColorValueNode = (node) => {
|
|
13076
|
-
if (node.type ===
|
|
13077
|
-
|
|
13536
|
+
if (node.type === import_utils76.AST_NODE_TYPES.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value) && !CSS_VAR_REFERENCE_RE.test(node.value)) {
|
|
13537
|
+
report2(node, "inlineColor", { value: node.value });
|
|
13078
13538
|
}
|
|
13079
13539
|
};
|
|
13080
13540
|
return {
|
|
13081
13541
|
"JSXAttribute[name.name='className']"(node) {
|
|
13082
13542
|
if (node.value === null) return;
|
|
13083
|
-
if (node.value.type ===
|
|
13084
|
-
else if (node.value.type ===
|
|
13085
|
-
if (node.value.expression.type !==
|
|
13543
|
+
if (node.value.type === import_utils76.AST_NODE_TYPES.Literal) checkClassNode(node.value);
|
|
13544
|
+
else if (node.value.type === import_utils76.AST_NODE_TYPES.JSXExpressionContainer) {
|
|
13545
|
+
if (node.value.expression.type !== import_utils76.AST_NODE_TYPES.JSXEmptyExpression) {
|
|
13086
13546
|
checkClassNode(node.value.expression);
|
|
13087
13547
|
}
|
|
13088
13548
|
}
|
|
13089
13549
|
},
|
|
13090
13550
|
CallExpression(node) {
|
|
13091
|
-
if (node.callee.type ===
|
|
13551
|
+
if (node.callee.type === import_utils76.AST_NODE_TYPES.Identifier && node.callee.name === "require" && node.arguments[0]?.type === import_utils76.AST_NODE_TYPES.Literal && typeof node.arguments[0].value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.arguments[0].value)) {
|
|
13092
13552
|
importsEmailOrPdfRenderer = true;
|
|
13093
13553
|
}
|
|
13094
|
-
if (node.callee.type ===
|
|
13554
|
+
if (node.callee.type === import_utils76.AST_NODE_TYPES.Identifier && CLASS_FNS.has(node.callee.name)) {
|
|
13095
13555
|
for (const arg of node.arguments) {
|
|
13096
|
-
if (arg.type !==
|
|
13556
|
+
if (arg.type !== import_utils76.AST_NODE_TYPES.SpreadElement) checkClassNode(arg);
|
|
13097
13557
|
}
|
|
13098
13558
|
}
|
|
13099
13559
|
},
|
|
13100
13560
|
VariableDeclarator(node) {
|
|
13101
|
-
if (node.id.type ===
|
|
13561
|
+
if (node.id.type === import_utils76.AST_NODE_TYPES.Identifier && CLASS_NAME_RE.test(node.id.name)) {
|
|
13102
13562
|
checkClassNode(node.init);
|
|
13103
13563
|
}
|
|
13104
13564
|
},
|
|
@@ -13108,9 +13568,9 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13108
13568
|
},
|
|
13109
13569
|
// SVG artwork colors are exempt; component presentation colors still report.
|
|
13110
13570
|
"JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
|
|
13111
|
-
if (node.value?.type !==
|
|
13571
|
+
if (node.value?.type !== import_utils76.AST_NODE_TYPES.Literal) return;
|
|
13112
13572
|
const owner = node.parent.name;
|
|
13113
|
-
if (owner.type ===
|
|
13573
|
+
if (owner.type === import_utils76.AST_NODE_TYPES.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
|
|
13114
13574
|
return;
|
|
13115
13575
|
}
|
|
13116
13576
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
@@ -13124,7 +13584,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13124
13584
|
if (name !== null && STYLE_COLOR_PROPS.has(name)) checkColorValueNode(node.value);
|
|
13125
13585
|
},
|
|
13126
13586
|
ImportExpression(node) {
|
|
13127
|
-
if (node.source.type ===
|
|
13587
|
+
if (node.source.type === import_utils76.AST_NODE_TYPES.Literal && typeof node.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.source.value)) {
|
|
13128
13588
|
importsEmailOrPdfRenderer = true;
|
|
13129
13589
|
}
|
|
13130
13590
|
},
|
|
@@ -13137,7 +13597,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13137
13597
|
});
|
|
13138
13598
|
|
|
13139
13599
|
// src/rules/prefer-server-actions.ts
|
|
13140
|
-
var
|
|
13600
|
+
var import_utils77 = require("@typescript-eslint/utils");
|
|
13141
13601
|
var PREFER_SERVER_ACTIONS_DOCUMENTATION = {
|
|
13142
13602
|
summary: "Prefer Next.js Server Actions over /api/* mutations.",
|
|
13143
13603
|
rationale: "Server Actions preserve typed application calls and avoid an internal JSON request-response boundary.",
|
|
@@ -13326,7 +13786,7 @@ var prefer_server_actions_default = createRule({
|
|
|
13326
13786
|
});
|
|
13327
13787
|
|
|
13328
13788
|
// src/rules/prefer-whole-object-assertion.ts
|
|
13329
|
-
var
|
|
13789
|
+
var import_utils78 = require("@typescript-eslint/utils");
|
|
13330
13790
|
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
13331
13791
|
var SYNTHETIC_LITERAL_MATCHERS = /* @__PURE__ */ new Map([
|
|
13332
13792
|
["toBeNull", "null"],
|
|
@@ -13351,11 +13811,11 @@ var PREFER_WHOLE_OBJECT_ASSERTION_DOCUMENTATION = {
|
|
|
13351
13811
|
};
|
|
13352
13812
|
function literalText(node, getText) {
|
|
13353
13813
|
switch (node.type) {
|
|
13354
|
-
case
|
|
13814
|
+
case import_utils78.AST_NODE_TYPES.Literal:
|
|
13355
13815
|
return "regex" in node ? null : getText(node);
|
|
13356
|
-
case
|
|
13816
|
+
case import_utils78.AST_NODE_TYPES.TemplateLiteral:
|
|
13357
13817
|
return node.expressions.length === 0 ? getText(node) : null;
|
|
13358
|
-
case
|
|
13818
|
+
case import_utils78.AST_NODE_TYPES.UnaryExpression:
|
|
13359
13819
|
return NUMERIC_SIGNS2.has(node.operator) && literalText(node.argument, getText) !== null ? getText(node) : null;
|
|
13360
13820
|
default:
|
|
13361
13821
|
return null;
|
|
@@ -13363,15 +13823,15 @@ function literalText(node, getText) {
|
|
|
13363
13823
|
}
|
|
13364
13824
|
function isPureReceiver(node) {
|
|
13365
13825
|
switch (node.type) {
|
|
13366
|
-
case
|
|
13367
|
-
case
|
|
13826
|
+
case import_utils78.AST_NODE_TYPES.Identifier:
|
|
13827
|
+
case import_utils78.AST_NODE_TYPES.ThisExpression:
|
|
13368
13828
|
return true;
|
|
13369
|
-
case
|
|
13829
|
+
case import_utils78.AST_NODE_TYPES.MemberExpression:
|
|
13370
13830
|
if (node.optional) {
|
|
13371
13831
|
return false;
|
|
13372
13832
|
}
|
|
13373
13833
|
if (node.computed) {
|
|
13374
|
-
return node.property.type ===
|
|
13834
|
+
return node.property.type === import_utils78.AST_NODE_TYPES.Literal && isPureReceiver(node.object);
|
|
13375
13835
|
}
|
|
13376
13836
|
return isPureReceiver(node.object);
|
|
13377
13837
|
default:
|
|
@@ -13379,7 +13839,7 @@ function isPureReceiver(node) {
|
|
|
13379
13839
|
}
|
|
13380
13840
|
}
|
|
13381
13841
|
function literalIndex(node) {
|
|
13382
|
-
if (node.type !==
|
|
13842
|
+
if (node.type !== import_utils78.AST_NODE_TYPES.Literal || typeof node.value !== "number") {
|
|
13383
13843
|
return null;
|
|
13384
13844
|
}
|
|
13385
13845
|
return Number.isInteger(node.value) && node.value >= 0 ? node.value : null;
|
|
@@ -13387,8 +13847,8 @@ function literalIndex(node) {
|
|
|
13387
13847
|
function propertyAccess(node) {
|
|
13388
13848
|
const path = [];
|
|
13389
13849
|
let current = node;
|
|
13390
|
-
while (current.type ===
|
|
13391
|
-
if (current.property.type !==
|
|
13850
|
+
while (current.type === import_utils78.AST_NODE_TYPES.MemberExpression && !current.computed && !current.optional) {
|
|
13851
|
+
if (current.property.type !== import_utils78.AST_NODE_TYPES.Identifier || COLLECTION_PROPERTIES.has(current.property.name) || LITERAL_KEY_HAZARDS.has(current.property.name)) return null;
|
|
13392
13852
|
path.unshift(current.property.name);
|
|
13393
13853
|
current = current.object;
|
|
13394
13854
|
}
|
|
@@ -13416,24 +13876,24 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13416
13876
|
}
|
|
13417
13877
|
const { sourceCode } = context;
|
|
13418
13878
|
function parseAssertion(statement) {
|
|
13419
|
-
if (statement.type !==
|
|
13879
|
+
if (statement.type !== import_utils78.AST_NODE_TYPES.ExpressionStatement) {
|
|
13420
13880
|
return null;
|
|
13421
13881
|
}
|
|
13422
13882
|
const call = statement.expression;
|
|
13423
|
-
if (call.type !==
|
|
13883
|
+
if (call.type !== import_utils78.AST_NODE_TYPES.CallExpression) {
|
|
13424
13884
|
return null;
|
|
13425
13885
|
}
|
|
13426
13886
|
const callee = call.callee;
|
|
13427
|
-
if (callee.type !==
|
|
13887
|
+
if (callee.type !== import_utils78.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils78.AST_NODE_TYPES.Identifier) {
|
|
13428
13888
|
return null;
|
|
13429
13889
|
}
|
|
13430
13890
|
const matcher = callee.property.name;
|
|
13431
13891
|
const expectCall = callee.object;
|
|
13432
|
-
if (expectCall.type !==
|
|
13892
|
+
if (expectCall.type !== import_utils78.AST_NODE_TYPES.CallExpression || expectCall.callee.type !== import_utils78.AST_NODE_TYPES.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
13433
13893
|
return null;
|
|
13434
13894
|
}
|
|
13435
13895
|
const actual = expectCall.arguments[0];
|
|
13436
|
-
if (actual === void 0 || actual.type !==
|
|
13896
|
+
if (actual === void 0 || actual.type !== import_utils78.AST_NODE_TYPES.MemberExpression || actual.optional) {
|
|
13437
13897
|
return null;
|
|
13438
13898
|
}
|
|
13439
13899
|
if (!isPureReceiver(actual.object)) {
|
|
@@ -13462,7 +13922,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13462
13922
|
return null;
|
|
13463
13923
|
}
|
|
13464
13924
|
const expected = call.arguments[0];
|
|
13465
|
-
if (call.arguments.length !== 1 || expected === void 0 || expected.type ===
|
|
13925
|
+
if (call.arguments.length !== 1 || expected === void 0 || expected.type === import_utils78.AST_NODE_TYPES.SpreadElement) {
|
|
13466
13926
|
return null;
|
|
13467
13927
|
}
|
|
13468
13928
|
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
@@ -13603,7 +14063,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13603
14063
|
});
|
|
13604
14064
|
|
|
13605
14065
|
// src/rules/repeated-static-call-cases.ts
|
|
13606
|
-
var
|
|
14066
|
+
var import_utils79 = require("@typescript-eslint/utils");
|
|
13607
14067
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
13608
14068
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
13609
14069
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
@@ -13624,67 +14084,67 @@ var EXPECT_MODIFIERS = /* @__PURE__ */ new Set(["not", "rejects", "resolves"]);
|
|
|
13624
14084
|
var SNAPSHOT_MATCHERS = /snapshot/iu;
|
|
13625
14085
|
var MIN_CASES2 = 3;
|
|
13626
14086
|
function staticMemberName5(node) {
|
|
13627
|
-
if (!node.computed && node.property.type ===
|
|
13628
|
-
if (node.computed && node.property.type ===
|
|
14087
|
+
if (!node.computed && node.property.type === import_utils79.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
14088
|
+
if (node.computed && node.property.type === import_utils79.AST_NODE_TYPES.Literal && typeof node.property.value === "string") return node.property.value;
|
|
13629
14089
|
return null;
|
|
13630
14090
|
}
|
|
13631
|
-
function
|
|
13632
|
-
const variable =
|
|
14091
|
+
function importedName6(identifier, context, modules) {
|
|
14092
|
+
const variable = import_utils79.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
13633
14093
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
13634
14094
|
for (const definition of variable.defs) {
|
|
13635
|
-
if (definition.node.type !==
|
|
14095
|
+
if (definition.node.type !== import_utils79.AST_NODE_TYPES.ImportSpecifier) continue;
|
|
13636
14096
|
const declaration = definition.node.parent;
|
|
13637
|
-
if (declaration.type !==
|
|
14097
|
+
if (declaration.type !== import_utils79.AST_NODE_TYPES.ImportDeclaration || typeof declaration.source.value !== "string" || !modules.has(declaration.source.value)) continue;
|
|
13638
14098
|
const imported = definition.node.imported;
|
|
13639
|
-
return imported.type ===
|
|
14099
|
+
return imported.type === import_utils79.AST_NODE_TYPES.Identifier ? imported.name : String(imported.value);
|
|
13640
14100
|
}
|
|
13641
14101
|
return null;
|
|
13642
14102
|
}
|
|
13643
14103
|
function isDirectTestCallback2(node, context) {
|
|
13644
|
-
if (node.type !==
|
|
14104
|
+
if (node.type !== import_utils79.AST_NODE_TYPES.ArrowFunctionExpression && node.type !== import_utils79.AST_NODE_TYPES.FunctionExpression) return false;
|
|
13645
14105
|
const call = node.parent;
|
|
13646
|
-
if (call?.type !==
|
|
14106
|
+
if (call?.type !== import_utils79.AST_NODE_TYPES.CallExpression || !call.arguments.includes(node)) return false;
|
|
13647
14107
|
const root = testRoot2(call.callee);
|
|
13648
|
-
return root !== null && TEST_NAMES2.has(
|
|
14108
|
+
return root !== null && TEST_NAMES2.has(importedName6(root, context, TEST_MODULES4) ?? "");
|
|
13649
14109
|
}
|
|
13650
14110
|
function testRoot2(callee) {
|
|
13651
|
-
if (callee.type ===
|
|
13652
|
-
if (callee.type !==
|
|
14111
|
+
if (callee.type === import_utils79.AST_NODE_TYPES.Identifier) return callee;
|
|
14112
|
+
if (callee.type !== import_utils79.AST_NODE_TYPES.MemberExpression) return null;
|
|
13653
14113
|
const modifier = staticMemberName5(callee);
|
|
13654
14114
|
return modifier !== null && TEST_MODIFIERS4.has(modifier) ? testRoot2(callee.object) : null;
|
|
13655
14115
|
}
|
|
13656
14116
|
function isStatic(node) {
|
|
13657
|
-
if (node.type ===
|
|
14117
|
+
if (node.type === import_utils79.AST_NODE_TYPES.TSAsExpression || node.type === import_utils79.AST_NODE_TYPES.TSTypeAssertion || node.type === import_utils79.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils79.AST_NODE_TYPES.TSNonNullExpression) return isStatic(node.expression);
|
|
13658
14118
|
switch (node.type) {
|
|
13659
|
-
case
|
|
14119
|
+
case import_utils79.AST_NODE_TYPES.Literal:
|
|
13660
14120
|
return true;
|
|
13661
|
-
case
|
|
14121
|
+
case import_utils79.AST_NODE_TYPES.TemplateLiteral:
|
|
13662
14122
|
return node.expressions.length === 0;
|
|
13663
|
-
case
|
|
14123
|
+
case import_utils79.AST_NODE_TYPES.UnaryExpression:
|
|
13664
14124
|
return (node.operator === "+" || node.operator === "-") && isStatic(node.argument);
|
|
13665
|
-
case
|
|
13666
|
-
return node.elements.every((item) => item !== null && item.type !==
|
|
13667
|
-
case
|
|
13668
|
-
return node.properties.every((property) => property.type ===
|
|
14125
|
+
case import_utils79.AST_NODE_TYPES.ArrayExpression:
|
|
14126
|
+
return node.elements.every((item) => item !== null && item.type !== import_utils79.AST_NODE_TYPES.SpreadElement && isStatic(item));
|
|
14127
|
+
case import_utils79.AST_NODE_TYPES.ObjectExpression:
|
|
14128
|
+
return node.properties.every((property) => property.type === import_utils79.AST_NODE_TYPES.Property && !property.computed && property.kind === "init" && property.value.type !== import_utils79.AST_NODE_TYPES.AssignmentPattern && isStatic(property.value));
|
|
13669
14129
|
default:
|
|
13670
14130
|
return false;
|
|
13671
14131
|
}
|
|
13672
14132
|
}
|
|
13673
14133
|
function staticShape(node) {
|
|
13674
|
-
if (node.type ===
|
|
14134
|
+
if (node.type === import_utils79.AST_NODE_TYPES.TSAsExpression || node.type === import_utils79.AST_NODE_TYPES.TSTypeAssertion || node.type === import_utils79.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils79.AST_NODE_TYPES.TSNonNullExpression) return staticShape(node.expression);
|
|
13675
14135
|
switch (node.type) {
|
|
13676
|
-
case
|
|
14136
|
+
case import_utils79.AST_NODE_TYPES.Literal:
|
|
13677
14137
|
return `literal:${typeof node.value}`;
|
|
13678
|
-
case
|
|
14138
|
+
case import_utils79.AST_NODE_TYPES.TemplateLiteral:
|
|
13679
14139
|
return "template";
|
|
13680
|
-
case
|
|
14140
|
+
case import_utils79.AST_NODE_TYPES.UnaryExpression:
|
|
13681
14141
|
return `unary:${node.operator}:${staticShape(node.argument)}`;
|
|
13682
|
-
case
|
|
13683
|
-
return `array(${node.elements.map((item) => item === null || item.type ===
|
|
13684
|
-
case
|
|
14142
|
+
case import_utils79.AST_NODE_TYPES.ArrayExpression:
|
|
14143
|
+
return `array(${node.elements.map((item) => item === null || item.type === import_utils79.AST_NODE_TYPES.SpreadElement ? "invalid" : staticShape(item)).join(",")})`;
|
|
14144
|
+
case import_utils79.AST_NODE_TYPES.ObjectExpression:
|
|
13685
14145
|
return `object(${node.properties.map((property) => {
|
|
13686
|
-
if (property.type !==
|
|
13687
|
-
const key = property.key.type ===
|
|
14146
|
+
if (property.type !== import_utils79.AST_NODE_TYPES.Property || property.computed || property.value.type === import_utils79.AST_NODE_TYPES.AssignmentPattern) return "invalid";
|
|
14147
|
+
const key = property.key.type === import_utils79.AST_NODE_TYPES.Identifier ? property.key.name : String(property.key.value);
|
|
13688
14148
|
return `${key}:${staticShape(property.value)}`;
|
|
13689
14149
|
}).join(",")})`;
|
|
13690
14150
|
default:
|
|
@@ -13692,16 +14152,16 @@ function staticShape(node) {
|
|
|
13692
14152
|
}
|
|
13693
14153
|
}
|
|
13694
14154
|
function assertionShape(statement, context) {
|
|
13695
|
-
if (statement.type !==
|
|
14155
|
+
if (statement.type !== import_utils79.AST_NODE_TYPES.ExpressionStatement || statement.expression.type !== import_utils79.AST_NODE_TYPES.CallExpression) return null;
|
|
13696
14156
|
const matcherCall = statement.expression;
|
|
13697
|
-
if (matcherCall.callee.type !==
|
|
14157
|
+
if (matcherCall.callee.type !== import_utils79.AST_NODE_TYPES.MemberExpression || matcherCall.callee.computed || matcherCall.callee.property.type !== import_utils79.AST_NODE_TYPES.Identifier || matcherCall.arguments.length !== 1) return null;
|
|
13698
14158
|
const matcher = matcherCall.callee.property.name;
|
|
13699
14159
|
if (SNAPSHOT_MATCHERS.test(matcher)) return null;
|
|
13700
14160
|
const chain = expectCallFromMatcher(matcherCall.callee);
|
|
13701
|
-
if (chain === null || chain.call.callee.type !==
|
|
14161
|
+
if (chain === null || chain.call.callee.type !== import_utils79.AST_NODE_TYPES.Identifier || importedName6(chain.call.callee, context, ASSERTION_MODULES3) !== "expect" || chain.call.arguments.length !== 1) return null;
|
|
13702
14162
|
const observed = chain.call.arguments[0];
|
|
13703
14163
|
const expected = matcherCall.arguments[0];
|
|
13704
|
-
if (observed?.type !==
|
|
14164
|
+
if (observed?.type !== import_utils79.AST_NODE_TYPES.CallExpression || observed.callee.type !== import_utils79.AST_NODE_TYPES.Identifier || observed.arguments.length === 0 || observed.arguments.some((arg) => arg.type === import_utils79.AST_NODE_TYPES.SpreadElement || !isStatic(arg)) || expected?.type === import_utils79.AST_NODE_TYPES.SpreadElement || expected === void 0 || !isStatic(expected)) return null;
|
|
13705
14165
|
const skeleton = `${observed.callee.name}/${observed.arguments.map((item) => staticShape(item)).join(",")}/${chain.modifiers.join(".")}/${matcher}/${staticShape(expected)}`;
|
|
13706
14166
|
const values = [...observed.arguments, expected].map((item) => context.sourceCode.getText(item)).join("\0");
|
|
13707
14167
|
return { statement, skeleton, values };
|
|
@@ -13709,13 +14169,13 @@ function assertionShape(statement, context) {
|
|
|
13709
14169
|
function expectCallFromMatcher(node) {
|
|
13710
14170
|
const modifiers = [];
|
|
13711
14171
|
let receiver = node.object;
|
|
13712
|
-
while (receiver.type ===
|
|
14172
|
+
while (receiver.type === import_utils79.AST_NODE_TYPES.MemberExpression) {
|
|
13713
14173
|
const modifier = staticMemberName5(receiver);
|
|
13714
14174
|
if (modifier === null || !EXPECT_MODIFIERS.has(modifier)) return null;
|
|
13715
14175
|
modifiers.unshift(modifier);
|
|
13716
14176
|
receiver = receiver.object;
|
|
13717
14177
|
}
|
|
13718
|
-
return receiver.type ===
|
|
14178
|
+
return receiver.type === import_utils79.AST_NODE_TYPES.CallExpression ? { call: receiver, modifiers } : null;
|
|
13719
14179
|
}
|
|
13720
14180
|
var repeated_static_call_cases_default = createRule({
|
|
13721
14181
|
name: "repeated-static-call-cases",
|
|
@@ -13735,7 +14195,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13735
14195
|
return {
|
|
13736
14196
|
"CallExpression > ArrowFunctionExpression, CallExpression > FunctionExpression"(node) {
|
|
13737
14197
|
const call = node.parent;
|
|
13738
|
-
if (call?.type ===
|
|
14198
|
+
if (call?.type === import_utils79.AST_NODE_TYPES.CallExpression) {
|
|
13739
14199
|
const duplicate = duplicateTestBodyCandidate(call, sourceCode);
|
|
13740
14200
|
if (duplicate !== null && duplicate.body === node) {
|
|
13741
14201
|
const groups = duplicateGroups.get(duplicate.container) ?? /* @__PURE__ */ new Map();
|
|
@@ -13745,7 +14205,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13745
14205
|
duplicateGroups.set(duplicate.container, groups);
|
|
13746
14206
|
}
|
|
13747
14207
|
}
|
|
13748
|
-
if (!isDirectTestCallback2(node, context) || node.body.type !==
|
|
14208
|
+
if (!isDirectTestCallback2(node, context) || node.body.type !== import_utils79.AST_NODE_TYPES.BlockStatement) return;
|
|
13749
14209
|
let run = [];
|
|
13750
14210
|
const flush = () => {
|
|
13751
14211
|
if (run.length >= MIN_CASES2 && new Set(run.map((item) => item.values)).size > 1) {
|
|
@@ -13786,7 +14246,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13786
14246
|
});
|
|
13787
14247
|
|
|
13788
14248
|
// src/rules/prefer-zod-infer.ts
|
|
13789
|
-
var
|
|
14249
|
+
var import_utils80 = require("@typescript-eslint/utils");
|
|
13790
14250
|
var PREFER_ZOD_INFER_DOCUMENTATION = {
|
|
13791
14251
|
summary: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
|
|
13792
14252
|
rationale: "A derived type stays synchronized when the runtime schema changes.",
|
|
@@ -13839,47 +14299,47 @@ var ZOD_TYPE_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
|
13839
14299
|
"Schema"
|
|
13840
14300
|
]);
|
|
13841
14301
|
var LEAF_NODE_TYPES = {
|
|
13842
|
-
string: [
|
|
13843
|
-
email: [
|
|
13844
|
-
url: [
|
|
13845
|
-
uuid: [
|
|
13846
|
-
ulid: [
|
|
13847
|
-
cuid: [
|
|
13848
|
-
cuid2: [
|
|
13849
|
-
nanoid: [
|
|
13850
|
-
iso: [
|
|
13851
|
-
number: [
|
|
13852
|
-
int: [
|
|
13853
|
-
float32: [
|
|
13854
|
-
float64: [
|
|
13855
|
-
boolean: [
|
|
13856
|
-
bigint: [
|
|
13857
|
-
symbol: [
|
|
13858
|
-
any: [
|
|
13859
|
-
unknown: [
|
|
13860
|
-
never: [
|
|
13861
|
-
void: [
|
|
13862
|
-
null: [
|
|
13863
|
-
undefined: [
|
|
13864
|
-
literal: [
|
|
13865
|
-
date: [
|
|
13866
|
-
array: [
|
|
13867
|
-
tuple: [
|
|
13868
|
-
object: [
|
|
13869
|
-
strictObject: [
|
|
13870
|
-
looseObject: [
|
|
13871
|
-
record: [
|
|
13872
|
-
map: [
|
|
13873
|
-
set: [
|
|
13874
|
-
promise: [
|
|
13875
|
-
enum: [
|
|
13876
|
-
nativeEnum: [
|
|
13877
|
-
union: [
|
|
13878
|
-
discriminatedUnion: [
|
|
13879
|
-
intersection: [
|
|
14302
|
+
string: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14303
|
+
email: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14304
|
+
url: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14305
|
+
uuid: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14306
|
+
ulid: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14307
|
+
cuid: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14308
|
+
cuid2: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14309
|
+
nanoid: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14310
|
+
iso: [import_utils80.AST_NODE_TYPES.TSStringKeyword],
|
|
14311
|
+
number: [import_utils80.AST_NODE_TYPES.TSNumberKeyword],
|
|
14312
|
+
int: [import_utils80.AST_NODE_TYPES.TSNumberKeyword],
|
|
14313
|
+
float32: [import_utils80.AST_NODE_TYPES.TSNumberKeyword],
|
|
14314
|
+
float64: [import_utils80.AST_NODE_TYPES.TSNumberKeyword],
|
|
14315
|
+
boolean: [import_utils80.AST_NODE_TYPES.TSBooleanKeyword],
|
|
14316
|
+
bigint: [import_utils80.AST_NODE_TYPES.TSBigIntKeyword],
|
|
14317
|
+
symbol: [import_utils80.AST_NODE_TYPES.TSSymbolKeyword],
|
|
14318
|
+
any: [import_utils80.AST_NODE_TYPES.TSAnyKeyword],
|
|
14319
|
+
unknown: [import_utils80.AST_NODE_TYPES.TSUnknownKeyword],
|
|
14320
|
+
never: [import_utils80.AST_NODE_TYPES.TSNeverKeyword],
|
|
14321
|
+
void: [import_utils80.AST_NODE_TYPES.TSVoidKeyword],
|
|
14322
|
+
null: [import_utils80.AST_NODE_TYPES.TSNullKeyword],
|
|
14323
|
+
undefined: [import_utils80.AST_NODE_TYPES.TSUndefinedKeyword],
|
|
14324
|
+
literal: [import_utils80.AST_NODE_TYPES.TSLiteralType],
|
|
14325
|
+
date: [import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14326
|
+
array: [import_utils80.AST_NODE_TYPES.TSArrayType, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14327
|
+
tuple: [import_utils80.AST_NODE_TYPES.TSTupleType],
|
|
14328
|
+
object: [import_utils80.AST_NODE_TYPES.TSTypeLiteral, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14329
|
+
strictObject: [import_utils80.AST_NODE_TYPES.TSTypeLiteral, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14330
|
+
looseObject: [import_utils80.AST_NODE_TYPES.TSTypeLiteral, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14331
|
+
record: [import_utils80.AST_NODE_TYPES.TSTypeReference, import_utils80.AST_NODE_TYPES.TSTypeLiteral],
|
|
14332
|
+
map: [import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14333
|
+
set: [import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14334
|
+
promise: [import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14335
|
+
enum: [import_utils80.AST_NODE_TYPES.TSUnionType, import_utils80.AST_NODE_TYPES.TSTypeReference, import_utils80.AST_NODE_TYPES.TSLiteralType],
|
|
14336
|
+
nativeEnum: [import_utils80.AST_NODE_TYPES.TSUnionType, import_utils80.AST_NODE_TYPES.TSTypeReference, import_utils80.AST_NODE_TYPES.TSLiteralType],
|
|
14337
|
+
union: [import_utils80.AST_NODE_TYPES.TSUnionType, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14338
|
+
discriminatedUnion: [import_utils80.AST_NODE_TYPES.TSUnionType, import_utils80.AST_NODE_TYPES.TSTypeReference],
|
|
14339
|
+
intersection: [import_utils80.AST_NODE_TYPES.TSIntersectionType, import_utils80.AST_NODE_TYPES.TSTypeReference]
|
|
13880
14340
|
};
|
|
13881
14341
|
function primitiveLiteralKey(node) {
|
|
13882
|
-
if (node.type !==
|
|
14342
|
+
if (node.type !== import_utils80.AST_NODE_TYPES.Literal) {
|
|
13883
14343
|
return null;
|
|
13884
14344
|
}
|
|
13885
14345
|
if (node.value === null) {
|
|
@@ -13911,13 +14371,13 @@ function staticZodDomain(leaf, call) {
|
|
|
13911
14371
|
}
|
|
13912
14372
|
if (leaf === "literal") {
|
|
13913
14373
|
const [argument] = call.arguments;
|
|
13914
|
-
if (argument === void 0 || argument.type ===
|
|
14374
|
+
if (argument === void 0 || argument.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
13915
14375
|
return null;
|
|
13916
14376
|
}
|
|
13917
|
-
if (argument.type ===
|
|
14377
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ArrayExpression) {
|
|
13918
14378
|
return exactDomain(
|
|
13919
14379
|
argument.elements.map(
|
|
13920
|
-
(element) => element === null || element.type ===
|
|
14380
|
+
(element) => element === null || element.type === import_utils80.AST_NODE_TYPES.SpreadElement ? null : primitiveLiteralKey(element)
|
|
13921
14381
|
)
|
|
13922
14382
|
);
|
|
13923
14383
|
}
|
|
@@ -13925,13 +14385,13 @@ function staticZodDomain(leaf, call) {
|
|
|
13925
14385
|
}
|
|
13926
14386
|
if (leaf === "enum") {
|
|
13927
14387
|
const [argument] = call.arguments;
|
|
13928
|
-
if (argument === void 0 || argument.type ===
|
|
14388
|
+
if (argument === void 0 || argument.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
13929
14389
|
return null;
|
|
13930
14390
|
}
|
|
13931
|
-
if (argument.type ===
|
|
14391
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ArrayExpression) {
|
|
13932
14392
|
return exactDomain(
|
|
13933
14393
|
argument.elements.map((element) => {
|
|
13934
|
-
if (element === null || element.type ===
|
|
14394
|
+
if (element === null || element.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
13935
14395
|
return null;
|
|
13936
14396
|
}
|
|
13937
14397
|
const key = primitiveLiteralKey(element);
|
|
@@ -13939,10 +14399,10 @@ function staticZodDomain(leaf, call) {
|
|
|
13939
14399
|
})
|
|
13940
14400
|
);
|
|
13941
14401
|
}
|
|
13942
|
-
if (argument.type ===
|
|
14402
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ObjectExpression) {
|
|
13943
14403
|
return exactDomain(
|
|
13944
14404
|
argument.properties.map((property) => {
|
|
13945
|
-
if (property.type !==
|
|
14405
|
+
if (property.type !== import_utils80.AST_NODE_TYPES.Property || property.computed || property.kind !== "init" || property.method || property.shorthand) {
|
|
13946
14406
|
return null;
|
|
13947
14407
|
}
|
|
13948
14408
|
const key = primitiveLiteralKey(property.value);
|
|
@@ -13969,15 +14429,15 @@ function sameDomain(left, right) {
|
|
|
13969
14429
|
return true;
|
|
13970
14430
|
}
|
|
13971
14431
|
function isExportedDeclaration(node) {
|
|
13972
|
-
return node.parent?.type ===
|
|
14432
|
+
return node.parent?.type === import_utils80.AST_NODE_TYPES.ExportNamedDeclaration;
|
|
13973
14433
|
}
|
|
13974
14434
|
function isModuleLevelConst(node) {
|
|
13975
14435
|
const declaration = node.parent;
|
|
13976
|
-
if (declaration.type !==
|
|
14436
|
+
if (declaration.type !== import_utils80.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const") {
|
|
13977
14437
|
return false;
|
|
13978
14438
|
}
|
|
13979
14439
|
const container = declaration.parent;
|
|
13980
|
-
return container.type ===
|
|
14440
|
+
return container.type === import_utils80.AST_NODE_TYPES.Program || container.type === import_utils80.AST_NODE_TYPES.ExportNamedDeclaration && container.parent.type === import_utils80.AST_NODE_TYPES.Program;
|
|
13981
14441
|
}
|
|
13982
14442
|
function normalizeSchemaName(name) {
|
|
13983
14443
|
return name.replace(/Schema$/i, "").replace(/^Z(?=[A-Z])/, "").toLowerCase();
|
|
@@ -13986,20 +14446,20 @@ function normalizeTypeName(name) {
|
|
|
13986
14446
|
return name.replace(/Type$/, "").toLowerCase();
|
|
13987
14447
|
}
|
|
13988
14448
|
function unwrapNullish(annotation) {
|
|
13989
|
-
if (annotation.type !==
|
|
14449
|
+
if (annotation.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
13990
14450
|
return {
|
|
13991
14451
|
core: annotation,
|
|
13992
|
-
nullable: annotation.type ===
|
|
14452
|
+
nullable: annotation.type === import_utils80.AST_NODE_TYPES.TSNullKeyword
|
|
13993
14453
|
};
|
|
13994
14454
|
}
|
|
13995
14455
|
const rest = [];
|
|
13996
14456
|
let nullable = false;
|
|
13997
14457
|
for (const member of annotation.types) {
|
|
13998
|
-
if (member.type ===
|
|
14458
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSNullKeyword) {
|
|
13999
14459
|
nullable = true;
|
|
14000
14460
|
continue;
|
|
14001
14461
|
}
|
|
14002
|
-
if (member.type ===
|
|
14462
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSUndefinedKeyword) {
|
|
14003
14463
|
continue;
|
|
14004
14464
|
}
|
|
14005
14465
|
rest.push(member);
|
|
@@ -14033,18 +14493,18 @@ function leafAgrees(field, annotation) {
|
|
|
14033
14493
|
return null;
|
|
14034
14494
|
}
|
|
14035
14495
|
if (leaf === "date") {
|
|
14036
|
-
return core.type ===
|
|
14496
|
+
return core.type === import_utils80.AST_NODE_TYPES.TSTypeReference && core.typeName.type === import_utils80.AST_NODE_TYPES.Identifier && core.typeName.name === "Date";
|
|
14037
14497
|
}
|
|
14038
14498
|
return expected.includes(core.type);
|
|
14039
14499
|
}
|
|
14040
14500
|
function typeLiteralDomain(annotation) {
|
|
14041
|
-
const members = annotation.type ===
|
|
14501
|
+
const members = annotation.type === import_utils80.AST_NODE_TYPES.TSUnionType ? annotation.types : [annotation];
|
|
14042
14502
|
const keys = [];
|
|
14043
14503
|
for (const member of members) {
|
|
14044
|
-
if (member.type ===
|
|
14504
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSNullKeyword) {
|
|
14045
14505
|
continue;
|
|
14046
14506
|
}
|
|
14047
|
-
if (member.type !==
|
|
14507
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSLiteralType) {
|
|
14048
14508
|
return null;
|
|
14049
14509
|
}
|
|
14050
14510
|
keys.push(primitiveLiteralKey(member.literal));
|
|
@@ -14052,11 +14512,11 @@ function typeLiteralDomain(annotation) {
|
|
|
14052
14512
|
return exactDomain(keys);
|
|
14053
14513
|
}
|
|
14054
14514
|
function staticStringUnionDomain(node) {
|
|
14055
|
-
if (node.type !==
|
|
14515
|
+
if (node.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
14056
14516
|
return null;
|
|
14057
14517
|
}
|
|
14058
14518
|
const keys = node.types.map((member) => {
|
|
14059
|
-
if (member.type !==
|
|
14519
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSLiteralType) {
|
|
14060
14520
|
return null;
|
|
14061
14521
|
}
|
|
14062
14522
|
const key = primitiveLiteralKey(member.literal);
|
|
@@ -14124,14 +14584,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14124
14584
|
function zodCallChain(node) {
|
|
14125
14585
|
const chain = [];
|
|
14126
14586
|
let current = node;
|
|
14127
|
-
while (current.type ===
|
|
14587
|
+
while (current.type === import_utils80.AST_NODE_TYPES.CallExpression) {
|
|
14128
14588
|
const callee = current.callee;
|
|
14129
|
-
if (callee.type !==
|
|
14589
|
+
if (callee.type !== import_utils80.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14130
14590
|
return null;
|
|
14131
14591
|
}
|
|
14132
14592
|
chain.push(current);
|
|
14133
14593
|
const receiver = callee.object;
|
|
14134
|
-
if (receiver.type ===
|
|
14594
|
+
if (receiver.type === import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14135
14595
|
return zodNamespaces.has(receiver.name) ? chain.reverse() : null;
|
|
14136
14596
|
}
|
|
14137
14597
|
current = receiver;
|
|
@@ -14140,14 +14600,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14140
14600
|
}
|
|
14141
14601
|
function methodName2(call) {
|
|
14142
14602
|
const callee = call.callee;
|
|
14143
|
-
return callee.type ===
|
|
14603
|
+
return callee.type === import_utils80.AST_NODE_TYPES.MemberExpression && callee.property.type === import_utils80.AST_NODE_TYPES.Identifier ? callee.property.name : "";
|
|
14144
14604
|
}
|
|
14145
14605
|
function recordZodImport(node) {
|
|
14146
14606
|
if (!isZodModule(node.source.value)) {
|
|
14147
14607
|
return;
|
|
14148
14608
|
}
|
|
14149
14609
|
for (const specifier of node.specifiers) {
|
|
14150
|
-
if (specifier.type ===
|
|
14610
|
+
if (specifier.type === import_utils80.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils80.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils80.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === import_utils80.AST_NODE_TYPES.Identifier && specifier.imported.name === "z") {
|
|
14151
14611
|
zodNamespaces.add(specifier.local.name);
|
|
14152
14612
|
}
|
|
14153
14613
|
}
|
|
@@ -14157,13 +14617,13 @@ var prefer_zod_infer_default = createRule({
|
|
|
14157
14617
|
let current = node;
|
|
14158
14618
|
let leaf = null;
|
|
14159
14619
|
let leafCall = null;
|
|
14160
|
-
while (current.type ===
|
|
14620
|
+
while (current.type === import_utils80.AST_NODE_TYPES.CallExpression) {
|
|
14161
14621
|
const callee = current.callee;
|
|
14162
|
-
if (callee.type !==
|
|
14622
|
+
if (callee.type !== import_utils80.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14163
14623
|
break;
|
|
14164
14624
|
}
|
|
14165
14625
|
const receiver = callee.object;
|
|
14166
|
-
if (receiver.type ===
|
|
14626
|
+
if (receiver.type === import_utils80.AST_NODE_TYPES.Identifier && zodNamespaces.has(receiver.name)) {
|
|
14167
14627
|
leaf = callee.property.name;
|
|
14168
14628
|
leafCall = current;
|
|
14169
14629
|
break;
|
|
@@ -14194,20 +14654,20 @@ var prefer_zod_infer_default = createRule({
|
|
|
14194
14654
|
return domain instanceof Set && domain.size >= 2 ? domain : null;
|
|
14195
14655
|
}
|
|
14196
14656
|
function inferredSchemaName(node) {
|
|
14197
|
-
if (node.type !==
|
|
14657
|
+
if (node.type !== import_utils80.AST_NODE_TYPES.TSTypeReference || node.typeName.type !== import_utils80.AST_NODE_TYPES.TSQualifiedName || node.typeName.left.type !== import_utils80.AST_NODE_TYPES.Identifier || !zodNamespaces.has(node.typeName.left.name) || node.typeName.right.name !== "infer") {
|
|
14198
14658
|
return null;
|
|
14199
14659
|
}
|
|
14200
14660
|
const arguments_ = node.typeArguments?.params ?? [];
|
|
14201
14661
|
const [argument] = arguments_;
|
|
14202
|
-
return arguments_.length === 1 && argument?.type ===
|
|
14662
|
+
return arguments_.length === 1 && argument?.type === import_utils80.AST_NODE_TYPES.TSTypeQuery && argument.exprName.type === import_utils80.AST_NODE_TYPES.Identifier ? argument.exprName.name : null;
|
|
14203
14663
|
}
|
|
14204
14664
|
function recordLiteralUnions(members, owner, ownerName, exported) {
|
|
14205
14665
|
for (const member of members) {
|
|
14206
|
-
if (member.type !==
|
|
14666
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSPropertySignature || member.computed || member.optional || member.readonly || member.typeAnnotation === void 0) {
|
|
14207
14667
|
continue;
|
|
14208
14668
|
}
|
|
14209
14669
|
const key = member.key;
|
|
14210
|
-
const propertyName5 = key.type ===
|
|
14670
|
+
const propertyName5 = key.type === import_utils80.AST_NODE_TYPES.Identifier ? key.name : key.type === import_utils80.AST_NODE_TYPES.Literal && typeof key.value === "string" ? key.value : null;
|
|
14211
14671
|
if (propertyName5 === null) {
|
|
14212
14672
|
continue;
|
|
14213
14673
|
}
|
|
@@ -14217,7 +14677,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14217
14677
|
}
|
|
14218
14678
|
const annotation = member.typeAnnotation.typeAnnotation;
|
|
14219
14679
|
const domain = staticStringUnionDomain(annotation);
|
|
14220
|
-
if (domain === null || annotation.type !==
|
|
14680
|
+
if (domain === null || annotation.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
14221
14681
|
continue;
|
|
14222
14682
|
}
|
|
14223
14683
|
literalUnionOccurrences.push({
|
|
@@ -14248,16 +14708,16 @@ var prefer_zod_infer_default = createRule({
|
|
|
14248
14708
|
return null;
|
|
14249
14709
|
}
|
|
14250
14710
|
const shape = base.arguments[0];
|
|
14251
|
-
if (shape === void 0 || shape.type !==
|
|
14711
|
+
if (shape === void 0 || shape.type !== import_utils80.AST_NODE_TYPES.ObjectExpression) {
|
|
14252
14712
|
return null;
|
|
14253
14713
|
}
|
|
14254
14714
|
const fields = /* @__PURE__ */ new Map();
|
|
14255
14715
|
for (const property of shape.properties) {
|
|
14256
|
-
if (property.type !==
|
|
14716
|
+
if (property.type !== import_utils80.AST_NODE_TYPES.Property || property.computed) {
|
|
14257
14717
|
return null;
|
|
14258
14718
|
}
|
|
14259
14719
|
const { key } = property;
|
|
14260
|
-
const name = key.type ===
|
|
14720
|
+
const name = key.type === import_utils80.AST_NODE_TYPES.Identifier ? key.name : key.type === import_utils80.AST_NODE_TYPES.Literal && typeof key.value === "string" ? key.value : null;
|
|
14261
14721
|
if (name === null) {
|
|
14262
14722
|
return null;
|
|
14263
14723
|
}
|
|
@@ -14268,11 +14728,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
14268
14728
|
function typeMembers(members) {
|
|
14269
14729
|
const result = /* @__PURE__ */ new Map();
|
|
14270
14730
|
for (const member of members) {
|
|
14271
|
-
if (member.type !==
|
|
14731
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSPropertySignature || member.computed) {
|
|
14272
14732
|
return null;
|
|
14273
14733
|
}
|
|
14274
14734
|
const { key } = member;
|
|
14275
|
-
const name = key.type ===
|
|
14735
|
+
const name = key.type === import_utils80.AST_NODE_TYPES.Identifier ? key.name : key.type === import_utils80.AST_NODE_TYPES.Literal && typeof key.value === "string" ? key.value : null;
|
|
14276
14736
|
if (name === null) {
|
|
14277
14737
|
return null;
|
|
14278
14738
|
}
|
|
@@ -14287,8 +14747,8 @@ var prefer_zod_infer_default = createRule({
|
|
|
14287
14747
|
return result.size === 0 ? null : result;
|
|
14288
14748
|
}
|
|
14289
14749
|
function collectConstrainedNames(node) {
|
|
14290
|
-
if (node.type ===
|
|
14291
|
-
if (node.typeName.type ===
|
|
14750
|
+
if (node.type === import_utils80.AST_NODE_TYPES.TSTypeReference) {
|
|
14751
|
+
if (node.typeName.type === import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14292
14752
|
constrainedTypeNames.add(node.typeName.name);
|
|
14293
14753
|
}
|
|
14294
14754
|
for (const argument of node.typeArguments?.params ?? []) {
|
|
@@ -14296,11 +14756,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
14296
14756
|
}
|
|
14297
14757
|
return;
|
|
14298
14758
|
}
|
|
14299
|
-
if (node.type ===
|
|
14759
|
+
if (node.type === import_utils80.AST_NODE_TYPES.TSArrayType) {
|
|
14300
14760
|
collectConstrainedNames(node.elementType);
|
|
14301
14761
|
return;
|
|
14302
14762
|
}
|
|
14303
|
-
if (node.type ===
|
|
14763
|
+
if (node.type === import_utils80.AST_NODE_TYPES.TSUnionType || node.type === import_utils80.AST_NODE_TYPES.TSIntersectionType) {
|
|
14304
14764
|
for (const member of node.types) {
|
|
14305
14765
|
collectConstrainedNames(member);
|
|
14306
14766
|
}
|
|
@@ -14344,7 +14804,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14344
14804
|
return {
|
|
14345
14805
|
Program(node) {
|
|
14346
14806
|
for (const statement of node.body) {
|
|
14347
|
-
if (statement.type ===
|
|
14807
|
+
if (statement.type === import_utils80.AST_NODE_TYPES.ImportDeclaration) {
|
|
14348
14808
|
recordZodImport(statement);
|
|
14349
14809
|
}
|
|
14350
14810
|
}
|
|
@@ -14353,7 +14813,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14353
14813
|
recordZodImport(node);
|
|
14354
14814
|
},
|
|
14355
14815
|
VariableDeclarator(node) {
|
|
14356
|
-
if (node.id.type !==
|
|
14816
|
+
if (node.id.type !== import_utils80.AST_NODE_TYPES.Identifier || node.init == null) {
|
|
14357
14817
|
return;
|
|
14358
14818
|
}
|
|
14359
14819
|
const fields = schemaFields(node.init);
|
|
@@ -14370,14 +14830,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14370
14830
|
},
|
|
14371
14831
|
/** Records `XSchema.transform(...)` and equivalent module-level reshaping. */
|
|
14372
14832
|
"MemberExpression[computed=false]"(node) {
|
|
14373
|
-
if (node.object.type ===
|
|
14833
|
+
if (node.object.type === import_utils80.AST_NODE_TYPES.Identifier && node.property.type === import_utils80.AST_NODE_TYPES.Identifier && MODULE_LEVEL_RESHAPERS.has(node.property.name)) {
|
|
14374
14834
|
reshapedSchemaNames.add(node.object.name);
|
|
14375
14835
|
}
|
|
14376
14836
|
},
|
|
14377
14837
|
/** Records every type argument carried by a Zod constraint. */
|
|
14378
14838
|
TSTypeReference(node) {
|
|
14379
14839
|
const { typeName } = node;
|
|
14380
|
-
const referenced = typeName.type ===
|
|
14840
|
+
const referenced = typeName.type === import_utils80.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils80.AST_NODE_TYPES.TSQualifiedName && typeName.right.type === import_utils80.AST_NODE_TYPES.Identifier ? typeName.right.name : null;
|
|
14381
14841
|
if (referenced === null || !ZOD_TYPE_CONSTRAINTS.has(referenced)) {
|
|
14382
14842
|
return;
|
|
14383
14843
|
}
|
|
@@ -14409,7 +14869,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14409
14869
|
typeName: node.id.name
|
|
14410
14870
|
});
|
|
14411
14871
|
}
|
|
14412
|
-
if (node.typeParameters !== void 0 || node.typeAnnotation.type !==
|
|
14872
|
+
if (node.typeParameters !== void 0 || node.typeAnnotation.type !== import_utils80.AST_NODE_TYPES.TSTypeLiteral) {
|
|
14413
14873
|
return;
|
|
14414
14874
|
}
|
|
14415
14875
|
const members = typeMembers(node.typeAnnotation.members);
|
|
@@ -14508,8 +14968,8 @@ var prefer_zod_infer_default = createRule({
|
|
|
14508
14968
|
});
|
|
14509
14969
|
|
|
14510
14970
|
// src/rules/require-assert-never.ts
|
|
14511
|
-
var
|
|
14512
|
-
var
|
|
14971
|
+
var import_utils81 = require("@typescript-eslint/utils");
|
|
14972
|
+
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
14513
14973
|
var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
14514
14974
|
summary: "Require an empty switch default to call `assertNever` so discriminated unions remain exhaustive at compile time.",
|
|
14515
14975
|
rationale: "An empty default silently accepts new union members instead of making the compiler identify the missing case.",
|
|
@@ -14521,14 +14981,14 @@ var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
|
14521
14981
|
]
|
|
14522
14982
|
};
|
|
14523
14983
|
var isRuntimeHandlingStatement = (statement) => {
|
|
14524
|
-
if (statement.type ===
|
|
14525
|
-
if (statement.type ===
|
|
14984
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.EmptyStatement) return false;
|
|
14985
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.BreakStatement) {
|
|
14526
14986
|
return statement.label !== null;
|
|
14527
14987
|
}
|
|
14528
|
-
if (statement.type ===
|
|
14988
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.TSTypeAliasDeclaration || statement.type === import_utils81.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
14529
14989
|
return false;
|
|
14530
14990
|
}
|
|
14531
|
-
if (statement.type ===
|
|
14991
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.BlockStatement) {
|
|
14532
14992
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
14533
14993
|
}
|
|
14534
14994
|
return true;
|
|
@@ -14544,7 +15004,7 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
14544
15004
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
14545
15005
|
}
|
|
14546
15006
|
const only = defaultCase.consequent[0];
|
|
14547
|
-
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type ===
|
|
15007
|
+
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils81.AST_NODE_TYPES.BlockStatement && !only.body.some(isRuntimeHandlingStatement)) {
|
|
14548
15008
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
14549
15009
|
}
|
|
14550
15010
|
return false;
|
|
@@ -14556,7 +15016,7 @@ function isExhaustiveFiniteSwitch(node, services) {
|
|
|
14556
15016
|
const constituents = discriminantType.isUnion() ? discriminantType.types : [discriminantType];
|
|
14557
15017
|
if (!discriminantType.isUnion() || constituents.length < 2) return false;
|
|
14558
15018
|
if (constituents.every(
|
|
14559
|
-
(constituent) => (constituent.flags &
|
|
15019
|
+
(constituent) => (constituent.flags & import_typescript2.default.TypeFlags.BooleanLiteral) !== 0
|
|
14560
15020
|
)) {
|
|
14561
15021
|
return false;
|
|
14562
15022
|
}
|
|
@@ -14580,7 +15040,7 @@ function isExhaustiveFiniteSwitch(node, services) {
|
|
|
14580
15040
|
return [...expected].every((key) => handled.has(key));
|
|
14581
15041
|
}
|
|
14582
15042
|
function finiteTypeKey(type, checker) {
|
|
14583
|
-
const finiteFlags =
|
|
15043
|
+
const finiteFlags = import_typescript2.default.TypeFlags.StringLiteral | import_typescript2.default.TypeFlags.NumberLiteral | import_typescript2.default.TypeFlags.BooleanLiteral | import_typescript2.default.TypeFlags.EnumLiteral | import_typescript2.default.TypeFlags.UniqueESSymbol | import_typescript2.default.TypeFlags.Null | import_typescript2.default.TypeFlags.Undefined;
|
|
14584
15044
|
return (type.flags & finiteFlags) !== 0 ? checker.typeToString(type) : null;
|
|
14585
15045
|
}
|
|
14586
15046
|
var require_assert_never_default = createRule({
|
|
@@ -14600,7 +15060,7 @@ var require_assert_never_default = createRule({
|
|
|
14600
15060
|
create(context) {
|
|
14601
15061
|
let services;
|
|
14602
15062
|
try {
|
|
14603
|
-
services =
|
|
15063
|
+
services = import_utils81.ESLintUtils.getParserServices(context);
|
|
14604
15064
|
} catch {
|
|
14605
15065
|
services = null;
|
|
14606
15066
|
}
|
|
@@ -14627,7 +15087,7 @@ var require_assert_never_default = createRule({
|
|
|
14627
15087
|
});
|
|
14628
15088
|
|
|
14629
15089
|
// src/rules/require-fetch-timeout.ts
|
|
14630
|
-
var
|
|
15090
|
+
var import_utils82 = require("@typescript-eslint/utils");
|
|
14631
15091
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
14632
15092
|
summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
|
|
14633
15093
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -14653,14 +15113,14 @@ function matchesAnyPattern3(filename, patterns) {
|
|
|
14653
15113
|
return false;
|
|
14654
15114
|
}
|
|
14655
15115
|
function initProvablyLacksSignal(init) {
|
|
14656
|
-
if (init.type !==
|
|
15116
|
+
if (init.type !== import_utils82.AST_NODE_TYPES.ObjectExpression) {
|
|
14657
15117
|
return false;
|
|
14658
15118
|
}
|
|
14659
15119
|
for (const prop of init.properties) {
|
|
14660
|
-
if (prop.type ===
|
|
15120
|
+
if (prop.type === import_utils82.AST_NODE_TYPES.SpreadElement) {
|
|
14661
15121
|
return false;
|
|
14662
15122
|
}
|
|
14663
|
-
if (prop.key.type ===
|
|
15123
|
+
if (prop.key.type === import_utils82.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils82.AST_NODE_TYPES.Literal && prop.key.value === "signal") {
|
|
14664
15124
|
return false;
|
|
14665
15125
|
}
|
|
14666
15126
|
if (prop.computed) {
|
|
@@ -14670,7 +15130,7 @@ function initProvablyLacksSignal(init) {
|
|
|
14670
15130
|
return true;
|
|
14671
15131
|
}
|
|
14672
15132
|
function isInlineUrl(node, resolvesToGlobal) {
|
|
14673
|
-
return node.type ===
|
|
15133
|
+
return node.type === import_utils82.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils82.AST_NODE_TYPES.TemplateLiteral || node.type === import_utils82.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils82.AST_NODE_TYPES.Identifier && node.callee.name === "URL" && resolvesToGlobal(node.callee);
|
|
14674
15134
|
}
|
|
14675
15135
|
var require_fetch_timeout_default = createRule({
|
|
14676
15136
|
name: "require-fetch-timeout",
|
|
@@ -14708,30 +15168,30 @@ var require_fetch_timeout_default = createRule({
|
|
|
14708
15168
|
}
|
|
14709
15169
|
function resolvesToGlobal(identifier) {
|
|
14710
15170
|
const scope = context.sourceCode.getScope(identifier);
|
|
14711
|
-
const variable =
|
|
15171
|
+
const variable = import_utils82.ASTUtils.findVariable(scope, identifier.name);
|
|
14712
15172
|
return variable === null || variable.defs.length === 0;
|
|
14713
15173
|
}
|
|
14714
15174
|
function isGlobalFetchCall2(callee) {
|
|
14715
|
-
if (callee.type ===
|
|
15175
|
+
if (callee.type === import_utils82.AST_NODE_TYPES.Identifier) {
|
|
14716
15176
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
14717
15177
|
}
|
|
14718
|
-
return callee.type ===
|
|
15178
|
+
return callee.type === import_utils82.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils82.AST_NODE_TYPES.Identifier && callee.property.name === "fetch" && callee.object.type === import_utils82.AST_NODE_TYPES.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
14719
15179
|
}
|
|
14720
15180
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
14721
|
-
const variable =
|
|
15181
|
+
const variable = import_utils82.ASTUtils.findVariable(
|
|
14722
15182
|
context.sourceCode.getScope(identifier),
|
|
14723
15183
|
identifier.name
|
|
14724
15184
|
);
|
|
14725
15185
|
if (variable?.defs.length !== 1) return false;
|
|
14726
15186
|
const definition = variable.defs[0];
|
|
14727
|
-
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !==
|
|
15187
|
+
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !== import_utils82.AST_NODE_TYPES.ObjectExpression || !initProvablyLacksSignal(definition.node.init)) {
|
|
14728
15188
|
return false;
|
|
14729
15189
|
}
|
|
14730
15190
|
for (const reference of variable.references) {
|
|
14731
15191
|
const ref = reference.identifier;
|
|
14732
15192
|
if (ref === identifier || ref === definition.name) continue;
|
|
14733
15193
|
const member = ref.parent;
|
|
14734
|
-
if (member.type !==
|
|
15194
|
+
if (member.type !== import_utils82.AST_NODE_TYPES.MemberExpression || member.object !== ref || member.computed || member.property.type !== import_utils82.AST_NODE_TYPES.Identifier || member.property.name === "signal" || member.parent.type !== import_utils82.AST_NODE_TYPES.AssignmentExpression || member.parent.left !== member) {
|
|
14735
15195
|
return false;
|
|
14736
15196
|
}
|
|
14737
15197
|
}
|
|
@@ -14746,7 +15206,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
14746
15206
|
if (node.arguments.length === 1 && first !== void 0 && !isInlineUrl(first, resolvesToGlobal)) {
|
|
14747
15207
|
return;
|
|
14748
15208
|
}
|
|
14749
|
-
if (init === void 0 || initProvablyLacksSignal(init) || init.type ===
|
|
15209
|
+
if (init === void 0 || initProvablyLacksSignal(init) || init.type === import_utils82.AST_NODE_TYPES.Identifier && localConstInitProvablyLacksSignal(init)) {
|
|
14750
15210
|
context.report({ node, messageId: "missingSignal" });
|
|
14751
15211
|
}
|
|
14752
15212
|
}
|
|
@@ -14755,7 +15215,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
14755
15215
|
});
|
|
14756
15216
|
|
|
14757
15217
|
// src/rules/require-port-for-service.ts
|
|
14758
|
-
var
|
|
15218
|
+
var import_utils83 = require("@typescript-eslint/utils");
|
|
14759
15219
|
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
14760
15220
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
14761
15221
|
rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
|
|
@@ -14780,45 +15240,45 @@ var ROUTER_FACTORY_NAME = "Router";
|
|
|
14780
15240
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
14781
15241
|
var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set(["=", "&&=", "??=", "||="]);
|
|
14782
15242
|
var staticMemberName6 = (member) => {
|
|
14783
|
-
if (member.property.type ===
|
|
14784
|
-
if (!member.computed && member.property.type ===
|
|
14785
|
-
return member.computed && member.property.type ===
|
|
15243
|
+
if (member.property.type === import_utils83.AST_NODE_TYPES.PrivateIdentifier) return `#${member.property.name}`;
|
|
15244
|
+
if (!member.computed && member.property.type === import_utils83.AST_NODE_TYPES.Identifier) return member.property.name;
|
|
15245
|
+
return member.computed && member.property.type === import_utils83.AST_NODE_TYPES.Literal && typeof member.property.value === "string" ? member.property.value : null;
|
|
14786
15246
|
};
|
|
14787
15247
|
var detachedValueExports = (program) => {
|
|
14788
15248
|
const names = /* @__PURE__ */ new Set();
|
|
14789
15249
|
for (const statement of program.body) {
|
|
14790
|
-
if (statement.type ===
|
|
15250
|
+
if (statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
|
|
14791
15251
|
for (const specifier of statement.specifiers) {
|
|
14792
15252
|
if (specifier.exportKind !== "type") names.add(specifier.local.name);
|
|
14793
15253
|
}
|
|
14794
|
-
} else if (statement.type ===
|
|
15254
|
+
} else if (statement.type === import_utils83.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14795
15255
|
names.add(statement.declaration.name);
|
|
14796
|
-
} else if (statement.type ===
|
|
15256
|
+
} else if (statement.type === import_utils83.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14797
15257
|
names.add(statement.expression.name);
|
|
14798
15258
|
}
|
|
14799
15259
|
}
|
|
14800
15260
|
return names;
|
|
14801
15261
|
};
|
|
14802
|
-
var isExportedClass2 = (node, detached) => node.parent.type ===
|
|
15262
|
+
var isExportedClass2 = (node, detached) => node.parent.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration || node.parent.type === import_utils83.AST_NODE_TYPES.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
|
|
14803
15263
|
var readTypeReference = (annotation) => {
|
|
14804
|
-
if (annotation?.type ===
|
|
15264
|
+
if (annotation?.type === import_utils83.AST_NODE_TYPES.TSUnionType) {
|
|
14805
15265
|
const members = annotation.types.filter(
|
|
14806
|
-
(member) => member.type !==
|
|
15266
|
+
(member) => member.type !== import_utils83.AST_NODE_TYPES.TSUndefinedKeyword && member.type !== import_utils83.AST_NODE_TYPES.TSNullKeyword
|
|
14807
15267
|
);
|
|
14808
15268
|
annotation = members.length === 1 ? members[0] : void 0;
|
|
14809
15269
|
}
|
|
14810
|
-
if (annotation === void 0 || annotation.type !==
|
|
15270
|
+
if (annotation === void 0 || annotation.type !== import_utils83.AST_NODE_TYPES.TSTypeReference) return null;
|
|
14811
15271
|
const { typeName } = annotation;
|
|
14812
|
-
const rightmost = typeName.type ===
|
|
15272
|
+
const rightmost = typeName.type === import_utils83.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils83.AST_NODE_TYPES.TSQualifiedName ? typeName.right.name : null;
|
|
14813
15273
|
if (rightmost === null) return null;
|
|
14814
15274
|
return { typeName: rightmost, display: qualifiedName(typeName) };
|
|
14815
15275
|
};
|
|
14816
|
-
var qualifiedName = (name) => name.type ===
|
|
15276
|
+
var qualifiedName = (name) => name.type === import_utils83.AST_NODE_TYPES.Identifier ? name.name : name.type === import_utils83.AST_NODE_TYPES.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
14817
15277
|
var propertySignatureTypes = (members) => {
|
|
14818
15278
|
const types = /* @__PURE__ */ new Map();
|
|
14819
15279
|
for (const member of members) {
|
|
14820
|
-
if (member.type !==
|
|
14821
|
-
if (member.computed || member.key.type !==
|
|
15280
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
15281
|
+
if (member.computed || member.key.type !== import_utils83.AST_NODE_TYPES.Identifier) continue;
|
|
14822
15282
|
const reference = readTypeReference(member.typeAnnotation?.typeAnnotation);
|
|
14823
15283
|
if (reference === null) continue;
|
|
14824
15284
|
types.set(member.key.name, reference);
|
|
@@ -14829,18 +15289,18 @@ var fileTypeIndex = (program) => {
|
|
|
14829
15289
|
const objects = /* @__PURE__ */ new Map();
|
|
14830
15290
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
14831
15291
|
for (const statement of program.body) {
|
|
14832
|
-
const declaration = statement.type ===
|
|
14833
|
-
if (declaration?.type ===
|
|
15292
|
+
const declaration = statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15293
|
+
if (declaration?.type === import_utils83.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
14834
15294
|
objects.set(declaration.id.name, propertySignatureTypes(declaration.body.body));
|
|
14835
15295
|
continue;
|
|
14836
15296
|
}
|
|
14837
|
-
if (declaration?.type !==
|
|
15297
|
+
if (declaration?.type !== import_utils83.AST_NODE_TYPES.TSTypeAliasDeclaration) continue;
|
|
14838
15298
|
const aliased = declaration.typeAnnotation;
|
|
14839
|
-
if (aliased.type ===
|
|
15299
|
+
if (aliased.type === import_utils83.AST_NODE_TYPES.TSFunctionType || aliased.type === import_utils83.AST_NODE_TYPES.TSConstructorType) {
|
|
14840
15300
|
functionAliases.add(declaration.id.name);
|
|
14841
15301
|
continue;
|
|
14842
15302
|
}
|
|
14843
|
-
const literals = aliased.type ===
|
|
15303
|
+
const literals = aliased.type === import_utils83.AST_NODE_TYPES.TSTypeLiteral ? [aliased] : aliased.type === import_utils83.AST_NODE_TYPES.TSIntersectionType ? aliased.types.filter((part) => part.type === import_utils83.AST_NODE_TYPES.TSTypeLiteral) : [];
|
|
14844
15304
|
if (literals.length === 0) continue;
|
|
14845
15305
|
const merged = /* @__PURE__ */ new Map();
|
|
14846
15306
|
for (const literal of literals) {
|
|
@@ -14869,10 +15329,10 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
14869
15329
|
while (pending.length > 0) {
|
|
14870
15330
|
const current = pending.pop();
|
|
14871
15331
|
if (current === void 0) break;
|
|
14872
|
-
if (current.type ===
|
|
14873
|
-
const expression = current.type ===
|
|
14874
|
-
const storedField = expression?.type ===
|
|
14875
|
-
if (expression?.type !==
|
|
15332
|
+
if (current.type === import_utils83.AST_NODE_TYPES.ArrowFunctionExpression || current.type === import_utils83.AST_NODE_TYPES.FunctionExpression || current.type === import_utils83.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils83.AST_NODE_TYPES.ClassExpression || current.type === import_utils83.AST_NODE_TYPES.ClassDeclaration) continue;
|
|
15333
|
+
const expression = current.type === import_utils83.AST_NODE_TYPES.ExpressionStatement ? current.expression : null;
|
|
15334
|
+
const storedField = expression?.type === import_utils83.AST_NODE_TYPES.AssignmentExpression && expression.left.type === import_utils83.AST_NODE_TYPES.MemberExpression && expression.left.object.type === import_utils83.AST_NODE_TYPES.ThisExpression ? staticMemberName6(expression.left) : null;
|
|
15335
|
+
if (expression?.type !== import_utils83.AST_NODE_TYPES.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== import_utils83.AST_NODE_TYPES.MemberExpression || expression.left.object.type !== import_utils83.AST_NODE_TYPES.ThisExpression || storedField === null) {
|
|
14876
15336
|
for (const key of Object.keys(current)) {
|
|
14877
15337
|
if (key === "parent") continue;
|
|
14878
15338
|
const value = current[key];
|
|
@@ -14885,14 +15345,14 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
14885
15345
|
continue;
|
|
14886
15346
|
}
|
|
14887
15347
|
let source = expression.right;
|
|
14888
|
-
while (source.type ===
|
|
14889
|
-
if (source.type ===
|
|
15348
|
+
while (source.type === import_utils83.AST_NODE_TYPES.TSNonNullExpression || source.type === import_utils83.AST_NODE_TYPES.TSAsExpression || source.type === import_utils83.AST_NODE_TYPES.TSSatisfiesExpression || source.type === import_utils83.AST_NODE_TYPES.TSTypeAssertion) source = source.expression;
|
|
15349
|
+
if (source.type === import_utils83.AST_NODE_TYPES.NewExpression) {
|
|
14890
15350
|
constructedFields += 1;
|
|
14891
|
-
} else if (source.type ===
|
|
15351
|
+
} else if (source.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14892
15352
|
const fields = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
|
|
14893
15353
|
fields.add(storedField);
|
|
14894
15354
|
storedFieldsFrom.set(source.name, fields);
|
|
14895
|
-
} else if (source.type ===
|
|
15355
|
+
} else if (source.type === import_utils83.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14896
15356
|
const fields = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
|
|
14897
15357
|
fields.add(storedField);
|
|
14898
15358
|
storedFieldsFrom.set(source.object.name, fields);
|
|
@@ -14910,7 +15370,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
14910
15370
|
const collaborators = [];
|
|
14911
15371
|
for (const parameter of ctor.value.params) {
|
|
14912
15372
|
for (const reference of parameterCollaborators(parameter, declared, storedMemberFieldsFrom)) {
|
|
14913
|
-
const fields = parameter.type ===
|
|
15373
|
+
const fields = parameter.type === import_utils83.AST_NODE_TYPES.TSParameterProperty ? [reference.name] : reference.fields.length > 0 ? reference.fields : [...storedFieldsFrom.get(reference.name) ?? []];
|
|
14914
15374
|
if (fields.length === 0) continue;
|
|
14915
15375
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
14916
15376
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -14925,8 +15385,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
14925
15385
|
};
|
|
14926
15386
|
var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
14927
15387
|
let target = parameter;
|
|
14928
|
-
if (target.type ===
|
|
14929
|
-
if (target.type ===
|
|
15388
|
+
if (target.type === import_utils83.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
15389
|
+
if (target.type === import_utils83.AST_NODE_TYPES.ObjectPattern) {
|
|
14930
15390
|
return objectPatternCollaborators(target, declared);
|
|
14931
15391
|
}
|
|
14932
15392
|
const named2 = namedParameterCollaborator(parameter);
|
|
@@ -14935,9 +15395,9 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
|
14935
15395
|
};
|
|
14936
15396
|
var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
14937
15397
|
let target = annotated;
|
|
14938
|
-
if (target.type ===
|
|
14939
|
-
if (target.type ===
|
|
14940
|
-
if (target.type !==
|
|
15398
|
+
if (target.type === import_utils83.AST_NODE_TYPES.TSParameterProperty) target = target.parameter;
|
|
15399
|
+
if (target.type === import_utils83.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
15400
|
+
if (target.type !== import_utils83.AST_NODE_TYPES.Identifier) return [];
|
|
14941
15401
|
const members = bagMemberTypes(target.typeAnnotation?.typeAnnotation, declared);
|
|
14942
15402
|
if (members === null) return [];
|
|
14943
15403
|
const storedMembers = storedMemberFieldsFrom.get(target.name);
|
|
@@ -14953,9 +15413,9 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
|
14953
15413
|
};
|
|
14954
15414
|
var namedParameterCollaborator = (annotated) => {
|
|
14955
15415
|
let target = annotated;
|
|
14956
|
-
if (target.type ===
|
|
14957
|
-
if (target.type ===
|
|
14958
|
-
if (target.type !==
|
|
15416
|
+
if (target.type === import_utils83.AST_NODE_TYPES.TSParameterProperty) target = target.parameter;
|
|
15417
|
+
if (target.type === import_utils83.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
15418
|
+
if (target.type !== import_utils83.AST_NODE_TYPES.Identifier) return null;
|
|
14959
15419
|
const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
|
|
14960
15420
|
if (reference === null) return null;
|
|
14961
15421
|
return { name: target.name, ...reference, fields: [] };
|
|
@@ -14967,11 +15427,11 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
14967
15427
|
if (members === null) return [];
|
|
14968
15428
|
const collaborators = [];
|
|
14969
15429
|
for (const property of pattern.properties) {
|
|
14970
|
-
if (property.type !==
|
|
14971
|
-
if (property.key.type !==
|
|
15430
|
+
if (property.type !== import_utils83.AST_NODE_TYPES.Property || property.computed) continue;
|
|
15431
|
+
if (property.key.type !== import_utils83.AST_NODE_TYPES.Identifier) continue;
|
|
14972
15432
|
const key = property.key.name;
|
|
14973
|
-
const bound = property.value.type ===
|
|
14974
|
-
if (bound.type !==
|
|
15433
|
+
const bound = property.value.type === import_utils83.AST_NODE_TYPES.AssignmentPattern ? property.value.left : property.value;
|
|
15434
|
+
if (bound.type !== import_utils83.AST_NODE_TYPES.Identifier) continue;
|
|
14975
15435
|
if (CONFIGISH_NAME_RE.test(key)) continue;
|
|
14976
15436
|
const reference = members.get(key);
|
|
14977
15437
|
if (reference === void 0) continue;
|
|
@@ -14981,21 +15441,21 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
14981
15441
|
};
|
|
14982
15442
|
var bagMemberTypes = (annotation, declared) => {
|
|
14983
15443
|
if (annotation === void 0) return null;
|
|
14984
|
-
if (annotation.type ===
|
|
15444
|
+
if (annotation.type === import_utils83.AST_NODE_TYPES.TSTypeLiteral) {
|
|
14985
15445
|
return propertySignatureTypes(annotation.members);
|
|
14986
15446
|
}
|
|
14987
|
-
if (annotation.type !==
|
|
15447
|
+
if (annotation.type !== import_utils83.AST_NODE_TYPES.TSTypeReference || annotation.typeName.type !== import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14988
15448
|
return null;
|
|
14989
15449
|
}
|
|
14990
15450
|
return declared().objects.get(annotation.typeName.name) ?? null;
|
|
14991
15451
|
};
|
|
14992
15452
|
var isFrameworkWiring = (body2) => subtreeHas(body2, (node) => {
|
|
14993
|
-
if (node.type ===
|
|
15453
|
+
if (node.type === import_utils83.AST_NODE_TYPES.CallExpression) {
|
|
14994
15454
|
const { callee } = node;
|
|
14995
|
-
if (callee.type ===
|
|
14996
|
-
return callee.type ===
|
|
15455
|
+
if (callee.type === import_utils83.AST_NODE_TYPES.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
15456
|
+
return callee.type === import_utils83.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils83.AST_NODE_TYPES.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
14997
15457
|
}
|
|
14998
|
-
return node.type ===
|
|
15458
|
+
return node.type === import_utils83.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils83.AST_NODE_TYPES.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
14999
15459
|
});
|
|
15000
15460
|
var subtreeHas = (root, found) => {
|
|
15001
15461
|
let hit = false;
|
|
@@ -15022,19 +15482,19 @@ var invokedInstanceField = (call) => {
|
|
|
15022
15482
|
const direct = instanceField(call.callee);
|
|
15023
15483
|
if (direct !== null) return direct;
|
|
15024
15484
|
let callee = call.callee;
|
|
15025
|
-
while (callee.type ===
|
|
15026
|
-
return callee.type ===
|
|
15485
|
+
while (callee.type === import_utils83.AST_NODE_TYPES.ChainExpression || callee.type === import_utils83.AST_NODE_TYPES.TSAsExpression || callee.type === import_utils83.AST_NODE_TYPES.TSNonNullExpression || callee.type === import_utils83.AST_NODE_TYPES.TSSatisfiesExpression || callee.type === import_utils83.AST_NODE_TYPES.TSTypeAssertion) callee = callee.expression;
|
|
15486
|
+
return callee.type === import_utils83.AST_NODE_TYPES.MemberExpression ? instanceField(callee.object) : null;
|
|
15027
15487
|
};
|
|
15028
15488
|
var instanceField = (candidate2) => {
|
|
15029
15489
|
let node = candidate2;
|
|
15030
|
-
while (node.type ===
|
|
15031
|
-
return node.type ===
|
|
15490
|
+
while (node.type === import_utils83.AST_NODE_TYPES.ChainExpression || node.type === import_utils83.AST_NODE_TYPES.TSAsExpression || node.type === import_utils83.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils83.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils83.AST_NODE_TYPES.TSTypeAssertion) node = node.expression;
|
|
15491
|
+
return node.type === import_utils83.AST_NODE_TYPES.MemberExpression && node.object.type === import_utils83.AST_NODE_TYPES.ThisExpression ? staticMemberName6(node) : null;
|
|
15032
15492
|
};
|
|
15033
15493
|
var behaviorallyInvokedFields = (body2) => {
|
|
15034
15494
|
const invoked = /* @__PURE__ */ new Set();
|
|
15035
15495
|
const visit = (current) => {
|
|
15036
|
-
if (current.type ===
|
|
15037
|
-
if (current.type ===
|
|
15496
|
+
if (current.type === import_utils83.AST_NODE_TYPES.ClassDeclaration || current.type === import_utils83.AST_NODE_TYPES.ClassExpression || current.type === import_utils83.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils83.AST_NODE_TYPES.FunctionExpression) return;
|
|
15497
|
+
if (current.type === import_utils83.AST_NODE_TYPES.CallExpression) {
|
|
15038
15498
|
const field = invokedInstanceField(current);
|
|
15039
15499
|
if (field !== null) invoked.add(field);
|
|
15040
15500
|
}
|
|
@@ -15047,14 +15507,14 @@ var behaviorallyInvokedFields = (body2) => {
|
|
|
15047
15507
|
}
|
|
15048
15508
|
};
|
|
15049
15509
|
for (const member of body2.body) {
|
|
15050
|
-
if (member.type ===
|
|
15051
|
-
if (member.type ===
|
|
15510
|
+
if (member.type === import_utils83.AST_NODE_TYPES.StaticBlock || member.static) continue;
|
|
15511
|
+
if (member.type === import_utils83.AST_NODE_TYPES.MethodDefinition) {
|
|
15052
15512
|
if (member.value.body !== null && member.value.body !== void 0) visit(member.value.body);
|
|
15053
15513
|
continue;
|
|
15054
15514
|
}
|
|
15055
|
-
if (member.type !==
|
|
15515
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.PropertyDefinition || member.value === null) continue;
|
|
15056
15516
|
visit(
|
|
15057
|
-
member.value.type ===
|
|
15517
|
+
member.value.type === import_utils83.AST_NODE_TYPES.ArrowFunctionExpression ? member.value.body : member.value
|
|
15058
15518
|
);
|
|
15059
15519
|
}
|
|
15060
15520
|
return invoked;
|
|
@@ -15074,25 +15534,26 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
15074
15534
|
var fileInterfaceNames = (program) => {
|
|
15075
15535
|
const names = [];
|
|
15076
15536
|
for (const statement of program.body) {
|
|
15077
|
-
const declaration = statement.type ===
|
|
15078
|
-
if (declaration?.type ===
|
|
15537
|
+
const declaration = statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15538
|
+
if (declaration?.type === import_utils83.AST_NODE_TYPES.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
15079
15539
|
}
|
|
15080
15540
|
return names;
|
|
15081
15541
|
};
|
|
15082
15542
|
var publicMethodNames = (body2, functionAliases) => {
|
|
15083
15543
|
const names = [];
|
|
15084
15544
|
for (const member of body2.body) {
|
|
15085
|
-
if (member.type ===
|
|
15545
|
+
if (member.type === import_utils83.AST_NODE_TYPES.PropertyDefinition) {
|
|
15086
15546
|
if (member.static || member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15087
|
-
if (member.
|
|
15088
|
-
|
|
15547
|
+
if (member.key.type === import_utils83.AST_NODE_TYPES.PrivateIdentifier) continue;
|
|
15548
|
+
if (member.value?.type !== import_utils83.AST_NODE_TYPES.ArrowFunctionExpression && member.value?.type !== import_utils83.AST_NODE_TYPES.FunctionExpression && member.typeAnnotation?.typeAnnotation.type !== import_utils83.AST_NODE_TYPES.TSFunctionType && !(member.typeAnnotation?.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === import_utils83.AST_NODE_TYPES.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name))) continue;
|
|
15549
|
+
names.push(member.key.type === import_utils83.AST_NODE_TYPES.Identifier ? member.key.name : "\u2026");
|
|
15089
15550
|
continue;
|
|
15090
15551
|
}
|
|
15091
|
-
if (member.type !==
|
|
15552
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.MethodDefinition) continue;
|
|
15092
15553
|
if (member.kind !== "method" || member.static) continue;
|
|
15093
15554
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15094
|
-
if (member.key.type ===
|
|
15095
|
-
if (member.key.type ===
|
|
15555
|
+
if (member.key.type === import_utils83.AST_NODE_TYPES.PrivateIdentifier) continue;
|
|
15556
|
+
if (member.key.type === import_utils83.AST_NODE_TYPES.Identifier) names.push(member.key.name);
|
|
15096
15557
|
else names.push("\u2026");
|
|
15097
15558
|
}
|
|
15098
15559
|
return names;
|
|
@@ -15100,13 +15561,13 @@ var publicMethodNames = (body2, functionAliases) => {
|
|
|
15100
15561
|
var isFluentConstructionObject = (node, getText) => {
|
|
15101
15562
|
if (node.id === null) return false;
|
|
15102
15563
|
const methods = node.body.body.filter(
|
|
15103
|
-
(member) => member.type ===
|
|
15564
|
+
(member) => member.type === import_utils83.AST_NODE_TYPES.MethodDefinition && member.kind === "method" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.value.body !== null
|
|
15104
15565
|
);
|
|
15105
15566
|
if (methods.length === 0) return false;
|
|
15106
15567
|
return methods.every((member) => {
|
|
15107
15568
|
const result = member.value.returnType?.typeAnnotation;
|
|
15108
15569
|
if (result === void 0) return false;
|
|
15109
|
-
const returnsOwnType = result.type ===
|
|
15570
|
+
const returnsOwnType = result.type === import_utils83.AST_NODE_TYPES.TSTypeReference && result.typeName.type === import_utils83.AST_NODE_TYPES.Identifier && result.typeName.name === node.id?.name;
|
|
15110
15571
|
return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
|
|
15111
15572
|
});
|
|
15112
15573
|
};
|
|
@@ -15114,10 +15575,10 @@ function localClassAbstractness(program) {
|
|
|
15114
15575
|
const classes = /* @__PURE__ */ new Map();
|
|
15115
15576
|
const parents = /* @__PURE__ */ new Map();
|
|
15116
15577
|
for (const statement of program.body) {
|
|
15117
|
-
const declaration = statement.type ===
|
|
15118
|
-
if (declaration?.type ===
|
|
15578
|
+
const declaration = statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils83.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
15579
|
+
if (declaration?.type === import_utils83.AST_NODE_TYPES.ClassDeclaration && declaration.id !== null) {
|
|
15119
15580
|
classes.set(declaration.id.name, declaration.abstract === true);
|
|
15120
|
-
if (declaration.superClass?.type ===
|
|
15581
|
+
if (declaration.superClass?.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15121
15582
|
parents.set(declaration.id.name, declaration.superClass.name);
|
|
15122
15583
|
}
|
|
15123
15584
|
}
|
|
@@ -15139,43 +15600,43 @@ function localInterfaceSurfaces(program) {
|
|
|
15139
15600
|
const parents = /* @__PURE__ */ new Map();
|
|
15140
15601
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
15141
15602
|
for (const statement of program.body) {
|
|
15142
|
-
const declaration = statement.type ===
|
|
15143
|
-
if (declaration?.type ===
|
|
15603
|
+
const declaration = statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15604
|
+
if (declaration?.type === import_utils83.AST_NODE_TYPES.TSTypeAliasDeclaration && (declaration.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSFunctionType || declaration.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSConstructorType)) functionAliases.add(declaration.id.name);
|
|
15144
15605
|
}
|
|
15145
15606
|
for (const statement of program.body) {
|
|
15146
|
-
const declaration = statement.type ===
|
|
15147
|
-
if (declaration?.type ===
|
|
15607
|
+
const declaration = statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
15608
|
+
if (declaration?.type === import_utils83.AST_NODE_TYPES.TSTypeAliasDeclaration) {
|
|
15148
15609
|
const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15149
|
-
const parts = declaration.typeAnnotation.type ===
|
|
15610
|
+
const parts = declaration.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
|
|
15150
15611
|
const inherited = parents.get(declaration.id.name) ?? [];
|
|
15151
15612
|
for (const part of parts) {
|
|
15152
|
-
if (part.type ===
|
|
15613
|
+
if (part.type === import_utils83.AST_NODE_TYPES.TSTypeReference && part.typeName.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15153
15614
|
inherited.push(part.typeName.name);
|
|
15154
15615
|
continue;
|
|
15155
15616
|
}
|
|
15156
|
-
if (part.type !==
|
|
15617
|
+
if (part.type !== import_utils83.AST_NODE_TYPES.TSTypeLiteral) continue;
|
|
15157
15618
|
for (const member of part.members) {
|
|
15158
|
-
if (member.type !==
|
|
15159
|
-
if (member.computed || member.key.type !==
|
|
15160
|
-
if (member.type ===
|
|
15619
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.TSMethodSignature && member.type !== import_utils83.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
15620
|
+
if (member.computed || member.key.type !== import_utils83.AST_NODE_TYPES.Identifier) continue;
|
|
15621
|
+
if (member.type === import_utils83.AST_NODE_TYPES.TSMethodSignature) {
|
|
15161
15622
|
callables2.add(member.key.name);
|
|
15162
15623
|
continue;
|
|
15163
15624
|
}
|
|
15164
|
-
if (member.type !==
|
|
15625
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
15165
15626
|
const annotation = member.typeAnnotation?.typeAnnotation;
|
|
15166
|
-
if (annotation?.type ===
|
|
15627
|
+
if (annotation?.type === import_utils83.AST_NODE_TYPES.TSFunctionType || annotation?.type === import_utils83.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils83.AST_NODE_TYPES.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(member.key.name);
|
|
15167
15628
|
}
|
|
15168
15629
|
}
|
|
15169
15630
|
interfaces.set(declaration.id.name, callables2);
|
|
15170
15631
|
parents.set(declaration.id.name, inherited);
|
|
15171
15632
|
continue;
|
|
15172
15633
|
}
|
|
15173
|
-
if (declaration?.type !==
|
|
15634
|
+
if (declaration?.type !== import_utils83.AST_NODE_TYPES.TSInterfaceDeclaration) continue;
|
|
15174
15635
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15175
15636
|
for (const member of declaration.body.body) {
|
|
15176
|
-
if (member.type !==
|
|
15177
|
-
if (member.computed || member.key.type !==
|
|
15178
|
-
if (member.type ===
|
|
15637
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.TSMethodSignature && member.type !== import_utils83.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
15638
|
+
if (member.computed || member.key.type !== import_utils83.AST_NODE_TYPES.Identifier) continue;
|
|
15639
|
+
if (member.type === import_utils83.AST_NODE_TYPES.TSMethodSignature || member.typeAnnotation?.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSFunctionType || member.typeAnnotation?.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === import_utils83.AST_NODE_TYPES.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name)) callables.add(member.key.name);
|
|
15179
15640
|
}
|
|
15180
15641
|
interfaces.set(declaration.id.name, callables);
|
|
15181
15642
|
parents.set(
|
|
@@ -15183,7 +15644,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15183
15644
|
[
|
|
15184
15645
|
...parents.get(declaration.id.name) ?? [],
|
|
15185
15646
|
...declaration.extends.flatMap(
|
|
15186
|
-
(heritage) => heritage.expression.type ===
|
|
15647
|
+
(heritage) => heritage.expression.type === import_utils83.AST_NODE_TYPES.Identifier ? [heritage.expression.name] : ["*"]
|
|
15187
15648
|
)
|
|
15188
15649
|
]
|
|
15189
15650
|
);
|
|
@@ -15210,7 +15671,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15210
15671
|
}
|
|
15211
15672
|
function hasServicePort(node, methods, classes, interfaces) {
|
|
15212
15673
|
if (node.superClass !== null) {
|
|
15213
|
-
if (node.superClass.type !==
|
|
15674
|
+
if (node.superClass.type !== import_utils83.AST_NODE_TYPES.Identifier) return true;
|
|
15214
15675
|
const localAbstract = classes.get(node.superClass.name);
|
|
15215
15676
|
if (localAbstract === void 0 || localAbstract) return true;
|
|
15216
15677
|
}
|
|
@@ -15222,7 +15683,7 @@ function hasServicePort(node, methods, classes, interfaces) {
|
|
|
15222
15683
|
if (node.implements.length === 0) return false;
|
|
15223
15684
|
const combined = /* @__PURE__ */ new Set();
|
|
15224
15685
|
for (const implementation of node.implements) {
|
|
15225
|
-
if (implementation.expression.type !==
|
|
15686
|
+
if (implementation.expression.type !== import_utils83.AST_NODE_TYPES.Identifier) return true;
|
|
15226
15687
|
const name = implementation.expression.name;
|
|
15227
15688
|
const localAbstract = classes.get(name);
|
|
15228
15689
|
if (localAbstract === true) return true;
|
|
@@ -15265,7 +15726,7 @@ var require_port_for_service_default = createRule({
|
|
|
15265
15726
|
if (node.abstract === true) return;
|
|
15266
15727
|
if (node.decorators.length > 0) return;
|
|
15267
15728
|
const ctor = node.body.body.find(
|
|
15268
|
-
(member) => member.type ===
|
|
15729
|
+
(member) => member.type === import_utils83.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor" && member.value.body !== null && member.value.body !== void 0
|
|
15269
15730
|
);
|
|
15270
15731
|
if (ctor === void 0) return;
|
|
15271
15732
|
const constructorFacts = readConstructor(
|
|
@@ -15299,8 +15760,120 @@ var require_port_for_service_default = createRule({
|
|
|
15299
15760
|
}
|
|
15300
15761
|
});
|
|
15301
15762
|
|
|
15763
|
+
// src/rules/require-sql-access-class.ts
|
|
15764
|
+
var import_utils84 = require("@typescript-eslint/utils");
|
|
15765
|
+
var SQL_METHODS = /* @__PURE__ */ new Set([
|
|
15766
|
+
"all",
|
|
15767
|
+
"batch",
|
|
15768
|
+
"delete",
|
|
15769
|
+
"dump",
|
|
15770
|
+
"exec",
|
|
15771
|
+
"execute",
|
|
15772
|
+
"get",
|
|
15773
|
+
"insert",
|
|
15774
|
+
"pragma",
|
|
15775
|
+
"prepare",
|
|
15776
|
+
"run",
|
|
15777
|
+
"select",
|
|
15778
|
+
"transaction",
|
|
15779
|
+
"update"
|
|
15780
|
+
]);
|
|
15781
|
+
var DATABASE_NAMES = /^(?:db|database|connection|pool|query|transaction|tx)$/iu;
|
|
15782
|
+
var REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION = {
|
|
15783
|
+
summary: "Keep SQL reads and writes inside a class that receives its database dependency.",
|
|
15784
|
+
rationale: "Free-function database access hides connection ownership and makes transaction, retry, observability, and test boundaries inconsistent.",
|
|
15785
|
+
remediation: "Move the query into a repository or store class and inject the pool, connection, transaction, or typed database binding through its constructor.",
|
|
15786
|
+
category: "architecture",
|
|
15787
|
+
limitations: [
|
|
15788
|
+
"The rule recognizes conventional database receiver names and Cloudflare DB bindings; unusually named or heavily aliased clients require architectural review.",
|
|
15789
|
+
"Query construction without execution is not reported."
|
|
15790
|
+
],
|
|
15791
|
+
examples: [
|
|
15792
|
+
{
|
|
15793
|
+
id: "injected-repository",
|
|
15794
|
+
title: "Own queries in an injected repository",
|
|
15795
|
+
outcome: "no-match",
|
|
15796
|
+
files: [
|
|
15797
|
+
{
|
|
15798
|
+
path: "src/user-repository.ts",
|
|
15799
|
+
source: "export class UserRepository { constructor(private readonly db: Database.Database) {} find(id: string) { return this.db.prepare('SELECT id FROM user WHERE id = ?').get(id); } }"
|
|
15800
|
+
}
|
|
15801
|
+
],
|
|
15802
|
+
focusPath: "src/user-repository.ts",
|
|
15803
|
+
expectedCount: 0,
|
|
15804
|
+
public: true
|
|
15805
|
+
},
|
|
15806
|
+
{
|
|
15807
|
+
id: "free-query",
|
|
15808
|
+
title: "Do not execute SQL in a free function",
|
|
15809
|
+
outcome: "match",
|
|
15810
|
+
files: [
|
|
15811
|
+
{
|
|
15812
|
+
path: "src/users.ts",
|
|
15813
|
+
source: "export function find(database: Database.Database, id: string) { return database.prepare('SELECT id FROM user WHERE id = ?').get(id); }"
|
|
15814
|
+
}
|
|
15815
|
+
],
|
|
15816
|
+
focusPath: "src/users.ts",
|
|
15817
|
+
expectedCount: 1,
|
|
15818
|
+
public: true
|
|
15819
|
+
}
|
|
15820
|
+
]
|
|
15821
|
+
};
|
|
15822
|
+
function memberName4(node) {
|
|
15823
|
+
if (!node.computed && node.property.type === import_utils84.AST_NODE_TYPES.Identifier)
|
|
15824
|
+
return node.property.name;
|
|
15825
|
+
if (node.computed && node.property.type === import_utils84.AST_NODE_TYPES.Literal && typeof node.property.value === "string")
|
|
15826
|
+
return node.property.value;
|
|
15827
|
+
return null;
|
|
15828
|
+
}
|
|
15829
|
+
function databaseReceiver(node) {
|
|
15830
|
+
if (node.type === import_utils84.AST_NODE_TYPES.Identifier)
|
|
15831
|
+
return DATABASE_NAMES.test(node.name);
|
|
15832
|
+
if (node.type !== import_utils84.AST_NODE_TYPES.MemberExpression) return false;
|
|
15833
|
+
const name = memberName4(node);
|
|
15834
|
+
return name === "DB" || name !== null && DATABASE_NAMES.test(name);
|
|
15835
|
+
}
|
|
15836
|
+
function belongsToClass(node) {
|
|
15837
|
+
let current = node.parent;
|
|
15838
|
+
while (current != null) {
|
|
15839
|
+
if (current.type === import_utils84.AST_NODE_TYPES.ClassDeclaration || current.type === import_utils84.AST_NODE_TYPES.ClassExpression)
|
|
15840
|
+
return true;
|
|
15841
|
+
current = current.parent;
|
|
15842
|
+
}
|
|
15843
|
+
return false;
|
|
15844
|
+
}
|
|
15845
|
+
var require_sql_access_class_default = createRule({
|
|
15846
|
+
name: "require-sql-access-class",
|
|
15847
|
+
documentation: REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION,
|
|
15848
|
+
meta: {
|
|
15849
|
+
type: "suggestion",
|
|
15850
|
+
docs: {
|
|
15851
|
+
description: "Keep SQL reads and writes inside a class that receives its database dependency."
|
|
15852
|
+
},
|
|
15853
|
+
schema: [],
|
|
15854
|
+
messages: {
|
|
15855
|
+
moveSqlIntoClass: "Move this database operation into a repository or store class with an injected connection or pool."
|
|
15856
|
+
}
|
|
15857
|
+
},
|
|
15858
|
+
defaultOptions: [],
|
|
15859
|
+
create(context) {
|
|
15860
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text))
|
|
15861
|
+
return {};
|
|
15862
|
+
return {
|
|
15863
|
+
CallExpression(node) {
|
|
15864
|
+
if (belongsToClass(node) || node.callee.type !== import_utils84.AST_NODE_TYPES.MemberExpression)
|
|
15865
|
+
return;
|
|
15866
|
+
const method = memberName4(node.callee);
|
|
15867
|
+
if (method === null || !SQL_METHODS.has(method) || !databaseReceiver(node.callee.object))
|
|
15868
|
+
return;
|
|
15869
|
+
context.report({ node, messageId: "moveSqlIntoClass" });
|
|
15870
|
+
}
|
|
15871
|
+
};
|
|
15872
|
+
}
|
|
15873
|
+
});
|
|
15874
|
+
|
|
15302
15875
|
// src/rules/require-static-next-matcher.ts
|
|
15303
|
-
var
|
|
15876
|
+
var import_utils85 = require("@typescript-eslint/utils");
|
|
15304
15877
|
var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
15305
15878
|
summary: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
|
|
15306
15879
|
rationale: "Next.js must statically analyze matcher values at build time; computed values are ignored.",
|
|
@@ -15313,34 +15886,34 @@ var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
|
15313
15886
|
};
|
|
15314
15887
|
var NEXT_ENTRY_FILE = /(?:^|[/\\])(?:middleware|proxy)\.[cm]?[jt]sx?$/u;
|
|
15315
15888
|
function unwrapExpression3(node) {
|
|
15316
|
-
if (node.type ===
|
|
15889
|
+
if (node.type === import_utils85.AST_NODE_TYPES.TSAsExpression || node.type === import_utils85.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils85.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils85.AST_NODE_TYPES.TSTypeAssertion) {
|
|
15317
15890
|
return unwrapExpression3(node.expression);
|
|
15318
15891
|
}
|
|
15319
15892
|
return node;
|
|
15320
15893
|
}
|
|
15321
15894
|
function isStaticValue(node) {
|
|
15322
15895
|
const value = unwrapExpression3(node);
|
|
15323
|
-
if (value.type ===
|
|
15896
|
+
if (value.type === import_utils85.AST_NODE_TYPES.Literal) {
|
|
15324
15897
|
return true;
|
|
15325
15898
|
}
|
|
15326
|
-
if (value.type ===
|
|
15899
|
+
if (value.type === import_utils85.AST_NODE_TYPES.TemplateLiteral) {
|
|
15327
15900
|
return value.expressions.length === 0;
|
|
15328
15901
|
}
|
|
15329
|
-
if (value.type ===
|
|
15902
|
+
if (value.type === import_utils85.AST_NODE_TYPES.ArrayExpression) {
|
|
15330
15903
|
return value.elements.every(
|
|
15331
|
-
(element) => element !== null && element.type !==
|
|
15904
|
+
(element) => element !== null && element.type !== import_utils85.AST_NODE_TYPES.SpreadElement && isStaticValue(element)
|
|
15332
15905
|
);
|
|
15333
15906
|
}
|
|
15334
|
-
if (value.type ===
|
|
15907
|
+
if (value.type === import_utils85.AST_NODE_TYPES.ObjectExpression) {
|
|
15335
15908
|
return value.properties.every(
|
|
15336
|
-
(property) => property.type ===
|
|
15909
|
+
(property) => property.type === import_utils85.AST_NODE_TYPES.Property && property.kind === "init" && !property.computed && property.value.type !== import_utils85.AST_NODE_TYPES.AssignmentPattern && isStaticValue(property.value)
|
|
15337
15910
|
);
|
|
15338
15911
|
}
|
|
15339
15912
|
return false;
|
|
15340
15913
|
}
|
|
15341
15914
|
function propertyName4(property) {
|
|
15342
15915
|
if (property.computed) return null;
|
|
15343
|
-
if (property.key.type ===
|
|
15916
|
+
if (property.key.type === import_utils85.AST_NODE_TYPES.Identifier) return property.key.name;
|
|
15344
15917
|
return typeof property.key.value === "string" ? property.key.value : null;
|
|
15345
15918
|
}
|
|
15346
15919
|
var require_static_next_matcher_default = createRule({
|
|
@@ -15363,19 +15936,19 @@ var require_static_next_matcher_default = createRule({
|
|
|
15363
15936
|
}
|
|
15364
15937
|
return {
|
|
15365
15938
|
ExportNamedDeclaration(node) {
|
|
15366
|
-
if (node.declaration?.type !==
|
|
15939
|
+
if (node.declaration?.type !== import_utils85.AST_NODE_TYPES.VariableDeclaration) {
|
|
15367
15940
|
return;
|
|
15368
15941
|
}
|
|
15369
15942
|
for (const declaration of node.declaration.declarations) {
|
|
15370
|
-
if (declaration.id.type !==
|
|
15943
|
+
if (declaration.id.type !== import_utils85.AST_NODE_TYPES.Identifier || declaration.id.name !== "config" || declaration.init === null) {
|
|
15371
15944
|
continue;
|
|
15372
15945
|
}
|
|
15373
15946
|
const config = unwrapExpression3(declaration.init);
|
|
15374
|
-
if (config.type !==
|
|
15947
|
+
if (config.type !== import_utils85.AST_NODE_TYPES.ObjectExpression) {
|
|
15375
15948
|
continue;
|
|
15376
15949
|
}
|
|
15377
15950
|
for (const property of config.properties) {
|
|
15378
|
-
if (property.type !==
|
|
15951
|
+
if (property.type !== import_utils85.AST_NODE_TYPES.Property || propertyName4(property) !== "matcher" || property.value.type === import_utils85.AST_NODE_TYPES.AssignmentPattern) {
|
|
15379
15952
|
continue;
|
|
15380
15953
|
}
|
|
15381
15954
|
if (!isStaticValue(property.value)) {
|
|
@@ -15389,7 +15962,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
15389
15962
|
});
|
|
15390
15963
|
|
|
15391
15964
|
// src/rules/require-use-form-default-values.ts
|
|
15392
|
-
var
|
|
15965
|
+
var import_utils86 = require("@typescript-eslint/utils");
|
|
15393
15966
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
15394
15967
|
summary: "react-hook-form useForm call without defaultValues",
|
|
15395
15968
|
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.",
|
|
@@ -15443,13 +16016,13 @@ var require_use_form_default_values_default = createRule({
|
|
|
15443
16016
|
if (node.source.value !== "react-hook-form") return;
|
|
15444
16017
|
for (const specifier of node.specifiers) {
|
|
15445
16018
|
if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
|
|
15446
|
-
const variable =
|
|
16019
|
+
const variable = import_utils86.ASTUtils.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
15447
16020
|
if (variable) importedHooks.add(variable);
|
|
15448
16021
|
}
|
|
15449
16022
|
},
|
|
15450
16023
|
CallExpression(node) {
|
|
15451
16024
|
if (node.callee.type !== "Identifier") return;
|
|
15452
|
-
const variable =
|
|
16025
|
+
const variable = import_utils86.ASTUtils.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
|
|
15453
16026
|
const options = node.arguments[0];
|
|
15454
16027
|
if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
|
|
15455
16028
|
context.report({ node, messageId: "requireUseFormDefaultValues" });
|
|
@@ -15459,7 +16032,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
15459
16032
|
});
|
|
15460
16033
|
|
|
15461
16034
|
// src/rules/require-use-server-in-actions-file.ts
|
|
15462
|
-
var
|
|
16035
|
+
var import_utils87 = require("@typescript-eslint/utils");
|
|
15463
16036
|
var ACTION_MODULE_RE = /(?:^|\/)app\/.*\/(?:actions|[^/]+-actions)\.[cm]?[jt]s$/u;
|
|
15464
16037
|
var REQUIRE_USE_SERVER_IN_ACTIONS_FILE_DOCUMENTATION = {
|
|
15465
16038
|
summary: "route action module missing the use server directive",
|
|
@@ -15525,7 +16098,7 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
15525
16098
|
});
|
|
15526
16099
|
|
|
15527
16100
|
// src/rules/require-zod-form-validation.ts
|
|
15528
|
-
var
|
|
16101
|
+
var import_utils88 = require("@typescript-eslint/utils");
|
|
15529
16102
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
15530
16103
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
15531
16104
|
rationale: "FormData values are untrusted strings or files and need runtime validation before use.",
|
|
@@ -15550,14 +16123,14 @@ var FORM_VALUE_METHODS = /* @__PURE__ */ new Set(["get", "getAll"]);
|
|
|
15550
16123
|
var zodReceiverRoot = (node) => {
|
|
15551
16124
|
let current = node;
|
|
15552
16125
|
while (true) {
|
|
15553
|
-
if (current.type ===
|
|
16126
|
+
if (current.type === import_utils88.AST_NODE_TYPES.Identifier) {
|
|
15554
16127
|
return current;
|
|
15555
16128
|
}
|
|
15556
|
-
if (current.type ===
|
|
16129
|
+
if (current.type === import_utils88.AST_NODE_TYPES.CallExpression) {
|
|
15557
16130
|
current = current.callee;
|
|
15558
16131
|
continue;
|
|
15559
16132
|
}
|
|
15560
|
-
if (current.type ===
|
|
16133
|
+
if (current.type === import_utils88.AST_NODE_TYPES.MemberExpression) {
|
|
15561
16134
|
current = current.object;
|
|
15562
16135
|
continue;
|
|
15563
16136
|
}
|
|
@@ -15566,12 +16139,12 @@ var zodReceiverRoot = (node) => {
|
|
|
15566
16139
|
};
|
|
15567
16140
|
var isFormDataMethodCall = (node) => {
|
|
15568
16141
|
let current = node;
|
|
15569
|
-
if (current.type ===
|
|
16142
|
+
if (current.type === import_utils88.AST_NODE_TYPES.AwaitExpression) {
|
|
15570
16143
|
current = current.argument;
|
|
15571
16144
|
}
|
|
15572
|
-
if (current.type !==
|
|
16145
|
+
if (current.type !== import_utils88.AST_NODE_TYPES.CallExpression) return false;
|
|
15573
16146
|
const callee = current.callee;
|
|
15574
|
-
return callee.type ===
|
|
16147
|
+
return callee.type === import_utils88.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils88.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
|
|
15575
16148
|
};
|
|
15576
16149
|
var require_zod_form_validation_default = createRule({
|
|
15577
16150
|
name: "require-zod-form-validation",
|
|
@@ -15592,7 +16165,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15592
16165
|
return {};
|
|
15593
16166
|
}
|
|
15594
16167
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
15595
|
-
const resolvedBinding = (identifier) =>
|
|
16168
|
+
const resolvedBinding = (identifier) => import_utils88.ASTUtils.findVariable(
|
|
15596
16169
|
context.sourceCode.getScope(identifier),
|
|
15597
16170
|
identifier.name
|
|
15598
16171
|
);
|
|
@@ -15602,16 +16175,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15602
16175
|
return false;
|
|
15603
16176
|
}
|
|
15604
16177
|
const definition = binding.defs[0];
|
|
15605
|
-
if (definition?.type !== "Variable" || definition.node.type !==
|
|
16178
|
+
if (definition?.type !== "Variable" || definition.node.type !== import_utils88.AST_NODE_TYPES.VariableDeclarator) {
|
|
15606
16179
|
return false;
|
|
15607
16180
|
}
|
|
15608
16181
|
const init = definition.node.init;
|
|
15609
|
-
return init?.type ===
|
|
16182
|
+
return init?.type === import_utils88.AST_NODE_TYPES.ObjectExpression || init?.type === import_utils88.AST_NODE_TYPES.ArrayExpression || init?.type === import_utils88.AST_NODE_TYPES.Literal || init?.type === import_utils88.AST_NODE_TYPES.ArrowFunctionExpression || init?.type === import_utils88.AST_NODE_TYPES.FunctionExpression;
|
|
15610
16183
|
};
|
|
15611
16184
|
const isZodParseCall = (node) => {
|
|
15612
|
-
if (node.type !==
|
|
16185
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.CallExpression) return false;
|
|
15613
16186
|
const callee = node.callee;
|
|
15614
|
-
if (callee.type !==
|
|
16187
|
+
if (callee.type !== import_utils88.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils88.AST_NODE_TYPES.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
|
|
15615
16188
|
return false;
|
|
15616
16189
|
}
|
|
15617
16190
|
const root = zodReceiverRoot(callee.object);
|
|
@@ -15620,14 +16193,14 @@ var require_zod_form_validation_default = createRule({
|
|
|
15620
16193
|
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
15621
16194
|
};
|
|
15622
16195
|
const isFormSourceIdentifier = (node) => {
|
|
15623
|
-
if (node.type !==
|
|
16196
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.Identifier) return false;
|
|
15624
16197
|
const conventionalName = /formdata/i.test(node.name);
|
|
15625
16198
|
let scope = context.sourceCode.getScope(node);
|
|
15626
16199
|
while (scope !== null) {
|
|
15627
16200
|
const variable = scope.set.get(node.name);
|
|
15628
16201
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
15629
16202
|
const def = variable.defs[0];
|
|
15630
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
16203
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils88.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
|
|
15631
16204
|
return isFormDataMethodCall(def.node.init);
|
|
15632
16205
|
}
|
|
15633
16206
|
return def?.type === "Parameter" && conventionalName;
|
|
@@ -15638,8 +16211,8 @@ var require_zod_form_validation_default = createRule({
|
|
|
15638
16211
|
};
|
|
15639
16212
|
const isFormDataGetCall = (node) => {
|
|
15640
16213
|
const callee = node.callee;
|
|
15641
|
-
if (callee.type !==
|
|
15642
|
-
if (callee.property.type !==
|
|
16214
|
+
if (callee.type !== import_utils88.AST_NODE_TYPES.MemberExpression) return false;
|
|
16215
|
+
if (callee.property.type !== import_utils88.AST_NODE_TYPES.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
15643
16216
|
return false;
|
|
15644
16217
|
}
|
|
15645
16218
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -15655,16 +16228,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15655
16228
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
15656
16229
|
const isInstanceofNarrowing = (node) => {
|
|
15657
16230
|
const parent = node.parent;
|
|
15658
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
16231
|
+
return parent !== null && parent !== void 0 && parent.type === import_utils88.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node && parent.right.type === import_utils88.AST_NODE_TYPES.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
|
|
15659
16232
|
};
|
|
15660
16233
|
const boundDeclarator = (node) => {
|
|
15661
16234
|
let current = node;
|
|
15662
16235
|
let parent = current.parent;
|
|
15663
|
-
while ((parent.type ===
|
|
16236
|
+
while ((parent.type === import_utils88.AST_NODE_TYPES.TSAsExpression || parent.type === import_utils88.AST_NODE_TYPES.TSSatisfiesExpression || parent.type === import_utils88.AST_NODE_TYPES.TSNonNullExpression || parent.type === import_utils88.AST_NODE_TYPES.ChainExpression) && parent.expression === current) {
|
|
15664
16237
|
current = parent;
|
|
15665
16238
|
parent = current.parent;
|
|
15666
16239
|
}
|
|
15667
|
-
if (parent.type ===
|
|
16240
|
+
if (parent.type === import_utils88.AST_NODE_TYPES.VariableDeclarator && parent.init === current && parent.id.type === import_utils88.AST_NODE_TYPES.Identifier) {
|
|
15668
16241
|
return parent;
|
|
15669
16242
|
}
|
|
15670
16243
|
return null;
|
|
@@ -15673,7 +16246,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15673
16246
|
let current = node;
|
|
15674
16247
|
while (current.parent !== void 0) {
|
|
15675
16248
|
const parent = current.parent;
|
|
15676
|
-
if (parent.type ===
|
|
16249
|
+
if (parent.type === import_utils88.AST_NODE_TYPES.BlockStatement || parent.type === import_utils88.AST_NODE_TYPES.Program) {
|
|
15677
16250
|
return current;
|
|
15678
16251
|
}
|
|
15679
16252
|
current = parent;
|
|
@@ -15682,12 +16255,12 @@ var require_zod_form_validation_default = createRule({
|
|
|
15682
16255
|
};
|
|
15683
16256
|
const zodParseMethod = (call) => {
|
|
15684
16257
|
const callee = call.callee;
|
|
15685
|
-
return callee.type ===
|
|
16258
|
+
return callee.type === import_utils88.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils88.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
15686
16259
|
};
|
|
15687
16260
|
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
15688
16261
|
let current = node.parent;
|
|
15689
16262
|
while (current !== void 0 && current !== statement) {
|
|
15690
|
-
if (current.type ===
|
|
16263
|
+
if (current.type === import_utils88.AST_NODE_TYPES.LogicalExpression || current.type === import_utils88.AST_NODE_TYPES.ConditionalExpression) {
|
|
15691
16264
|
return true;
|
|
15692
16265
|
}
|
|
15693
16266
|
current = current.parent;
|
|
@@ -15697,7 +16270,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15697
16270
|
const isAwaitedBeforeStatement = (node, statement) => {
|
|
15698
16271
|
let current = node.parent;
|
|
15699
16272
|
while (current !== void 0 && current !== statement) {
|
|
15700
|
-
if (current.type ===
|
|
16273
|
+
if (current.type === import_utils88.AST_NODE_TYPES.AwaitExpression) return true;
|
|
15701
16274
|
current = current.parent;
|
|
15702
16275
|
}
|
|
15703
16276
|
return false;
|
|
@@ -15710,7 +16283,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15710
16283
|
if (declarationStatement === null || validationStatement === null || declarationStatement.parent !== validationStatement.parent || validationStatement.range[0] <= declarationStatement.range[1] || hasConditionalAncestorBeforeStatement(parse2, validationStatement)) {
|
|
15711
16284
|
return null;
|
|
15712
16285
|
}
|
|
15713
|
-
if (validationStatement.type !==
|
|
16286
|
+
if (validationStatement.type !== import_utils88.AST_NODE_TYPES.VariableDeclaration && validationStatement.type !== import_utils88.AST_NODE_TYPES.ExpressionStatement) {
|
|
15714
16287
|
return null;
|
|
15715
16288
|
}
|
|
15716
16289
|
const method = zodParseMethod(parse2);
|
|
@@ -15722,16 +16295,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15722
16295
|
};
|
|
15723
16296
|
const isSafePrevalidationInspection = (identifier) => {
|
|
15724
16297
|
const parent = identifier.parent;
|
|
15725
|
-
if (parent.type ===
|
|
16298
|
+
if (parent.type === import_utils88.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof") {
|
|
15726
16299
|
return true;
|
|
15727
16300
|
}
|
|
15728
|
-
if (parent.type !==
|
|
16301
|
+
if (parent.type !== import_utils88.AST_NODE_TYPES.BinaryExpression || parent.left !== identifier) {
|
|
15729
16302
|
return false;
|
|
15730
16303
|
}
|
|
15731
16304
|
if (parent.operator === "instanceof") {
|
|
15732
|
-
return parent.right.type ===
|
|
16305
|
+
return parent.right.type === import_utils88.AST_NODE_TYPES.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
|
|
15733
16306
|
}
|
|
15734
|
-
return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type ===
|
|
16307
|
+
return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type === import_utils88.AST_NODE_TYPES.Literal && parent.right.value === null || parent.right.type === import_utils88.AST_NODE_TYPES.Identifier && parent.right.name === "undefined");
|
|
15735
16308
|
};
|
|
15736
16309
|
const isDescendantOf = (node, ancestor) => {
|
|
15737
16310
|
let current = node;
|
|
@@ -15742,23 +16315,23 @@ var require_zod_form_validation_default = createRule({
|
|
|
15742
16315
|
return false;
|
|
15743
16316
|
};
|
|
15744
16317
|
const blockTerminates = (node) => {
|
|
15745
|
-
if (node.type ===
|
|
16318
|
+
if (node.type === import_utils88.AST_NODE_TYPES.ReturnStatement || node.type === import_utils88.AST_NODE_TYPES.ThrowStatement) {
|
|
15746
16319
|
return true;
|
|
15747
16320
|
}
|
|
15748
|
-
if (node.type !==
|
|
16321
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.BlockStatement || node.body.length === 0) return false;
|
|
15749
16322
|
const last = node.body.at(-1);
|
|
15750
16323
|
return last !== void 0 && blockTerminates(last);
|
|
15751
16324
|
};
|
|
15752
16325
|
const narrowingIf = (identifier) => {
|
|
15753
16326
|
const comparison = identifier.parent;
|
|
15754
|
-
if (comparison?.type !==
|
|
16327
|
+
if (comparison?.type !== import_utils88.AST_NODE_TYPES.BinaryExpression || comparison.operator !== "instanceof" || comparison.left !== identifier || comparison.right.type !== import_utils88.AST_NODE_TYPES.Identifier || comparison.right.name !== "File" && comparison.right.name !== "Blob") {
|
|
15755
16328
|
return null;
|
|
15756
16329
|
}
|
|
15757
16330
|
const maybeNegation = comparison.parent;
|
|
15758
|
-
const negated = maybeNegation?.type ===
|
|
16331
|
+
const negated = maybeNegation?.type === import_utils88.AST_NODE_TYPES.UnaryExpression && maybeNegation.operator === "!";
|
|
15759
16332
|
const test = negated ? maybeNegation : comparison;
|
|
15760
16333
|
const branch = test.parent;
|
|
15761
|
-
return branch?.type ===
|
|
16334
|
+
return branch?.type === import_utils88.AST_NODE_TYPES.IfStatement && branch.test === test ? { branch, positive: !negated } : null;
|
|
15762
16335
|
};
|
|
15763
16336
|
const useDominatedByNarrowing = (use, narrowings) => narrowings.some(({ branch, positive }) => {
|
|
15764
16337
|
if (positive) return isDescendantOf(use, branch.consequent);
|
|
@@ -15778,7 +16351,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15778
16351
|
const variable = context.sourceCode.getDeclaredVariables(declarator)[0];
|
|
15779
16352
|
if (variable === void 0) return false;
|
|
15780
16353
|
const references = variable.references.filter((reference) => !reference.isWriteOnly()).map((reference) => reference.identifier).filter(
|
|
15781
|
-
(identifier) => identifier.type ===
|
|
16354
|
+
(identifier) => identifier.type === import_utils88.AST_NODE_TYPES.Identifier
|
|
15782
16355
|
);
|
|
15783
16356
|
if (references.length === 0) return false;
|
|
15784
16357
|
const narrowings = references.map(narrowingIf).filter(
|
|
@@ -15804,7 +16377,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15804
16377
|
ImportDeclaration(node) {
|
|
15805
16378
|
if (!isZodModule(node.source.value)) return;
|
|
15806
16379
|
for (const specifier of node.specifiers) {
|
|
15807
|
-
if (specifier.type ===
|
|
16380
|
+
if (specifier.type === import_utils88.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils88.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils88.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils88.AST_NODE_TYPES.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
|
|
15808
16381
|
const binding = resolvedBinding(specifier.local);
|
|
15809
16382
|
if (binding !== null) zodBindings.add(binding);
|
|
15810
16383
|
}
|
|
@@ -15825,7 +16398,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15825
16398
|
});
|
|
15826
16399
|
|
|
15827
16400
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
15828
|
-
var
|
|
16401
|
+
var import_utils89 = require("@typescript-eslint/utils");
|
|
15829
16402
|
var STORE_INSERT_REQUIRES_ON_CONFLICT_DOCUMENTATION = {
|
|
15830
16403
|
summary: "Require embedded inserts in explicitly replayable callables to carry conflict handling.",
|
|
15831
16404
|
rationale: "A callable named as an enqueue, seed, migration, schedule, ensure, or upsert promises replay safety.",
|
|
@@ -15889,7 +16462,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
15889
16462
|
});
|
|
15890
16463
|
|
|
15891
16464
|
// src/rules/stepdown.ts
|
|
15892
|
-
var
|
|
16465
|
+
var import_utils90 = require("@typescript-eslint/utils");
|
|
15893
16466
|
var STEPDOWN_DOCUMENTATION = {
|
|
15894
16467
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
15895
16468
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -15909,7 +16482,7 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
15909
16482
|
]
|
|
15910
16483
|
};
|
|
15911
16484
|
function isFunction(node) {
|
|
15912
|
-
return node.type ===
|
|
16485
|
+
return node.type === import_utils90.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils90.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils90.AST_NODE_TYPES.FunctionExpression;
|
|
15913
16486
|
}
|
|
15914
16487
|
function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true, makeFix) {
|
|
15915
16488
|
const byName = new Map(scopeDefinitions.map((definition) => [definition.name, definition]));
|
|
@@ -16006,8 +16579,8 @@ function moduleScope(context, program) {
|
|
|
16006
16579
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
16007
16580
|
const overloadNames = new Set(
|
|
16008
16581
|
program.body.flatMap((statement) => {
|
|
16009
|
-
const node = statement.type ===
|
|
16010
|
-
return node?.type ===
|
|
16582
|
+
const node = statement.type === import_utils90.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
16583
|
+
return node?.type === import_utils90.AST_NODE_TYPES.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
|
|
16011
16584
|
})
|
|
16012
16585
|
);
|
|
16013
16586
|
const exported = exportedNames(program);
|
|
@@ -16031,7 +16604,7 @@ function moduleScope(context, program) {
|
|
|
16031
16604
|
const nearestFunction2 = [...ancestors].reverse().find(isFunction);
|
|
16032
16605
|
const parent = identifier.parent;
|
|
16033
16606
|
const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
|
|
16034
|
-
if (callerDefinition === void 0 || parent.type !==
|
|
16607
|
+
if (callerDefinition === void 0 || parent.type !== import_utils90.AST_NODE_TYPES.CallExpression || parent.callee !== identifier) {
|
|
16035
16608
|
pinned.add(definition.name);
|
|
16036
16609
|
continue;
|
|
16037
16610
|
}
|
|
@@ -16046,38 +16619,38 @@ function moduleScope(context, program) {
|
|
|
16046
16619
|
function exportedNames(program) {
|
|
16047
16620
|
const names = /* @__PURE__ */ new Set();
|
|
16048
16621
|
for (const statement of program.body) {
|
|
16049
|
-
if (statement.type !==
|
|
16050
|
-
if (statement.declaration?.type ===
|
|
16622
|
+
if (statement.type !== import_utils90.AST_NODE_TYPES.ExportNamedDeclaration || statement.exportKind === "type" || statement.source !== null) continue;
|
|
16623
|
+
if (statement.declaration?.type === import_utils90.AST_NODE_TYPES.FunctionDeclaration && statement.declaration.id !== null) {
|
|
16051
16624
|
names.add(statement.declaration.id.name);
|
|
16052
16625
|
}
|
|
16053
|
-
if (statement.declaration?.type ===
|
|
16626
|
+
if (statement.declaration?.type === import_utils90.AST_NODE_TYPES.VariableDeclaration) {
|
|
16054
16627
|
for (const declarator of statement.declaration.declarations) {
|
|
16055
|
-
if (declarator.id.type ===
|
|
16628
|
+
if (declarator.id.type === import_utils90.AST_NODE_TYPES.Identifier) names.add(declarator.id.name);
|
|
16056
16629
|
}
|
|
16057
16630
|
}
|
|
16058
16631
|
for (const specifier of statement.specifiers) {
|
|
16059
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
16632
|
+
if (specifier.exportKind !== "type" && specifier.local.type === import_utils90.AST_NODE_TYPES.Identifier) {
|
|
16060
16633
|
names.add(specifier.local.name);
|
|
16061
16634
|
}
|
|
16062
16635
|
}
|
|
16063
16636
|
}
|
|
16064
16637
|
for (const statement of program.body) {
|
|
16065
|
-
if (statement.type ===
|
|
16066
|
-
if (statement.type ===
|
|
16638
|
+
if (statement.type === import_utils90.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils90.AST_NODE_TYPES.Identifier) names.add(statement.declaration.name);
|
|
16639
|
+
if (statement.type === import_utils90.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils90.AST_NODE_TYPES.FunctionDeclaration && statement.declaration.id !== null) names.add(statement.declaration.id.name);
|
|
16067
16640
|
}
|
|
16068
16641
|
return names;
|
|
16069
16642
|
}
|
|
16070
16643
|
function moduleDefinitions(program) {
|
|
16071
16644
|
const definitions = [];
|
|
16072
16645
|
for (const statement of program.body) {
|
|
16073
|
-
const node = statement.type ===
|
|
16074
|
-
if (node?.type ===
|
|
16646
|
+
const node = statement.type === import_utils90.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils90.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
16647
|
+
if (node?.type === import_utils90.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && node.body !== null) {
|
|
16075
16648
|
definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
16076
16649
|
continue;
|
|
16077
16650
|
}
|
|
16078
|
-
if (node?.type !==
|
|
16651
|
+
if (node?.type !== import_utils90.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const") continue;
|
|
16079
16652
|
for (const declarator of node.declarations) {
|
|
16080
|
-
if (declarator.id.type ===
|
|
16653
|
+
if (declarator.id.type === import_utils90.AST_NODE_TYPES.Identifier && declarator.init !== null && isFunction(declarator.init)) {
|
|
16081
16654
|
definitions.push({
|
|
16082
16655
|
name: declarator.id.name,
|
|
16083
16656
|
node: declarator,
|
|
@@ -16090,21 +16663,21 @@ function moduleDefinitions(program) {
|
|
|
16090
16663
|
return definitions;
|
|
16091
16664
|
}
|
|
16092
16665
|
function methodName(node) {
|
|
16093
|
-
if (node.key.type ===
|
|
16094
|
-
return !node.computed && node.key.type ===
|
|
16666
|
+
if (node.key.type === import_utils90.AST_NODE_TYPES.PrivateIdentifier) return `#${node.key.name}`;
|
|
16667
|
+
return !node.computed && node.key.type === import_utils90.AST_NODE_TYPES.Identifier ? node.key.name : null;
|
|
16095
16668
|
}
|
|
16096
16669
|
function referencedMethod(context, node, classVariables) {
|
|
16097
|
-
const objectVariable = node.object.type ===
|
|
16670
|
+
const objectVariable = node.object.type === import_utils90.AST_NODE_TYPES.Identifier ? import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
|
|
16098
16671
|
const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
|
|
16099
|
-
if (node.object.type !==
|
|
16100
|
-
if (node.property.type ===
|
|
16101
|
-
if (!node.computed && node.property.type ===
|
|
16102
|
-
return node.computed && node.property.type ===
|
|
16672
|
+
if (node.object.type !== import_utils90.AST_NODE_TYPES.ThisExpression && !isClassReference) return null;
|
|
16673
|
+
if (node.property.type === import_utils90.AST_NODE_TYPES.PrivateIdentifier) return `#${node.property.name}`;
|
|
16674
|
+
if (!node.computed && node.property.type === import_utils90.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
16675
|
+
return node.computed && node.property.type === import_utils90.AST_NODE_TYPES.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
16103
16676
|
}
|
|
16104
16677
|
function referencedPropertyName(node) {
|
|
16105
|
-
if (node.property.type ===
|
|
16106
|
-
if (!node.computed && node.property.type ===
|
|
16107
|
-
return node.computed && node.property.type ===
|
|
16678
|
+
if (node.property.type === import_utils90.AST_NODE_TYPES.PrivateIdentifier) return `#${node.property.name}`;
|
|
16679
|
+
if (!node.computed && node.property.type === import_utils90.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
16680
|
+
return node.computed && node.property.type === import_utils90.AST_NODE_TYPES.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
16108
16681
|
}
|
|
16109
16682
|
function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
16110
16683
|
visit(node, nestedFunction);
|
|
@@ -16120,7 +16693,7 @@ function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
|
16120
16693
|
}
|
|
16121
16694
|
function classScope(context, node, computedReferenceNames) {
|
|
16122
16695
|
const methods = node.body.body.filter(
|
|
16123
|
-
(member) => member.type ===
|
|
16696
|
+
(member) => member.type === import_utils90.AST_NODE_TYPES.MethodDefinition
|
|
16124
16697
|
);
|
|
16125
16698
|
const counts = /* @__PURE__ */ new Map();
|
|
16126
16699
|
for (const method of methods) {
|
|
@@ -16128,8 +16701,8 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16128
16701
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16129
16702
|
}
|
|
16130
16703
|
for (const member of node.body.body) {
|
|
16131
|
-
if (member.type !==
|
|
16132
|
-
const name = !member.computed && member.key.type ===
|
|
16704
|
+
if (member.type !== import_utils90.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
|
|
16705
|
+
const name = !member.computed && member.key.type === import_utils90.AST_NODE_TYPES.Identifier ? member.key.name : null;
|
|
16133
16706
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16134
16707
|
}
|
|
16135
16708
|
const scopeDefinitions = methods.flatMap((method) => {
|
|
@@ -16138,7 +16711,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16138
16711
|
});
|
|
16139
16712
|
const definitions = methods.flatMap((method) => {
|
|
16140
16713
|
const name = methodName(method);
|
|
16141
|
-
const isPrivate = method.accessibility === "private" || method.key.type ===
|
|
16714
|
+
const isPrivate = method.accessibility === "private" || method.key.type === import_utils90.AST_NODE_TYPES.PrivateIdentifier;
|
|
16142
16715
|
return name !== null && isPrivate && counts.get(name) === 1 && method.decorators.length === 0 ? [{ name, node: method }] : [];
|
|
16143
16716
|
});
|
|
16144
16717
|
if (definitions.length === 0) return;
|
|
@@ -16147,11 +16720,11 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16147
16720
|
const pinned = /* @__PURE__ */ new Set();
|
|
16148
16721
|
const classVariables = /* @__PURE__ */ new Set();
|
|
16149
16722
|
if (node.id !== null) {
|
|
16150
|
-
const internal =
|
|
16723
|
+
const internal = import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
16151
16724
|
if (internal !== null) classVariables.add(internal);
|
|
16152
16725
|
}
|
|
16153
|
-
if (node.type ===
|
|
16154
|
-
const outer =
|
|
16726
|
+
if (node.type === import_utils90.AST_NODE_TYPES.ClassExpression && node.parent.type === import_utils90.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils90.AST_NODE_TYPES.Identifier) {
|
|
16727
|
+
const outer = import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
16155
16728
|
if (outer !== null) classVariables.add(outer);
|
|
16156
16729
|
}
|
|
16157
16730
|
for (const method of methods) {
|
|
@@ -16167,27 +16740,27 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16167
16740
|
}
|
|
16168
16741
|
const thisValue = (value) => {
|
|
16169
16742
|
let current = value;
|
|
16170
|
-
while (current?.type ===
|
|
16171
|
-
return current?.type ===
|
|
16743
|
+
while (current?.type === import_utils90.AST_NODE_TYPES.TSAsExpression || current?.type === import_utils90.AST_NODE_TYPES.TSSatisfiesExpression || current?.type === import_utils90.AST_NODE_TYPES.TSNonNullExpression) current = current.expression;
|
|
16744
|
+
return current?.type === import_utils90.AST_NODE_TYPES.ThisExpression;
|
|
16172
16745
|
};
|
|
16173
16746
|
const collectAlias = (current, nestedFunction) => {
|
|
16174
|
-
if (nestedFunction || current.type !==
|
|
16175
|
-
if (current.type ===
|
|
16176
|
-
const binding = current.type ===
|
|
16177
|
-
const value = current.type ===
|
|
16747
|
+
if (nestedFunction || current.type !== import_utils90.AST_NODE_TYPES.VariableDeclarator && current.type !== import_utils90.AST_NODE_TYPES.AssignmentPattern) return;
|
|
16748
|
+
if (current.type === import_utils90.AST_NODE_TYPES.VariableDeclarator && (current.parent.type !== import_utils90.AST_NODE_TYPES.VariableDeclaration || current.parent.kind !== "const")) return;
|
|
16749
|
+
const binding = current.type === import_utils90.AST_NODE_TYPES.VariableDeclarator ? current.id : current.left;
|
|
16750
|
+
const value = current.type === import_utils90.AST_NODE_TYPES.VariableDeclarator ? current.init : current.right;
|
|
16178
16751
|
if (!thisValue(value)) return;
|
|
16179
|
-
if (binding.type ===
|
|
16752
|
+
if (binding.type === import_utils90.AST_NODE_TYPES.ObjectPattern) {
|
|
16180
16753
|
for (const property of binding.properties) {
|
|
16181
|
-
if (property.type ===
|
|
16754
|
+
if (property.type === import_utils90.AST_NODE_TYPES.RestElement) {
|
|
16182
16755
|
for (const name of privateNames) pinned.add(name);
|
|
16183
|
-
} else if (property.key.type ===
|
|
16756
|
+
} else if (property.key.type === import_utils90.AST_NODE_TYPES.Identifier && privateNames.has(property.key.name)) {
|
|
16184
16757
|
pinned.add(property.key.name);
|
|
16185
16758
|
}
|
|
16186
16759
|
}
|
|
16187
16760
|
return;
|
|
16188
16761
|
}
|
|
16189
|
-
if (binding.type !==
|
|
16190
|
-
const variable =
|
|
16762
|
+
if (binding.type !== import_utils90.AST_NODE_TYPES.Identifier) return;
|
|
16763
|
+
const variable = import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
16191
16764
|
if (variable !== null) {
|
|
16192
16765
|
methodClassVariables.add(variable);
|
|
16193
16766
|
methodAliases.add(variable);
|
|
@@ -16200,16 +16773,16 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16200
16773
|
walk2(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
16201
16774
|
}
|
|
16202
16775
|
const visitCall = (current, nestedFunction) => {
|
|
16203
|
-
if (current.type ===
|
|
16776
|
+
if (current.type === import_utils90.AST_NODE_TYPES.VariableDeclarator && current.id.type === import_utils90.AST_NODE_TYPES.ObjectPattern && thisValue(current.init)) {
|
|
16204
16777
|
for (const property of current.id.properties) {
|
|
16205
|
-
if (property.type ===
|
|
16778
|
+
if (property.type === import_utils90.AST_NODE_TYPES.RestElement) {
|
|
16206
16779
|
for (const name of privateNames) pinned.add(name);
|
|
16207
16780
|
continue;
|
|
16208
16781
|
}
|
|
16209
|
-
if (property.type ===
|
|
16782
|
+
if (property.type === import_utils90.AST_NODE_TYPES.Property && property.key.type === import_utils90.AST_NODE_TYPES.Identifier && privateNames.has(property.key.name)) pinned.add(property.key.name);
|
|
16210
16783
|
}
|
|
16211
16784
|
}
|
|
16212
|
-
if (current.type !==
|
|
16785
|
+
if (current.type !== import_utils90.AST_NODE_TYPES.MemberExpression) return;
|
|
16213
16786
|
const target = referencedMethod(context, current, methodClassVariables);
|
|
16214
16787
|
if (target === null) {
|
|
16215
16788
|
const possibleTarget = referencedPropertyName(current);
|
|
@@ -16217,12 +16790,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16217
16790
|
return;
|
|
16218
16791
|
}
|
|
16219
16792
|
if (!privateNames.has(target)) return;
|
|
16220
|
-
const objectVariable = current.object.type ===
|
|
16793
|
+
const objectVariable = current.object.type === import_utils90.AST_NODE_TYPES.Identifier ? import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
|
|
16221
16794
|
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
16222
16795
|
pinned.add(target);
|
|
16223
16796
|
return;
|
|
16224
16797
|
}
|
|
16225
|
-
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !==
|
|
16798
|
+
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !== import_utils90.AST_NODE_TYPES.CallExpression || current.parent.callee !== current) {
|
|
16226
16799
|
pinned.add(target);
|
|
16227
16800
|
return;
|
|
16228
16801
|
}
|
|
@@ -16242,9 +16815,9 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16242
16815
|
}
|
|
16243
16816
|
}
|
|
16244
16817
|
for (const member of node.body.body) {
|
|
16245
|
-
if (member.type ===
|
|
16818
|
+
if (member.type === import_utils90.AST_NODE_TYPES.MethodDefinition || member.type === import_utils90.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
|
|
16246
16819
|
walk2(member, context.sourceCode.visitorKeys, (current) => {
|
|
16247
|
-
if (current.type !==
|
|
16820
|
+
if (current.type !== import_utils90.AST_NODE_TYPES.MemberExpression) return;
|
|
16248
16821
|
const target = referencedMethod(context, current, classVariables);
|
|
16249
16822
|
const possibleTarget = target ?? referencedPropertyName(current);
|
|
16250
16823
|
if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
|
|
@@ -16296,12 +16869,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16296
16869
|
}
|
|
16297
16870
|
function isClassRuntimeBarrier(member) {
|
|
16298
16871
|
switch (member.type) {
|
|
16299
|
-
case
|
|
16872
|
+
case import_utils90.AST_NODE_TYPES.StaticBlock:
|
|
16300
16873
|
return true;
|
|
16301
|
-
case
|
|
16302
|
-
case
|
|
16874
|
+
case import_utils90.AST_NODE_TYPES.PropertyDefinition:
|
|
16875
|
+
case import_utils90.AST_NODE_TYPES.AccessorProperty:
|
|
16303
16876
|
return member.static || member.computed || member.decorators.length > 0 || member.value !== null;
|
|
16304
|
-
case
|
|
16877
|
+
case import_utils90.AST_NODE_TYPES.MethodDefinition:
|
|
16305
16878
|
return member.computed || member.decorators.length > 0;
|
|
16306
16879
|
default:
|
|
16307
16880
|
return false;
|
|
@@ -16334,7 +16907,7 @@ var stepdown_default = createRule({
|
|
|
16334
16907
|
moduleScope(context, program);
|
|
16335
16908
|
const computedReferenceNames = /* @__PURE__ */ new Set();
|
|
16336
16909
|
walk2(program, context.sourceCode.visitorKeys, (node) => {
|
|
16337
|
-
if (node.type ===
|
|
16910
|
+
if (node.type === import_utils90.AST_NODE_TYPES.MemberExpression && node.computed && node.property.type === import_utils90.AST_NODE_TYPES.Literal && typeof node.property.value === "string") computedReferenceNames.add(node.property.value);
|
|
16338
16911
|
});
|
|
16339
16912
|
for (const node of classes) classScope(context, node, computedReferenceNames);
|
|
16340
16913
|
}
|
|
@@ -16343,7 +16916,7 @@ var stepdown_default = createRule({
|
|
|
16343
16916
|
});
|
|
16344
16917
|
|
|
16345
16918
|
// src/rules/source-coupled-test.ts
|
|
16346
|
-
var
|
|
16919
|
+
var import_utils91 = require("@typescript-eslint/utils");
|
|
16347
16920
|
var GENERAL_SOURCE_SUFFIX_RE = /\.(?:bash|sh|ya?ml|jsonc|py|[cm]?[jt]s)$/iu;
|
|
16348
16921
|
var FS_MODULES = /* @__PURE__ */ new Set(["fs", "node:fs", "fs/promises", "node:fs/promises"]);
|
|
16349
16922
|
var FS_READERS = /* @__PURE__ */ new Set(["readFile", "readFileSync"]);
|
|
@@ -16412,28 +16985,28 @@ var SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
|
16412
16985
|
]
|
|
16413
16986
|
};
|
|
16414
16987
|
function staticMemberName7(node) {
|
|
16415
|
-
if (!node.computed && node.property.type ===
|
|
16416
|
-
if (node.computed && node.property.type ===
|
|
16988
|
+
if (!node.computed && node.property.type === import_utils91.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
16989
|
+
if (node.computed && node.property.type === import_utils91.AST_NODE_TYPES.Literal && typeof node.property.value === "string") return node.property.value;
|
|
16417
16990
|
return null;
|
|
16418
16991
|
}
|
|
16419
|
-
function
|
|
16420
|
-
if (node.type ===
|
|
16421
|
-
if (node.type ===
|
|
16422
|
-
if (node.type ===
|
|
16992
|
+
function unwrap6(node) {
|
|
16993
|
+
if (node.type === import_utils91.AST_NODE_TYPES.AwaitExpression) return unwrap6(node.argument);
|
|
16994
|
+
if (node.type === import_utils91.AST_NODE_TYPES.ChainExpression) return unwrap6(node.expression);
|
|
16995
|
+
if (node.type === import_utils91.AST_NODE_TYPES.TSAsExpression || node.type === import_utils91.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils91.AST_NODE_TYPES.TSTypeAssertion) return unwrap6(node.expression);
|
|
16423
16996
|
return node;
|
|
16424
16997
|
}
|
|
16425
16998
|
function stringValue(node) {
|
|
16426
|
-
const current =
|
|
16427
|
-
if (current.type ===
|
|
16428
|
-
if (current.type ===
|
|
16999
|
+
const current = unwrap6(node);
|
|
17000
|
+
if (current.type === import_utils91.AST_NODE_TYPES.Literal && typeof current.value === "string") return current.value;
|
|
17001
|
+
if (current.type === import_utils91.AST_NODE_TYPES.TemplateLiteral && current.expressions.length === 0) return current.quasis[0]?.value.cooked ?? null;
|
|
16429
17002
|
return null;
|
|
16430
17003
|
}
|
|
16431
17004
|
function importSource(node) {
|
|
16432
17005
|
return typeof node.source.value === "string" ? node.source.value : null;
|
|
16433
17006
|
}
|
|
16434
17007
|
function requireSource(node) {
|
|
16435
|
-
const current =
|
|
16436
|
-
if (current.type !==
|
|
17008
|
+
const current = unwrap6(node);
|
|
17009
|
+
if (current.type !== import_utils91.AST_NODE_TYPES.CallExpression || current.callee.type !== import_utils91.AST_NODE_TYPES.Identifier || current.callee.name !== "require" || current.arguments.length !== 1 || current.arguments[0]?.type === import_utils91.AST_NODE_TYPES.SpreadElement) return null;
|
|
16437
17010
|
return stringValue(current.arguments[0]);
|
|
16438
17011
|
}
|
|
16439
17012
|
function newScope() {
|
|
@@ -16470,80 +17043,80 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16470
17043
|
return /* @__PURE__ */ new Set();
|
|
16471
17044
|
};
|
|
16472
17045
|
const sourcePath = (node) => {
|
|
16473
|
-
const current =
|
|
17046
|
+
const current = unwrap6(node);
|
|
16474
17047
|
const value = stringValue(current);
|
|
16475
17048
|
if (value !== null) return sourceSuffixRe.test(value);
|
|
16476
|
-
if (current.type ===
|
|
16477
|
-
if (current.type ===
|
|
17049
|
+
if (current.type === import_utils91.AST_NODE_TYPES.Identifier) return visible("paths", current.name);
|
|
17050
|
+
if (current.type === import_utils91.AST_NODE_TYPES.BinaryExpression && current.operator === "+") {
|
|
16478
17051
|
return sourcePath(current.left) || sourcePath(current.right);
|
|
16479
17052
|
}
|
|
16480
|
-
if (current.type ===
|
|
16481
|
-
if (current.type ===
|
|
16482
|
-
return current.arguments.some((argument) => argument.type !==
|
|
17053
|
+
if (current.type === import_utils91.AST_NODE_TYPES.TemplateLiteral) return current.expressions.some(sourcePath);
|
|
17054
|
+
if (current.type === import_utils91.AST_NODE_TYPES.CallExpression || current.type === import_utils91.AST_NODE_TYPES.NewExpression) {
|
|
17055
|
+
return current.arguments.some((argument) => argument.type !== import_utils91.AST_NODE_TYPES.SpreadElement && sourcePath(argument));
|
|
16483
17056
|
}
|
|
16484
|
-
if (current.type ===
|
|
17057
|
+
if (current.type === import_utils91.AST_NODE_TYPES.MemberExpression) return sourcePath(current.object);
|
|
16485
17058
|
return false;
|
|
16486
17059
|
};
|
|
16487
17060
|
const rawRead = (node) => {
|
|
16488
|
-
const current =
|
|
16489
|
-
if (current.type !==
|
|
16490
|
-
const callee =
|
|
16491
|
-
if (callee.type ===
|
|
17061
|
+
const current = unwrap6(node);
|
|
17062
|
+
if (current.type !== import_utils91.AST_NODE_TYPES.CallExpression || current.arguments.length === 0) return false;
|
|
17063
|
+
const callee = unwrap6(current.callee);
|
|
17064
|
+
if (callee.type === import_utils91.AST_NODE_TYPES.Identifier) {
|
|
16492
17065
|
return visible("fsReaders", callee.name) && sourcePath(current.arguments[0]);
|
|
16493
17066
|
}
|
|
16494
|
-
if (callee.type !==
|
|
17067
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return false;
|
|
16495
17068
|
const name2 = staticMemberName7(callee);
|
|
16496
|
-
const object =
|
|
16497
|
-
return name2 !== null && FS_READERS.has(name2) && object.type ===
|
|
17069
|
+
const object = unwrap6(callee.object);
|
|
17070
|
+
return name2 !== null && FS_READERS.has(name2) && object.type === import_utils91.AST_NODE_TYPES.Identifier && visible("fsObjects", object.name) && sourcePath(current.arguments[0]);
|
|
16498
17071
|
};
|
|
16499
17072
|
const rawOrigins = (node) => {
|
|
16500
|
-
const current =
|
|
16501
|
-
if (current.type ===
|
|
17073
|
+
const current = unwrap6(node);
|
|
17074
|
+
if (current.type === import_utils91.AST_NODE_TYPES.Identifier) return visibleRawOrigins(current.name);
|
|
16502
17075
|
if (rawRead(current)) return /* @__PURE__ */ new Set([`${current.range[0]}:${current.range[1]}`]);
|
|
16503
|
-
if (current.type ===
|
|
16504
|
-
if (current.type ===
|
|
16505
|
-
if (current.type !==
|
|
16506
|
-
const callee =
|
|
16507
|
-
if (callee.type !==
|
|
17076
|
+
if (current.type === import_utils91.AST_NODE_TYPES.BinaryExpression && current.operator === "+") return /* @__PURE__ */ new Set([...rawOrigins(current.left), ...rawOrigins(current.right)]);
|
|
17077
|
+
if (current.type === import_utils91.AST_NODE_TYPES.MemberExpression && staticMemberName7(current) === "length") return rawOrigins(current.object);
|
|
17078
|
+
if (current.type !== import_utils91.AST_NODE_TYPES.CallExpression) return /* @__PURE__ */ new Set();
|
|
17079
|
+
const callee = unwrap6(current.callee);
|
|
17080
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return /* @__PURE__ */ new Set();
|
|
16508
17081
|
const name2 = staticMemberName7(callee);
|
|
16509
17082
|
return name2 !== null && TEXT_TRANSFORMS.has(name2) ? rawOrigins(callee.object) : /* @__PURE__ */ new Set();
|
|
16510
17083
|
};
|
|
16511
17084
|
const evidenceOrigins = (node) => {
|
|
16512
|
-
const current =
|
|
17085
|
+
const current = unwrap6(node);
|
|
16513
17086
|
const direct = rawOrigins(current);
|
|
16514
17087
|
if (direct.size > 0) return direct;
|
|
16515
|
-
if (current.type ===
|
|
16516
|
-
if (current.type ===
|
|
16517
|
-
if (current.type !==
|
|
16518
|
-
const callee =
|
|
16519
|
-
if (callee.type !==
|
|
17088
|
+
if (current.type === import_utils91.AST_NODE_TYPES.BinaryExpression || current.type === import_utils91.AST_NODE_TYPES.LogicalExpression) return /* @__PURE__ */ new Set([...evidenceOrigins(current.left), ...evidenceOrigins(current.right)]);
|
|
17089
|
+
if (current.type === import_utils91.AST_NODE_TYPES.UnaryExpression) return evidenceOrigins(current.argument);
|
|
17090
|
+
if (current.type !== import_utils91.AST_NODE_TYPES.CallExpression) return /* @__PURE__ */ new Set();
|
|
17091
|
+
const callee = unwrap6(current.callee);
|
|
17092
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return /* @__PURE__ */ new Set();
|
|
16520
17093
|
const name2 = staticMemberName7(callee);
|
|
16521
17094
|
if (name2 !== null && TEXT_PREDICATES.has(name2)) return rawOrigins(callee.object);
|
|
16522
|
-
if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type ===
|
|
17095
|
+
if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type === import_utils91.AST_NODE_TYPES.SpreadElement ? [] : [...rawOrigins(argument)]));
|
|
16523
17096
|
return /* @__PURE__ */ new Set();
|
|
16524
17097
|
};
|
|
16525
17098
|
const rawAssertionOrigins = (node) => {
|
|
16526
|
-
const callee =
|
|
16527
|
-
if (callee.type ===
|
|
16528
|
-
return new Set(node.arguments.flatMap((argument) => argument.type ===
|
|
17099
|
+
const callee = unwrap6(node.callee);
|
|
17100
|
+
if (callee.type === import_utils91.AST_NODE_TYPES.Identifier && callee.name === "assert") {
|
|
17101
|
+
return new Set(node.arguments.flatMap((argument) => argument.type === import_utils91.AST_NODE_TYPES.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
16529
17102
|
}
|
|
16530
|
-
if (callee.type !==
|
|
17103
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return /* @__PURE__ */ new Set();
|
|
16531
17104
|
const matcher = staticMemberName7(callee);
|
|
16532
17105
|
if (matcher === null) return /* @__PURE__ */ new Set();
|
|
16533
|
-
let receiver =
|
|
16534
|
-
while (receiver.type ===
|
|
16535
|
-
if (receiver.type ===
|
|
17106
|
+
let receiver = unwrap6(callee.object);
|
|
17107
|
+
while (receiver.type === import_utils91.AST_NODE_TYPES.MemberExpression && EXPECT_MODIFIERS2.has(staticMemberName7(receiver) ?? "")) receiver = unwrap6(receiver.object);
|
|
17108
|
+
if (receiver.type === import_utils91.AST_NODE_TYPES.CallExpression && receiver.callee.type === import_utils91.AST_NODE_TYPES.Identifier && receiver.callee.name === "expect") {
|
|
16536
17109
|
if (!EXPECT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
16537
|
-
return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type ===
|
|
17110
|
+
return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type === import_utils91.AST_NODE_TYPES.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
16538
17111
|
}
|
|
16539
|
-
if (receiver.type !==
|
|
16540
|
-
return new Set(node.arguments.flatMap((argument) => argument.type ===
|
|
17112
|
+
if (receiver.type !== import_utils91.AST_NODE_TYPES.Identifier || receiver.name !== "assert" || !ASSERT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
17113
|
+
return new Set(node.arguments.flatMap((argument) => argument.type === import_utils91.AST_NODE_TYPES.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
16541
17114
|
};
|
|
16542
17115
|
const rawRegexExtractionOrigins = (node) => {
|
|
16543
|
-
const callee =
|
|
16544
|
-
if (callee.type !==
|
|
17116
|
+
const callee = unwrap6(node.callee);
|
|
17117
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression || staticMemberName7(callee) !== "matchAll" || node.arguments.length !== 1) return /* @__PURE__ */ new Set();
|
|
16545
17118
|
const argument = node.arguments[0];
|
|
16546
|
-
if (argument?.type !==
|
|
17119
|
+
if (argument?.type !== import_utils91.AST_NODE_TYPES.Literal || !(argument.value instanceof RegExp)) return /* @__PURE__ */ new Set();
|
|
16547
17120
|
return rawOrigins(callee.object);
|
|
16548
17121
|
};
|
|
16549
17122
|
const declare = (name2, state) => {
|
|
@@ -16563,16 +17136,16 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16563
17136
|
}
|
|
16564
17137
|
};
|
|
16565
17138
|
const sourceCollection = (node) => {
|
|
16566
|
-
const current =
|
|
16567
|
-
return current.type ===
|
|
17139
|
+
const current = unwrap6(node);
|
|
17140
|
+
return current.type === import_utils91.AST_NODE_TYPES.ArrayExpression && current.elements.length > 0 && current.elements.every((element) => element !== null && element.type !== import_utils91.AST_NODE_TYPES.SpreadElement && sourcePath(element));
|
|
16568
17141
|
};
|
|
16569
17142
|
const declaredNames2 = (node) => {
|
|
16570
|
-
const current =
|
|
16571
|
-
if (current.type ===
|
|
16572
|
-
if (current.type ===
|
|
16573
|
-
if (current.type ===
|
|
16574
|
-
if (current.type ===
|
|
16575
|
-
if (current.type ===
|
|
17143
|
+
const current = unwrap6(node);
|
|
17144
|
+
if (current.type === import_utils91.AST_NODE_TYPES.Identifier) return [current.name];
|
|
17145
|
+
if (current.type === import_utils91.AST_NODE_TYPES.AssignmentPattern) return declaredNames2(current.left);
|
|
17146
|
+
if (current.type === import_utils91.AST_NODE_TYPES.RestElement) return declaredNames2(current.argument);
|
|
17147
|
+
if (current.type === import_utils91.AST_NODE_TYPES.ArrayPattern) return current.elements.flatMap((element) => element === null ? [] : declaredNames2(element));
|
|
17148
|
+
if (current.type === import_utils91.AST_NODE_TYPES.ObjectPattern) return current.properties.flatMap((property) => property.type === import_utils91.AST_NODE_TYPES.RestElement ? declaredNames2(property.argument) : declaredNames2(property.value));
|
|
16576
17149
|
return [];
|
|
16577
17150
|
};
|
|
16578
17151
|
const enterFunction = (node) => {
|
|
@@ -16587,8 +17160,8 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16587
17160
|
const source = importSource(node);
|
|
16588
17161
|
if (source === null || !FS_MODULES.has(source)) return;
|
|
16589
17162
|
for (const specifier of node.specifiers) {
|
|
16590
|
-
if (specifier.type ===
|
|
16591
|
-
const imported = specifier.imported.type ===
|
|
17163
|
+
if (specifier.type === import_utils91.AST_NODE_TYPES.ImportSpecifier) {
|
|
17164
|
+
const imported = specifier.imported.type === import_utils91.AST_NODE_TYPES.Identifier ? specifier.imported.name : String(specifier.imported.value);
|
|
16592
17165
|
if (FS_READERS.has(imported)) declare(specifier.local.name, { fsReader: true });
|
|
16593
17166
|
} else {
|
|
16594
17167
|
declare(specifier.local.name, { fsObject: true });
|
|
@@ -16600,29 +17173,29 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16600
17173
|
VariableDeclarator(node) {
|
|
16601
17174
|
if (node.init === null) return;
|
|
16602
17175
|
const required = requireSource(node.init);
|
|
16603
|
-
if (required !== null && FS_MODULES.has(required) && node.id.type ===
|
|
17176
|
+
if (required !== null && FS_MODULES.has(required) && node.id.type === import_utils91.AST_NODE_TYPES.Identifier) {
|
|
16604
17177
|
declare(node.id.name, { fsObject: true });
|
|
16605
17178
|
return;
|
|
16606
17179
|
}
|
|
16607
|
-
if (node.id.type ===
|
|
17180
|
+
if (node.id.type === import_utils91.AST_NODE_TYPES.ObjectPattern && required !== null && FS_MODULES.has(required)) {
|
|
16608
17181
|
for (const property of node.id.properties) {
|
|
16609
|
-
if (property.type !==
|
|
16610
|
-
const key = property.key.type ===
|
|
17182
|
+
if (property.type !== import_utils91.AST_NODE_TYPES.Property || property.value.type !== import_utils91.AST_NODE_TYPES.Identifier) continue;
|
|
17183
|
+
const key = property.key.type === import_utils91.AST_NODE_TYPES.Identifier ? property.key.name : property.key.type === import_utils91.AST_NODE_TYPES.Literal ? String(property.key.value) : "";
|
|
16611
17184
|
if (FS_READERS.has(key)) declare(property.value.name, { fsReader: true });
|
|
16612
17185
|
}
|
|
16613
17186
|
return;
|
|
16614
17187
|
}
|
|
16615
|
-
if (node.id.type !==
|
|
17188
|
+
if (node.id.type !== import_utils91.AST_NODE_TYPES.Identifier) return;
|
|
16616
17189
|
declare(node.id.name, { collection: sourceCollection(node.init), path: sourcePath(node.init), rawOrigins: rawOrigins(node.init) });
|
|
16617
17190
|
},
|
|
16618
17191
|
AssignmentExpression(node) {
|
|
16619
|
-
if (node.left.type ===
|
|
17192
|
+
if (node.left.type === import_utils91.AST_NODE_TYPES.Identifier) declare(node.left.name, { path: sourcePath(node.right), rawOrigins: rawOrigins(node.right) });
|
|
16620
17193
|
},
|
|
16621
17194
|
ForOfStatement(node) {
|
|
16622
|
-
const right =
|
|
16623
|
-
const collection = right.type ===
|
|
16624
|
-
const left = node.left.type ===
|
|
16625
|
-
if (collection && left?.type ===
|
|
17195
|
+
const right = unwrap6(node.right);
|
|
17196
|
+
const collection = right.type === import_utils91.AST_NODE_TYPES.Identifier && visible("collections", right.name);
|
|
17197
|
+
const left = node.left.type === import_utils91.AST_NODE_TYPES.VariableDeclaration ? node.left.declarations[0]?.id : node.left;
|
|
17198
|
+
if (collection && left?.type === import_utils91.AST_NODE_TYPES.Identifier) declare(left.name, { path: true });
|
|
16626
17199
|
},
|
|
16627
17200
|
CallExpression(node) {
|
|
16628
17201
|
const origins = /* @__PURE__ */ new Set([
|
|
@@ -16643,6 +17216,128 @@ var source_coupled_test_default = createSourceCoupledRule(
|
|
|
16643
17216
|
GENERAL_SOURCE_SUFFIX_RE
|
|
16644
17217
|
);
|
|
16645
17218
|
|
|
17219
|
+
// src/rules/sole-export-matches-filename.ts
|
|
17220
|
+
var import_utils92 = require("@typescript-eslint/utils");
|
|
17221
|
+
var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
17222
|
+
summary: "Match a module filename to its sole named public runtime export.",
|
|
17223
|
+
rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
|
|
17224
|
+
remediation: "Rename the module stem to the kebab-case export name, or colocate genuinely related exports.",
|
|
17225
|
+
category: "maintainability",
|
|
17226
|
+
limitations: [
|
|
17227
|
+
"Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS, and re-exports are excluded.",
|
|
17228
|
+
"The rule compares the primary filename stem and preserves conventional suffixes such as .server or .worker."
|
|
17229
|
+
],
|
|
17230
|
+
examples: [
|
|
17231
|
+
{ id: "matching-class", title: "Match a class and module", outcome: "no-match", files: [{ path: "src/artifact-store.ts", source: "export class ArtifactStore {}" }], focusPath: "src/artifact-store.ts", expectedCount: 0, public: true },
|
|
17232
|
+
{ id: "mismatched-class", title: "Do not hide a sole class behind another filename", outcome: "match", files: [{ path: "src/artifacts.ts", source: "export class ArtifactStore {}" }], focusPath: "src/artifacts.ts", expectedCount: 1, public: true }
|
|
17233
|
+
]
|
|
17234
|
+
};
|
|
17235
|
+
var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
|
|
17236
|
+
"common",
|
|
17237
|
+
"config",
|
|
17238
|
+
"constants",
|
|
17239
|
+
"error",
|
|
17240
|
+
"errors",
|
|
17241
|
+
"global",
|
|
17242
|
+
"handler",
|
|
17243
|
+
"helpers",
|
|
17244
|
+
"index",
|
|
17245
|
+
"layout",
|
|
17246
|
+
"loading",
|
|
17247
|
+
"middleware",
|
|
17248
|
+
"misc",
|
|
17249
|
+
"models",
|
|
17250
|
+
"not-found",
|
|
17251
|
+
"page",
|
|
17252
|
+
"route",
|
|
17253
|
+
"schema",
|
|
17254
|
+
"shared",
|
|
17255
|
+
"template",
|
|
17256
|
+
"types",
|
|
17257
|
+
"util",
|
|
17258
|
+
"utils",
|
|
17259
|
+
"worker"
|
|
17260
|
+
]);
|
|
17261
|
+
function stem3(filename) {
|
|
17262
|
+
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
17263
|
+
return base.replace(/\.[cm]?[jt]sx?$/u, "").split(".")[0] ?? "";
|
|
17264
|
+
}
|
|
17265
|
+
function kebabCase(name) {
|
|
17266
|
+
return name.replace(/([A-Z]{2,})([A-Z][a-z])/gu, "$1-$2").replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replaceAll(/[^a-z0-9]+/giu, "-").replaceAll(/^-+|-+$/gu, "").toLowerCase();
|
|
17267
|
+
}
|
|
17268
|
+
function declarationExport(statement) {
|
|
17269
|
+
const declaration = statement.declaration;
|
|
17270
|
+
if (declaration === null || declaration.declare === true) return [];
|
|
17271
|
+
if (declaration.type === import_utils92.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils92.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils92.AST_NODE_TYPES.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
|
|
17272
|
+
if (declaration.type !== import_utils92.AST_NODE_TYPES.VariableDeclaration) return [];
|
|
17273
|
+
return declaration.declarations.flatMap(
|
|
17274
|
+
(item) => item.id.type === import_utils92.AST_NODE_TYPES.Identifier ? [{ name: item.id.name, node: item }] : []
|
|
17275
|
+
);
|
|
17276
|
+
}
|
|
17277
|
+
var sole_export_matches_filename_default = createRule({
|
|
17278
|
+
name: "sole-export-matches-filename",
|
|
17279
|
+
documentation: SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION,
|
|
17280
|
+
meta: {
|
|
17281
|
+
type: "suggestion",
|
|
17282
|
+
docs: { description: "Match a module filename to its sole named public runtime export." },
|
|
17283
|
+
schema: [],
|
|
17284
|
+
messages: {
|
|
17285
|
+
matchSoleExport: "This module's sole runtime export is `{{exported}}`; rename the file stem to `{{expected}}`."
|
|
17286
|
+
}
|
|
17287
|
+
},
|
|
17288
|
+
defaultOptions: [],
|
|
17289
|
+
create(context) {
|
|
17290
|
+
const fileStem = stem3(context.filename);
|
|
17291
|
+
const normalizedFilename = context.filename.replaceAll("\\", "/");
|
|
17292
|
+
if (EXCLUDED_STEMS.has(fileStem) || normalizedFilename.includes("/pages/") || context.filename.endsWith(".d.ts") || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
17293
|
+
return {
|
|
17294
|
+
"Program:exit"(program) {
|
|
17295
|
+
const exports2 = [];
|
|
17296
|
+
const publicExports = /* @__PURE__ */ new Set();
|
|
17297
|
+
for (const statement of program.body) {
|
|
17298
|
+
if (statement.type === import_utils92.AST_NODE_TYPES.ExportAllDeclaration || statement.type === import_utils92.AST_NODE_TYPES.ExportNamedDeclaration && statement.source !== null) return;
|
|
17299
|
+
if (statement.type === import_utils92.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
|
17300
|
+
publicExports.add("default");
|
|
17301
|
+
const declaration2 = statement.declaration;
|
|
17302
|
+
if ((declaration2.type === import_utils92.AST_NODE_TYPES.ClassDeclaration || declaration2.type === import_utils92.AST_NODE_TYPES.FunctionDeclaration) && declaration2.id !== null) exports2.push({ name: declaration2.id.name, node: declaration2 });
|
|
17303
|
+
else return;
|
|
17304
|
+
}
|
|
17305
|
+
if (statement.type !== import_utils92.AST_NODE_TYPES.ExportNamedDeclaration) continue;
|
|
17306
|
+
const declaration = statement.declaration;
|
|
17307
|
+
if (declaration !== null && "id" in declaration && declaration.id?.type === import_utils92.AST_NODE_TYPES.Identifier) {
|
|
17308
|
+
publicExports.add(declaration.id.name);
|
|
17309
|
+
}
|
|
17310
|
+
if (declaration?.type === import_utils92.AST_NODE_TYPES.VariableDeclaration) {
|
|
17311
|
+
for (const item of declaration.declarations) {
|
|
17312
|
+
if (item.id.type === import_utils92.AST_NODE_TYPES.Identifier) publicExports.add(item.id.name);
|
|
17313
|
+
}
|
|
17314
|
+
}
|
|
17315
|
+
for (const specifier of statement.specifiers) {
|
|
17316
|
+
const exported = specifier.exported.type === import_utils92.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
17317
|
+
publicExports.add(String(exported));
|
|
17318
|
+
}
|
|
17319
|
+
if (statement.exportKind === "type") continue;
|
|
17320
|
+
exports2.push(...declarationExport(statement));
|
|
17321
|
+
for (const specifier of statement.specifiers) {
|
|
17322
|
+
const exported = specifier.exported.type === import_utils92.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
17323
|
+
publicExports.add(String(exported));
|
|
17324
|
+
if (specifier.exportKind === "type") continue;
|
|
17325
|
+
if (exported === "default") exports2.push({ name: specifier.local.name, node: specifier });
|
|
17326
|
+
else exports2.push({ name: String(exported), node: specifier });
|
|
17327
|
+
}
|
|
17328
|
+
}
|
|
17329
|
+
const unique = new Map(exports2.map((item) => [item.name, item]));
|
|
17330
|
+
if (unique.size !== 1 || publicExports.size !== 1) return;
|
|
17331
|
+
const only = [...unique.values()][0];
|
|
17332
|
+
if (only === void 0) return;
|
|
17333
|
+
const expected = kebabCase(only.name);
|
|
17334
|
+
if (expected === "" || expected === fileStem.toLowerCase()) return;
|
|
17335
|
+
context.report({ node: only.node, messageId: "matchSoleExport", data: { exported: only.name, expected } });
|
|
17336
|
+
}
|
|
17337
|
+
};
|
|
17338
|
+
}
|
|
17339
|
+
});
|
|
17340
|
+
|
|
16646
17341
|
// src/rules/iac-source-coupled-test.ts
|
|
16647
17342
|
var IAC_SOURCE_SUFFIX_RE = /(?:\.tf\.json|\.tftest\.(?:hcl|json)|\.(?:hcl|tf|tfvars))$/iu;
|
|
16648
17343
|
var IAC_SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
@@ -16682,7 +17377,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
16682
17377
|
);
|
|
16683
17378
|
|
|
16684
17379
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
16685
|
-
var
|
|
17380
|
+
var import_utils93 = require("@typescript-eslint/utils");
|
|
16686
17381
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
16687
17382
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
16688
17383
|
rationale: "A reusable Zod schema is a runtime type contract. PascalCase mirrors that role; SCREAMING_SNAKE_CASE should remain reserved for scalar values and lookup tables.",
|
|
@@ -16814,18 +17509,18 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
|
16814
17509
|
"superRefine",
|
|
16815
17510
|
"transform"
|
|
16816
17511
|
]);
|
|
16817
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
17512
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils93.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
16818
17513
|
var calleeChainRoot = (node) => {
|
|
16819
17514
|
let current = node;
|
|
16820
17515
|
for (; ; ) {
|
|
16821
|
-
if (current.type ===
|
|
17516
|
+
if (current.type === import_utils93.AST_NODE_TYPES.Identifier) {
|
|
16822
17517
|
return current;
|
|
16823
17518
|
}
|
|
16824
|
-
if (current.type ===
|
|
17519
|
+
if (current.type === import_utils93.AST_NODE_TYPES.MemberExpression) {
|
|
16825
17520
|
current = current.object;
|
|
16826
17521
|
continue;
|
|
16827
17522
|
}
|
|
16828
|
-
if (current.type ===
|
|
17523
|
+
if (current.type === import_utils93.AST_NODE_TYPES.CallExpression) {
|
|
16829
17524
|
current = current.callee;
|
|
16830
17525
|
continue;
|
|
16831
17526
|
}
|
|
@@ -16836,13 +17531,13 @@ var chainMemberNames = (node) => {
|
|
|
16836
17531
|
const names = [];
|
|
16837
17532
|
let current = node;
|
|
16838
17533
|
for (; ; ) {
|
|
16839
|
-
if (current.type ===
|
|
16840
|
-
if (current.computed || current.property.type !==
|
|
17534
|
+
if (current.type === import_utils93.AST_NODE_TYPES.MemberExpression) {
|
|
17535
|
+
if (current.computed || current.property.type !== import_utils93.AST_NODE_TYPES.Identifier) return [];
|
|
16841
17536
|
names.push(current.property.name);
|
|
16842
17537
|
current = current.object;
|
|
16843
17538
|
continue;
|
|
16844
17539
|
}
|
|
16845
|
-
if (current.type ===
|
|
17540
|
+
if (current.type === import_utils93.AST_NODE_TYPES.CallExpression) {
|
|
16846
17541
|
current = current.callee;
|
|
16847
17542
|
continue;
|
|
16848
17543
|
}
|
|
@@ -16853,16 +17548,16 @@ var chainMemberNames = (node) => {
|
|
|
16853
17548
|
};
|
|
16854
17549
|
var unwrapExpression4 = (node) => {
|
|
16855
17550
|
let current = node;
|
|
16856
|
-
while (current.type ===
|
|
17551
|
+
while (current.type === import_utils93.AST_NODE_TYPES.TSAsExpression || current.type === import_utils93.AST_NODE_TYPES.TSSatisfiesExpression || current.type === import_utils93.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils93.AST_NODE_TYPES.TSTypeAssertion) {
|
|
16857
17552
|
current = current.expression;
|
|
16858
17553
|
}
|
|
16859
17554
|
return current;
|
|
16860
17555
|
};
|
|
16861
17556
|
var isModuleDeclarator = (node) => {
|
|
16862
17557
|
const declaration = node.parent;
|
|
16863
|
-
if (declaration.type !==
|
|
17558
|
+
if (declaration.type !== import_utils93.AST_NODE_TYPES.VariableDeclaration) return false;
|
|
16864
17559
|
const owner = declaration.parent;
|
|
16865
|
-
return owner.type ===
|
|
17560
|
+
return owner.type === import_utils93.AST_NODE_TYPES.Program || owner.type === import_utils93.AST_NODE_TYPES.ExportNamedDeclaration && owner.parent.type === import_utils93.AST_NODE_TYPES.Program;
|
|
16866
17561
|
};
|
|
16867
17562
|
var require_pascal_case_zod_schema_name_default = createRule({
|
|
16868
17563
|
name: "require-pascal-case-zod-schema-name",
|
|
@@ -16882,7 +17577,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
16882
17577
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
16883
17578
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
16884
17579
|
function resolvedBinding(identifier) {
|
|
16885
|
-
return
|
|
17580
|
+
return import_utils93.ASTUtils.findVariable(
|
|
16886
17581
|
context.sourceCode.getScope(identifier),
|
|
16887
17582
|
identifier.name
|
|
16888
17583
|
);
|
|
@@ -16903,8 +17598,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
16903
17598
|
}
|
|
16904
17599
|
function isConfirmedSchema(expression) {
|
|
16905
17600
|
const init = unwrapExpression4(expression);
|
|
16906
|
-
if (init.type ===
|
|
16907
|
-
if (init.type !==
|
|
17601
|
+
if (init.type === import_utils93.AST_NODE_TYPES.Identifier) return isSchemaBinding(init);
|
|
17602
|
+
if (init.type !== import_utils93.AST_NODE_TYPES.CallExpression || init.callee.type !== import_utils93.AST_NODE_TYPES.MemberExpression) {
|
|
16908
17603
|
return false;
|
|
16909
17604
|
}
|
|
16910
17605
|
const terminal = terminalMethodName(init.callee);
|
|
@@ -16924,7 +17619,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
16924
17619
|
ImportDeclaration(node) {
|
|
16925
17620
|
if (!isZodModule(node.source.value)) return;
|
|
16926
17621
|
for (const specifier of node.specifiers) {
|
|
16927
|
-
if (specifier.type ===
|
|
17622
|
+
if (specifier.type === import_utils93.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils93.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils93.AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === import_utils93.AST_NODE_TYPES.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
|
|
16928
17623
|
recordZodBinding(specifier.local);
|
|
16929
17624
|
}
|
|
16930
17625
|
}
|
|
@@ -16933,7 +17628,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
16933
17628
|
if (!isModuleDeclarator(node)) return;
|
|
16934
17629
|
const init = node.init;
|
|
16935
17630
|
if (init === null || init === void 0) return;
|
|
16936
|
-
if (node.id.type !==
|
|
17631
|
+
if (node.id.type !== import_utils93.AST_NODE_TYPES.Identifier) return;
|
|
16937
17632
|
if (!isConfirmedSchema(init)) return;
|
|
16938
17633
|
const binding = resolvedBinding(node.id);
|
|
16939
17634
|
if (binding !== null) schemaBindings.add(binding);
|
|
@@ -17091,10 +17786,16 @@ var RULES = {
|
|
|
17091
17786
|
"prefer-shadcn-primitives": prefer_shadcn_primitives_default,
|
|
17092
17787
|
"prefer-module-level-constant": prefer_module_level_constant_default,
|
|
17093
17788
|
"prefer-module-level-schema": prefer_module_level_schema_default,
|
|
17789
|
+
"prefer-named-complex-return-type": prefer_named_complex_return_type_default,
|
|
17094
17790
|
"prefer-native-random-uuid": prefer_native_random_uuid_default,
|
|
17791
|
+
"prefer-node-crypto-hash": prefer_node_crypto_hash_default,
|
|
17792
|
+
"prefer-node-fs-promises": prefer_node_fs_promises_default,
|
|
17095
17793
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
17794
|
+
"prefer-nullish-filter-predicate": prefer_nullish_filter_predicate_default,
|
|
17096
17795
|
"prefer-await-in-async-return": prefer_await_in_async_return_default,
|
|
17097
17796
|
"prefer-schema-for-api-payload": prefer_schema_for_api_payload_default,
|
|
17797
|
+
"prefer-shared-zod-enum": prefer_shared_zod_enum_default,
|
|
17798
|
+
"prefer-switch-for-repeated-equality": prefer_switch_for_repeated_equality_default,
|
|
17098
17799
|
"prefer-semantic-colors": prefer_semantic_colors_default,
|
|
17099
17800
|
"prefer-server-actions": prefer_server_actions_default,
|
|
17100
17801
|
"prefer-whole-object-assertion": prefer_whole_object_assertion_default,
|
|
@@ -17103,23 +17804,33 @@ var RULES = {
|
|
|
17103
17804
|
"require-assert-never": require_assert_never_default,
|
|
17104
17805
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
17105
17806
|
"require-port-for-service": require_port_for_service_default,
|
|
17807
|
+
"require-sql-access-class": require_sql_access_class_default,
|
|
17106
17808
|
"require-static-next-matcher": require_static_next_matcher_default,
|
|
17107
17809
|
"require-zod-form-validation": require_zod_form_validation_default,
|
|
17108
17810
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
17109
17811
|
"stepdown": stepdown_default,
|
|
17110
17812
|
"source-coupled-test": source_coupled_test_default,
|
|
17813
|
+
"sole-export-matches-filename": sole_export_matches_filename_default,
|
|
17111
17814
|
"require-pascal-case-zod-schema-name": require_pascal_case_zod_schema_name_default
|
|
17112
17815
|
};
|
|
17113
17816
|
var meta = {
|
|
17114
17817
|
name: "@sarj/eslint-plugin",
|
|
17115
|
-
version: "15.
|
|
17818
|
+
version: "15.15.0"
|
|
17116
17819
|
};
|
|
17117
17820
|
var APPLICATION_ONLY_RULES = [
|
|
17118
17821
|
"no-restricted-library-load",
|
|
17119
17822
|
"prefer-native-random-uuid",
|
|
17120
17823
|
"prefer-shadcn-primitives"
|
|
17121
17824
|
];
|
|
17122
|
-
var ADVISORY_RULES = [
|
|
17825
|
+
var ADVISORY_RULES = [
|
|
17826
|
+
"@sarj/prefer-named-complex-return-type",
|
|
17827
|
+
"@sarj/prefer-node-crypto-hash",
|
|
17828
|
+
"@sarj/prefer-shared-zod-enum",
|
|
17829
|
+
"@sarj/prefer-switch-for-repeated-equality",
|
|
17830
|
+
"@sarj/require-pascal-case-zod-schema-name",
|
|
17831
|
+
"@sarj/require-sql-access-class",
|
|
17832
|
+
"@sarj/sole-export-matches-filename"
|
|
17833
|
+
];
|
|
17123
17834
|
var RECOMMENDED_RULES = {
|
|
17124
17835
|
"@sarj/interface-contract-members-private": "error",
|
|
17125
17836
|
"@sarj/iac-source-coupled-test": "error",
|
|
@@ -17173,9 +17884,15 @@ var RECOMMENDED_RULES = {
|
|
|
17173
17884
|
"@sarj/prefer-immutable-module-constant": "error",
|
|
17174
17885
|
"@sarj/prefer-module-level-constant": "error",
|
|
17175
17886
|
"@sarj/prefer-module-level-schema": "error",
|
|
17887
|
+
"@sarj/prefer-named-complex-return-type": "warn",
|
|
17888
|
+
"@sarj/prefer-node-crypto-hash": "warn",
|
|
17889
|
+
"@sarj/prefer-node-fs-promises": "error",
|
|
17176
17890
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17891
|
+
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17177
17892
|
"@sarj/prefer-await-in-async-return": "error",
|
|
17178
17893
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
17894
|
+
"@sarj/prefer-shared-zod-enum": "warn",
|
|
17895
|
+
"@sarj/prefer-switch-for-repeated-equality": "warn",
|
|
17179
17896
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
17180
17897
|
"@sarj/prefer-server-actions": "error",
|
|
17181
17898
|
"@sarj/prefer-whole-object-assertion": "error",
|
|
@@ -17184,6 +17901,7 @@ var RECOMMENDED_RULES = {
|
|
|
17184
17901
|
"@sarj/require-assert-never": "error",
|
|
17185
17902
|
"@sarj/require-fetch-timeout": "error",
|
|
17186
17903
|
"@sarj/require-port-for-service": "error",
|
|
17904
|
+
"@sarj/require-sql-access-class": "warn",
|
|
17187
17905
|
"@sarj/require-static-next-matcher": "error",
|
|
17188
17906
|
"@sarj/require-use-form-default-values": "error",
|
|
17189
17907
|
"@sarj/require-use-server-in-actions-file": "error",
|
|
@@ -17191,6 +17909,7 @@ var RECOMMENDED_RULES = {
|
|
|
17191
17909
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
17192
17910
|
"@sarj/stepdown": "error",
|
|
17193
17911
|
"@sarj/source-coupled-test": "error",
|
|
17912
|
+
"@sarj/sole-export-matches-filename": "warn",
|
|
17194
17913
|
"@sarj/test-phase-label-comment": "error",
|
|
17195
17914
|
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17196
17915
|
};
|
|
@@ -17251,9 +17970,15 @@ var STRICT_RULES = {
|
|
|
17251
17970
|
"@sarj/prefer-immutable-module-constant": "error",
|
|
17252
17971
|
"@sarj/prefer-module-level-constant": "error",
|
|
17253
17972
|
"@sarj/prefer-module-level-schema": "error",
|
|
17973
|
+
"@sarj/prefer-named-complex-return-type": "warn",
|
|
17974
|
+
"@sarj/prefer-node-crypto-hash": "warn",
|
|
17975
|
+
"@sarj/prefer-node-fs-promises": "error",
|
|
17254
17976
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17977
|
+
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17255
17978
|
"@sarj/prefer-await-in-async-return": "error",
|
|
17256
17979
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
17980
|
+
"@sarj/prefer-shared-zod-enum": "warn",
|
|
17981
|
+
"@sarj/prefer-switch-for-repeated-equality": "warn",
|
|
17257
17982
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
17258
17983
|
"@sarj/prefer-server-actions": "error",
|
|
17259
17984
|
"@sarj/prefer-whole-object-assertion": "error",
|
|
@@ -17262,6 +17987,7 @@ var STRICT_RULES = {
|
|
|
17262
17987
|
"@sarj/require-assert-never": "error",
|
|
17263
17988
|
"@sarj/require-fetch-timeout": "error",
|
|
17264
17989
|
"@sarj/require-port-for-service": "error",
|
|
17990
|
+
"@sarj/require-sql-access-class": "warn",
|
|
17265
17991
|
"@sarj/require-static-next-matcher": "error",
|
|
17266
17992
|
"@sarj/require-use-form-default-values": "error",
|
|
17267
17993
|
"@sarj/require-use-server-in-actions-file": "error",
|
|
@@ -17269,6 +17995,7 @@ var STRICT_RULES = {
|
|
|
17269
17995
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
17270
17996
|
"@sarj/stepdown": "error",
|
|
17271
17997
|
"@sarj/source-coupled-test": "error",
|
|
17998
|
+
"@sarj/sole-export-matches-filename": "warn",
|
|
17272
17999
|
"@sarj/test-phase-label-comment": "error",
|
|
17273
18000
|
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17274
18001
|
};
|