@sarj/eslint-plugin 15.14.0 → 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 +1235 -667
- package/dist/index.d.cts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +1211 -643
- 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 = {
|
|
@@ -12040,7 +12230,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12040
12230
|
});
|
|
12041
12231
|
|
|
12042
12232
|
// src/rules/prefer-nullish-filter-predicate.ts
|
|
12043
|
-
var
|
|
12233
|
+
var import_utils71 = require("@typescript-eslint/utils");
|
|
12044
12234
|
var import_typescript = __toESM(require("typescript"), 1);
|
|
12045
12235
|
var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
12046
12236
|
summary: "Prefer an explicit nullish predicate when `filter(Boolean)` removes only nullish values but does not narrow the result type.",
|
|
@@ -12084,7 +12274,7 @@ var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
|
12084
12274
|
]
|
|
12085
12275
|
};
|
|
12086
12276
|
function isUnshadowedBoolean(node, context) {
|
|
12087
|
-
const variable =
|
|
12277
|
+
const variable = import_utils71.ASTUtils.findVariable(context.sourceCode.getScope(node), node.name);
|
|
12088
12278
|
return variable === null || variable.defs.length === 0;
|
|
12089
12279
|
}
|
|
12090
12280
|
function isBuiltinArrayFilter(node, services) {
|
|
@@ -12143,7 +12333,7 @@ function isProvablyTruthy(type, checker) {
|
|
|
12143
12333
|
}
|
|
12144
12334
|
function availableParameterName(node, context) {
|
|
12145
12335
|
for (const name of ["value", "item", "element", "candidate"]) {
|
|
12146
|
-
if (
|
|
12336
|
+
if (import_utils71.ASTUtils.findVariable(context.sourceCode.getScope(node), name) === null) return name;
|
|
12147
12337
|
}
|
|
12148
12338
|
return null;
|
|
12149
12339
|
}
|
|
@@ -12165,7 +12355,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
12165
12355
|
if (isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
12166
12356
|
let services;
|
|
12167
12357
|
try {
|
|
12168
|
-
services =
|
|
12358
|
+
services = import_utils71.ESLintUtils.getParserServices(context);
|
|
12169
12359
|
} catch {
|
|
12170
12360
|
services = null;
|
|
12171
12361
|
}
|
|
@@ -12174,7 +12364,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
12174
12364
|
CallExpression(node) {
|
|
12175
12365
|
const callee = node.callee;
|
|
12176
12366
|
const callback = node.arguments[0];
|
|
12177
|
-
if (node.arguments.length !== 1 || callback?.type !==
|
|
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;
|
|
12178
12368
|
const elementType = arrayElementType(callee.object, services);
|
|
12179
12369
|
const checker = services.program.getTypeChecker();
|
|
12180
12370
|
if (elementType === null || !isNullishPlusTruthy(elementType, checker)) return;
|
|
@@ -12196,7 +12386,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
12196
12386
|
});
|
|
12197
12387
|
|
|
12198
12388
|
// src/rules/prefer-await-in-async-return.ts
|
|
12199
|
-
var
|
|
12389
|
+
var import_utils72 = require("@typescript-eslint/utils");
|
|
12200
12390
|
var ts4 = __toESM(require("typescript"), 1);
|
|
12201
12391
|
var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
|
|
12202
12392
|
summary: "Prefer explicit `await` when an async function directly returns one typed Promise `.then` transform.",
|
|
@@ -12238,10 +12428,10 @@ var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
|
|
|
12238
12428
|
};
|
|
12239
12429
|
function directAsyncReturnOwner(node) {
|
|
12240
12430
|
const parent = node.parent;
|
|
12241
|
-
if (parent.type ===
|
|
12431
|
+
if (parent.type === import_utils72.AST_NODE_TYPES.ArrowFunctionExpression && parent.body === node) {
|
|
12242
12432
|
return parent.async && !parent.generator ? parent : null;
|
|
12243
12433
|
}
|
|
12244
|
-
if (parent.type !==
|
|
12434
|
+
if (parent.type !== import_utils72.AST_NODE_TYPES.ReturnStatement || parent.argument !== node) {
|
|
12245
12435
|
return null;
|
|
12246
12436
|
}
|
|
12247
12437
|
let owner = parent.parent;
|
|
@@ -12251,15 +12441,15 @@ function directAsyncReturnOwner(node) {
|
|
|
12251
12441
|
return owner !== void 0 && owner.async && !owner.generator ? owner : null;
|
|
12252
12442
|
}
|
|
12253
12443
|
function isRuntimeFunction(node) {
|
|
12254
|
-
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;
|
|
12255
12445
|
}
|
|
12256
12446
|
function promiseThenReceiver(node) {
|
|
12257
12447
|
const callee = node.callee;
|
|
12258
|
-
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) {
|
|
12259
12449
|
return null;
|
|
12260
12450
|
}
|
|
12261
12451
|
const callback = node.arguments[0];
|
|
12262
|
-
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) {
|
|
12263
12453
|
return null;
|
|
12264
12454
|
}
|
|
12265
12455
|
return callee.object;
|
|
@@ -12300,32 +12490,32 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12300
12490
|
create(context) {
|
|
12301
12491
|
let services;
|
|
12302
12492
|
try {
|
|
12303
|
-
services =
|
|
12493
|
+
services = import_utils72.ESLintUtils.getParserServices(context);
|
|
12304
12494
|
} catch {
|
|
12305
12495
|
services = null;
|
|
12306
12496
|
}
|
|
12307
12497
|
if (services === null) return {};
|
|
12308
12498
|
const frameworkLoaders = /* @__PURE__ */ new Set();
|
|
12309
12499
|
const rememberFrameworkLoader = (identifier) => {
|
|
12310
|
-
const variable =
|
|
12500
|
+
const variable = import_utils72.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
12311
12501
|
if (variable !== null) frameworkLoaders.add(variable);
|
|
12312
12502
|
};
|
|
12313
12503
|
const isFrameworkLoaderCallback = (owner) => {
|
|
12314
12504
|
const parent = owner.parent;
|
|
12315
|
-
if (parent.type !==
|
|
12316
|
-
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);
|
|
12317
12507
|
return variable !== null && frameworkLoaders.has(variable);
|
|
12318
12508
|
};
|
|
12319
12509
|
return {
|
|
12320
12510
|
ImportDeclaration(node) {
|
|
12321
12511
|
if (node.source.value === "react") {
|
|
12322
12512
|
for (const specifier of node.specifiers) {
|
|
12323
|
-
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);
|
|
12324
12514
|
}
|
|
12325
12515
|
}
|
|
12326
12516
|
if (node.source.value === "next/dynamic") {
|
|
12327
12517
|
for (const specifier of node.specifiers) {
|
|
12328
|
-
if (specifier.type ===
|
|
12518
|
+
if (specifier.type === import_utils72.AST_NODE_TYPES.ImportDefaultSpecifier) rememberFrameworkLoader(specifier.local);
|
|
12329
12519
|
}
|
|
12330
12520
|
}
|
|
12331
12521
|
},
|
|
@@ -12343,7 +12533,7 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12343
12533
|
});
|
|
12344
12534
|
|
|
12345
12535
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
12346
|
-
var
|
|
12536
|
+
var import_utils73 = require("@typescript-eslint/utils");
|
|
12347
12537
|
var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
|
|
12348
12538
|
summary: "Require Zod (or similar) schema validation on `response.json()` / `JSON.parse()` results before property access.",
|
|
12349
12539
|
rationale: "External JSON is untrusted at runtime even when its expected TypeScript shape is known statically.",
|
|
@@ -12355,12 +12545,12 @@ var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
|
|
|
12355
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 }
|
|
12356
12546
|
]
|
|
12357
12547
|
};
|
|
12358
|
-
var
|
|
12548
|
+
var unwrap5 = (node) => {
|
|
12359
12549
|
let current = node;
|
|
12360
12550
|
while (current !== null && current !== void 0) {
|
|
12361
|
-
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) {
|
|
12362
12552
|
current = current.expression;
|
|
12363
|
-
} else if (current.type ===
|
|
12553
|
+
} else if (current.type === import_utils73.AST_NODE_TYPES.ChainExpression) {
|
|
12364
12554
|
current = current.expression;
|
|
12365
12555
|
} else {
|
|
12366
12556
|
break;
|
|
@@ -12374,24 +12564,24 @@ var PROMISE_CHAIN_METHODS = /* @__PURE__ */ new Set([
|
|
|
12374
12564
|
"finally"
|
|
12375
12565
|
]);
|
|
12376
12566
|
var isSchemaParseReference = (node) => {
|
|
12377
|
-
const inner =
|
|
12378
|
-
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");
|
|
12379
12569
|
};
|
|
12380
12570
|
var isRawPayloadSource = (node, isKnownLocalText) => {
|
|
12381
|
-
let current =
|
|
12571
|
+
let current = unwrap5(node);
|
|
12382
12572
|
if (current === null) return false;
|
|
12383
|
-
if (current.type ===
|
|
12384
|
-
current =
|
|
12573
|
+
if (current.type === import_utils73.AST_NODE_TYPES.AwaitExpression) {
|
|
12574
|
+
current = unwrap5(current.argument);
|
|
12385
12575
|
}
|
|
12386
|
-
if (current === null || current.type !==
|
|
12576
|
+
if (current === null || current.type !== import_utils73.AST_NODE_TYPES.CallExpression) {
|
|
12387
12577
|
return false;
|
|
12388
12578
|
}
|
|
12389
|
-
const callee =
|
|
12390
|
-
if (callee === null || callee.type !==
|
|
12579
|
+
const callee = unwrap5(current.callee);
|
|
12580
|
+
if (callee === null || callee.type !== import_utils73.AST_NODE_TYPES.MemberExpression) {
|
|
12391
12581
|
return false;
|
|
12392
12582
|
}
|
|
12393
|
-
const property =
|
|
12394
|
-
if (property === null || property.type !==
|
|
12583
|
+
const property = unwrap5(callee.property);
|
|
12584
|
+
if (property === null || property.type !== import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12395
12585
|
return false;
|
|
12396
12586
|
}
|
|
12397
12587
|
if (property.name === "json") {
|
|
@@ -12400,18 +12590,18 @@ var isRawPayloadSource = (node, isKnownLocalText) => {
|
|
|
12400
12590
|
if (PROMISE_CHAIN_METHODS.has(property.name)) {
|
|
12401
12591
|
return !current.arguments.some(isSchemaParseReference) && isRawPayloadSource(callee.object);
|
|
12402
12592
|
}
|
|
12403
|
-
const object =
|
|
12404
|
-
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;
|
|
12405
12595
|
};
|
|
12406
12596
|
var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
|
|
12407
12597
|
var isDirectLocalFileRead = (node) => {
|
|
12408
|
-
let current =
|
|
12409
|
-
if (current?.type ===
|
|
12410
|
-
current =
|
|
12598
|
+
let current = unwrap5(node);
|
|
12599
|
+
if (current?.type === import_utils73.AST_NODE_TYPES.AwaitExpression) {
|
|
12600
|
+
current = unwrap5(current.argument);
|
|
12411
12601
|
}
|
|
12412
|
-
if (current?.type !==
|
|
12413
|
-
const callee =
|
|
12414
|
-
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;
|
|
12415
12605
|
return name !== null && FILE_READ_RE.test(name);
|
|
12416
12606
|
};
|
|
12417
12607
|
var isLocalFileRead = (node) => {
|
|
@@ -12438,15 +12628,15 @@ var isLocalFileRead = (node) => {
|
|
|
12438
12628
|
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
12439
12629
|
var isInsideAssertion = (node) => {
|
|
12440
12630
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12441
|
-
if (current.type !==
|
|
12631
|
+
if (current.type !== import_utils73.AST_NODE_TYPES.CallExpression) continue;
|
|
12442
12632
|
let callee = current.callee;
|
|
12443
|
-
while (callee.type ===
|
|
12633
|
+
while (callee.type === import_utils73.AST_NODE_TYPES.MemberExpression) {
|
|
12444
12634
|
callee = callee.object;
|
|
12445
12635
|
}
|
|
12446
|
-
if (callee.type ===
|
|
12636
|
+
if (callee.type === import_utils73.AST_NODE_TYPES.CallExpression) {
|
|
12447
12637
|
callee = callee.callee;
|
|
12448
12638
|
}
|
|
12449
|
-
if (callee.type ===
|
|
12639
|
+
if (callee.type === import_utils73.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
12450
12640
|
return true;
|
|
12451
12641
|
}
|
|
12452
12642
|
}
|
|
@@ -12465,22 +12655,22 @@ var GUARD_NAME_RE = /^(?:is|validate|parse|assert|decode|coerce)[A-Z]/;
|
|
|
12465
12655
|
var isValidationRead = (node) => {
|
|
12466
12656
|
let current = node;
|
|
12467
12657
|
let parent = current.parent;
|
|
12468
|
-
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)) {
|
|
12469
12659
|
current = parent;
|
|
12470
12660
|
parent = parent.parent;
|
|
12471
12661
|
}
|
|
12472
12662
|
if (parent === null || parent === void 0) return false;
|
|
12473
|
-
if (parent.type ===
|
|
12663
|
+
if (parent.type === import_utils73.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
|
|
12474
12664
|
return true;
|
|
12475
12665
|
}
|
|
12476
|
-
if (parent.type !==
|
|
12666
|
+
if (parent.type !== import_utils73.AST_NODE_TYPES.CallExpression || !parent.arguments.some((arg) => arg === current)) {
|
|
12477
12667
|
return false;
|
|
12478
12668
|
}
|
|
12479
12669
|
const callee = parent.callee;
|
|
12480
|
-
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") {
|
|
12481
12671
|
return parent.arguments.length === 1;
|
|
12482
12672
|
}
|
|
12483
|
-
return callee.type ===
|
|
12673
|
+
return callee.type === import_utils73.AST_NODE_TYPES.Identifier && GUARD_NAME_RE.test(callee.name);
|
|
12484
12674
|
};
|
|
12485
12675
|
var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
|
|
12486
12676
|
"bigint",
|
|
@@ -12491,13 +12681,13 @@ var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
|
|
|
12491
12681
|
"undefined"
|
|
12492
12682
|
]);
|
|
12493
12683
|
var bindingValidationPolarity = (test, bindingName) => {
|
|
12494
|
-
if (test.type ===
|
|
12684
|
+
if (test.type === import_utils73.AST_NODE_TYPES.UnaryExpression && test.operator === "!") {
|
|
12495
12685
|
const inner = bindingValidationPolarity(test.argument, bindingName);
|
|
12496
12686
|
return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
|
|
12497
12687
|
}
|
|
12498
|
-
if (test.type ===
|
|
12499
|
-
const typeofName = (node) => node.type ===
|
|
12500
|
-
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;
|
|
12501
12691
|
const matches = typeofName(test.left) === bindingName && literalType(test.right) !== null || typeofName(test.right) === bindingName && literalType(test.left) !== null;
|
|
12502
12692
|
if (!matches) return null;
|
|
12503
12693
|
if (test.operator === "===" || test.operator === "==") {
|
|
@@ -12505,9 +12695,9 @@ var bindingValidationPolarity = (test, bindingName) => {
|
|
|
12505
12695
|
}
|
|
12506
12696
|
return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
|
|
12507
12697
|
}
|
|
12508
|
-
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;
|
|
12509
12699
|
};
|
|
12510
|
-
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;
|
|
12511
12701
|
var isSamePlainMember = (node, access) => {
|
|
12512
12702
|
const candidate2 = plainMemberAccess(node);
|
|
12513
12703
|
return candidate2 !== null && candidate2.object === access.object && candidate2.property === access.property;
|
|
@@ -12515,19 +12705,19 @@ var isSamePlainMember = (node, access) => {
|
|
|
12515
12705
|
var nodeWithin2 = (node, container) => node.range[0] >= container.range[0] && node.range[1] <= container.range[1];
|
|
12516
12706
|
var isUseWithinValidatedBranch = (node, bindingName) => {
|
|
12517
12707
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12518
|
-
if (current.type ===
|
|
12708
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12519
12709
|
const polarity = bindingValidationPolarity(current.test, bindingName);
|
|
12520
12710
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
|
|
12521
12711
|
return true;
|
|
12522
12712
|
}
|
|
12523
12713
|
}
|
|
12524
|
-
if (current.type ===
|
|
12714
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12525
12715
|
const polarity = bindingValidationPolarity(current.test, bindingName);
|
|
12526
12716
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
|
|
12527
12717
|
return true;
|
|
12528
12718
|
}
|
|
12529
12719
|
}
|
|
12530
|
-
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) {
|
|
12531
12721
|
return false;
|
|
12532
12722
|
}
|
|
12533
12723
|
}
|
|
@@ -12535,32 +12725,32 @@ var isUseWithinValidatedBranch = (node, bindingName) => {
|
|
|
12535
12725
|
};
|
|
12536
12726
|
var isMemberUseWithinValidatedBranch = (node, access) => {
|
|
12537
12727
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12538
|
-
if (current.type ===
|
|
12728
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12539
12729
|
const polarity = memberValidationPolarity(current.test, access);
|
|
12540
12730
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
|
|
12541
12731
|
return true;
|
|
12542
12732
|
}
|
|
12543
12733
|
}
|
|
12544
|
-
if (current.type ===
|
|
12734
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12545
12735
|
const polarity = memberValidationPolarity(current.test, access);
|
|
12546
12736
|
if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
|
|
12547
12737
|
return true;
|
|
12548
12738
|
}
|
|
12549
12739
|
}
|
|
12550
|
-
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) {
|
|
12551
12741
|
return false;
|
|
12552
12742
|
}
|
|
12553
12743
|
}
|
|
12554
12744
|
return false;
|
|
12555
12745
|
};
|
|
12556
12746
|
var memberValidationPolarity = (test, access) => {
|
|
12557
|
-
if (test.type ===
|
|
12747
|
+
if (test.type === import_utils73.AST_NODE_TYPES.UnaryExpression && test.operator === "!") {
|
|
12558
12748
|
const inner = memberValidationPolarity(test.argument, access);
|
|
12559
12749
|
return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
|
|
12560
12750
|
}
|
|
12561
|
-
if (test.type ===
|
|
12562
|
-
const isMatchingTypeof = (node) => node.type ===
|
|
12563
|
-
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);
|
|
12564
12754
|
if (!(isMatchingTypeof(test.left) && isPrimitiveType(test.right) || isMatchingTypeof(test.right) && isPrimitiveType(test.left))) {
|
|
12565
12755
|
return null;
|
|
12566
12756
|
}
|
|
@@ -12569,15 +12759,15 @@ var memberValidationPolarity = (test, access) => {
|
|
|
12569
12759
|
}
|
|
12570
12760
|
return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
|
|
12571
12761
|
}
|
|
12572
|
-
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;
|
|
12573
12763
|
};
|
|
12574
12764
|
var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
12575
12765
|
const isValidationReference = (identifier) => {
|
|
12576
12766
|
for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12577
|
-
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) {
|
|
12578
12768
|
return true;
|
|
12579
12769
|
}
|
|
12580
|
-
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) {
|
|
12581
12771
|
return false;
|
|
12582
12772
|
}
|
|
12583
12773
|
}
|
|
@@ -12585,7 +12775,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12585
12775
|
};
|
|
12586
12776
|
const isGuardedUse = (identifier) => {
|
|
12587
12777
|
for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
12588
|
-
if (current.type ===
|
|
12778
|
+
if (current.type === import_utils73.AST_NODE_TYPES.ConditionalExpression) {
|
|
12589
12779
|
const polarity = bindingValidationPolarity(current.test, identifier.name);
|
|
12590
12780
|
if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
|
|
12591
12781
|
return true;
|
|
@@ -12594,7 +12784,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12594
12784
|
return true;
|
|
12595
12785
|
}
|
|
12596
12786
|
}
|
|
12597
|
-
if (current.type ===
|
|
12787
|
+
if (current.type === import_utils73.AST_NODE_TYPES.IfStatement) {
|
|
12598
12788
|
const polarity = bindingValidationPolarity(current.test, identifier.name);
|
|
12599
12789
|
if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
|
|
12600
12790
|
return true;
|
|
@@ -12603,14 +12793,14 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12603
12793
|
return true;
|
|
12604
12794
|
}
|
|
12605
12795
|
}
|
|
12606
|
-
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) {
|
|
12607
12797
|
return false;
|
|
12608
12798
|
}
|
|
12609
12799
|
}
|
|
12610
12800
|
return false;
|
|
12611
12801
|
};
|
|
12612
12802
|
const declarator = member.parent;
|
|
12613
|
-
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") {
|
|
12614
12804
|
return false;
|
|
12615
12805
|
}
|
|
12616
12806
|
const extracted = context.sourceCode.getDeclaredVariables(declarator)[0];
|
|
@@ -12618,7 +12808,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
|
|
|
12618
12808
|
let hasValueUse = false;
|
|
12619
12809
|
for (const reference of extracted.references) {
|
|
12620
12810
|
const identifier = reference.identifier;
|
|
12621
|
-
if (identifier.type !==
|
|
12811
|
+
if (identifier.type !== import_utils73.AST_NODE_TYPES.Identifier) return false;
|
|
12622
12812
|
if (nodeWithin2(identifier, declarator)) continue;
|
|
12623
12813
|
if (isValidationReference(identifier)) continue;
|
|
12624
12814
|
hasValueUse = true;
|
|
@@ -12631,17 +12821,17 @@ var isGuardTestPosition = (node) => {
|
|
|
12631
12821
|
let parent = current.parent;
|
|
12632
12822
|
while (parent !== void 0 && parent !== null) {
|
|
12633
12823
|
switch (parent.type) {
|
|
12634
|
-
case
|
|
12635
|
-
case
|
|
12636
|
-
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:
|
|
12637
12827
|
current = parent;
|
|
12638
12828
|
parent = parent.parent;
|
|
12639
12829
|
continue;
|
|
12640
|
-
case
|
|
12641
|
-
case
|
|
12642
|
-
case
|
|
12643
|
-
case
|
|
12644
|
-
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:
|
|
12645
12835
|
return parent.test === current;
|
|
12646
12836
|
default:
|
|
12647
12837
|
return false;
|
|
@@ -12650,8 +12840,8 @@ var isGuardTestPosition = (node) => {
|
|
|
12650
12840
|
return false;
|
|
12651
12841
|
};
|
|
12652
12842
|
var unvalidatedVariableRef = (node, scope, tracked) => {
|
|
12653
|
-
const unwrapped =
|
|
12654
|
-
if (unwrapped === null || unwrapped.type !==
|
|
12843
|
+
const unwrapped = unwrap5(node);
|
|
12844
|
+
if (unwrapped === null || unwrapped.type !== import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12655
12845
|
return null;
|
|
12656
12846
|
}
|
|
12657
12847
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -12679,8 +12869,8 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12679
12869
|
const aliasGroups = /* @__PURE__ */ new Map();
|
|
12680
12870
|
const localFileTextVariables = /* @__PURE__ */ new Set();
|
|
12681
12871
|
const localFileTextRef = (node, scope) => {
|
|
12682
|
-
const unwrapped =
|
|
12683
|
-
if (unwrapped?.type !==
|
|
12872
|
+
const unwrapped = unwrap5(node);
|
|
12873
|
+
if (unwrapped?.type !== import_utils73.AST_NODE_TYPES.Identifier) return null;
|
|
12684
12874
|
const variable = findVariable2(scope, unwrapped.name);
|
|
12685
12875
|
return variable !== null && localFileTextVariables.has(variable) ? variable : null;
|
|
12686
12876
|
};
|
|
@@ -12749,7 +12939,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12749
12939
|
return {
|
|
12750
12940
|
VariableDeclarator(node) {
|
|
12751
12941
|
const scope = context.sourceCode.getScope(node);
|
|
12752
|
-
if (node.id.type ===
|
|
12942
|
+
if (node.id.type === import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12753
12943
|
const variable = context.sourceCode.getDeclaredVariables(node)[0];
|
|
12754
12944
|
if (variable !== void 0) {
|
|
12755
12945
|
updateLocalFileText(variable, node.init, scope);
|
|
@@ -12757,7 +12947,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12757
12947
|
trackInitializer(node, scope);
|
|
12758
12948
|
return;
|
|
12759
12949
|
}
|
|
12760
|
-
if (node.id.type ===
|
|
12950
|
+
if (node.id.type === import_utils73.AST_NODE_TYPES.ObjectPattern || node.id.type === import_utils73.AST_NODE_TYPES.ArrayPattern) {
|
|
12761
12951
|
if (isRawPayloadSource(
|
|
12762
12952
|
node.init,
|
|
12763
12953
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
@@ -12774,7 +12964,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12774
12964
|
},
|
|
12775
12965
|
AssignmentExpression(node) {
|
|
12776
12966
|
const scope = context.sourceCode.getScope(node);
|
|
12777
|
-
if (node.left.type ===
|
|
12967
|
+
if (node.left.type === import_utils73.AST_NODE_TYPES.Identifier) {
|
|
12778
12968
|
const variable = findVariable2(scope, node.left.name);
|
|
12779
12969
|
if (variable === null) return;
|
|
12780
12970
|
const isLocalText = (candidate2) => localFileTextRef(candidate2, scope) !== null;
|
|
@@ -12788,7 +12978,7 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12788
12978
|
}
|
|
12789
12979
|
return;
|
|
12790
12980
|
}
|
|
12791
|
-
if (node.left.type ===
|
|
12981
|
+
if (node.left.type === import_utils73.AST_NODE_TYPES.ObjectPattern || node.left.type === import_utils73.AST_NODE_TYPES.ArrayPattern) {
|
|
12792
12982
|
if (isRawPayloadSource(
|
|
12793
12983
|
node.right,
|
|
12794
12984
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
@@ -12808,15 +12998,15 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12808
12998
|
}
|
|
12809
12999
|
},
|
|
12810
13000
|
CallExpression(node) {
|
|
12811
|
-
if (node.callee.type !==
|
|
13001
|
+
if (node.callee.type !== import_utils73.AST_NODE_TYPES.Identifier) return;
|
|
12812
13002
|
if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
|
|
12813
13003
|
return;
|
|
12814
13004
|
}
|
|
12815
13005
|
const scope = context.sourceCode.getScope(node);
|
|
12816
13006
|
for (const arg of node.arguments) {
|
|
12817
|
-
if (arg.type ===
|
|
12818
|
-
const unwrapped =
|
|
12819
|
-
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) {
|
|
12820
13010
|
continue;
|
|
12821
13011
|
}
|
|
12822
13012
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -12827,20 +13017,20 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12827
13017
|
if (isInsideAssertion(node)) return;
|
|
12828
13018
|
if (isValidationRead(node)) return;
|
|
12829
13019
|
const scope = context.sourceCode.getScope(node);
|
|
12830
|
-
const obj =
|
|
13020
|
+
const obj = unwrap5(node.object);
|
|
12831
13021
|
if (isRawPayloadSource(
|
|
12832
13022
|
obj,
|
|
12833
13023
|
(candidate2) => localFileTextRef(candidate2, scope) !== null
|
|
12834
13024
|
)) {
|
|
12835
13025
|
const parent = node.parent;
|
|
12836
|
-
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))) {
|
|
12837
13027
|
return;
|
|
12838
13028
|
}
|
|
12839
13029
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
12840
13030
|
return;
|
|
12841
13031
|
}
|
|
12842
|
-
const variable = obj?.type ===
|
|
12843
|
-
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) {
|
|
12844
13034
|
if (isUseWithinValidatedBranch(node, obj.name)) {
|
|
12845
13035
|
return;
|
|
12846
13036
|
}
|
|
@@ -12859,8 +13049,122 @@ var prefer_schema_for_api_payload_default = createRule({
|
|
|
12859
13049
|
}
|
|
12860
13050
|
});
|
|
12861
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
|
+
|
|
12862
13166
|
// src/rules/prefer-semantic-colors.ts
|
|
12863
|
-
var
|
|
13167
|
+
var import_utils76 = require("@typescript-eslint/utils");
|
|
12864
13168
|
var import_fs = require("fs");
|
|
12865
13169
|
var import_path = require("path");
|
|
12866
13170
|
|
|
@@ -12972,7 +13276,7 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
12972
13276
|
var isInsideSvg = (node) => {
|
|
12973
13277
|
let current = node.parent;
|
|
12974
13278
|
while (current !== void 0 && current !== null) {
|
|
12975
|
-
if (current.type ===
|
|
13279
|
+
if (current.type === import_utils76.AST_NODE_TYPES.JSXElement) {
|
|
12976
13280
|
const name = jsxElementName(current);
|
|
12977
13281
|
if (name !== null && isSvgLikeElementName(name)) return true;
|
|
12978
13282
|
}
|
|
@@ -12982,8 +13286,8 @@ var isInsideSvg = (node) => {
|
|
|
12982
13286
|
};
|
|
12983
13287
|
function jsxElementName(node) {
|
|
12984
13288
|
const name = node.openingElement.name;
|
|
12985
|
-
if (name.type ===
|
|
12986
|
-
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) {
|
|
12987
13291
|
return name.property.name;
|
|
12988
13292
|
}
|
|
12989
13293
|
return null;
|
|
@@ -13009,7 +13313,7 @@ function isSvgLikeElementName(name) {
|
|
|
13009
13313
|
var isInsideIconFactoryPath = (node) => {
|
|
13010
13314
|
let current = node.parent;
|
|
13011
13315
|
while (current !== void 0 && current !== null) {
|
|
13012
|
-
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") {
|
|
13013
13317
|
return true;
|
|
13014
13318
|
}
|
|
13015
13319
|
current = current.parent;
|
|
@@ -13143,12 +13447,12 @@ var expandWorkspaceGlob = (root, glob) => {
|
|
|
13143
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));
|
|
13144
13448
|
};
|
|
13145
13449
|
var propName = (key) => {
|
|
13146
|
-
if (key.type ===
|
|
13147
|
-
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;
|
|
13148
13452
|
return null;
|
|
13149
13453
|
};
|
|
13150
13454
|
var staticallyImportsEmailOrPdfRenderer = (program) => program.body.some((statement) => {
|
|
13151
|
-
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) {
|
|
13152
13456
|
return false;
|
|
13153
13457
|
}
|
|
13154
13458
|
return statement.source !== null && typeof statement.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(statement.source.value);
|
|
@@ -13185,43 +13489,43 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13185
13489
|
}
|
|
13186
13490
|
let importsEmailOrPdfRenderer = false;
|
|
13187
13491
|
const pendingReports = [];
|
|
13188
|
-
const
|
|
13492
|
+
const report2 = (node, messageId, data) => {
|
|
13189
13493
|
pendingReports.push({ node, messageId, data });
|
|
13190
13494
|
};
|
|
13191
13495
|
const reportClasses = (value, node) => {
|
|
13192
13496
|
for (const token of classTokens(value)) {
|
|
13193
13497
|
const base = tailwindBase(token);
|
|
13194
13498
|
if (RAW_PALETTE_RE.test(base)) {
|
|
13195
|
-
|
|
13499
|
+
report2(node, "rawPalette", { class: token });
|
|
13196
13500
|
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
13197
|
-
|
|
13501
|
+
report2(node, "arbitraryColor", { class: token });
|
|
13198
13502
|
}
|
|
13199
13503
|
}
|
|
13200
13504
|
};
|
|
13201
13505
|
const checkClassNode = (node) => {
|
|
13202
13506
|
if (node === null) return;
|
|
13203
13507
|
switch (node.type) {
|
|
13204
|
-
case
|
|
13508
|
+
case import_utils76.AST_NODE_TYPES.Literal:
|
|
13205
13509
|
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
13206
13510
|
break;
|
|
13207
|
-
case
|
|
13511
|
+
case import_utils76.AST_NODE_TYPES.TemplateLiteral:
|
|
13208
13512
|
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
13209
13513
|
break;
|
|
13210
|
-
case
|
|
13514
|
+
case import_utils76.AST_NODE_TYPES.ArrayExpression:
|
|
13211
13515
|
for (const element of node.elements) {
|
|
13212
|
-
if (element !== null && element.type !==
|
|
13516
|
+
if (element !== null && element.type !== import_utils76.AST_NODE_TYPES.SpreadElement) checkClassNode(element);
|
|
13213
13517
|
}
|
|
13214
13518
|
break;
|
|
13215
|
-
case
|
|
13519
|
+
case import_utils76.AST_NODE_TYPES.ObjectExpression:
|
|
13216
13520
|
for (const property of node.properties) {
|
|
13217
|
-
if (property.type ===
|
|
13521
|
+
if (property.type === import_utils76.AST_NODE_TYPES.Property) checkClassNode(property.value);
|
|
13218
13522
|
}
|
|
13219
13523
|
break;
|
|
13220
|
-
case
|
|
13524
|
+
case import_utils76.AST_NODE_TYPES.ConditionalExpression:
|
|
13221
13525
|
checkClassNode(node.consequent);
|
|
13222
13526
|
checkClassNode(node.alternate);
|
|
13223
13527
|
break;
|
|
13224
|
-
case
|
|
13528
|
+
case import_utils76.AST_NODE_TYPES.LogicalExpression:
|
|
13225
13529
|
checkClassNode(node.right);
|
|
13226
13530
|
break;
|
|
13227
13531
|
default:
|
|
@@ -13229,32 +13533,32 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13229
13533
|
}
|
|
13230
13534
|
};
|
|
13231
13535
|
const checkColorValueNode = (node) => {
|
|
13232
|
-
if (node.type ===
|
|
13233
|
-
|
|
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 });
|
|
13234
13538
|
}
|
|
13235
13539
|
};
|
|
13236
13540
|
return {
|
|
13237
13541
|
"JSXAttribute[name.name='className']"(node) {
|
|
13238
13542
|
if (node.value === null) return;
|
|
13239
|
-
if (node.value.type ===
|
|
13240
|
-
else if (node.value.type ===
|
|
13241
|
-
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) {
|
|
13242
13546
|
checkClassNode(node.value.expression);
|
|
13243
13547
|
}
|
|
13244
13548
|
}
|
|
13245
13549
|
},
|
|
13246
13550
|
CallExpression(node) {
|
|
13247
|
-
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)) {
|
|
13248
13552
|
importsEmailOrPdfRenderer = true;
|
|
13249
13553
|
}
|
|
13250
|
-
if (node.callee.type ===
|
|
13554
|
+
if (node.callee.type === import_utils76.AST_NODE_TYPES.Identifier && CLASS_FNS.has(node.callee.name)) {
|
|
13251
13555
|
for (const arg of node.arguments) {
|
|
13252
|
-
if (arg.type !==
|
|
13556
|
+
if (arg.type !== import_utils76.AST_NODE_TYPES.SpreadElement) checkClassNode(arg);
|
|
13253
13557
|
}
|
|
13254
13558
|
}
|
|
13255
13559
|
},
|
|
13256
13560
|
VariableDeclarator(node) {
|
|
13257
|
-
if (node.id.type ===
|
|
13561
|
+
if (node.id.type === import_utils76.AST_NODE_TYPES.Identifier && CLASS_NAME_RE.test(node.id.name)) {
|
|
13258
13562
|
checkClassNode(node.init);
|
|
13259
13563
|
}
|
|
13260
13564
|
},
|
|
@@ -13264,9 +13568,9 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13264
13568
|
},
|
|
13265
13569
|
// SVG artwork colors are exempt; component presentation colors still report.
|
|
13266
13570
|
"JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
|
|
13267
|
-
if (node.value?.type !==
|
|
13571
|
+
if (node.value?.type !== import_utils76.AST_NODE_TYPES.Literal) return;
|
|
13268
13572
|
const owner = node.parent.name;
|
|
13269
|
-
if (owner.type ===
|
|
13573
|
+
if (owner.type === import_utils76.AST_NODE_TYPES.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
|
|
13270
13574
|
return;
|
|
13271
13575
|
}
|
|
13272
13576
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
@@ -13280,7 +13584,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13280
13584
|
if (name !== null && STYLE_COLOR_PROPS.has(name)) checkColorValueNode(node.value);
|
|
13281
13585
|
},
|
|
13282
13586
|
ImportExpression(node) {
|
|
13283
|
-
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)) {
|
|
13284
13588
|
importsEmailOrPdfRenderer = true;
|
|
13285
13589
|
}
|
|
13286
13590
|
},
|
|
@@ -13293,7 +13597,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13293
13597
|
});
|
|
13294
13598
|
|
|
13295
13599
|
// src/rules/prefer-server-actions.ts
|
|
13296
|
-
var
|
|
13600
|
+
var import_utils77 = require("@typescript-eslint/utils");
|
|
13297
13601
|
var PREFER_SERVER_ACTIONS_DOCUMENTATION = {
|
|
13298
13602
|
summary: "Prefer Next.js Server Actions over /api/* mutations.",
|
|
13299
13603
|
rationale: "Server Actions preserve typed application calls and avoid an internal JSON request-response boundary.",
|
|
@@ -13482,7 +13786,7 @@ var prefer_server_actions_default = createRule({
|
|
|
13482
13786
|
});
|
|
13483
13787
|
|
|
13484
13788
|
// src/rules/prefer-whole-object-assertion.ts
|
|
13485
|
-
var
|
|
13789
|
+
var import_utils78 = require("@typescript-eslint/utils");
|
|
13486
13790
|
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
13487
13791
|
var SYNTHETIC_LITERAL_MATCHERS = /* @__PURE__ */ new Map([
|
|
13488
13792
|
["toBeNull", "null"],
|
|
@@ -13507,11 +13811,11 @@ var PREFER_WHOLE_OBJECT_ASSERTION_DOCUMENTATION = {
|
|
|
13507
13811
|
};
|
|
13508
13812
|
function literalText(node, getText) {
|
|
13509
13813
|
switch (node.type) {
|
|
13510
|
-
case
|
|
13814
|
+
case import_utils78.AST_NODE_TYPES.Literal:
|
|
13511
13815
|
return "regex" in node ? null : getText(node);
|
|
13512
|
-
case
|
|
13816
|
+
case import_utils78.AST_NODE_TYPES.TemplateLiteral:
|
|
13513
13817
|
return node.expressions.length === 0 ? getText(node) : null;
|
|
13514
|
-
case
|
|
13818
|
+
case import_utils78.AST_NODE_TYPES.UnaryExpression:
|
|
13515
13819
|
return NUMERIC_SIGNS2.has(node.operator) && literalText(node.argument, getText) !== null ? getText(node) : null;
|
|
13516
13820
|
default:
|
|
13517
13821
|
return null;
|
|
@@ -13519,15 +13823,15 @@ function literalText(node, getText) {
|
|
|
13519
13823
|
}
|
|
13520
13824
|
function isPureReceiver(node) {
|
|
13521
13825
|
switch (node.type) {
|
|
13522
|
-
case
|
|
13523
|
-
case
|
|
13826
|
+
case import_utils78.AST_NODE_TYPES.Identifier:
|
|
13827
|
+
case import_utils78.AST_NODE_TYPES.ThisExpression:
|
|
13524
13828
|
return true;
|
|
13525
|
-
case
|
|
13829
|
+
case import_utils78.AST_NODE_TYPES.MemberExpression:
|
|
13526
13830
|
if (node.optional) {
|
|
13527
13831
|
return false;
|
|
13528
13832
|
}
|
|
13529
13833
|
if (node.computed) {
|
|
13530
|
-
return node.property.type ===
|
|
13834
|
+
return node.property.type === import_utils78.AST_NODE_TYPES.Literal && isPureReceiver(node.object);
|
|
13531
13835
|
}
|
|
13532
13836
|
return isPureReceiver(node.object);
|
|
13533
13837
|
default:
|
|
@@ -13535,7 +13839,7 @@ function isPureReceiver(node) {
|
|
|
13535
13839
|
}
|
|
13536
13840
|
}
|
|
13537
13841
|
function literalIndex(node) {
|
|
13538
|
-
if (node.type !==
|
|
13842
|
+
if (node.type !== import_utils78.AST_NODE_TYPES.Literal || typeof node.value !== "number") {
|
|
13539
13843
|
return null;
|
|
13540
13844
|
}
|
|
13541
13845
|
return Number.isInteger(node.value) && node.value >= 0 ? node.value : null;
|
|
@@ -13543,8 +13847,8 @@ function literalIndex(node) {
|
|
|
13543
13847
|
function propertyAccess(node) {
|
|
13544
13848
|
const path = [];
|
|
13545
13849
|
let current = node;
|
|
13546
|
-
while (current.type ===
|
|
13547
|
-
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;
|
|
13548
13852
|
path.unshift(current.property.name);
|
|
13549
13853
|
current = current.object;
|
|
13550
13854
|
}
|
|
@@ -13572,24 +13876,24 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13572
13876
|
}
|
|
13573
13877
|
const { sourceCode } = context;
|
|
13574
13878
|
function parseAssertion(statement) {
|
|
13575
|
-
if (statement.type !==
|
|
13879
|
+
if (statement.type !== import_utils78.AST_NODE_TYPES.ExpressionStatement) {
|
|
13576
13880
|
return null;
|
|
13577
13881
|
}
|
|
13578
13882
|
const call = statement.expression;
|
|
13579
|
-
if (call.type !==
|
|
13883
|
+
if (call.type !== import_utils78.AST_NODE_TYPES.CallExpression) {
|
|
13580
13884
|
return null;
|
|
13581
13885
|
}
|
|
13582
13886
|
const callee = call.callee;
|
|
13583
|
-
if (callee.type !==
|
|
13887
|
+
if (callee.type !== import_utils78.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils78.AST_NODE_TYPES.Identifier) {
|
|
13584
13888
|
return null;
|
|
13585
13889
|
}
|
|
13586
13890
|
const matcher = callee.property.name;
|
|
13587
13891
|
const expectCall = callee.object;
|
|
13588
|
-
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) {
|
|
13589
13893
|
return null;
|
|
13590
13894
|
}
|
|
13591
13895
|
const actual = expectCall.arguments[0];
|
|
13592
|
-
if (actual === void 0 || actual.type !==
|
|
13896
|
+
if (actual === void 0 || actual.type !== import_utils78.AST_NODE_TYPES.MemberExpression || actual.optional) {
|
|
13593
13897
|
return null;
|
|
13594
13898
|
}
|
|
13595
13899
|
if (!isPureReceiver(actual.object)) {
|
|
@@ -13618,7 +13922,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13618
13922
|
return null;
|
|
13619
13923
|
}
|
|
13620
13924
|
const expected = call.arguments[0];
|
|
13621
|
-
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) {
|
|
13622
13926
|
return null;
|
|
13623
13927
|
}
|
|
13624
13928
|
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
@@ -13759,7 +14063,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13759
14063
|
});
|
|
13760
14064
|
|
|
13761
14065
|
// src/rules/repeated-static-call-cases.ts
|
|
13762
|
-
var
|
|
14066
|
+
var import_utils79 = require("@typescript-eslint/utils");
|
|
13763
14067
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
13764
14068
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
13765
14069
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
@@ -13780,67 +14084,67 @@ var EXPECT_MODIFIERS = /* @__PURE__ */ new Set(["not", "rejects", "resolves"]);
|
|
|
13780
14084
|
var SNAPSHOT_MATCHERS = /snapshot/iu;
|
|
13781
14085
|
var MIN_CASES2 = 3;
|
|
13782
14086
|
function staticMemberName5(node) {
|
|
13783
|
-
if (!node.computed && node.property.type ===
|
|
13784
|
-
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;
|
|
13785
14089
|
return null;
|
|
13786
14090
|
}
|
|
13787
|
-
function
|
|
13788
|
-
const variable =
|
|
14091
|
+
function importedName6(identifier, context, modules) {
|
|
14092
|
+
const variable = import_utils79.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
13789
14093
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
13790
14094
|
for (const definition of variable.defs) {
|
|
13791
|
-
if (definition.node.type !==
|
|
14095
|
+
if (definition.node.type !== import_utils79.AST_NODE_TYPES.ImportSpecifier) continue;
|
|
13792
14096
|
const declaration = definition.node.parent;
|
|
13793
|
-
if (declaration.type !==
|
|
14097
|
+
if (declaration.type !== import_utils79.AST_NODE_TYPES.ImportDeclaration || typeof declaration.source.value !== "string" || !modules.has(declaration.source.value)) continue;
|
|
13794
14098
|
const imported = definition.node.imported;
|
|
13795
|
-
return imported.type ===
|
|
14099
|
+
return imported.type === import_utils79.AST_NODE_TYPES.Identifier ? imported.name : String(imported.value);
|
|
13796
14100
|
}
|
|
13797
14101
|
return null;
|
|
13798
14102
|
}
|
|
13799
14103
|
function isDirectTestCallback2(node, context) {
|
|
13800
|
-
if (node.type !==
|
|
14104
|
+
if (node.type !== import_utils79.AST_NODE_TYPES.ArrowFunctionExpression && node.type !== import_utils79.AST_NODE_TYPES.FunctionExpression) return false;
|
|
13801
14105
|
const call = node.parent;
|
|
13802
|
-
if (call?.type !==
|
|
14106
|
+
if (call?.type !== import_utils79.AST_NODE_TYPES.CallExpression || !call.arguments.includes(node)) return false;
|
|
13803
14107
|
const root = testRoot2(call.callee);
|
|
13804
|
-
return root !== null && TEST_NAMES2.has(
|
|
14108
|
+
return root !== null && TEST_NAMES2.has(importedName6(root, context, TEST_MODULES4) ?? "");
|
|
13805
14109
|
}
|
|
13806
14110
|
function testRoot2(callee) {
|
|
13807
|
-
if (callee.type ===
|
|
13808
|
-
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;
|
|
13809
14113
|
const modifier = staticMemberName5(callee);
|
|
13810
14114
|
return modifier !== null && TEST_MODIFIERS4.has(modifier) ? testRoot2(callee.object) : null;
|
|
13811
14115
|
}
|
|
13812
14116
|
function isStatic(node) {
|
|
13813
|
-
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);
|
|
13814
14118
|
switch (node.type) {
|
|
13815
|
-
case
|
|
14119
|
+
case import_utils79.AST_NODE_TYPES.Literal:
|
|
13816
14120
|
return true;
|
|
13817
|
-
case
|
|
14121
|
+
case import_utils79.AST_NODE_TYPES.TemplateLiteral:
|
|
13818
14122
|
return node.expressions.length === 0;
|
|
13819
|
-
case
|
|
14123
|
+
case import_utils79.AST_NODE_TYPES.UnaryExpression:
|
|
13820
14124
|
return (node.operator === "+" || node.operator === "-") && isStatic(node.argument);
|
|
13821
|
-
case
|
|
13822
|
-
return node.elements.every((item) => item !== null && item.type !==
|
|
13823
|
-
case
|
|
13824
|
-
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));
|
|
13825
14129
|
default:
|
|
13826
14130
|
return false;
|
|
13827
14131
|
}
|
|
13828
14132
|
}
|
|
13829
14133
|
function staticShape(node) {
|
|
13830
|
-
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);
|
|
13831
14135
|
switch (node.type) {
|
|
13832
|
-
case
|
|
14136
|
+
case import_utils79.AST_NODE_TYPES.Literal:
|
|
13833
14137
|
return `literal:${typeof node.value}`;
|
|
13834
|
-
case
|
|
14138
|
+
case import_utils79.AST_NODE_TYPES.TemplateLiteral:
|
|
13835
14139
|
return "template";
|
|
13836
|
-
case
|
|
14140
|
+
case import_utils79.AST_NODE_TYPES.UnaryExpression:
|
|
13837
14141
|
return `unary:${node.operator}:${staticShape(node.argument)}`;
|
|
13838
|
-
case
|
|
13839
|
-
return `array(${node.elements.map((item) => item === null || item.type ===
|
|
13840
|
-
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:
|
|
13841
14145
|
return `object(${node.properties.map((property) => {
|
|
13842
|
-
if (property.type !==
|
|
13843
|
-
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);
|
|
13844
14148
|
return `${key}:${staticShape(property.value)}`;
|
|
13845
14149
|
}).join(",")})`;
|
|
13846
14150
|
default:
|
|
@@ -13848,16 +14152,16 @@ function staticShape(node) {
|
|
|
13848
14152
|
}
|
|
13849
14153
|
}
|
|
13850
14154
|
function assertionShape(statement, context) {
|
|
13851
|
-
if (statement.type !==
|
|
14155
|
+
if (statement.type !== import_utils79.AST_NODE_TYPES.ExpressionStatement || statement.expression.type !== import_utils79.AST_NODE_TYPES.CallExpression) return null;
|
|
13852
14156
|
const matcherCall = statement.expression;
|
|
13853
|
-
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;
|
|
13854
14158
|
const matcher = matcherCall.callee.property.name;
|
|
13855
14159
|
if (SNAPSHOT_MATCHERS.test(matcher)) return null;
|
|
13856
14160
|
const chain = expectCallFromMatcher(matcherCall.callee);
|
|
13857
|
-
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;
|
|
13858
14162
|
const observed = chain.call.arguments[0];
|
|
13859
14163
|
const expected = matcherCall.arguments[0];
|
|
13860
|
-
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;
|
|
13861
14165
|
const skeleton = `${observed.callee.name}/${observed.arguments.map((item) => staticShape(item)).join(",")}/${chain.modifiers.join(".")}/${matcher}/${staticShape(expected)}`;
|
|
13862
14166
|
const values = [...observed.arguments, expected].map((item) => context.sourceCode.getText(item)).join("\0");
|
|
13863
14167
|
return { statement, skeleton, values };
|
|
@@ -13865,13 +14169,13 @@ function assertionShape(statement, context) {
|
|
|
13865
14169
|
function expectCallFromMatcher(node) {
|
|
13866
14170
|
const modifiers = [];
|
|
13867
14171
|
let receiver = node.object;
|
|
13868
|
-
while (receiver.type ===
|
|
14172
|
+
while (receiver.type === import_utils79.AST_NODE_TYPES.MemberExpression) {
|
|
13869
14173
|
const modifier = staticMemberName5(receiver);
|
|
13870
14174
|
if (modifier === null || !EXPECT_MODIFIERS.has(modifier)) return null;
|
|
13871
14175
|
modifiers.unshift(modifier);
|
|
13872
14176
|
receiver = receiver.object;
|
|
13873
14177
|
}
|
|
13874
|
-
return receiver.type ===
|
|
14178
|
+
return receiver.type === import_utils79.AST_NODE_TYPES.CallExpression ? { call: receiver, modifiers } : null;
|
|
13875
14179
|
}
|
|
13876
14180
|
var repeated_static_call_cases_default = createRule({
|
|
13877
14181
|
name: "repeated-static-call-cases",
|
|
@@ -13891,7 +14195,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13891
14195
|
return {
|
|
13892
14196
|
"CallExpression > ArrowFunctionExpression, CallExpression > FunctionExpression"(node) {
|
|
13893
14197
|
const call = node.parent;
|
|
13894
|
-
if (call?.type ===
|
|
14198
|
+
if (call?.type === import_utils79.AST_NODE_TYPES.CallExpression) {
|
|
13895
14199
|
const duplicate = duplicateTestBodyCandidate(call, sourceCode);
|
|
13896
14200
|
if (duplicate !== null && duplicate.body === node) {
|
|
13897
14201
|
const groups = duplicateGroups.get(duplicate.container) ?? /* @__PURE__ */ new Map();
|
|
@@ -13901,7 +14205,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13901
14205
|
duplicateGroups.set(duplicate.container, groups);
|
|
13902
14206
|
}
|
|
13903
14207
|
}
|
|
13904
|
-
if (!isDirectTestCallback2(node, context) || node.body.type !==
|
|
14208
|
+
if (!isDirectTestCallback2(node, context) || node.body.type !== import_utils79.AST_NODE_TYPES.BlockStatement) return;
|
|
13905
14209
|
let run = [];
|
|
13906
14210
|
const flush = () => {
|
|
13907
14211
|
if (run.length >= MIN_CASES2 && new Set(run.map((item) => item.values)).size > 1) {
|
|
@@ -13942,7 +14246,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13942
14246
|
});
|
|
13943
14247
|
|
|
13944
14248
|
// src/rules/prefer-zod-infer.ts
|
|
13945
|
-
var
|
|
14249
|
+
var import_utils80 = require("@typescript-eslint/utils");
|
|
13946
14250
|
var PREFER_ZOD_INFER_DOCUMENTATION = {
|
|
13947
14251
|
summary: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
|
|
13948
14252
|
rationale: "A derived type stays synchronized when the runtime schema changes.",
|
|
@@ -13995,47 +14299,47 @@ var ZOD_TYPE_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
|
13995
14299
|
"Schema"
|
|
13996
14300
|
]);
|
|
13997
14301
|
var LEAF_NODE_TYPES = {
|
|
13998
|
-
string: [
|
|
13999
|
-
email: [
|
|
14000
|
-
url: [
|
|
14001
|
-
uuid: [
|
|
14002
|
-
ulid: [
|
|
14003
|
-
cuid: [
|
|
14004
|
-
cuid2: [
|
|
14005
|
-
nanoid: [
|
|
14006
|
-
iso: [
|
|
14007
|
-
number: [
|
|
14008
|
-
int: [
|
|
14009
|
-
float32: [
|
|
14010
|
-
float64: [
|
|
14011
|
-
boolean: [
|
|
14012
|
-
bigint: [
|
|
14013
|
-
symbol: [
|
|
14014
|
-
any: [
|
|
14015
|
-
unknown: [
|
|
14016
|
-
never: [
|
|
14017
|
-
void: [
|
|
14018
|
-
null: [
|
|
14019
|
-
undefined: [
|
|
14020
|
-
literal: [
|
|
14021
|
-
date: [
|
|
14022
|
-
array: [
|
|
14023
|
-
tuple: [
|
|
14024
|
-
object: [
|
|
14025
|
-
strictObject: [
|
|
14026
|
-
looseObject: [
|
|
14027
|
-
record: [
|
|
14028
|
-
map: [
|
|
14029
|
-
set: [
|
|
14030
|
-
promise: [
|
|
14031
|
-
enum: [
|
|
14032
|
-
nativeEnum: [
|
|
14033
|
-
union: [
|
|
14034
|
-
discriminatedUnion: [
|
|
14035
|
-
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]
|
|
14036
14340
|
};
|
|
14037
14341
|
function primitiveLiteralKey(node) {
|
|
14038
|
-
if (node.type !==
|
|
14342
|
+
if (node.type !== import_utils80.AST_NODE_TYPES.Literal) {
|
|
14039
14343
|
return null;
|
|
14040
14344
|
}
|
|
14041
14345
|
if (node.value === null) {
|
|
@@ -14067,13 +14371,13 @@ function staticZodDomain(leaf, call) {
|
|
|
14067
14371
|
}
|
|
14068
14372
|
if (leaf === "literal") {
|
|
14069
14373
|
const [argument] = call.arguments;
|
|
14070
|
-
if (argument === void 0 || argument.type ===
|
|
14374
|
+
if (argument === void 0 || argument.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
14071
14375
|
return null;
|
|
14072
14376
|
}
|
|
14073
|
-
if (argument.type ===
|
|
14377
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ArrayExpression) {
|
|
14074
14378
|
return exactDomain(
|
|
14075
14379
|
argument.elements.map(
|
|
14076
|
-
(element) => element === null || element.type ===
|
|
14380
|
+
(element) => element === null || element.type === import_utils80.AST_NODE_TYPES.SpreadElement ? null : primitiveLiteralKey(element)
|
|
14077
14381
|
)
|
|
14078
14382
|
);
|
|
14079
14383
|
}
|
|
@@ -14081,13 +14385,13 @@ function staticZodDomain(leaf, call) {
|
|
|
14081
14385
|
}
|
|
14082
14386
|
if (leaf === "enum") {
|
|
14083
14387
|
const [argument] = call.arguments;
|
|
14084
|
-
if (argument === void 0 || argument.type ===
|
|
14388
|
+
if (argument === void 0 || argument.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
14085
14389
|
return null;
|
|
14086
14390
|
}
|
|
14087
|
-
if (argument.type ===
|
|
14391
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ArrayExpression) {
|
|
14088
14392
|
return exactDomain(
|
|
14089
14393
|
argument.elements.map((element) => {
|
|
14090
|
-
if (element === null || element.type ===
|
|
14394
|
+
if (element === null || element.type === import_utils80.AST_NODE_TYPES.SpreadElement) {
|
|
14091
14395
|
return null;
|
|
14092
14396
|
}
|
|
14093
14397
|
const key = primitiveLiteralKey(element);
|
|
@@ -14095,10 +14399,10 @@ function staticZodDomain(leaf, call) {
|
|
|
14095
14399
|
})
|
|
14096
14400
|
);
|
|
14097
14401
|
}
|
|
14098
|
-
if (argument.type ===
|
|
14402
|
+
if (argument.type === import_utils80.AST_NODE_TYPES.ObjectExpression) {
|
|
14099
14403
|
return exactDomain(
|
|
14100
14404
|
argument.properties.map((property) => {
|
|
14101
|
-
if (property.type !==
|
|
14405
|
+
if (property.type !== import_utils80.AST_NODE_TYPES.Property || property.computed || property.kind !== "init" || property.method || property.shorthand) {
|
|
14102
14406
|
return null;
|
|
14103
14407
|
}
|
|
14104
14408
|
const key = primitiveLiteralKey(property.value);
|
|
@@ -14125,15 +14429,15 @@ function sameDomain(left, right) {
|
|
|
14125
14429
|
return true;
|
|
14126
14430
|
}
|
|
14127
14431
|
function isExportedDeclaration(node) {
|
|
14128
|
-
return node.parent?.type ===
|
|
14432
|
+
return node.parent?.type === import_utils80.AST_NODE_TYPES.ExportNamedDeclaration;
|
|
14129
14433
|
}
|
|
14130
14434
|
function isModuleLevelConst(node) {
|
|
14131
14435
|
const declaration = node.parent;
|
|
14132
|
-
if (declaration.type !==
|
|
14436
|
+
if (declaration.type !== import_utils80.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const") {
|
|
14133
14437
|
return false;
|
|
14134
14438
|
}
|
|
14135
14439
|
const container = declaration.parent;
|
|
14136
|
-
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;
|
|
14137
14441
|
}
|
|
14138
14442
|
function normalizeSchemaName(name) {
|
|
14139
14443
|
return name.replace(/Schema$/i, "").replace(/^Z(?=[A-Z])/, "").toLowerCase();
|
|
@@ -14142,20 +14446,20 @@ function normalizeTypeName(name) {
|
|
|
14142
14446
|
return name.replace(/Type$/, "").toLowerCase();
|
|
14143
14447
|
}
|
|
14144
14448
|
function unwrapNullish(annotation) {
|
|
14145
|
-
if (annotation.type !==
|
|
14449
|
+
if (annotation.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
14146
14450
|
return {
|
|
14147
14451
|
core: annotation,
|
|
14148
|
-
nullable: annotation.type ===
|
|
14452
|
+
nullable: annotation.type === import_utils80.AST_NODE_TYPES.TSNullKeyword
|
|
14149
14453
|
};
|
|
14150
14454
|
}
|
|
14151
14455
|
const rest = [];
|
|
14152
14456
|
let nullable = false;
|
|
14153
14457
|
for (const member of annotation.types) {
|
|
14154
|
-
if (member.type ===
|
|
14458
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSNullKeyword) {
|
|
14155
14459
|
nullable = true;
|
|
14156
14460
|
continue;
|
|
14157
14461
|
}
|
|
14158
|
-
if (member.type ===
|
|
14462
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSUndefinedKeyword) {
|
|
14159
14463
|
continue;
|
|
14160
14464
|
}
|
|
14161
14465
|
rest.push(member);
|
|
@@ -14189,18 +14493,18 @@ function leafAgrees(field, annotation) {
|
|
|
14189
14493
|
return null;
|
|
14190
14494
|
}
|
|
14191
14495
|
if (leaf === "date") {
|
|
14192
|
-
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";
|
|
14193
14497
|
}
|
|
14194
14498
|
return expected.includes(core.type);
|
|
14195
14499
|
}
|
|
14196
14500
|
function typeLiteralDomain(annotation) {
|
|
14197
|
-
const members = annotation.type ===
|
|
14501
|
+
const members = annotation.type === import_utils80.AST_NODE_TYPES.TSUnionType ? annotation.types : [annotation];
|
|
14198
14502
|
const keys = [];
|
|
14199
14503
|
for (const member of members) {
|
|
14200
|
-
if (member.type ===
|
|
14504
|
+
if (member.type === import_utils80.AST_NODE_TYPES.TSNullKeyword) {
|
|
14201
14505
|
continue;
|
|
14202
14506
|
}
|
|
14203
|
-
if (member.type !==
|
|
14507
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSLiteralType) {
|
|
14204
14508
|
return null;
|
|
14205
14509
|
}
|
|
14206
14510
|
keys.push(primitiveLiteralKey(member.literal));
|
|
@@ -14208,11 +14512,11 @@ function typeLiteralDomain(annotation) {
|
|
|
14208
14512
|
return exactDomain(keys);
|
|
14209
14513
|
}
|
|
14210
14514
|
function staticStringUnionDomain(node) {
|
|
14211
|
-
if (node.type !==
|
|
14515
|
+
if (node.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
14212
14516
|
return null;
|
|
14213
14517
|
}
|
|
14214
14518
|
const keys = node.types.map((member) => {
|
|
14215
|
-
if (member.type !==
|
|
14519
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSLiteralType) {
|
|
14216
14520
|
return null;
|
|
14217
14521
|
}
|
|
14218
14522
|
const key = primitiveLiteralKey(member.literal);
|
|
@@ -14280,14 +14584,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14280
14584
|
function zodCallChain(node) {
|
|
14281
14585
|
const chain = [];
|
|
14282
14586
|
let current = node;
|
|
14283
|
-
while (current.type ===
|
|
14587
|
+
while (current.type === import_utils80.AST_NODE_TYPES.CallExpression) {
|
|
14284
14588
|
const callee = current.callee;
|
|
14285
|
-
if (callee.type !==
|
|
14589
|
+
if (callee.type !== import_utils80.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14286
14590
|
return null;
|
|
14287
14591
|
}
|
|
14288
14592
|
chain.push(current);
|
|
14289
14593
|
const receiver = callee.object;
|
|
14290
|
-
if (receiver.type ===
|
|
14594
|
+
if (receiver.type === import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14291
14595
|
return zodNamespaces.has(receiver.name) ? chain.reverse() : null;
|
|
14292
14596
|
}
|
|
14293
14597
|
current = receiver;
|
|
@@ -14296,14 +14600,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14296
14600
|
}
|
|
14297
14601
|
function methodName2(call) {
|
|
14298
14602
|
const callee = call.callee;
|
|
14299
|
-
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 : "";
|
|
14300
14604
|
}
|
|
14301
14605
|
function recordZodImport(node) {
|
|
14302
14606
|
if (!isZodModule(node.source.value)) {
|
|
14303
14607
|
return;
|
|
14304
14608
|
}
|
|
14305
14609
|
for (const specifier of node.specifiers) {
|
|
14306
|
-
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") {
|
|
14307
14611
|
zodNamespaces.add(specifier.local.name);
|
|
14308
14612
|
}
|
|
14309
14613
|
}
|
|
@@ -14313,13 +14617,13 @@ var prefer_zod_infer_default = createRule({
|
|
|
14313
14617
|
let current = node;
|
|
14314
14618
|
let leaf = null;
|
|
14315
14619
|
let leafCall = null;
|
|
14316
|
-
while (current.type ===
|
|
14620
|
+
while (current.type === import_utils80.AST_NODE_TYPES.CallExpression) {
|
|
14317
14621
|
const callee = current.callee;
|
|
14318
|
-
if (callee.type !==
|
|
14622
|
+
if (callee.type !== import_utils80.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils80.AST_NODE_TYPES.Identifier) {
|
|
14319
14623
|
break;
|
|
14320
14624
|
}
|
|
14321
14625
|
const receiver = callee.object;
|
|
14322
|
-
if (receiver.type ===
|
|
14626
|
+
if (receiver.type === import_utils80.AST_NODE_TYPES.Identifier && zodNamespaces.has(receiver.name)) {
|
|
14323
14627
|
leaf = callee.property.name;
|
|
14324
14628
|
leafCall = current;
|
|
14325
14629
|
break;
|
|
@@ -14350,20 +14654,20 @@ var prefer_zod_infer_default = createRule({
|
|
|
14350
14654
|
return domain instanceof Set && domain.size >= 2 ? domain : null;
|
|
14351
14655
|
}
|
|
14352
14656
|
function inferredSchemaName(node) {
|
|
14353
|
-
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") {
|
|
14354
14658
|
return null;
|
|
14355
14659
|
}
|
|
14356
14660
|
const arguments_ = node.typeArguments?.params ?? [];
|
|
14357
14661
|
const [argument] = arguments_;
|
|
14358
|
-
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;
|
|
14359
14663
|
}
|
|
14360
14664
|
function recordLiteralUnions(members, owner, ownerName, exported) {
|
|
14361
14665
|
for (const member of members) {
|
|
14362
|
-
if (member.type !==
|
|
14666
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSPropertySignature || member.computed || member.optional || member.readonly || member.typeAnnotation === void 0) {
|
|
14363
14667
|
continue;
|
|
14364
14668
|
}
|
|
14365
14669
|
const key = member.key;
|
|
14366
|
-
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;
|
|
14367
14671
|
if (propertyName5 === null) {
|
|
14368
14672
|
continue;
|
|
14369
14673
|
}
|
|
@@ -14373,7 +14677,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14373
14677
|
}
|
|
14374
14678
|
const annotation = member.typeAnnotation.typeAnnotation;
|
|
14375
14679
|
const domain = staticStringUnionDomain(annotation);
|
|
14376
|
-
if (domain === null || annotation.type !==
|
|
14680
|
+
if (domain === null || annotation.type !== import_utils80.AST_NODE_TYPES.TSUnionType) {
|
|
14377
14681
|
continue;
|
|
14378
14682
|
}
|
|
14379
14683
|
literalUnionOccurrences.push({
|
|
@@ -14404,16 +14708,16 @@ var prefer_zod_infer_default = createRule({
|
|
|
14404
14708
|
return null;
|
|
14405
14709
|
}
|
|
14406
14710
|
const shape = base.arguments[0];
|
|
14407
|
-
if (shape === void 0 || shape.type !==
|
|
14711
|
+
if (shape === void 0 || shape.type !== import_utils80.AST_NODE_TYPES.ObjectExpression) {
|
|
14408
14712
|
return null;
|
|
14409
14713
|
}
|
|
14410
14714
|
const fields = /* @__PURE__ */ new Map();
|
|
14411
14715
|
for (const property of shape.properties) {
|
|
14412
|
-
if (property.type !==
|
|
14716
|
+
if (property.type !== import_utils80.AST_NODE_TYPES.Property || property.computed) {
|
|
14413
14717
|
return null;
|
|
14414
14718
|
}
|
|
14415
14719
|
const { key } = property;
|
|
14416
|
-
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;
|
|
14417
14721
|
if (name === null) {
|
|
14418
14722
|
return null;
|
|
14419
14723
|
}
|
|
@@ -14424,11 +14728,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
14424
14728
|
function typeMembers(members) {
|
|
14425
14729
|
const result = /* @__PURE__ */ new Map();
|
|
14426
14730
|
for (const member of members) {
|
|
14427
|
-
if (member.type !==
|
|
14731
|
+
if (member.type !== import_utils80.AST_NODE_TYPES.TSPropertySignature || member.computed) {
|
|
14428
14732
|
return null;
|
|
14429
14733
|
}
|
|
14430
14734
|
const { key } = member;
|
|
14431
|
-
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;
|
|
14432
14736
|
if (name === null) {
|
|
14433
14737
|
return null;
|
|
14434
14738
|
}
|
|
@@ -14443,8 +14747,8 @@ var prefer_zod_infer_default = createRule({
|
|
|
14443
14747
|
return result.size === 0 ? null : result;
|
|
14444
14748
|
}
|
|
14445
14749
|
function collectConstrainedNames(node) {
|
|
14446
|
-
if (node.type ===
|
|
14447
|
-
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) {
|
|
14448
14752
|
constrainedTypeNames.add(node.typeName.name);
|
|
14449
14753
|
}
|
|
14450
14754
|
for (const argument of node.typeArguments?.params ?? []) {
|
|
@@ -14452,11 +14756,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
14452
14756
|
}
|
|
14453
14757
|
return;
|
|
14454
14758
|
}
|
|
14455
|
-
if (node.type ===
|
|
14759
|
+
if (node.type === import_utils80.AST_NODE_TYPES.TSArrayType) {
|
|
14456
14760
|
collectConstrainedNames(node.elementType);
|
|
14457
14761
|
return;
|
|
14458
14762
|
}
|
|
14459
|
-
if (node.type ===
|
|
14763
|
+
if (node.type === import_utils80.AST_NODE_TYPES.TSUnionType || node.type === import_utils80.AST_NODE_TYPES.TSIntersectionType) {
|
|
14460
14764
|
for (const member of node.types) {
|
|
14461
14765
|
collectConstrainedNames(member);
|
|
14462
14766
|
}
|
|
@@ -14500,7 +14804,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14500
14804
|
return {
|
|
14501
14805
|
Program(node) {
|
|
14502
14806
|
for (const statement of node.body) {
|
|
14503
|
-
if (statement.type ===
|
|
14807
|
+
if (statement.type === import_utils80.AST_NODE_TYPES.ImportDeclaration) {
|
|
14504
14808
|
recordZodImport(statement);
|
|
14505
14809
|
}
|
|
14506
14810
|
}
|
|
@@ -14509,7 +14813,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14509
14813
|
recordZodImport(node);
|
|
14510
14814
|
},
|
|
14511
14815
|
VariableDeclarator(node) {
|
|
14512
|
-
if (node.id.type !==
|
|
14816
|
+
if (node.id.type !== import_utils80.AST_NODE_TYPES.Identifier || node.init == null) {
|
|
14513
14817
|
return;
|
|
14514
14818
|
}
|
|
14515
14819
|
const fields = schemaFields(node.init);
|
|
@@ -14526,14 +14830,14 @@ var prefer_zod_infer_default = createRule({
|
|
|
14526
14830
|
},
|
|
14527
14831
|
/** Records `XSchema.transform(...)` and equivalent module-level reshaping. */
|
|
14528
14832
|
"MemberExpression[computed=false]"(node) {
|
|
14529
|
-
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)) {
|
|
14530
14834
|
reshapedSchemaNames.add(node.object.name);
|
|
14531
14835
|
}
|
|
14532
14836
|
},
|
|
14533
14837
|
/** Records every type argument carried by a Zod constraint. */
|
|
14534
14838
|
TSTypeReference(node) {
|
|
14535
14839
|
const { typeName } = node;
|
|
14536
|
-
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;
|
|
14537
14841
|
if (referenced === null || !ZOD_TYPE_CONSTRAINTS.has(referenced)) {
|
|
14538
14842
|
return;
|
|
14539
14843
|
}
|
|
@@ -14565,7 +14869,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14565
14869
|
typeName: node.id.name
|
|
14566
14870
|
});
|
|
14567
14871
|
}
|
|
14568
|
-
if (node.typeParameters !== void 0 || node.typeAnnotation.type !==
|
|
14872
|
+
if (node.typeParameters !== void 0 || node.typeAnnotation.type !== import_utils80.AST_NODE_TYPES.TSTypeLiteral) {
|
|
14569
14873
|
return;
|
|
14570
14874
|
}
|
|
14571
14875
|
const members = typeMembers(node.typeAnnotation.members);
|
|
@@ -14664,7 +14968,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
14664
14968
|
});
|
|
14665
14969
|
|
|
14666
14970
|
// src/rules/require-assert-never.ts
|
|
14667
|
-
var
|
|
14971
|
+
var import_utils81 = require("@typescript-eslint/utils");
|
|
14668
14972
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
14669
14973
|
var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
14670
14974
|
summary: "Require an empty switch default to call `assertNever` so discriminated unions remain exhaustive at compile time.",
|
|
@@ -14677,14 +14981,14 @@ var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
|
14677
14981
|
]
|
|
14678
14982
|
};
|
|
14679
14983
|
var isRuntimeHandlingStatement = (statement) => {
|
|
14680
|
-
if (statement.type ===
|
|
14681
|
-
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) {
|
|
14682
14986
|
return statement.label !== null;
|
|
14683
14987
|
}
|
|
14684
|
-
if (statement.type ===
|
|
14988
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.TSTypeAliasDeclaration || statement.type === import_utils81.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
14685
14989
|
return false;
|
|
14686
14990
|
}
|
|
14687
|
-
if (statement.type ===
|
|
14991
|
+
if (statement.type === import_utils81.AST_NODE_TYPES.BlockStatement) {
|
|
14688
14992
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
14689
14993
|
}
|
|
14690
14994
|
return true;
|
|
@@ -14700,7 +15004,7 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
14700
15004
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
14701
15005
|
}
|
|
14702
15006
|
const only = defaultCase.consequent[0];
|
|
14703
|
-
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)) {
|
|
14704
15008
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
14705
15009
|
}
|
|
14706
15010
|
return false;
|
|
@@ -14756,7 +15060,7 @@ var require_assert_never_default = createRule({
|
|
|
14756
15060
|
create(context) {
|
|
14757
15061
|
let services;
|
|
14758
15062
|
try {
|
|
14759
|
-
services =
|
|
15063
|
+
services = import_utils81.ESLintUtils.getParserServices(context);
|
|
14760
15064
|
} catch {
|
|
14761
15065
|
services = null;
|
|
14762
15066
|
}
|
|
@@ -14783,7 +15087,7 @@ var require_assert_never_default = createRule({
|
|
|
14783
15087
|
});
|
|
14784
15088
|
|
|
14785
15089
|
// src/rules/require-fetch-timeout.ts
|
|
14786
|
-
var
|
|
15090
|
+
var import_utils82 = require("@typescript-eslint/utils");
|
|
14787
15091
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
14788
15092
|
summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
|
|
14789
15093
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -14809,14 +15113,14 @@ function matchesAnyPattern3(filename, patterns) {
|
|
|
14809
15113
|
return false;
|
|
14810
15114
|
}
|
|
14811
15115
|
function initProvablyLacksSignal(init) {
|
|
14812
|
-
if (init.type !==
|
|
15116
|
+
if (init.type !== import_utils82.AST_NODE_TYPES.ObjectExpression) {
|
|
14813
15117
|
return false;
|
|
14814
15118
|
}
|
|
14815
15119
|
for (const prop of init.properties) {
|
|
14816
|
-
if (prop.type ===
|
|
15120
|
+
if (prop.type === import_utils82.AST_NODE_TYPES.SpreadElement) {
|
|
14817
15121
|
return false;
|
|
14818
15122
|
}
|
|
14819
|
-
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") {
|
|
14820
15124
|
return false;
|
|
14821
15125
|
}
|
|
14822
15126
|
if (prop.computed) {
|
|
@@ -14826,7 +15130,7 @@ function initProvablyLacksSignal(init) {
|
|
|
14826
15130
|
return true;
|
|
14827
15131
|
}
|
|
14828
15132
|
function isInlineUrl(node, resolvesToGlobal) {
|
|
14829
|
-
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);
|
|
14830
15134
|
}
|
|
14831
15135
|
var require_fetch_timeout_default = createRule({
|
|
14832
15136
|
name: "require-fetch-timeout",
|
|
@@ -14864,30 +15168,30 @@ var require_fetch_timeout_default = createRule({
|
|
|
14864
15168
|
}
|
|
14865
15169
|
function resolvesToGlobal(identifier) {
|
|
14866
15170
|
const scope = context.sourceCode.getScope(identifier);
|
|
14867
|
-
const variable =
|
|
15171
|
+
const variable = import_utils82.ASTUtils.findVariable(scope, identifier.name);
|
|
14868
15172
|
return variable === null || variable.defs.length === 0;
|
|
14869
15173
|
}
|
|
14870
15174
|
function isGlobalFetchCall2(callee) {
|
|
14871
|
-
if (callee.type ===
|
|
15175
|
+
if (callee.type === import_utils82.AST_NODE_TYPES.Identifier) {
|
|
14872
15176
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
14873
15177
|
}
|
|
14874
|
-
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);
|
|
14875
15179
|
}
|
|
14876
15180
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
14877
|
-
const variable =
|
|
15181
|
+
const variable = import_utils82.ASTUtils.findVariable(
|
|
14878
15182
|
context.sourceCode.getScope(identifier),
|
|
14879
15183
|
identifier.name
|
|
14880
15184
|
);
|
|
14881
15185
|
if (variable?.defs.length !== 1) return false;
|
|
14882
15186
|
const definition = variable.defs[0];
|
|
14883
|
-
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)) {
|
|
14884
15188
|
return false;
|
|
14885
15189
|
}
|
|
14886
15190
|
for (const reference of variable.references) {
|
|
14887
15191
|
const ref = reference.identifier;
|
|
14888
15192
|
if (ref === identifier || ref === definition.name) continue;
|
|
14889
15193
|
const member = ref.parent;
|
|
14890
|
-
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) {
|
|
14891
15195
|
return false;
|
|
14892
15196
|
}
|
|
14893
15197
|
}
|
|
@@ -14902,7 +15206,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
14902
15206
|
if (node.arguments.length === 1 && first !== void 0 && !isInlineUrl(first, resolvesToGlobal)) {
|
|
14903
15207
|
return;
|
|
14904
15208
|
}
|
|
14905
|
-
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)) {
|
|
14906
15210
|
context.report({ node, messageId: "missingSignal" });
|
|
14907
15211
|
}
|
|
14908
15212
|
}
|
|
@@ -14911,7 +15215,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
14911
15215
|
});
|
|
14912
15216
|
|
|
14913
15217
|
// src/rules/require-port-for-service.ts
|
|
14914
|
-
var
|
|
15218
|
+
var import_utils83 = require("@typescript-eslint/utils");
|
|
14915
15219
|
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
14916
15220
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
14917
15221
|
rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
|
|
@@ -14936,45 +15240,45 @@ var ROUTER_FACTORY_NAME = "Router";
|
|
|
14936
15240
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
14937
15241
|
var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set(["=", "&&=", "??=", "||="]);
|
|
14938
15242
|
var staticMemberName6 = (member) => {
|
|
14939
|
-
if (member.property.type ===
|
|
14940
|
-
if (!member.computed && member.property.type ===
|
|
14941
|
-
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;
|
|
14942
15246
|
};
|
|
14943
15247
|
var detachedValueExports = (program) => {
|
|
14944
15248
|
const names = /* @__PURE__ */ new Set();
|
|
14945
15249
|
for (const statement of program.body) {
|
|
14946
|
-
if (statement.type ===
|
|
15250
|
+
if (statement.type === import_utils83.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
|
|
14947
15251
|
for (const specifier of statement.specifiers) {
|
|
14948
15252
|
if (specifier.exportKind !== "type") names.add(specifier.local.name);
|
|
14949
15253
|
}
|
|
14950
|
-
} else if (statement.type ===
|
|
15254
|
+
} else if (statement.type === import_utils83.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14951
15255
|
names.add(statement.declaration.name);
|
|
14952
|
-
} else if (statement.type ===
|
|
15256
|
+
} else if (statement.type === import_utils83.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
14953
15257
|
names.add(statement.expression.name);
|
|
14954
15258
|
}
|
|
14955
15259
|
}
|
|
14956
15260
|
return names;
|
|
14957
15261
|
};
|
|
14958
|
-
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);
|
|
14959
15263
|
var readTypeReference = (annotation) => {
|
|
14960
|
-
if (annotation?.type ===
|
|
15264
|
+
if (annotation?.type === import_utils83.AST_NODE_TYPES.TSUnionType) {
|
|
14961
15265
|
const members = annotation.types.filter(
|
|
14962
|
-
(member) => member.type !==
|
|
15266
|
+
(member) => member.type !== import_utils83.AST_NODE_TYPES.TSUndefinedKeyword && member.type !== import_utils83.AST_NODE_TYPES.TSNullKeyword
|
|
14963
15267
|
);
|
|
14964
15268
|
annotation = members.length === 1 ? members[0] : void 0;
|
|
14965
15269
|
}
|
|
14966
|
-
if (annotation === void 0 || annotation.type !==
|
|
15270
|
+
if (annotation === void 0 || annotation.type !== import_utils83.AST_NODE_TYPES.TSTypeReference) return null;
|
|
14967
15271
|
const { typeName } = annotation;
|
|
14968
|
-
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;
|
|
14969
15273
|
if (rightmost === null) return null;
|
|
14970
15274
|
return { typeName: rightmost, display: qualifiedName(typeName) };
|
|
14971
15275
|
};
|
|
14972
|
-
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}` : "";
|
|
14973
15277
|
var propertySignatureTypes = (members) => {
|
|
14974
15278
|
const types = /* @__PURE__ */ new Map();
|
|
14975
15279
|
for (const member of members) {
|
|
14976
|
-
if (member.type !==
|
|
14977
|
-
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;
|
|
14978
15282
|
const reference = readTypeReference(member.typeAnnotation?.typeAnnotation);
|
|
14979
15283
|
if (reference === null) continue;
|
|
14980
15284
|
types.set(member.key.name, reference);
|
|
@@ -14985,18 +15289,18 @@ var fileTypeIndex = (program) => {
|
|
|
14985
15289
|
const objects = /* @__PURE__ */ new Map();
|
|
14986
15290
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
14987
15291
|
for (const statement of program.body) {
|
|
14988
|
-
const declaration = statement.type ===
|
|
14989
|
-
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) {
|
|
14990
15294
|
objects.set(declaration.id.name, propertySignatureTypes(declaration.body.body));
|
|
14991
15295
|
continue;
|
|
14992
15296
|
}
|
|
14993
|
-
if (declaration?.type !==
|
|
15297
|
+
if (declaration?.type !== import_utils83.AST_NODE_TYPES.TSTypeAliasDeclaration) continue;
|
|
14994
15298
|
const aliased = declaration.typeAnnotation;
|
|
14995
|
-
if (aliased.type ===
|
|
15299
|
+
if (aliased.type === import_utils83.AST_NODE_TYPES.TSFunctionType || aliased.type === import_utils83.AST_NODE_TYPES.TSConstructorType) {
|
|
14996
15300
|
functionAliases.add(declaration.id.name);
|
|
14997
15301
|
continue;
|
|
14998
15302
|
}
|
|
14999
|
-
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) : [];
|
|
15000
15304
|
if (literals.length === 0) continue;
|
|
15001
15305
|
const merged = /* @__PURE__ */ new Map();
|
|
15002
15306
|
for (const literal of literals) {
|
|
@@ -15025,10 +15329,10 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15025
15329
|
while (pending.length > 0) {
|
|
15026
15330
|
const current = pending.pop();
|
|
15027
15331
|
if (current === void 0) break;
|
|
15028
|
-
if (current.type ===
|
|
15029
|
-
const expression = current.type ===
|
|
15030
|
-
const storedField = expression?.type ===
|
|
15031
|
-
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) {
|
|
15032
15336
|
for (const key of Object.keys(current)) {
|
|
15033
15337
|
if (key === "parent") continue;
|
|
15034
15338
|
const value = current[key];
|
|
@@ -15041,14 +15345,14 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15041
15345
|
continue;
|
|
15042
15346
|
}
|
|
15043
15347
|
let source = expression.right;
|
|
15044
|
-
while (source.type ===
|
|
15045
|
-
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) {
|
|
15046
15350
|
constructedFields += 1;
|
|
15047
|
-
} else if (source.type ===
|
|
15351
|
+
} else if (source.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15048
15352
|
const fields = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
|
|
15049
15353
|
fields.add(storedField);
|
|
15050
15354
|
storedFieldsFrom.set(source.name, fields);
|
|
15051
|
-
} else if (source.type ===
|
|
15355
|
+
} else if (source.type === import_utils83.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15052
15356
|
const fields = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
|
|
15053
15357
|
fields.add(storedField);
|
|
15054
15358
|
storedFieldsFrom.set(source.object.name, fields);
|
|
@@ -15066,7 +15370,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15066
15370
|
const collaborators = [];
|
|
15067
15371
|
for (const parameter of ctor.value.params) {
|
|
15068
15372
|
for (const reference of parameterCollaborators(parameter, declared, storedMemberFieldsFrom)) {
|
|
15069
|
-
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) ?? []];
|
|
15070
15374
|
if (fields.length === 0) continue;
|
|
15071
15375
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
15072
15376
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -15081,8 +15385,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
15081
15385
|
};
|
|
15082
15386
|
var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
15083
15387
|
let target = parameter;
|
|
15084
|
-
if (target.type ===
|
|
15085
|
-
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) {
|
|
15086
15390
|
return objectPatternCollaborators(target, declared);
|
|
15087
15391
|
}
|
|
15088
15392
|
const named2 = namedParameterCollaborator(parameter);
|
|
@@ -15091,9 +15395,9 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
|
15091
15395
|
};
|
|
15092
15396
|
var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
15093
15397
|
let target = annotated;
|
|
15094
|
-
if (target.type ===
|
|
15095
|
-
if (target.type ===
|
|
15096
|
-
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 [];
|
|
15097
15401
|
const members = bagMemberTypes(target.typeAnnotation?.typeAnnotation, declared);
|
|
15098
15402
|
if (members === null) return [];
|
|
15099
15403
|
const storedMembers = storedMemberFieldsFrom.get(target.name);
|
|
@@ -15109,9 +15413,9 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
|
15109
15413
|
};
|
|
15110
15414
|
var namedParameterCollaborator = (annotated) => {
|
|
15111
15415
|
let target = annotated;
|
|
15112
|
-
if (target.type ===
|
|
15113
|
-
if (target.type ===
|
|
15114
|
-
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;
|
|
15115
15419
|
const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
|
|
15116
15420
|
if (reference === null) return null;
|
|
15117
15421
|
return { name: target.name, ...reference, fields: [] };
|
|
@@ -15123,11 +15427,11 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
15123
15427
|
if (members === null) return [];
|
|
15124
15428
|
const collaborators = [];
|
|
15125
15429
|
for (const property of pattern.properties) {
|
|
15126
|
-
if (property.type !==
|
|
15127
|
-
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;
|
|
15128
15432
|
const key = property.key.name;
|
|
15129
|
-
const bound = property.value.type ===
|
|
15130
|
-
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;
|
|
15131
15435
|
if (CONFIGISH_NAME_RE.test(key)) continue;
|
|
15132
15436
|
const reference = members.get(key);
|
|
15133
15437
|
if (reference === void 0) continue;
|
|
@@ -15137,21 +15441,21 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
15137
15441
|
};
|
|
15138
15442
|
var bagMemberTypes = (annotation, declared) => {
|
|
15139
15443
|
if (annotation === void 0) return null;
|
|
15140
|
-
if (annotation.type ===
|
|
15444
|
+
if (annotation.type === import_utils83.AST_NODE_TYPES.TSTypeLiteral) {
|
|
15141
15445
|
return propertySignatureTypes(annotation.members);
|
|
15142
15446
|
}
|
|
15143
|
-
if (annotation.type !==
|
|
15447
|
+
if (annotation.type !== import_utils83.AST_NODE_TYPES.TSTypeReference || annotation.typeName.type !== import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15144
15448
|
return null;
|
|
15145
15449
|
}
|
|
15146
15450
|
return declared().objects.get(annotation.typeName.name) ?? null;
|
|
15147
15451
|
};
|
|
15148
15452
|
var isFrameworkWiring = (body2) => subtreeHas(body2, (node) => {
|
|
15149
|
-
if (node.type ===
|
|
15453
|
+
if (node.type === import_utils83.AST_NODE_TYPES.CallExpression) {
|
|
15150
15454
|
const { callee } = node;
|
|
15151
|
-
if (callee.type ===
|
|
15152
|
-
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;
|
|
15153
15457
|
}
|
|
15154
|
-
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);
|
|
15155
15459
|
});
|
|
15156
15460
|
var subtreeHas = (root, found) => {
|
|
15157
15461
|
let hit = false;
|
|
@@ -15178,19 +15482,19 @@ var invokedInstanceField = (call) => {
|
|
|
15178
15482
|
const direct = instanceField(call.callee);
|
|
15179
15483
|
if (direct !== null) return direct;
|
|
15180
15484
|
let callee = call.callee;
|
|
15181
|
-
while (callee.type ===
|
|
15182
|
-
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;
|
|
15183
15487
|
};
|
|
15184
15488
|
var instanceField = (candidate2) => {
|
|
15185
15489
|
let node = candidate2;
|
|
15186
|
-
while (node.type ===
|
|
15187
|
-
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;
|
|
15188
15492
|
};
|
|
15189
15493
|
var behaviorallyInvokedFields = (body2) => {
|
|
15190
15494
|
const invoked = /* @__PURE__ */ new Set();
|
|
15191
15495
|
const visit = (current) => {
|
|
15192
|
-
if (current.type ===
|
|
15193
|
-
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) {
|
|
15194
15498
|
const field = invokedInstanceField(current);
|
|
15195
15499
|
if (field !== null) invoked.add(field);
|
|
15196
15500
|
}
|
|
@@ -15203,14 +15507,14 @@ var behaviorallyInvokedFields = (body2) => {
|
|
|
15203
15507
|
}
|
|
15204
15508
|
};
|
|
15205
15509
|
for (const member of body2.body) {
|
|
15206
|
-
if (member.type ===
|
|
15207
|
-
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) {
|
|
15208
15512
|
if (member.value.body !== null && member.value.body !== void 0) visit(member.value.body);
|
|
15209
15513
|
continue;
|
|
15210
15514
|
}
|
|
15211
|
-
if (member.type !==
|
|
15515
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.PropertyDefinition || member.value === null) continue;
|
|
15212
15516
|
visit(
|
|
15213
|
-
member.value.type ===
|
|
15517
|
+
member.value.type === import_utils83.AST_NODE_TYPES.ArrowFunctionExpression ? member.value.body : member.value
|
|
15214
15518
|
);
|
|
15215
15519
|
}
|
|
15216
15520
|
return invoked;
|
|
@@ -15230,25 +15534,26 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
15230
15534
|
var fileInterfaceNames = (program) => {
|
|
15231
15535
|
const names = [];
|
|
15232
15536
|
for (const statement of program.body) {
|
|
15233
|
-
const declaration = statement.type ===
|
|
15234
|
-
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);
|
|
15235
15539
|
}
|
|
15236
15540
|
return names;
|
|
15237
15541
|
};
|
|
15238
15542
|
var publicMethodNames = (body2, functionAliases) => {
|
|
15239
15543
|
const names = [];
|
|
15240
15544
|
for (const member of body2.body) {
|
|
15241
|
-
if (member.type ===
|
|
15545
|
+
if (member.type === import_utils83.AST_NODE_TYPES.PropertyDefinition) {
|
|
15242
15546
|
if (member.static || member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15243
|
-
if (member.
|
|
15244
|
-
|
|
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");
|
|
15245
15550
|
continue;
|
|
15246
15551
|
}
|
|
15247
|
-
if (member.type !==
|
|
15552
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.MethodDefinition) continue;
|
|
15248
15553
|
if (member.kind !== "method" || member.static) continue;
|
|
15249
15554
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
15250
|
-
if (member.key.type ===
|
|
15251
|
-
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);
|
|
15252
15557
|
else names.push("\u2026");
|
|
15253
15558
|
}
|
|
15254
15559
|
return names;
|
|
@@ -15256,13 +15561,13 @@ var publicMethodNames = (body2, functionAliases) => {
|
|
|
15256
15561
|
var isFluentConstructionObject = (node, getText) => {
|
|
15257
15562
|
if (node.id === null) return false;
|
|
15258
15563
|
const methods = node.body.body.filter(
|
|
15259
|
-
(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
|
|
15260
15565
|
);
|
|
15261
15566
|
if (methods.length === 0) return false;
|
|
15262
15567
|
return methods.every((member) => {
|
|
15263
15568
|
const result = member.value.returnType?.typeAnnotation;
|
|
15264
15569
|
if (result === void 0) return false;
|
|
15265
|
-
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;
|
|
15266
15571
|
return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
|
|
15267
15572
|
});
|
|
15268
15573
|
};
|
|
@@ -15270,10 +15575,10 @@ function localClassAbstractness(program) {
|
|
|
15270
15575
|
const classes = /* @__PURE__ */ new Map();
|
|
15271
15576
|
const parents = /* @__PURE__ */ new Map();
|
|
15272
15577
|
for (const statement of program.body) {
|
|
15273
|
-
const declaration = statement.type ===
|
|
15274
|
-
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) {
|
|
15275
15580
|
classes.set(declaration.id.name, declaration.abstract === true);
|
|
15276
|
-
if (declaration.superClass?.type ===
|
|
15581
|
+
if (declaration.superClass?.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15277
15582
|
parents.set(declaration.id.name, declaration.superClass.name);
|
|
15278
15583
|
}
|
|
15279
15584
|
}
|
|
@@ -15295,43 +15600,43 @@ function localInterfaceSurfaces(program) {
|
|
|
15295
15600
|
const parents = /* @__PURE__ */ new Map();
|
|
15296
15601
|
const functionAliases = /* @__PURE__ */ new Set();
|
|
15297
15602
|
for (const statement of program.body) {
|
|
15298
|
-
const declaration = statement.type ===
|
|
15299
|
-
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);
|
|
15300
15605
|
}
|
|
15301
15606
|
for (const statement of program.body) {
|
|
15302
|
-
const declaration = statement.type ===
|
|
15303
|
-
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) {
|
|
15304
15609
|
const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15305
|
-
const parts = declaration.typeAnnotation.type ===
|
|
15610
|
+
const parts = declaration.typeAnnotation.type === import_utils83.AST_NODE_TYPES.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
|
|
15306
15611
|
const inherited = parents.get(declaration.id.name) ?? [];
|
|
15307
15612
|
for (const part of parts) {
|
|
15308
|
-
if (part.type ===
|
|
15613
|
+
if (part.type === import_utils83.AST_NODE_TYPES.TSTypeReference && part.typeName.type === import_utils83.AST_NODE_TYPES.Identifier) {
|
|
15309
15614
|
inherited.push(part.typeName.name);
|
|
15310
15615
|
continue;
|
|
15311
15616
|
}
|
|
15312
|
-
if (part.type !==
|
|
15617
|
+
if (part.type !== import_utils83.AST_NODE_TYPES.TSTypeLiteral) continue;
|
|
15313
15618
|
for (const member of part.members) {
|
|
15314
|
-
if (member.type !==
|
|
15315
|
-
if (member.computed || member.key.type !==
|
|
15316
|
-
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) {
|
|
15317
15622
|
callables2.add(member.key.name);
|
|
15318
15623
|
continue;
|
|
15319
15624
|
}
|
|
15320
|
-
if (member.type !==
|
|
15625
|
+
if (member.type !== import_utils83.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
15321
15626
|
const annotation = member.typeAnnotation?.typeAnnotation;
|
|
15322
|
-
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);
|
|
15323
15628
|
}
|
|
15324
15629
|
}
|
|
15325
15630
|
interfaces.set(declaration.id.name, callables2);
|
|
15326
15631
|
parents.set(declaration.id.name, inherited);
|
|
15327
15632
|
continue;
|
|
15328
15633
|
}
|
|
15329
|
-
if (declaration?.type !==
|
|
15634
|
+
if (declaration?.type !== import_utils83.AST_NODE_TYPES.TSInterfaceDeclaration) continue;
|
|
15330
15635
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
15331
15636
|
for (const member of declaration.body.body) {
|
|
15332
|
-
if (member.type !==
|
|
15333
|
-
if (member.computed || member.key.type !==
|
|
15334
|
-
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);
|
|
15335
15640
|
}
|
|
15336
15641
|
interfaces.set(declaration.id.name, callables);
|
|
15337
15642
|
parents.set(
|
|
@@ -15339,7 +15644,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15339
15644
|
[
|
|
15340
15645
|
...parents.get(declaration.id.name) ?? [],
|
|
15341
15646
|
...declaration.extends.flatMap(
|
|
15342
|
-
(heritage) => heritage.expression.type ===
|
|
15647
|
+
(heritage) => heritage.expression.type === import_utils83.AST_NODE_TYPES.Identifier ? [heritage.expression.name] : ["*"]
|
|
15343
15648
|
)
|
|
15344
15649
|
]
|
|
15345
15650
|
);
|
|
@@ -15366,7 +15671,7 @@ function localInterfaceSurfaces(program) {
|
|
|
15366
15671
|
}
|
|
15367
15672
|
function hasServicePort(node, methods, classes, interfaces) {
|
|
15368
15673
|
if (node.superClass !== null) {
|
|
15369
|
-
if (node.superClass.type !==
|
|
15674
|
+
if (node.superClass.type !== import_utils83.AST_NODE_TYPES.Identifier) return true;
|
|
15370
15675
|
const localAbstract = classes.get(node.superClass.name);
|
|
15371
15676
|
if (localAbstract === void 0 || localAbstract) return true;
|
|
15372
15677
|
}
|
|
@@ -15378,7 +15683,7 @@ function hasServicePort(node, methods, classes, interfaces) {
|
|
|
15378
15683
|
if (node.implements.length === 0) return false;
|
|
15379
15684
|
const combined = /* @__PURE__ */ new Set();
|
|
15380
15685
|
for (const implementation of node.implements) {
|
|
15381
|
-
if (implementation.expression.type !==
|
|
15686
|
+
if (implementation.expression.type !== import_utils83.AST_NODE_TYPES.Identifier) return true;
|
|
15382
15687
|
const name = implementation.expression.name;
|
|
15383
15688
|
const localAbstract = classes.get(name);
|
|
15384
15689
|
if (localAbstract === true) return true;
|
|
@@ -15421,7 +15726,7 @@ var require_port_for_service_default = createRule({
|
|
|
15421
15726
|
if (node.abstract === true) return;
|
|
15422
15727
|
if (node.decorators.length > 0) return;
|
|
15423
15728
|
const ctor = node.body.body.find(
|
|
15424
|
-
(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
|
|
15425
15730
|
);
|
|
15426
15731
|
if (ctor === void 0) return;
|
|
15427
15732
|
const constructorFacts = readConstructor(
|
|
@@ -15455,8 +15760,120 @@ var require_port_for_service_default = createRule({
|
|
|
15455
15760
|
}
|
|
15456
15761
|
});
|
|
15457
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
|
+
|
|
15458
15875
|
// src/rules/require-static-next-matcher.ts
|
|
15459
|
-
var
|
|
15876
|
+
var import_utils85 = require("@typescript-eslint/utils");
|
|
15460
15877
|
var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
15461
15878
|
summary: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
|
|
15462
15879
|
rationale: "Next.js must statically analyze matcher values at build time; computed values are ignored.",
|
|
@@ -15469,34 +15886,34 @@ var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
|
15469
15886
|
};
|
|
15470
15887
|
var NEXT_ENTRY_FILE = /(?:^|[/\\])(?:middleware|proxy)\.[cm]?[jt]sx?$/u;
|
|
15471
15888
|
function unwrapExpression3(node) {
|
|
15472
|
-
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) {
|
|
15473
15890
|
return unwrapExpression3(node.expression);
|
|
15474
15891
|
}
|
|
15475
15892
|
return node;
|
|
15476
15893
|
}
|
|
15477
15894
|
function isStaticValue(node) {
|
|
15478
15895
|
const value = unwrapExpression3(node);
|
|
15479
|
-
if (value.type ===
|
|
15896
|
+
if (value.type === import_utils85.AST_NODE_TYPES.Literal) {
|
|
15480
15897
|
return true;
|
|
15481
15898
|
}
|
|
15482
|
-
if (value.type ===
|
|
15899
|
+
if (value.type === import_utils85.AST_NODE_TYPES.TemplateLiteral) {
|
|
15483
15900
|
return value.expressions.length === 0;
|
|
15484
15901
|
}
|
|
15485
|
-
if (value.type ===
|
|
15902
|
+
if (value.type === import_utils85.AST_NODE_TYPES.ArrayExpression) {
|
|
15486
15903
|
return value.elements.every(
|
|
15487
|
-
(element) => element !== null && element.type !==
|
|
15904
|
+
(element) => element !== null && element.type !== import_utils85.AST_NODE_TYPES.SpreadElement && isStaticValue(element)
|
|
15488
15905
|
);
|
|
15489
15906
|
}
|
|
15490
|
-
if (value.type ===
|
|
15907
|
+
if (value.type === import_utils85.AST_NODE_TYPES.ObjectExpression) {
|
|
15491
15908
|
return value.properties.every(
|
|
15492
|
-
(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)
|
|
15493
15910
|
);
|
|
15494
15911
|
}
|
|
15495
15912
|
return false;
|
|
15496
15913
|
}
|
|
15497
15914
|
function propertyName4(property) {
|
|
15498
15915
|
if (property.computed) return null;
|
|
15499
|
-
if (property.key.type ===
|
|
15916
|
+
if (property.key.type === import_utils85.AST_NODE_TYPES.Identifier) return property.key.name;
|
|
15500
15917
|
return typeof property.key.value === "string" ? property.key.value : null;
|
|
15501
15918
|
}
|
|
15502
15919
|
var require_static_next_matcher_default = createRule({
|
|
@@ -15519,19 +15936,19 @@ var require_static_next_matcher_default = createRule({
|
|
|
15519
15936
|
}
|
|
15520
15937
|
return {
|
|
15521
15938
|
ExportNamedDeclaration(node) {
|
|
15522
|
-
if (node.declaration?.type !==
|
|
15939
|
+
if (node.declaration?.type !== import_utils85.AST_NODE_TYPES.VariableDeclaration) {
|
|
15523
15940
|
return;
|
|
15524
15941
|
}
|
|
15525
15942
|
for (const declaration of node.declaration.declarations) {
|
|
15526
|
-
if (declaration.id.type !==
|
|
15943
|
+
if (declaration.id.type !== import_utils85.AST_NODE_TYPES.Identifier || declaration.id.name !== "config" || declaration.init === null) {
|
|
15527
15944
|
continue;
|
|
15528
15945
|
}
|
|
15529
15946
|
const config = unwrapExpression3(declaration.init);
|
|
15530
|
-
if (config.type !==
|
|
15947
|
+
if (config.type !== import_utils85.AST_NODE_TYPES.ObjectExpression) {
|
|
15531
15948
|
continue;
|
|
15532
15949
|
}
|
|
15533
15950
|
for (const property of config.properties) {
|
|
15534
|
-
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) {
|
|
15535
15952
|
continue;
|
|
15536
15953
|
}
|
|
15537
15954
|
if (!isStaticValue(property.value)) {
|
|
@@ -15545,7 +15962,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
15545
15962
|
});
|
|
15546
15963
|
|
|
15547
15964
|
// src/rules/require-use-form-default-values.ts
|
|
15548
|
-
var
|
|
15965
|
+
var import_utils86 = require("@typescript-eslint/utils");
|
|
15549
15966
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
15550
15967
|
summary: "react-hook-form useForm call without defaultValues",
|
|
15551
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.",
|
|
@@ -15599,13 +16016,13 @@ var require_use_form_default_values_default = createRule({
|
|
|
15599
16016
|
if (node.source.value !== "react-hook-form") return;
|
|
15600
16017
|
for (const specifier of node.specifiers) {
|
|
15601
16018
|
if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
|
|
15602
|
-
const variable =
|
|
16019
|
+
const variable = import_utils86.ASTUtils.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
15603
16020
|
if (variable) importedHooks.add(variable);
|
|
15604
16021
|
}
|
|
15605
16022
|
},
|
|
15606
16023
|
CallExpression(node) {
|
|
15607
16024
|
if (node.callee.type !== "Identifier") return;
|
|
15608
|
-
const variable =
|
|
16025
|
+
const variable = import_utils86.ASTUtils.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
|
|
15609
16026
|
const options = node.arguments[0];
|
|
15610
16027
|
if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
|
|
15611
16028
|
context.report({ node, messageId: "requireUseFormDefaultValues" });
|
|
@@ -15615,7 +16032,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
15615
16032
|
});
|
|
15616
16033
|
|
|
15617
16034
|
// src/rules/require-use-server-in-actions-file.ts
|
|
15618
|
-
var
|
|
16035
|
+
var import_utils87 = require("@typescript-eslint/utils");
|
|
15619
16036
|
var ACTION_MODULE_RE = /(?:^|\/)app\/.*\/(?:actions|[^/]+-actions)\.[cm]?[jt]s$/u;
|
|
15620
16037
|
var REQUIRE_USE_SERVER_IN_ACTIONS_FILE_DOCUMENTATION = {
|
|
15621
16038
|
summary: "route action module missing the use server directive",
|
|
@@ -15681,7 +16098,7 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
15681
16098
|
});
|
|
15682
16099
|
|
|
15683
16100
|
// src/rules/require-zod-form-validation.ts
|
|
15684
|
-
var
|
|
16101
|
+
var import_utils88 = require("@typescript-eslint/utils");
|
|
15685
16102
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
15686
16103
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
15687
16104
|
rationale: "FormData values are untrusted strings or files and need runtime validation before use.",
|
|
@@ -15706,14 +16123,14 @@ var FORM_VALUE_METHODS = /* @__PURE__ */ new Set(["get", "getAll"]);
|
|
|
15706
16123
|
var zodReceiverRoot = (node) => {
|
|
15707
16124
|
let current = node;
|
|
15708
16125
|
while (true) {
|
|
15709
|
-
if (current.type ===
|
|
16126
|
+
if (current.type === import_utils88.AST_NODE_TYPES.Identifier) {
|
|
15710
16127
|
return current;
|
|
15711
16128
|
}
|
|
15712
|
-
if (current.type ===
|
|
16129
|
+
if (current.type === import_utils88.AST_NODE_TYPES.CallExpression) {
|
|
15713
16130
|
current = current.callee;
|
|
15714
16131
|
continue;
|
|
15715
16132
|
}
|
|
15716
|
-
if (current.type ===
|
|
16133
|
+
if (current.type === import_utils88.AST_NODE_TYPES.MemberExpression) {
|
|
15717
16134
|
current = current.object;
|
|
15718
16135
|
continue;
|
|
15719
16136
|
}
|
|
@@ -15722,12 +16139,12 @@ var zodReceiverRoot = (node) => {
|
|
|
15722
16139
|
};
|
|
15723
16140
|
var isFormDataMethodCall = (node) => {
|
|
15724
16141
|
let current = node;
|
|
15725
|
-
if (current.type ===
|
|
16142
|
+
if (current.type === import_utils88.AST_NODE_TYPES.AwaitExpression) {
|
|
15726
16143
|
current = current.argument;
|
|
15727
16144
|
}
|
|
15728
|
-
if (current.type !==
|
|
16145
|
+
if (current.type !== import_utils88.AST_NODE_TYPES.CallExpression) return false;
|
|
15729
16146
|
const callee = current.callee;
|
|
15730
|
-
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";
|
|
15731
16148
|
};
|
|
15732
16149
|
var require_zod_form_validation_default = createRule({
|
|
15733
16150
|
name: "require-zod-form-validation",
|
|
@@ -15748,7 +16165,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15748
16165
|
return {};
|
|
15749
16166
|
}
|
|
15750
16167
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
15751
|
-
const resolvedBinding = (identifier) =>
|
|
16168
|
+
const resolvedBinding = (identifier) => import_utils88.ASTUtils.findVariable(
|
|
15752
16169
|
context.sourceCode.getScope(identifier),
|
|
15753
16170
|
identifier.name
|
|
15754
16171
|
);
|
|
@@ -15758,16 +16175,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15758
16175
|
return false;
|
|
15759
16176
|
}
|
|
15760
16177
|
const definition = binding.defs[0];
|
|
15761
|
-
if (definition?.type !== "Variable" || definition.node.type !==
|
|
16178
|
+
if (definition?.type !== "Variable" || definition.node.type !== import_utils88.AST_NODE_TYPES.VariableDeclarator) {
|
|
15762
16179
|
return false;
|
|
15763
16180
|
}
|
|
15764
16181
|
const init = definition.node.init;
|
|
15765
|
-
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;
|
|
15766
16183
|
};
|
|
15767
16184
|
const isZodParseCall = (node) => {
|
|
15768
|
-
if (node.type !==
|
|
16185
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.CallExpression) return false;
|
|
15769
16186
|
const callee = node.callee;
|
|
15770
|
-
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)) {
|
|
15771
16188
|
return false;
|
|
15772
16189
|
}
|
|
15773
16190
|
const root = zodReceiverRoot(callee.object);
|
|
@@ -15776,14 +16193,14 @@ var require_zod_form_validation_default = createRule({
|
|
|
15776
16193
|
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
15777
16194
|
};
|
|
15778
16195
|
const isFormSourceIdentifier = (node) => {
|
|
15779
|
-
if (node.type !==
|
|
16196
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.Identifier) return false;
|
|
15780
16197
|
const conventionalName = /formdata/i.test(node.name);
|
|
15781
16198
|
let scope = context.sourceCode.getScope(node);
|
|
15782
16199
|
while (scope !== null) {
|
|
15783
16200
|
const variable = scope.set.get(node.name);
|
|
15784
16201
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
15785
16202
|
const def = variable.defs[0];
|
|
15786
|
-
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) {
|
|
15787
16204
|
return isFormDataMethodCall(def.node.init);
|
|
15788
16205
|
}
|
|
15789
16206
|
return def?.type === "Parameter" && conventionalName;
|
|
@@ -15794,8 +16211,8 @@ var require_zod_form_validation_default = createRule({
|
|
|
15794
16211
|
};
|
|
15795
16212
|
const isFormDataGetCall = (node) => {
|
|
15796
16213
|
const callee = node.callee;
|
|
15797
|
-
if (callee.type !==
|
|
15798
|
-
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)) {
|
|
15799
16216
|
return false;
|
|
15800
16217
|
}
|
|
15801
16218
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -15811,16 +16228,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15811
16228
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
15812
16229
|
const isInstanceofNarrowing = (node) => {
|
|
15813
16230
|
const parent = node.parent;
|
|
15814
|
-
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");
|
|
15815
16232
|
};
|
|
15816
16233
|
const boundDeclarator = (node) => {
|
|
15817
16234
|
let current = node;
|
|
15818
16235
|
let parent = current.parent;
|
|
15819
|
-
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) {
|
|
15820
16237
|
current = parent;
|
|
15821
16238
|
parent = current.parent;
|
|
15822
16239
|
}
|
|
15823
|
-
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) {
|
|
15824
16241
|
return parent;
|
|
15825
16242
|
}
|
|
15826
16243
|
return null;
|
|
@@ -15829,7 +16246,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15829
16246
|
let current = node;
|
|
15830
16247
|
while (current.parent !== void 0) {
|
|
15831
16248
|
const parent = current.parent;
|
|
15832
|
-
if (parent.type ===
|
|
16249
|
+
if (parent.type === import_utils88.AST_NODE_TYPES.BlockStatement || parent.type === import_utils88.AST_NODE_TYPES.Program) {
|
|
15833
16250
|
return current;
|
|
15834
16251
|
}
|
|
15835
16252
|
current = parent;
|
|
@@ -15838,12 +16255,12 @@ var require_zod_form_validation_default = createRule({
|
|
|
15838
16255
|
};
|
|
15839
16256
|
const zodParseMethod = (call) => {
|
|
15840
16257
|
const callee = call.callee;
|
|
15841
|
-
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;
|
|
15842
16259
|
};
|
|
15843
16260
|
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
15844
16261
|
let current = node.parent;
|
|
15845
16262
|
while (current !== void 0 && current !== statement) {
|
|
15846
|
-
if (current.type ===
|
|
16263
|
+
if (current.type === import_utils88.AST_NODE_TYPES.LogicalExpression || current.type === import_utils88.AST_NODE_TYPES.ConditionalExpression) {
|
|
15847
16264
|
return true;
|
|
15848
16265
|
}
|
|
15849
16266
|
current = current.parent;
|
|
@@ -15853,7 +16270,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15853
16270
|
const isAwaitedBeforeStatement = (node, statement) => {
|
|
15854
16271
|
let current = node.parent;
|
|
15855
16272
|
while (current !== void 0 && current !== statement) {
|
|
15856
|
-
if (current.type ===
|
|
16273
|
+
if (current.type === import_utils88.AST_NODE_TYPES.AwaitExpression) return true;
|
|
15857
16274
|
current = current.parent;
|
|
15858
16275
|
}
|
|
15859
16276
|
return false;
|
|
@@ -15866,7 +16283,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15866
16283
|
if (declarationStatement === null || validationStatement === null || declarationStatement.parent !== validationStatement.parent || validationStatement.range[0] <= declarationStatement.range[1] || hasConditionalAncestorBeforeStatement(parse2, validationStatement)) {
|
|
15867
16284
|
return null;
|
|
15868
16285
|
}
|
|
15869
|
-
if (validationStatement.type !==
|
|
16286
|
+
if (validationStatement.type !== import_utils88.AST_NODE_TYPES.VariableDeclaration && validationStatement.type !== import_utils88.AST_NODE_TYPES.ExpressionStatement) {
|
|
15870
16287
|
return null;
|
|
15871
16288
|
}
|
|
15872
16289
|
const method = zodParseMethod(parse2);
|
|
@@ -15878,16 +16295,16 @@ var require_zod_form_validation_default = createRule({
|
|
|
15878
16295
|
};
|
|
15879
16296
|
const isSafePrevalidationInspection = (identifier) => {
|
|
15880
16297
|
const parent = identifier.parent;
|
|
15881
|
-
if (parent.type ===
|
|
16298
|
+
if (parent.type === import_utils88.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof") {
|
|
15882
16299
|
return true;
|
|
15883
16300
|
}
|
|
15884
|
-
if (parent.type !==
|
|
16301
|
+
if (parent.type !== import_utils88.AST_NODE_TYPES.BinaryExpression || parent.left !== identifier) {
|
|
15885
16302
|
return false;
|
|
15886
16303
|
}
|
|
15887
16304
|
if (parent.operator === "instanceof") {
|
|
15888
|
-
return parent.right.type ===
|
|
16305
|
+
return parent.right.type === import_utils88.AST_NODE_TYPES.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
|
|
15889
16306
|
}
|
|
15890
|
-
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");
|
|
15891
16308
|
};
|
|
15892
16309
|
const isDescendantOf = (node, ancestor) => {
|
|
15893
16310
|
let current = node;
|
|
@@ -15898,23 +16315,23 @@ var require_zod_form_validation_default = createRule({
|
|
|
15898
16315
|
return false;
|
|
15899
16316
|
};
|
|
15900
16317
|
const blockTerminates = (node) => {
|
|
15901
|
-
if (node.type ===
|
|
16318
|
+
if (node.type === import_utils88.AST_NODE_TYPES.ReturnStatement || node.type === import_utils88.AST_NODE_TYPES.ThrowStatement) {
|
|
15902
16319
|
return true;
|
|
15903
16320
|
}
|
|
15904
|
-
if (node.type !==
|
|
16321
|
+
if (node.type !== import_utils88.AST_NODE_TYPES.BlockStatement || node.body.length === 0) return false;
|
|
15905
16322
|
const last = node.body.at(-1);
|
|
15906
16323
|
return last !== void 0 && blockTerminates(last);
|
|
15907
16324
|
};
|
|
15908
16325
|
const narrowingIf = (identifier) => {
|
|
15909
16326
|
const comparison = identifier.parent;
|
|
15910
|
-
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") {
|
|
15911
16328
|
return null;
|
|
15912
16329
|
}
|
|
15913
16330
|
const maybeNegation = comparison.parent;
|
|
15914
|
-
const negated = maybeNegation?.type ===
|
|
16331
|
+
const negated = maybeNegation?.type === import_utils88.AST_NODE_TYPES.UnaryExpression && maybeNegation.operator === "!";
|
|
15915
16332
|
const test = negated ? maybeNegation : comparison;
|
|
15916
16333
|
const branch = test.parent;
|
|
15917
|
-
return branch?.type ===
|
|
16334
|
+
return branch?.type === import_utils88.AST_NODE_TYPES.IfStatement && branch.test === test ? { branch, positive: !negated } : null;
|
|
15918
16335
|
};
|
|
15919
16336
|
const useDominatedByNarrowing = (use, narrowings) => narrowings.some(({ branch, positive }) => {
|
|
15920
16337
|
if (positive) return isDescendantOf(use, branch.consequent);
|
|
@@ -15934,7 +16351,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15934
16351
|
const variable = context.sourceCode.getDeclaredVariables(declarator)[0];
|
|
15935
16352
|
if (variable === void 0) return false;
|
|
15936
16353
|
const references = variable.references.filter((reference) => !reference.isWriteOnly()).map((reference) => reference.identifier).filter(
|
|
15937
|
-
(identifier) => identifier.type ===
|
|
16354
|
+
(identifier) => identifier.type === import_utils88.AST_NODE_TYPES.Identifier
|
|
15938
16355
|
);
|
|
15939
16356
|
if (references.length === 0) return false;
|
|
15940
16357
|
const narrowings = references.map(narrowingIf).filter(
|
|
@@ -15960,7 +16377,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15960
16377
|
ImportDeclaration(node) {
|
|
15961
16378
|
if (!isZodModule(node.source.value)) return;
|
|
15962
16379
|
for (const specifier of node.specifiers) {
|
|
15963
|
-
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")) {
|
|
15964
16381
|
const binding = resolvedBinding(specifier.local);
|
|
15965
16382
|
if (binding !== null) zodBindings.add(binding);
|
|
15966
16383
|
}
|
|
@@ -15981,7 +16398,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15981
16398
|
});
|
|
15982
16399
|
|
|
15983
16400
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
15984
|
-
var
|
|
16401
|
+
var import_utils89 = require("@typescript-eslint/utils");
|
|
15985
16402
|
var STORE_INSERT_REQUIRES_ON_CONFLICT_DOCUMENTATION = {
|
|
15986
16403
|
summary: "Require embedded inserts in explicitly replayable callables to carry conflict handling.",
|
|
15987
16404
|
rationale: "A callable named as an enqueue, seed, migration, schedule, ensure, or upsert promises replay safety.",
|
|
@@ -16045,7 +16462,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
16045
16462
|
});
|
|
16046
16463
|
|
|
16047
16464
|
// src/rules/stepdown.ts
|
|
16048
|
-
var
|
|
16465
|
+
var import_utils90 = require("@typescript-eslint/utils");
|
|
16049
16466
|
var STEPDOWN_DOCUMENTATION = {
|
|
16050
16467
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
16051
16468
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -16065,7 +16482,7 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
16065
16482
|
]
|
|
16066
16483
|
};
|
|
16067
16484
|
function isFunction(node) {
|
|
16068
|
-
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;
|
|
16069
16486
|
}
|
|
16070
16487
|
function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true, makeFix) {
|
|
16071
16488
|
const byName = new Map(scopeDefinitions.map((definition) => [definition.name, definition]));
|
|
@@ -16162,8 +16579,8 @@ function moduleScope(context, program) {
|
|
|
16162
16579
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
16163
16580
|
const overloadNames = new Set(
|
|
16164
16581
|
program.body.flatMap((statement) => {
|
|
16165
|
-
const node = statement.type ===
|
|
16166
|
-
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] : [];
|
|
16167
16584
|
})
|
|
16168
16585
|
);
|
|
16169
16586
|
const exported = exportedNames(program);
|
|
@@ -16187,7 +16604,7 @@ function moduleScope(context, program) {
|
|
|
16187
16604
|
const nearestFunction2 = [...ancestors].reverse().find(isFunction);
|
|
16188
16605
|
const parent = identifier.parent;
|
|
16189
16606
|
const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
|
|
16190
|
-
if (callerDefinition === void 0 || parent.type !==
|
|
16607
|
+
if (callerDefinition === void 0 || parent.type !== import_utils90.AST_NODE_TYPES.CallExpression || parent.callee !== identifier) {
|
|
16191
16608
|
pinned.add(definition.name);
|
|
16192
16609
|
continue;
|
|
16193
16610
|
}
|
|
@@ -16202,38 +16619,38 @@ function moduleScope(context, program) {
|
|
|
16202
16619
|
function exportedNames(program) {
|
|
16203
16620
|
const names = /* @__PURE__ */ new Set();
|
|
16204
16621
|
for (const statement of program.body) {
|
|
16205
|
-
if (statement.type !==
|
|
16206
|
-
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) {
|
|
16207
16624
|
names.add(statement.declaration.id.name);
|
|
16208
16625
|
}
|
|
16209
|
-
if (statement.declaration?.type ===
|
|
16626
|
+
if (statement.declaration?.type === import_utils90.AST_NODE_TYPES.VariableDeclaration) {
|
|
16210
16627
|
for (const declarator of statement.declaration.declarations) {
|
|
16211
|
-
if (declarator.id.type ===
|
|
16628
|
+
if (declarator.id.type === import_utils90.AST_NODE_TYPES.Identifier) names.add(declarator.id.name);
|
|
16212
16629
|
}
|
|
16213
16630
|
}
|
|
16214
16631
|
for (const specifier of statement.specifiers) {
|
|
16215
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
16632
|
+
if (specifier.exportKind !== "type" && specifier.local.type === import_utils90.AST_NODE_TYPES.Identifier) {
|
|
16216
16633
|
names.add(specifier.local.name);
|
|
16217
16634
|
}
|
|
16218
16635
|
}
|
|
16219
16636
|
}
|
|
16220
16637
|
for (const statement of program.body) {
|
|
16221
|
-
if (statement.type ===
|
|
16222
|
-
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);
|
|
16223
16640
|
}
|
|
16224
16641
|
return names;
|
|
16225
16642
|
}
|
|
16226
16643
|
function moduleDefinitions(program) {
|
|
16227
16644
|
const definitions = [];
|
|
16228
16645
|
for (const statement of program.body) {
|
|
16229
|
-
const node = statement.type ===
|
|
16230
|
-
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) {
|
|
16231
16648
|
definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
16232
16649
|
continue;
|
|
16233
16650
|
}
|
|
16234
|
-
if (node?.type !==
|
|
16651
|
+
if (node?.type !== import_utils90.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const") continue;
|
|
16235
16652
|
for (const declarator of node.declarations) {
|
|
16236
|
-
if (declarator.id.type ===
|
|
16653
|
+
if (declarator.id.type === import_utils90.AST_NODE_TYPES.Identifier && declarator.init !== null && isFunction(declarator.init)) {
|
|
16237
16654
|
definitions.push({
|
|
16238
16655
|
name: declarator.id.name,
|
|
16239
16656
|
node: declarator,
|
|
@@ -16246,21 +16663,21 @@ function moduleDefinitions(program) {
|
|
|
16246
16663
|
return definitions;
|
|
16247
16664
|
}
|
|
16248
16665
|
function methodName(node) {
|
|
16249
|
-
if (node.key.type ===
|
|
16250
|
-
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;
|
|
16251
16668
|
}
|
|
16252
16669
|
function referencedMethod(context, node, classVariables) {
|
|
16253
|
-
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;
|
|
16254
16671
|
const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
|
|
16255
|
-
if (node.object.type !==
|
|
16256
|
-
if (node.property.type ===
|
|
16257
|
-
if (!node.computed && node.property.type ===
|
|
16258
|
-
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;
|
|
16259
16676
|
}
|
|
16260
16677
|
function referencedPropertyName(node) {
|
|
16261
|
-
if (node.property.type ===
|
|
16262
|
-
if (!node.computed && node.property.type ===
|
|
16263
|
-
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;
|
|
16264
16681
|
}
|
|
16265
16682
|
function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
16266
16683
|
visit(node, nestedFunction);
|
|
@@ -16276,7 +16693,7 @@ function walk2(node, visitorKeys, visit, nestedFunction = false) {
|
|
|
16276
16693
|
}
|
|
16277
16694
|
function classScope(context, node, computedReferenceNames) {
|
|
16278
16695
|
const methods = node.body.body.filter(
|
|
16279
|
-
(member) => member.type ===
|
|
16696
|
+
(member) => member.type === import_utils90.AST_NODE_TYPES.MethodDefinition
|
|
16280
16697
|
);
|
|
16281
16698
|
const counts = /* @__PURE__ */ new Map();
|
|
16282
16699
|
for (const method of methods) {
|
|
@@ -16284,8 +16701,8 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16284
16701
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16285
16702
|
}
|
|
16286
16703
|
for (const member of node.body.body) {
|
|
16287
|
-
if (member.type !==
|
|
16288
|
-
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;
|
|
16289
16706
|
if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
16290
16707
|
}
|
|
16291
16708
|
const scopeDefinitions = methods.flatMap((method) => {
|
|
@@ -16294,7 +16711,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16294
16711
|
});
|
|
16295
16712
|
const definitions = methods.flatMap((method) => {
|
|
16296
16713
|
const name = methodName(method);
|
|
16297
|
-
const isPrivate = method.accessibility === "private" || method.key.type ===
|
|
16714
|
+
const isPrivate = method.accessibility === "private" || method.key.type === import_utils90.AST_NODE_TYPES.PrivateIdentifier;
|
|
16298
16715
|
return name !== null && isPrivate && counts.get(name) === 1 && method.decorators.length === 0 ? [{ name, node: method }] : [];
|
|
16299
16716
|
});
|
|
16300
16717
|
if (definitions.length === 0) return;
|
|
@@ -16303,11 +16720,11 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16303
16720
|
const pinned = /* @__PURE__ */ new Set();
|
|
16304
16721
|
const classVariables = /* @__PURE__ */ new Set();
|
|
16305
16722
|
if (node.id !== null) {
|
|
16306
|
-
const internal =
|
|
16723
|
+
const internal = import_utils90.ASTUtils.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
16307
16724
|
if (internal !== null) classVariables.add(internal);
|
|
16308
16725
|
}
|
|
16309
|
-
if (node.type ===
|
|
16310
|
-
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);
|
|
16311
16728
|
if (outer !== null) classVariables.add(outer);
|
|
16312
16729
|
}
|
|
16313
16730
|
for (const method of methods) {
|
|
@@ -16323,27 +16740,27 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16323
16740
|
}
|
|
16324
16741
|
const thisValue = (value) => {
|
|
16325
16742
|
let current = value;
|
|
16326
|
-
while (current?.type ===
|
|
16327
|
-
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;
|
|
16328
16745
|
};
|
|
16329
16746
|
const collectAlias = (current, nestedFunction) => {
|
|
16330
|
-
if (nestedFunction || current.type !==
|
|
16331
|
-
if (current.type ===
|
|
16332
|
-
const binding = current.type ===
|
|
16333
|
-
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;
|
|
16334
16751
|
if (!thisValue(value)) return;
|
|
16335
|
-
if (binding.type ===
|
|
16752
|
+
if (binding.type === import_utils90.AST_NODE_TYPES.ObjectPattern) {
|
|
16336
16753
|
for (const property of binding.properties) {
|
|
16337
|
-
if (property.type ===
|
|
16754
|
+
if (property.type === import_utils90.AST_NODE_TYPES.RestElement) {
|
|
16338
16755
|
for (const name of privateNames) pinned.add(name);
|
|
16339
|
-
} else if (property.key.type ===
|
|
16756
|
+
} else if (property.key.type === import_utils90.AST_NODE_TYPES.Identifier && privateNames.has(property.key.name)) {
|
|
16340
16757
|
pinned.add(property.key.name);
|
|
16341
16758
|
}
|
|
16342
16759
|
}
|
|
16343
16760
|
return;
|
|
16344
16761
|
}
|
|
16345
|
-
if (binding.type !==
|
|
16346
|
-
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);
|
|
16347
16764
|
if (variable !== null) {
|
|
16348
16765
|
methodClassVariables.add(variable);
|
|
16349
16766
|
methodAliases.add(variable);
|
|
@@ -16356,16 +16773,16 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16356
16773
|
walk2(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
16357
16774
|
}
|
|
16358
16775
|
const visitCall = (current, nestedFunction) => {
|
|
16359
|
-
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)) {
|
|
16360
16777
|
for (const property of current.id.properties) {
|
|
16361
|
-
if (property.type ===
|
|
16778
|
+
if (property.type === import_utils90.AST_NODE_TYPES.RestElement) {
|
|
16362
16779
|
for (const name of privateNames) pinned.add(name);
|
|
16363
16780
|
continue;
|
|
16364
16781
|
}
|
|
16365
|
-
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);
|
|
16366
16783
|
}
|
|
16367
16784
|
}
|
|
16368
|
-
if (current.type !==
|
|
16785
|
+
if (current.type !== import_utils90.AST_NODE_TYPES.MemberExpression) return;
|
|
16369
16786
|
const target = referencedMethod(context, current, methodClassVariables);
|
|
16370
16787
|
if (target === null) {
|
|
16371
16788
|
const possibleTarget = referencedPropertyName(current);
|
|
@@ -16373,12 +16790,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16373
16790
|
return;
|
|
16374
16791
|
}
|
|
16375
16792
|
if (!privateNames.has(target)) return;
|
|
16376
|
-
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;
|
|
16377
16794
|
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
16378
16795
|
pinned.add(target);
|
|
16379
16796
|
return;
|
|
16380
16797
|
}
|
|
16381
|
-
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) {
|
|
16382
16799
|
pinned.add(target);
|
|
16383
16800
|
return;
|
|
16384
16801
|
}
|
|
@@ -16398,9 +16815,9 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16398
16815
|
}
|
|
16399
16816
|
}
|
|
16400
16817
|
for (const member of node.body.body) {
|
|
16401
|
-
if (member.type ===
|
|
16818
|
+
if (member.type === import_utils90.AST_NODE_TYPES.MethodDefinition || member.type === import_utils90.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
|
|
16402
16819
|
walk2(member, context.sourceCode.visitorKeys, (current) => {
|
|
16403
|
-
if (current.type !==
|
|
16820
|
+
if (current.type !== import_utils90.AST_NODE_TYPES.MemberExpression) return;
|
|
16404
16821
|
const target = referencedMethod(context, current, classVariables);
|
|
16405
16822
|
const possibleTarget = target ?? referencedPropertyName(current);
|
|
16406
16823
|
if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
|
|
@@ -16452,12 +16869,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
16452
16869
|
}
|
|
16453
16870
|
function isClassRuntimeBarrier(member) {
|
|
16454
16871
|
switch (member.type) {
|
|
16455
|
-
case
|
|
16872
|
+
case import_utils90.AST_NODE_TYPES.StaticBlock:
|
|
16456
16873
|
return true;
|
|
16457
|
-
case
|
|
16458
|
-
case
|
|
16874
|
+
case import_utils90.AST_NODE_TYPES.PropertyDefinition:
|
|
16875
|
+
case import_utils90.AST_NODE_TYPES.AccessorProperty:
|
|
16459
16876
|
return member.static || member.computed || member.decorators.length > 0 || member.value !== null;
|
|
16460
|
-
case
|
|
16877
|
+
case import_utils90.AST_NODE_TYPES.MethodDefinition:
|
|
16461
16878
|
return member.computed || member.decorators.length > 0;
|
|
16462
16879
|
default:
|
|
16463
16880
|
return false;
|
|
@@ -16490,7 +16907,7 @@ var stepdown_default = createRule({
|
|
|
16490
16907
|
moduleScope(context, program);
|
|
16491
16908
|
const computedReferenceNames = /* @__PURE__ */ new Set();
|
|
16492
16909
|
walk2(program, context.sourceCode.visitorKeys, (node) => {
|
|
16493
|
-
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);
|
|
16494
16911
|
});
|
|
16495
16912
|
for (const node of classes) classScope(context, node, computedReferenceNames);
|
|
16496
16913
|
}
|
|
@@ -16499,7 +16916,7 @@ var stepdown_default = createRule({
|
|
|
16499
16916
|
});
|
|
16500
16917
|
|
|
16501
16918
|
// src/rules/source-coupled-test.ts
|
|
16502
|
-
var
|
|
16919
|
+
var import_utils91 = require("@typescript-eslint/utils");
|
|
16503
16920
|
var GENERAL_SOURCE_SUFFIX_RE = /\.(?:bash|sh|ya?ml|jsonc|py|[cm]?[jt]s)$/iu;
|
|
16504
16921
|
var FS_MODULES = /* @__PURE__ */ new Set(["fs", "node:fs", "fs/promises", "node:fs/promises"]);
|
|
16505
16922
|
var FS_READERS = /* @__PURE__ */ new Set(["readFile", "readFileSync"]);
|
|
@@ -16568,28 +16985,28 @@ var SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
|
16568
16985
|
]
|
|
16569
16986
|
};
|
|
16570
16987
|
function staticMemberName7(node) {
|
|
16571
|
-
if (!node.computed && node.property.type ===
|
|
16572
|
-
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;
|
|
16573
16990
|
return null;
|
|
16574
16991
|
}
|
|
16575
|
-
function
|
|
16576
|
-
if (node.type ===
|
|
16577
|
-
if (node.type ===
|
|
16578
|
-
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);
|
|
16579
16996
|
return node;
|
|
16580
16997
|
}
|
|
16581
16998
|
function stringValue(node) {
|
|
16582
|
-
const current =
|
|
16583
|
-
if (current.type ===
|
|
16584
|
-
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;
|
|
16585
17002
|
return null;
|
|
16586
17003
|
}
|
|
16587
17004
|
function importSource(node) {
|
|
16588
17005
|
return typeof node.source.value === "string" ? node.source.value : null;
|
|
16589
17006
|
}
|
|
16590
17007
|
function requireSource(node) {
|
|
16591
|
-
const current =
|
|
16592
|
-
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;
|
|
16593
17010
|
return stringValue(current.arguments[0]);
|
|
16594
17011
|
}
|
|
16595
17012
|
function newScope() {
|
|
@@ -16626,80 +17043,80 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16626
17043
|
return /* @__PURE__ */ new Set();
|
|
16627
17044
|
};
|
|
16628
17045
|
const sourcePath = (node) => {
|
|
16629
|
-
const current =
|
|
17046
|
+
const current = unwrap6(node);
|
|
16630
17047
|
const value = stringValue(current);
|
|
16631
17048
|
if (value !== null) return sourceSuffixRe.test(value);
|
|
16632
|
-
if (current.type ===
|
|
16633
|
-
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 === "+") {
|
|
16634
17051
|
return sourcePath(current.left) || sourcePath(current.right);
|
|
16635
17052
|
}
|
|
16636
|
-
if (current.type ===
|
|
16637
|
-
if (current.type ===
|
|
16638
|
-
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));
|
|
16639
17056
|
}
|
|
16640
|
-
if (current.type ===
|
|
17057
|
+
if (current.type === import_utils91.AST_NODE_TYPES.MemberExpression) return sourcePath(current.object);
|
|
16641
17058
|
return false;
|
|
16642
17059
|
};
|
|
16643
17060
|
const rawRead = (node) => {
|
|
16644
|
-
const current =
|
|
16645
|
-
if (current.type !==
|
|
16646
|
-
const callee =
|
|
16647
|
-
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) {
|
|
16648
17065
|
return visible("fsReaders", callee.name) && sourcePath(current.arguments[0]);
|
|
16649
17066
|
}
|
|
16650
|
-
if (callee.type !==
|
|
17067
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return false;
|
|
16651
17068
|
const name2 = staticMemberName7(callee);
|
|
16652
|
-
const object =
|
|
16653
|
-
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]);
|
|
16654
17071
|
};
|
|
16655
17072
|
const rawOrigins = (node) => {
|
|
16656
|
-
const current =
|
|
16657
|
-
if (current.type ===
|
|
17073
|
+
const current = unwrap6(node);
|
|
17074
|
+
if (current.type === import_utils91.AST_NODE_TYPES.Identifier) return visibleRawOrigins(current.name);
|
|
16658
17075
|
if (rawRead(current)) return /* @__PURE__ */ new Set([`${current.range[0]}:${current.range[1]}`]);
|
|
16659
|
-
if (current.type ===
|
|
16660
|
-
if (current.type ===
|
|
16661
|
-
if (current.type !==
|
|
16662
|
-
const callee =
|
|
16663
|
-
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();
|
|
16664
17081
|
const name2 = staticMemberName7(callee);
|
|
16665
17082
|
return name2 !== null && TEXT_TRANSFORMS.has(name2) ? rawOrigins(callee.object) : /* @__PURE__ */ new Set();
|
|
16666
17083
|
};
|
|
16667
17084
|
const evidenceOrigins = (node) => {
|
|
16668
|
-
const current =
|
|
17085
|
+
const current = unwrap6(node);
|
|
16669
17086
|
const direct = rawOrigins(current);
|
|
16670
17087
|
if (direct.size > 0) return direct;
|
|
16671
|
-
if (current.type ===
|
|
16672
|
-
if (current.type ===
|
|
16673
|
-
if (current.type !==
|
|
16674
|
-
const callee =
|
|
16675
|
-
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();
|
|
16676
17093
|
const name2 = staticMemberName7(callee);
|
|
16677
17094
|
if (name2 !== null && TEXT_PREDICATES.has(name2)) return rawOrigins(callee.object);
|
|
16678
|
-
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)]));
|
|
16679
17096
|
return /* @__PURE__ */ new Set();
|
|
16680
17097
|
};
|
|
16681
17098
|
const rawAssertionOrigins = (node) => {
|
|
16682
|
-
const callee =
|
|
16683
|
-
if (callee.type ===
|
|
16684
|
-
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)]));
|
|
16685
17102
|
}
|
|
16686
|
-
if (callee.type !==
|
|
17103
|
+
if (callee.type !== import_utils91.AST_NODE_TYPES.MemberExpression) return /* @__PURE__ */ new Set();
|
|
16687
17104
|
const matcher = staticMemberName7(callee);
|
|
16688
17105
|
if (matcher === null) return /* @__PURE__ */ new Set();
|
|
16689
|
-
let receiver =
|
|
16690
|
-
while (receiver.type ===
|
|
16691
|
-
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") {
|
|
16692
17109
|
if (!EXPECT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
16693
|
-
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)]));
|
|
16694
17111
|
}
|
|
16695
|
-
if (receiver.type !==
|
|
16696
|
-
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)]));
|
|
16697
17114
|
};
|
|
16698
17115
|
const rawRegexExtractionOrigins = (node) => {
|
|
16699
|
-
const callee =
|
|
16700
|
-
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();
|
|
16701
17118
|
const argument = node.arguments[0];
|
|
16702
|
-
if (argument?.type !==
|
|
17119
|
+
if (argument?.type !== import_utils91.AST_NODE_TYPES.Literal || !(argument.value instanceof RegExp)) return /* @__PURE__ */ new Set();
|
|
16703
17120
|
return rawOrigins(callee.object);
|
|
16704
17121
|
};
|
|
16705
17122
|
const declare = (name2, state) => {
|
|
@@ -16719,16 +17136,16 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16719
17136
|
}
|
|
16720
17137
|
};
|
|
16721
17138
|
const sourceCollection = (node) => {
|
|
16722
|
-
const current =
|
|
16723
|
-
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));
|
|
16724
17141
|
};
|
|
16725
17142
|
const declaredNames2 = (node) => {
|
|
16726
|
-
const current =
|
|
16727
|
-
if (current.type ===
|
|
16728
|
-
if (current.type ===
|
|
16729
|
-
if (current.type ===
|
|
16730
|
-
if (current.type ===
|
|
16731
|
-
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));
|
|
16732
17149
|
return [];
|
|
16733
17150
|
};
|
|
16734
17151
|
const enterFunction = (node) => {
|
|
@@ -16743,8 +17160,8 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16743
17160
|
const source = importSource(node);
|
|
16744
17161
|
if (source === null || !FS_MODULES.has(source)) return;
|
|
16745
17162
|
for (const specifier of node.specifiers) {
|
|
16746
|
-
if (specifier.type ===
|
|
16747
|
-
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);
|
|
16748
17165
|
if (FS_READERS.has(imported)) declare(specifier.local.name, { fsReader: true });
|
|
16749
17166
|
} else {
|
|
16750
17167
|
declare(specifier.local.name, { fsObject: true });
|
|
@@ -16756,29 +17173,29 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16756
17173
|
VariableDeclarator(node) {
|
|
16757
17174
|
if (node.init === null) return;
|
|
16758
17175
|
const required = requireSource(node.init);
|
|
16759
|
-
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) {
|
|
16760
17177
|
declare(node.id.name, { fsObject: true });
|
|
16761
17178
|
return;
|
|
16762
17179
|
}
|
|
16763
|
-
if (node.id.type ===
|
|
17180
|
+
if (node.id.type === import_utils91.AST_NODE_TYPES.ObjectPattern && required !== null && FS_MODULES.has(required)) {
|
|
16764
17181
|
for (const property of node.id.properties) {
|
|
16765
|
-
if (property.type !==
|
|
16766
|
-
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) : "";
|
|
16767
17184
|
if (FS_READERS.has(key)) declare(property.value.name, { fsReader: true });
|
|
16768
17185
|
}
|
|
16769
17186
|
return;
|
|
16770
17187
|
}
|
|
16771
|
-
if (node.id.type !==
|
|
17188
|
+
if (node.id.type !== import_utils91.AST_NODE_TYPES.Identifier) return;
|
|
16772
17189
|
declare(node.id.name, { collection: sourceCollection(node.init), path: sourcePath(node.init), rawOrigins: rawOrigins(node.init) });
|
|
16773
17190
|
},
|
|
16774
17191
|
AssignmentExpression(node) {
|
|
16775
|
-
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) });
|
|
16776
17193
|
},
|
|
16777
17194
|
ForOfStatement(node) {
|
|
16778
|
-
const right =
|
|
16779
|
-
const collection = right.type ===
|
|
16780
|
-
const left = node.left.type ===
|
|
16781
|
-
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 });
|
|
16782
17199
|
},
|
|
16783
17200
|
CallExpression(node) {
|
|
16784
17201
|
const origins = /* @__PURE__ */ new Set([
|
|
@@ -16799,6 +17216,128 @@ var source_coupled_test_default = createSourceCoupledRule(
|
|
|
16799
17216
|
GENERAL_SOURCE_SUFFIX_RE
|
|
16800
17217
|
);
|
|
16801
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
|
+
|
|
16802
17341
|
// src/rules/iac-source-coupled-test.ts
|
|
16803
17342
|
var IAC_SOURCE_SUFFIX_RE = /(?:\.tf\.json|\.tftest\.(?:hcl|json)|\.(?:hcl|tf|tfvars))$/iu;
|
|
16804
17343
|
var IAC_SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
@@ -16838,7 +17377,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
16838
17377
|
);
|
|
16839
17378
|
|
|
16840
17379
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
16841
|
-
var
|
|
17380
|
+
var import_utils93 = require("@typescript-eslint/utils");
|
|
16842
17381
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
16843
17382
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
16844
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.",
|
|
@@ -16970,18 +17509,18 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
|
16970
17509
|
"superRefine",
|
|
16971
17510
|
"transform"
|
|
16972
17511
|
]);
|
|
16973
|
-
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;
|
|
16974
17513
|
var calleeChainRoot = (node) => {
|
|
16975
17514
|
let current = node;
|
|
16976
17515
|
for (; ; ) {
|
|
16977
|
-
if (current.type ===
|
|
17516
|
+
if (current.type === import_utils93.AST_NODE_TYPES.Identifier) {
|
|
16978
17517
|
return current;
|
|
16979
17518
|
}
|
|
16980
|
-
if (current.type ===
|
|
17519
|
+
if (current.type === import_utils93.AST_NODE_TYPES.MemberExpression) {
|
|
16981
17520
|
current = current.object;
|
|
16982
17521
|
continue;
|
|
16983
17522
|
}
|
|
16984
|
-
if (current.type ===
|
|
17523
|
+
if (current.type === import_utils93.AST_NODE_TYPES.CallExpression) {
|
|
16985
17524
|
current = current.callee;
|
|
16986
17525
|
continue;
|
|
16987
17526
|
}
|
|
@@ -16992,13 +17531,13 @@ var chainMemberNames = (node) => {
|
|
|
16992
17531
|
const names = [];
|
|
16993
17532
|
let current = node;
|
|
16994
17533
|
for (; ; ) {
|
|
16995
|
-
if (current.type ===
|
|
16996
|
-
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 [];
|
|
16997
17536
|
names.push(current.property.name);
|
|
16998
17537
|
current = current.object;
|
|
16999
17538
|
continue;
|
|
17000
17539
|
}
|
|
17001
|
-
if (current.type ===
|
|
17540
|
+
if (current.type === import_utils93.AST_NODE_TYPES.CallExpression) {
|
|
17002
17541
|
current = current.callee;
|
|
17003
17542
|
continue;
|
|
17004
17543
|
}
|
|
@@ -17009,16 +17548,16 @@ var chainMemberNames = (node) => {
|
|
|
17009
17548
|
};
|
|
17010
17549
|
var unwrapExpression4 = (node) => {
|
|
17011
17550
|
let current = node;
|
|
17012
|
-
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) {
|
|
17013
17552
|
current = current.expression;
|
|
17014
17553
|
}
|
|
17015
17554
|
return current;
|
|
17016
17555
|
};
|
|
17017
17556
|
var isModuleDeclarator = (node) => {
|
|
17018
17557
|
const declaration = node.parent;
|
|
17019
|
-
if (declaration.type !==
|
|
17558
|
+
if (declaration.type !== import_utils93.AST_NODE_TYPES.VariableDeclaration) return false;
|
|
17020
17559
|
const owner = declaration.parent;
|
|
17021
|
-
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;
|
|
17022
17561
|
};
|
|
17023
17562
|
var require_pascal_case_zod_schema_name_default = createRule({
|
|
17024
17563
|
name: "require-pascal-case-zod-schema-name",
|
|
@@ -17038,7 +17577,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17038
17577
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
17039
17578
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
17040
17579
|
function resolvedBinding(identifier) {
|
|
17041
|
-
return
|
|
17580
|
+
return import_utils93.ASTUtils.findVariable(
|
|
17042
17581
|
context.sourceCode.getScope(identifier),
|
|
17043
17582
|
identifier.name
|
|
17044
17583
|
);
|
|
@@ -17059,8 +17598,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17059
17598
|
}
|
|
17060
17599
|
function isConfirmedSchema(expression) {
|
|
17061
17600
|
const init = unwrapExpression4(expression);
|
|
17062
|
-
if (init.type ===
|
|
17063
|
-
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) {
|
|
17064
17603
|
return false;
|
|
17065
17604
|
}
|
|
17066
17605
|
const terminal = terminalMethodName(init.callee);
|
|
@@ -17080,7 +17619,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17080
17619
|
ImportDeclaration(node) {
|
|
17081
17620
|
if (!isZodModule(node.source.value)) return;
|
|
17082
17621
|
for (const specifier of node.specifiers) {
|
|
17083
|
-
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")) {
|
|
17084
17623
|
recordZodBinding(specifier.local);
|
|
17085
17624
|
}
|
|
17086
17625
|
}
|
|
@@ -17089,7 +17628,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
17089
17628
|
if (!isModuleDeclarator(node)) return;
|
|
17090
17629
|
const init = node.init;
|
|
17091
17630
|
if (init === null || init === void 0) return;
|
|
17092
|
-
if (node.id.type !==
|
|
17631
|
+
if (node.id.type !== import_utils93.AST_NODE_TYPES.Identifier) return;
|
|
17093
17632
|
if (!isConfirmedSchema(init)) return;
|
|
17094
17633
|
const binding = resolvedBinding(node.id);
|
|
17095
17634
|
if (binding !== null) schemaBindings.add(binding);
|
|
@@ -17247,11 +17786,16 @@ var RULES = {
|
|
|
17247
17786
|
"prefer-shadcn-primitives": prefer_shadcn_primitives_default,
|
|
17248
17787
|
"prefer-module-level-constant": prefer_module_level_constant_default,
|
|
17249
17788
|
"prefer-module-level-schema": prefer_module_level_schema_default,
|
|
17789
|
+
"prefer-named-complex-return-type": prefer_named_complex_return_type_default,
|
|
17250
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,
|
|
17251
17793
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
17252
17794
|
"prefer-nullish-filter-predicate": prefer_nullish_filter_predicate_default,
|
|
17253
17795
|
"prefer-await-in-async-return": prefer_await_in_async_return_default,
|
|
17254
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,
|
|
17255
17799
|
"prefer-semantic-colors": prefer_semantic_colors_default,
|
|
17256
17800
|
"prefer-server-actions": prefer_server_actions_default,
|
|
17257
17801
|
"prefer-whole-object-assertion": prefer_whole_object_assertion_default,
|
|
@@ -17260,23 +17804,33 @@ var RULES = {
|
|
|
17260
17804
|
"require-assert-never": require_assert_never_default,
|
|
17261
17805
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
17262
17806
|
"require-port-for-service": require_port_for_service_default,
|
|
17807
|
+
"require-sql-access-class": require_sql_access_class_default,
|
|
17263
17808
|
"require-static-next-matcher": require_static_next_matcher_default,
|
|
17264
17809
|
"require-zod-form-validation": require_zod_form_validation_default,
|
|
17265
17810
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
17266
17811
|
"stepdown": stepdown_default,
|
|
17267
17812
|
"source-coupled-test": source_coupled_test_default,
|
|
17813
|
+
"sole-export-matches-filename": sole_export_matches_filename_default,
|
|
17268
17814
|
"require-pascal-case-zod-schema-name": require_pascal_case_zod_schema_name_default
|
|
17269
17815
|
};
|
|
17270
17816
|
var meta = {
|
|
17271
17817
|
name: "@sarj/eslint-plugin",
|
|
17272
|
-
version: "15.
|
|
17818
|
+
version: "15.15.0"
|
|
17273
17819
|
};
|
|
17274
17820
|
var APPLICATION_ONLY_RULES = [
|
|
17275
17821
|
"no-restricted-library-load",
|
|
17276
17822
|
"prefer-native-random-uuid",
|
|
17277
17823
|
"prefer-shadcn-primitives"
|
|
17278
17824
|
];
|
|
17279
|
-
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
|
+
];
|
|
17280
17834
|
var RECOMMENDED_RULES = {
|
|
17281
17835
|
"@sarj/interface-contract-members-private": "error",
|
|
17282
17836
|
"@sarj/iac-source-coupled-test": "error",
|
|
@@ -17330,10 +17884,15 @@ var RECOMMENDED_RULES = {
|
|
|
17330
17884
|
"@sarj/prefer-immutable-module-constant": "error",
|
|
17331
17885
|
"@sarj/prefer-module-level-constant": "error",
|
|
17332
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",
|
|
17333
17890
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17334
17891
|
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17335
17892
|
"@sarj/prefer-await-in-async-return": "error",
|
|
17336
17893
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
17894
|
+
"@sarj/prefer-shared-zod-enum": "warn",
|
|
17895
|
+
"@sarj/prefer-switch-for-repeated-equality": "warn",
|
|
17337
17896
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
17338
17897
|
"@sarj/prefer-server-actions": "error",
|
|
17339
17898
|
"@sarj/prefer-whole-object-assertion": "error",
|
|
@@ -17342,6 +17901,7 @@ var RECOMMENDED_RULES = {
|
|
|
17342
17901
|
"@sarj/require-assert-never": "error",
|
|
17343
17902
|
"@sarj/require-fetch-timeout": "error",
|
|
17344
17903
|
"@sarj/require-port-for-service": "error",
|
|
17904
|
+
"@sarj/require-sql-access-class": "warn",
|
|
17345
17905
|
"@sarj/require-static-next-matcher": "error",
|
|
17346
17906
|
"@sarj/require-use-form-default-values": "error",
|
|
17347
17907
|
"@sarj/require-use-server-in-actions-file": "error",
|
|
@@ -17349,6 +17909,7 @@ var RECOMMENDED_RULES = {
|
|
|
17349
17909
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
17350
17910
|
"@sarj/stepdown": "error",
|
|
17351
17911
|
"@sarj/source-coupled-test": "error",
|
|
17912
|
+
"@sarj/sole-export-matches-filename": "warn",
|
|
17352
17913
|
"@sarj/test-phase-label-comment": "error",
|
|
17353
17914
|
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17354
17915
|
};
|
|
@@ -17409,10 +17970,15 @@ var STRICT_RULES = {
|
|
|
17409
17970
|
"@sarj/prefer-immutable-module-constant": "error",
|
|
17410
17971
|
"@sarj/prefer-module-level-constant": "error",
|
|
17411
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",
|
|
17412
17976
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
17413
17977
|
"@sarj/prefer-nullish-filter-predicate": "error",
|
|
17414
17978
|
"@sarj/prefer-await-in-async-return": "error",
|
|
17415
17979
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
17980
|
+
"@sarj/prefer-shared-zod-enum": "warn",
|
|
17981
|
+
"@sarj/prefer-switch-for-repeated-equality": "warn",
|
|
17416
17982
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
17417
17983
|
"@sarj/prefer-server-actions": "error",
|
|
17418
17984
|
"@sarj/prefer-whole-object-assertion": "error",
|
|
@@ -17421,6 +17987,7 @@ var STRICT_RULES = {
|
|
|
17421
17987
|
"@sarj/require-assert-never": "error",
|
|
17422
17988
|
"@sarj/require-fetch-timeout": "error",
|
|
17423
17989
|
"@sarj/require-port-for-service": "error",
|
|
17990
|
+
"@sarj/require-sql-access-class": "warn",
|
|
17424
17991
|
"@sarj/require-static-next-matcher": "error",
|
|
17425
17992
|
"@sarj/require-use-form-default-values": "error",
|
|
17426
17993
|
"@sarj/require-use-server-in-actions-file": "error",
|
|
@@ -17428,6 +17995,7 @@ var STRICT_RULES = {
|
|
|
17428
17995
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
17429
17996
|
"@sarj/stepdown": "error",
|
|
17430
17997
|
"@sarj/source-coupled-test": "error",
|
|
17998
|
+
"@sarj/sole-export-matches-filename": "warn",
|
|
17431
17999
|
"@sarj/test-phase-label-comment": "error",
|
|
17432
18000
|
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17433
18001
|
};
|