@sarj/eslint-plugin 16.0.0 → 16.1.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 +479 -386
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +479 -386
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -442,8 +442,8 @@ var prefer_typed_reflection_default = createRule({
|
|
|
442
442
|
const services = ESLintUtils2.getParserServices(context);
|
|
443
443
|
if (!services.program) return {};
|
|
444
444
|
const checker = services.program.getTypeChecker();
|
|
445
|
-
const globalName = (node, name) => node.type === AST_NODE_TYPES2.Identifier && node.name === name && !ASTUtils.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
446
445
|
const isReflect = (node) => globalName(node, "Reflect") || node.type === AST_NODE_TYPES2.MemberExpression && propertyName(node) === "Reflect" && globalName(node.object, "globalThis");
|
|
446
|
+
const globalName = (node, name) => node.type === AST_NODE_TYPES2.Identifier && node.name === name && !ASTUtils.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
447
447
|
const closedObject = (type) => {
|
|
448
448
|
if (type.isUnion()) return type.types.every(closedObject);
|
|
449
449
|
return knownType(type) && type.getProperties().length > 0 && checker.getIndexInfosOfType(type).length === 0;
|
|
@@ -683,6 +683,14 @@ var no_reduce_accumulator_copy_default = createRule({
|
|
|
683
683
|
const accumulator = context.sourceCode.getDeclaredVariables(callback).find((variable) => variable.identifiers.includes(parameter));
|
|
684
684
|
if (!accumulator || accumulator.references.some((reference) => reference.isWrite())) return;
|
|
685
685
|
const referencesAccumulator = (value) => value.type === AST_NODE_TYPES4.Identifier && ASTUtils2.findVariable(context.sourceCode.getScope(value), value.name) === accumulator;
|
|
686
|
+
const inspect = (current) => {
|
|
687
|
+
if (current !== callback.body && [AST_NODE_TYPES4.ArrowFunctionExpression, AST_NODE_TYPES4.FunctionExpression, AST_NODE_TYPES4.FunctionDeclaration].some((kind) => kind === current.type)) return;
|
|
688
|
+
if (current.type === AST_NODE_TYPES4.SpreadElement && (arraySeed && current.parent.type === AST_NODE_TYPES4.ArrayExpression || objectSeed && current.parent.type === AST_NODE_TYPES4.ObjectExpression) && referencesAccumulator(current.argument)) {
|
|
689
|
+
context.report({ node: current, messageId: "copy" });
|
|
690
|
+
}
|
|
691
|
+
if (current.type === AST_NODE_TYPES4.CallExpression) inspectCall(current);
|
|
692
|
+
forEachAstChild(current, context.sourceCode.visitorKeys, inspect);
|
|
693
|
+
};
|
|
686
694
|
const inspectCall = (current) => {
|
|
687
695
|
if (current.callee.type !== AST_NODE_TYPES4.MemberExpression) return;
|
|
688
696
|
const member = current.callee;
|
|
@@ -695,14 +703,6 @@ var no_reduce_accumulator_copy_default = createRule({
|
|
|
695
703
|
const assignCopy = objectSeed && name === "assign" && globalObject && target?.type === AST_NODE_TYPES4.ObjectExpression && current.arguments.slice(1).some(referencesAccumulator);
|
|
696
704
|
if (directCopy || fromCopy || assignCopy) context.report({ node: current, messageId: "copy" });
|
|
697
705
|
};
|
|
698
|
-
const inspect = (current) => {
|
|
699
|
-
if (current !== callback.body && [AST_NODE_TYPES4.ArrowFunctionExpression, AST_NODE_TYPES4.FunctionExpression, AST_NODE_TYPES4.FunctionDeclaration].some((kind) => kind === current.type)) return;
|
|
700
|
-
if (current.type === AST_NODE_TYPES4.SpreadElement && (arraySeed && current.parent.type === AST_NODE_TYPES4.ArrayExpression || objectSeed && current.parent.type === AST_NODE_TYPES4.ObjectExpression) && referencesAccumulator(current.argument)) {
|
|
701
|
-
context.report({ node: current, messageId: "copy" });
|
|
702
|
-
}
|
|
703
|
-
if (current.type === AST_NODE_TYPES4.CallExpression) inspectCall(current);
|
|
704
|
-
forEachAstChild(current, context.sourceCode.visitorKeys, inspect);
|
|
705
|
-
};
|
|
706
706
|
inspect(callback.body);
|
|
707
707
|
}
|
|
708
708
|
};
|
|
@@ -3614,28 +3614,6 @@ var no_cors_wildcard_with_credentials_default = createRule({
|
|
|
3614
3614
|
const scopeHeaderSets = /* @__PURE__ */ new Map();
|
|
3615
3615
|
const variableIds = /* @__PURE__ */ new WeakMap();
|
|
3616
3616
|
let nextVariableId = 0;
|
|
3617
|
-
function variableId(variable) {
|
|
3618
|
-
const existing = variableIds.get(variable);
|
|
3619
|
-
if (existing !== void 0) return existing;
|
|
3620
|
-
const value = nextVariableId++;
|
|
3621
|
-
variableIds.set(variable, value);
|
|
3622
|
-
return value;
|
|
3623
|
-
}
|
|
3624
|
-
function receiverIdentity(node) {
|
|
3625
|
-
if (node.type === AST_NODE_TYPES22.Identifier) {
|
|
3626
|
-
const variable = ASTUtils5.findVariable(
|
|
3627
|
-
context.sourceCode.getScope(node),
|
|
3628
|
-
node.name
|
|
3629
|
-
);
|
|
3630
|
-
return variable === null ? `global:${node.name}` : `variable:${variableId(variable)}`;
|
|
3631
|
-
}
|
|
3632
|
-
if (node.type === AST_NODE_TYPES22.ThisExpression) return "this";
|
|
3633
|
-
if (node.type === AST_NODE_TYPES22.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES22.Identifier) {
|
|
3634
|
-
const owner = receiverIdentity(node.object);
|
|
3635
|
-
return owner === null ? null : `${owner}.${node.property.name}`;
|
|
3636
|
-
}
|
|
3637
|
-
return null;
|
|
3638
|
-
}
|
|
3639
3617
|
function recordHeaderSet(node, kind) {
|
|
3640
3618
|
if (node.callee.type !== AST_NODE_TYPES22.MemberExpression) return;
|
|
3641
3619
|
const receiver = receiverIdentity(node.callee.object);
|
|
@@ -3657,6 +3635,28 @@ var no_cors_wildcard_with_credentials_default = createRule({
|
|
|
3657
3635
|
entry.credentialsNodes.push(node);
|
|
3658
3636
|
}
|
|
3659
3637
|
}
|
|
3638
|
+
function receiverIdentity(node) {
|
|
3639
|
+
if (node.type === AST_NODE_TYPES22.Identifier) {
|
|
3640
|
+
const variable = ASTUtils5.findVariable(
|
|
3641
|
+
context.sourceCode.getScope(node),
|
|
3642
|
+
node.name
|
|
3643
|
+
);
|
|
3644
|
+
return variable === null ? `global:${node.name}` : `variable:${variableId(variable)}`;
|
|
3645
|
+
}
|
|
3646
|
+
if (node.type === AST_NODE_TYPES22.ThisExpression) return "this";
|
|
3647
|
+
if (node.type === AST_NODE_TYPES22.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES22.Identifier) {
|
|
3648
|
+
const owner = receiverIdentity(node.object);
|
|
3649
|
+
return owner === null ? null : `${owner}.${node.property.name}`;
|
|
3650
|
+
}
|
|
3651
|
+
return null;
|
|
3652
|
+
}
|
|
3653
|
+
function variableId(variable) {
|
|
3654
|
+
const existing = variableIds.get(variable);
|
|
3655
|
+
if (existing !== void 0) return existing;
|
|
3656
|
+
const value = nextVariableId++;
|
|
3657
|
+
variableIds.set(variable, value);
|
|
3658
|
+
return value;
|
|
3659
|
+
}
|
|
3660
3660
|
return {
|
|
3661
3661
|
NewExpression(node) {
|
|
3662
3662
|
if (isCorsWildcardCredentialsCall(node)) {
|
|
@@ -4446,20 +4446,6 @@ function functionComplexity(fn, visitorKeys) {
|
|
|
4446
4446
|
function add(node, nesting, construct) {
|
|
4447
4447
|
points.push({ line: node.loc.start.line, amount: nesting + 1, construct });
|
|
4448
4448
|
}
|
|
4449
|
-
function logical(node, nesting) {
|
|
4450
|
-
let previous;
|
|
4451
|
-
function flatten(expression) {
|
|
4452
|
-
if (expression.type !== AST_NODE_TYPES26.LogicalExpression || expression.operator === "??") {
|
|
4453
|
-
visit(expression, nesting);
|
|
4454
|
-
return;
|
|
4455
|
-
}
|
|
4456
|
-
flatten(expression.left);
|
|
4457
|
-
if (previous !== expression.operator) add(expression, 0, expression.operator);
|
|
4458
|
-
previous = expression.operator;
|
|
4459
|
-
flatten(expression.right);
|
|
4460
|
-
}
|
|
4461
|
-
flatten(node);
|
|
4462
|
-
}
|
|
4463
4449
|
function conditional(node, nesting) {
|
|
4464
4450
|
add(node, nesting, "if");
|
|
4465
4451
|
let branch = node;
|
|
@@ -4538,6 +4524,20 @@ function functionComplexity(fn, visitorKeys) {
|
|
|
4538
4524
|
}
|
|
4539
4525
|
visitChildren(node, nesting);
|
|
4540
4526
|
}
|
|
4527
|
+
function logical(node, nesting) {
|
|
4528
|
+
let previous;
|
|
4529
|
+
function flatten(expression) {
|
|
4530
|
+
if (expression.type !== AST_NODE_TYPES26.LogicalExpression || expression.operator === "??") {
|
|
4531
|
+
visit(expression, nesting);
|
|
4532
|
+
return;
|
|
4533
|
+
}
|
|
4534
|
+
flatten(expression.left);
|
|
4535
|
+
if (previous !== expression.operator) add(expression, 0, expression.operator);
|
|
4536
|
+
previous = expression.operator;
|
|
4537
|
+
flatten(expression.right);
|
|
4538
|
+
}
|
|
4539
|
+
flatten(node);
|
|
4540
|
+
}
|
|
4541
4541
|
function visitChildren(node, nesting) {
|
|
4542
4542
|
forEachAstChild(node, visitorKeys, (child) => visit(child, nesting));
|
|
4543
4543
|
}
|
|
@@ -5160,6 +5160,14 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
5160
5160
|
const callee = callback.type === AST_NODE_TYPES28.Identifier ? callback : callback.type === AST_NODE_TYPES28.ArrowFunctionExpression || callback.type === AST_NODE_TYPES28.FunctionExpression ? soleCall(callback)?.callee : null;
|
|
5161
5161
|
return callee?.type === AST_NODE_TYPES28.Identifier && bindingOf(callee) === bindingOf(parameter);
|
|
5162
5162
|
};
|
|
5163
|
+
let clientModule = null;
|
|
5164
|
+
const reportsSleepHere = () => {
|
|
5165
|
+
if (checkClientModules) {
|
|
5166
|
+
return true;
|
|
5167
|
+
}
|
|
5168
|
+
clientModule ??= isClientModule2();
|
|
5169
|
+
return !clientModule;
|
|
5170
|
+
};
|
|
5163
5171
|
function isClientModule2() {
|
|
5164
5172
|
if (/\.[cm]?[jt]sx$/.test(filename)) {
|
|
5165
5173
|
return true;
|
|
@@ -5175,14 +5183,6 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
5175
5183
|
}
|
|
5176
5184
|
return false;
|
|
5177
5185
|
}
|
|
5178
|
-
let clientModule = null;
|
|
5179
|
-
const reportsSleepHere = () => {
|
|
5180
|
-
if (checkClientModules) {
|
|
5181
|
-
return true;
|
|
5182
|
-
}
|
|
5183
|
-
clientModule ??= isClientModule2();
|
|
5184
|
-
return !clientModule;
|
|
5185
|
-
};
|
|
5186
5186
|
return {
|
|
5187
5187
|
NewExpression(node) {
|
|
5188
5188
|
if (node.callee.type !== AST_NODE_TYPES28.Identifier || node.callee.name !== "Promise" || !isGlobal(node.callee)) {
|
|
@@ -5615,13 +5615,6 @@ var no_detached_global_fetch_default = createRule({
|
|
|
5615
5615
|
const variable = bindingOf(identifier);
|
|
5616
5616
|
if (variable !== null && isStableAlias(variable)) aliases.add(variable);
|
|
5617
5617
|
}
|
|
5618
|
-
function isGlobalFetchMember(node) {
|
|
5619
|
-
if (!isGlobalReceiver(node.object)) return false;
|
|
5620
|
-
if (!node.computed) {
|
|
5621
|
-
return node.property.type === AST_NODE_TYPES30.Identifier && node.property.name === "fetch";
|
|
5622
|
-
}
|
|
5623
|
-
return node.property.type === AST_NODE_TYPES30.Literal && node.property.value === "fetch";
|
|
5624
|
-
}
|
|
5625
5618
|
function staticMemberName9(node) {
|
|
5626
5619
|
if (!node.computed) {
|
|
5627
5620
|
return node.property.type === AST_NODE_TYPES30.Identifier ? node.property.name : null;
|
|
@@ -5650,6 +5643,13 @@ var no_detached_global_fetch_default = createRule({
|
|
|
5650
5643
|
}
|
|
5651
5644
|
return false;
|
|
5652
5645
|
}
|
|
5646
|
+
function isGlobalFetchMember(node) {
|
|
5647
|
+
if (!isGlobalReceiver(node.object)) return false;
|
|
5648
|
+
if (!node.computed) {
|
|
5649
|
+
return node.property.type === AST_NODE_TYPES30.Identifier && node.property.name === "fetch";
|
|
5650
|
+
}
|
|
5651
|
+
return node.property.type === AST_NODE_TYPES30.Literal && node.property.value === "fetch";
|
|
5652
|
+
}
|
|
5653
5653
|
function recordAliasFromValue(identifier, value) {
|
|
5654
5654
|
if (mayBeRawFetch(value)) recordAlias(identifier);
|
|
5655
5655
|
}
|
|
@@ -6214,17 +6214,6 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
6214
6214
|
}
|
|
6215
6215
|
return false;
|
|
6216
6216
|
}
|
|
6217
|
-
function baseKind(node) {
|
|
6218
|
-
const callee = node.callee;
|
|
6219
|
-
if (callee.type === AST_NODE_TYPES32.Identifier) {
|
|
6220
|
-
return resolvesToTrackedImport(callee) ? constructors.get(callee.name) ?? null : null;
|
|
6221
|
-
}
|
|
6222
|
-
if (callee.type !== AST_NODE_TYPES32.MemberExpression || callee.object.type !== AST_NODE_TYPES32.Identifier || !namespaces.has(callee.object.name) || !resolvesToTrackedImport(callee.object)) {
|
|
6223
|
-
return null;
|
|
6224
|
-
}
|
|
6225
|
-
const name = memberName(callee);
|
|
6226
|
-
return name !== null && KINDS.has(name) ? name : null;
|
|
6227
|
-
}
|
|
6228
6217
|
function readChain(node) {
|
|
6229
6218
|
const calls = [];
|
|
6230
6219
|
let current = node;
|
|
@@ -6241,6 +6230,17 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
6241
6230
|
current = callee.object;
|
|
6242
6231
|
}
|
|
6243
6232
|
}
|
|
6233
|
+
function baseKind(node) {
|
|
6234
|
+
const callee = node.callee;
|
|
6235
|
+
if (callee.type === AST_NODE_TYPES32.Identifier) {
|
|
6236
|
+
return resolvesToTrackedImport(callee) ? constructors.get(callee.name) ?? null : null;
|
|
6237
|
+
}
|
|
6238
|
+
if (callee.type !== AST_NODE_TYPES32.MemberExpression || callee.object.type !== AST_NODE_TYPES32.Identifier || !namespaces.has(callee.object.name) || !resolvesToTrackedImport(callee.object)) {
|
|
6239
|
+
return null;
|
|
6240
|
+
}
|
|
6241
|
+
const name = memberName(callee);
|
|
6242
|
+
return name !== null && KINDS.has(name) ? name : null;
|
|
6243
|
+
}
|
|
6244
6244
|
function isInsideReshapingCall(node) {
|
|
6245
6245
|
let child = node;
|
|
6246
6246
|
let parent = child.parent;
|
|
@@ -6558,30 +6558,30 @@ var no_redundant_optional_array_default_default = createRule({
|
|
|
6558
6558
|
}
|
|
6559
6559
|
return false;
|
|
6560
6560
|
}
|
|
6561
|
-
function
|
|
6561
|
+
function isArraySchemaExpression(node) {
|
|
6562
6562
|
if (node.type !== AST_NODE_TYPES33.CallExpression) return false;
|
|
6563
6563
|
const { callee } = node;
|
|
6564
6564
|
if (callee.type === AST_NODE_TYPES33.Identifier) {
|
|
6565
|
-
return resolvesToTrackedImport(callee);
|
|
6565
|
+
return arrayConstructors.has(callee.name) && resolvesToTrackedImport(callee);
|
|
6566
6566
|
}
|
|
6567
6567
|
if (callee.type !== AST_NODE_TYPES33.MemberExpression) return false;
|
|
6568
|
-
|
|
6568
|
+
const method = memberName2(callee);
|
|
6569
|
+
if (method === "array" && (callee.object.type === AST_NODE_TYPES33.Identifier ? namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object) : isZodSchemaExpression(callee.object))) {
|
|
6569
6570
|
return true;
|
|
6570
6571
|
}
|
|
6571
|
-
return
|
|
6572
|
+
return isArraySchemaExpression(callee.object);
|
|
6572
6573
|
}
|
|
6573
|
-
function
|
|
6574
|
+
function isZodSchemaExpression(node) {
|
|
6574
6575
|
if (node.type !== AST_NODE_TYPES33.CallExpression) return false;
|
|
6575
6576
|
const { callee } = node;
|
|
6576
6577
|
if (callee.type === AST_NODE_TYPES33.Identifier) {
|
|
6577
|
-
return
|
|
6578
|
+
return resolvesToTrackedImport(callee);
|
|
6578
6579
|
}
|
|
6579
6580
|
if (callee.type !== AST_NODE_TYPES33.MemberExpression) return false;
|
|
6580
|
-
|
|
6581
|
-
if (method === "array" && (callee.object.type === AST_NODE_TYPES33.Identifier ? namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object) : isZodSchemaExpression(callee.object))) {
|
|
6581
|
+
if (callee.object.type === AST_NODE_TYPES33.Identifier && namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object)) {
|
|
6582
6582
|
return true;
|
|
6583
6583
|
}
|
|
6584
|
-
return
|
|
6584
|
+
return isZodSchemaExpression(callee.object);
|
|
6585
6585
|
}
|
|
6586
6586
|
return {
|
|
6587
6587
|
ImportDeclaration(node) {
|
|
@@ -7018,10 +7018,6 @@ var no_log_only_catch_default = createRule({
|
|
|
7018
7018
|
}
|
|
7019
7019
|
return matcher.isLoggingCall(statement.expression);
|
|
7020
7020
|
}
|
|
7021
|
-
function hasCommentDirectlyAbove(node) {
|
|
7022
|
-
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
7023
|
-
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
7024
|
-
}
|
|
7025
7021
|
function hasAdjacentRationale(node) {
|
|
7026
7022
|
const tryStatement = node.parent;
|
|
7027
7023
|
if (hasCommentDirectlyAbove(tryStatement) || hasCommentDirectlyAbove(node)) return true;
|
|
@@ -7031,6 +7027,10 @@ var no_log_only_catch_default = createRule({
|
|
|
7031
7027
|
}
|
|
7032
7028
|
return hasCommentDirectlyAbove(block.parent);
|
|
7033
7029
|
}
|
|
7030
|
+
function hasCommentDirectlyAbove(node) {
|
|
7031
|
+
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
7032
|
+
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
7033
|
+
}
|
|
7034
7034
|
if (isTestFile(filename) || BENCHMARK_DIR_RE.test(filename.replaceAll("\\", "/"))) {
|
|
7035
7035
|
return {};
|
|
7036
7036
|
}
|
|
@@ -8031,6 +8031,10 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8031
8031
|
data: { name, count: String(tuple.elements.length) }
|
|
8032
8032
|
});
|
|
8033
8033
|
};
|
|
8034
|
+
const enterFunction = (node) => {
|
|
8035
|
+
functionStack.push(node);
|
|
8036
|
+
check(node);
|
|
8037
|
+
};
|
|
8034
8038
|
const check = (node) => {
|
|
8035
8039
|
if (isQueryKeyFactory(node)) return;
|
|
8036
8040
|
const annotation = node.returnType?.typeAnnotation;
|
|
@@ -8046,10 +8050,6 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8046
8050
|
}
|
|
8047
8051
|
report2(annotation, name);
|
|
8048
8052
|
};
|
|
8049
|
-
const enterFunction = (node) => {
|
|
8050
|
-
functionStack.push(node);
|
|
8051
|
-
check(node);
|
|
8052
|
-
};
|
|
8053
8053
|
const exitFunction = () => {
|
|
8054
8054
|
functionStack.pop();
|
|
8055
8055
|
};
|
|
@@ -8496,32 +8496,16 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8496
8496
|
const definition = variable.defs[0];
|
|
8497
8497
|
return definition?.type === "Variable" && definition.parent.kind === "const" && definition.node.init !== null && !variable.references.some((reference) => reference.isWrite() && reference.init !== true) && !(definition.node.init.type === AST_NODE_TYPES42.ObjectExpression && variable.references.some((reference) => reference.identifier !== node && reference.init !== true)) ? definition.node.init : node;
|
|
8498
8498
|
}
|
|
8499
|
-
function
|
|
8500
|
-
if (node
|
|
8501
|
-
|
|
8502
|
-
for (const property of [...node.properties].reverse()) {
|
|
8503
|
-
if (property.type !== AST_NODE_TYPES42.Property || property.computed) continue;
|
|
8504
|
-
const key = property.key;
|
|
8505
|
-
const keyName = key.type === AST_NODE_TYPES42.Identifier ? key.name : key.type === AST_NODE_TYPES42.Literal && typeof key.value === "string" ? key.value : null;
|
|
8506
|
-
if (keyName !== name) continue;
|
|
8507
|
-
return property.value.type === AST_NODE_TYPES42.AssignmentPattern || property.value.type === AST_NODE_TYPES42.ArrayPattern || property.value.type === AST_NODE_TYPES42.ObjectPattern ? null : property.value;
|
|
8508
|
-
}
|
|
8509
|
-
return null;
|
|
8510
|
-
}
|
|
8511
|
-
function isInternalApiUrl(node) {
|
|
8512
|
-
const resolved = resolveNode2(node ?? void 0);
|
|
8513
|
-
if (resolved?.type === AST_NODE_TYPES42.Literal) {
|
|
8514
|
-
return typeof resolved.value === "string" && internalApiPrefixes.some(
|
|
8515
|
-
(prefix) => resolved.value === prefix || resolved.value.startsWith(`${prefix}/`)
|
|
8516
|
-
);
|
|
8499
|
+
function serverActionOwns(node) {
|
|
8500
|
+
if (node.callee.type !== AST_NODE_TYPES42.Identifier || !hasUseClientDirective || hasUseServerDirective || importsServerOnly || SERVER_ACTION_SKIP_FILE_RE.test(filename) || nonReactFramework) {
|
|
8501
|
+
return false;
|
|
8517
8502
|
}
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
);
|
|
8503
|
+
const url = node.arguments[0];
|
|
8504
|
+
const init = node.arguments[1];
|
|
8505
|
+
if (url === void 0 || url.type === AST_NODE_TYPES42.SpreadElement || init === void 0 || init.type === AST_NODE_TYPES42.SpreadElement || !isInternalApiUrl(url)) {
|
|
8506
|
+
return false;
|
|
8523
8507
|
}
|
|
8524
|
-
return
|
|
8508
|
+
return isMutationMethod2(propertyValue(resolveNode2(init), "method"));
|
|
8525
8509
|
}
|
|
8526
8510
|
function isMutationMethod2(node) {
|
|
8527
8511
|
const resolved = resolveNode2(node ?? void 0);
|
|
@@ -8538,16 +8522,32 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8538
8522
|
}
|
|
8539
8523
|
return resolved?.type === AST_NODE_TYPES42.LogicalExpression && resolved.operator === "||" && (isMutationMethod2(resolved.left) || isMutationMethod2(resolved.right));
|
|
8540
8524
|
}
|
|
8541
|
-
function
|
|
8542
|
-
|
|
8543
|
-
|
|
8525
|
+
function isInternalApiUrl(node) {
|
|
8526
|
+
const resolved = resolveNode2(node ?? void 0);
|
|
8527
|
+
if (resolved?.type === AST_NODE_TYPES42.Literal) {
|
|
8528
|
+
return typeof resolved.value === "string" && internalApiPrefixes.some(
|
|
8529
|
+
(prefix) => resolved.value === prefix || resolved.value.startsWith(`${prefix}/`)
|
|
8530
|
+
);
|
|
8544
8531
|
}
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8532
|
+
if (resolved?.type === AST_NODE_TYPES42.TemplateLiteral) {
|
|
8533
|
+
const prefix = resolved.quasis[0]?.value.cooked;
|
|
8534
|
+
return typeof prefix === "string" && internalApiPrefixes.some(
|
|
8535
|
+
(apiPrefix) => prefix === apiPrefix || prefix.startsWith(`${apiPrefix}/`)
|
|
8536
|
+
);
|
|
8549
8537
|
}
|
|
8550
|
-
return
|
|
8538
|
+
return resolved?.type === AST_NODE_TYPES42.BinaryExpression && resolved.operator === "+" && isInternalApiUrl(resolved.left);
|
|
8539
|
+
}
|
|
8540
|
+
function propertyValue(node, name) {
|
|
8541
|
+
if (node?.type !== AST_NODE_TYPES42.ObjectExpression) return null;
|
|
8542
|
+
if (node.properties.some((property) => property.type !== AST_NODE_TYPES42.Property || property.computed)) return null;
|
|
8543
|
+
for (const property of [...node.properties].reverse()) {
|
|
8544
|
+
if (property.type !== AST_NODE_TYPES42.Property || property.computed) continue;
|
|
8545
|
+
const key = property.key;
|
|
8546
|
+
const keyName = key.type === AST_NODE_TYPES42.Identifier ? key.name : key.type === AST_NODE_TYPES42.Literal && typeof key.value === "string" ? key.value : null;
|
|
8547
|
+
if (keyName !== name) continue;
|
|
8548
|
+
return property.value.type === AST_NODE_TYPES42.AssignmentPattern || property.value.type === AST_NODE_TYPES42.ArrayPattern || property.value.type === AST_NODE_TYPES42.ObjectPattern ? null : property.value;
|
|
8549
|
+
}
|
|
8550
|
+
return null;
|
|
8551
8551
|
}
|
|
8552
8552
|
if (allowed.some((re) => re.test(filename))) {
|
|
8553
8553
|
return {};
|
|
@@ -9646,35 +9646,30 @@ var no_secret_in_log_default = createRule({
|
|
|
9646
9646
|
create(context, [loggingOptions]) {
|
|
9647
9647
|
const matcher = createLogMatcher(loggingOptions);
|
|
9648
9648
|
const blobArmApplies = !isTestFile(context.filename);
|
|
9649
|
-
function
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9649
|
+
function inspectLoggedValue(value) {
|
|
9650
|
+
if (value.type === "ObjectExpression") {
|
|
9651
|
+
for (const property of literalProperties(value)) {
|
|
9652
|
+
if (reportSecretProperty(property) || reportRawBlob(property, property.value)) continue;
|
|
9653
|
+
inspectLoggedValue(property.value);
|
|
9654
|
+
}
|
|
9655
|
+
return;
|
|
9653
9656
|
}
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
const value = valueName(prop.value);
|
|
9660
|
-
if (value !== null && hasRedactionMarker(value)) return false;
|
|
9661
|
-
const name = value !== null && isSecretKeyword(value) ? value : keyName;
|
|
9662
|
-
if (name === null || !isSecretKeyword(name) || !isRawSecretValue(prop)) {
|
|
9663
|
-
return false;
|
|
9657
|
+
if (value.type === "ArrayExpression") {
|
|
9658
|
+
for (const element of value.elements) {
|
|
9659
|
+
if (element !== null && element.type !== "SpreadElement") inspectLoggedValue(element);
|
|
9660
|
+
}
|
|
9661
|
+
return;
|
|
9664
9662
|
}
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
function reportRawBlob(node, value) {
|
|
9669
|
-
if (!blobArmApplies) {
|
|
9670
|
-
return false;
|
|
9663
|
+
if (value.type === "TemplateLiteral") {
|
|
9664
|
+
for (const expression of value.expressions) inspectLoggedValue(expression);
|
|
9665
|
+
return;
|
|
9671
9666
|
}
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
return
|
|
9667
|
+
if (value.type === "BinaryExpression" && value.operator === "+") {
|
|
9668
|
+
inspectLoggedValue(value.left);
|
|
9669
|
+
inspectLoggedValue(value.right);
|
|
9670
|
+
return;
|
|
9676
9671
|
}
|
|
9677
|
-
|
|
9672
|
+
if (!reportSecretArgument(value)) reportRawBlob(value, value);
|
|
9678
9673
|
}
|
|
9679
9674
|
function literalProperties(value) {
|
|
9680
9675
|
const effective = /* @__PURE__ */ new Map();
|
|
@@ -9699,30 +9694,35 @@ var no_secret_in_log_default = createRule({
|
|
|
9699
9694
|
}
|
|
9700
9695
|
return [...effective.values()];
|
|
9701
9696
|
}
|
|
9702
|
-
function
|
|
9703
|
-
if (
|
|
9704
|
-
|
|
9705
|
-
if (reportSecretProperty(property) || reportRawBlob(property, property.value)) continue;
|
|
9706
|
-
inspectLoggedValue(property.value);
|
|
9707
|
-
}
|
|
9708
|
-
return;
|
|
9697
|
+
function reportRawBlob(node, value) {
|
|
9698
|
+
if (!blobArmApplies) {
|
|
9699
|
+
return false;
|
|
9709
9700
|
}
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
return;
|
|
9701
|
+
const name = rawBlobValueName(value);
|
|
9702
|
+
if (name !== null) {
|
|
9703
|
+
context.report({ node, messageId: "noRawBodyInLog", data: { name } });
|
|
9704
|
+
return true;
|
|
9715
9705
|
}
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9706
|
+
return false;
|
|
9707
|
+
}
|
|
9708
|
+
function reportSecretProperty(prop) {
|
|
9709
|
+
const keyName = propertyKeyName2(prop);
|
|
9710
|
+
const value = valueName(prop.value);
|
|
9711
|
+
if (value !== null && hasRedactionMarker(value)) return false;
|
|
9712
|
+
const name = value !== null && isSecretKeyword(value) ? value : keyName;
|
|
9713
|
+
if (name === null || !isSecretKeyword(name) || !isRawSecretValue(prop)) {
|
|
9714
|
+
return false;
|
|
9719
9715
|
}
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9716
|
+
context.report({ node: prop, messageId: "noSecretInLog", data: { name } });
|
|
9717
|
+
return true;
|
|
9718
|
+
}
|
|
9719
|
+
function reportSecretArgument(arg) {
|
|
9720
|
+
const name = valueName(arg);
|
|
9721
|
+
if (name === null || !isSecretKeyword(name)) {
|
|
9722
|
+
return false;
|
|
9724
9723
|
}
|
|
9725
|
-
|
|
9724
|
+
context.report({ node: arg, messageId: "noSecretInLog", data: { name } });
|
|
9725
|
+
return true;
|
|
9726
9726
|
}
|
|
9727
9727
|
return {
|
|
9728
9728
|
CallExpression(node) {
|
|
@@ -10020,9 +10020,6 @@ function bindsName(param, name) {
|
|
|
10020
10020
|
}
|
|
10021
10021
|
function subtreeReadsName(node, name) {
|
|
10022
10022
|
let found = false;
|
|
10023
|
-
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10024
|
-
(param) => bindsName(param, name)
|
|
10025
|
-
);
|
|
10026
10023
|
const recurse = (current) => {
|
|
10027
10024
|
if (found) {
|
|
10028
10025
|
return;
|
|
@@ -10039,6 +10036,9 @@ function subtreeReadsName(node, name) {
|
|
|
10039
10036
|
return found;
|
|
10040
10037
|
}, (key) => !isNonReadingProperty(current, key));
|
|
10041
10038
|
};
|
|
10039
|
+
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10040
|
+
(param) => bindsName(param, name)
|
|
10041
|
+
);
|
|
10042
10042
|
recurse(node);
|
|
10043
10043
|
return found;
|
|
10044
10044
|
}
|
|
@@ -11900,14 +11900,6 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11900
11900
|
const trail = startingOn.get(member.loc.end.line);
|
|
11901
11901
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
11902
11902
|
}
|
|
11903
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
11904
|
-
if (comment.loc.end.line >= member.node.loc.start.line) return false;
|
|
11905
|
-
const body2 = commentBody(comment);
|
|
11906
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
11907
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
11908
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
11909
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
11910
|
-
}
|
|
11911
11903
|
function check(node, members) {
|
|
11912
11904
|
const judged = members.map(named).filter((member) => member !== void 0);
|
|
11913
11905
|
if (judged.length === 0) return;
|
|
@@ -11946,6 +11938,14 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11946
11938
|
data: { restated: String(restated), commented: String(commented) }
|
|
11947
11939
|
});
|
|
11948
11940
|
}
|
|
11941
|
+
function isGroupLabel(comment, member, headsRun) {
|
|
11942
|
+
if (comment.loc.end.line >= member.node.loc.start.line) return false;
|
|
11943
|
+
const body2 = commentBody(comment);
|
|
11944
|
+
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
11945
|
+
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
11946
|
+
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
11947
|
+
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
11948
|
+
}
|
|
11949
11949
|
return {
|
|
11950
11950
|
ClassBody: (node) => {
|
|
11951
11951
|
check(node, node.body);
|
|
@@ -12181,14 +12181,6 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12181
12181
|
const trail = startingOn.get(member.loc.end.line);
|
|
12182
12182
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
12183
12183
|
}
|
|
12184
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
12185
|
-
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
12186
|
-
const body2 = commentBody(comment);
|
|
12187
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
12188
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
12189
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
12190
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
12191
|
-
}
|
|
12192
12184
|
function check(node) {
|
|
12193
12185
|
const members = node.type === AST_NODE_TYPES56.TSInterfaceBody ? node.body : node.members;
|
|
12194
12186
|
const named2 = members.filter(isNamedMember);
|
|
@@ -12224,6 +12216,14 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12224
12216
|
data: { restated: String(restated), commented: String(commented) }
|
|
12225
12217
|
});
|
|
12226
12218
|
}
|
|
12219
|
+
function isGroupLabel(comment, member, headsRun) {
|
|
12220
|
+
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
12221
|
+
const body2 = commentBody(comment);
|
|
12222
|
+
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
12223
|
+
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
12224
|
+
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
12225
|
+
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
12226
|
+
}
|
|
12227
12227
|
return {
|
|
12228
12228
|
TSInterfaceBody: check,
|
|
12229
12229
|
TSTypeLiteral: check
|
|
@@ -12542,6 +12542,11 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12542
12542
|
const binding = resolve2(identifier);
|
|
12543
12543
|
if (binding !== null) destination.add(binding);
|
|
12544
12544
|
}
|
|
12545
|
+
function checkAssertion(node) {
|
|
12546
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12547
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12545
12550
|
function isMockTypeReference(node) {
|
|
12546
12551
|
if (node.type !== AST_NODE_TYPES58.TSTypeReference) return false;
|
|
12547
12552
|
const typeName = node.typeName;
|
|
@@ -12555,11 +12560,6 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12555
12560
|
}
|
|
12556
12561
|
return false;
|
|
12557
12562
|
}
|
|
12558
|
-
function checkAssertion(node) {
|
|
12559
|
-
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12560
|
-
context.report({ node, messageId: "unsafeMockCast" });
|
|
12561
|
-
}
|
|
12562
|
-
}
|
|
12563
12563
|
return {
|
|
12564
12564
|
ImportDeclaration(node) {
|
|
12565
12565
|
if (!MOCK_MODULES.has(node.source.value)) return;
|
|
@@ -17894,7 +17894,7 @@ var staticallyImportsExternalRenderer = (program) => program.body.some((statemen
|
|
|
17894
17894
|
var semanticForegroundRoles = (filename) => {
|
|
17895
17895
|
const packageRoot = nearestPackageRoot(dirname2(filename));
|
|
17896
17896
|
if (packageRoot === null) return /* @__PURE__ */ new Set();
|
|
17897
|
-
const candidates = CSS_DETECTION_FILES.map((
|
|
17897
|
+
const candidates = CSS_DETECTION_FILES.map((relative3) => join2(packageRoot, relative3));
|
|
17898
17898
|
const fingerprint = candidates.map(fileFingerprint2).join("|");
|
|
17899
17899
|
const cached = SEMANTIC_DECLARATIONS_CACHE.get(packageRoot);
|
|
17900
17900
|
if (cached?.fingerprint === fingerprint) return cached.value;
|
|
@@ -17977,6 +17977,34 @@ var prefer_semantic_colors_default = createRule({
|
|
|
17977
17977
|
const key = `${node.range[0]}:${node.range[1]}:${messageId}:${JSON.stringify(data)}`;
|
|
17978
17978
|
pendingReports.set(key, { node, messageId, data });
|
|
17979
17979
|
};
|
|
17980
|
+
const checkClassNode = (node, objectKeys = false) => {
|
|
17981
|
+
if (node === null) return;
|
|
17982
|
+
switch (node.type) {
|
|
17983
|
+
case AST_NODE_TYPES87.Literal:
|
|
17984
|
+
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
17985
|
+
break;
|
|
17986
|
+
case AST_NODE_TYPES87.TemplateLiteral:
|
|
17987
|
+
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
17988
|
+
break;
|
|
17989
|
+
case AST_NODE_TYPES87.ArrayExpression:
|
|
17990
|
+
for (const element of node.elements) {
|
|
17991
|
+
if (element !== null && element.type !== AST_NODE_TYPES87.SpreadElement) checkClassNode(element, objectKeys);
|
|
17992
|
+
}
|
|
17993
|
+
break;
|
|
17994
|
+
case AST_NODE_TYPES87.ObjectExpression:
|
|
17995
|
+
checkClassProperties(node, objectKeys);
|
|
17996
|
+
break;
|
|
17997
|
+
case AST_NODE_TYPES87.ConditionalExpression:
|
|
17998
|
+
checkClassNode(node.consequent, objectKeys);
|
|
17999
|
+
checkClassNode(node.alternate, objectKeys);
|
|
18000
|
+
break;
|
|
18001
|
+
case AST_NODE_TYPES87.LogicalExpression:
|
|
18002
|
+
checkClassNode(node.right, objectKeys);
|
|
18003
|
+
break;
|
|
18004
|
+
default:
|
|
18005
|
+
break;
|
|
18006
|
+
}
|
|
18007
|
+
};
|
|
17980
18008
|
const reportClasses = (value, node) => {
|
|
17981
18009
|
const tokens = classTokens(value);
|
|
17982
18010
|
for (const token of tokens) {
|
|
@@ -18008,34 +18036,6 @@ var prefer_semantic_colors_default = createRule({
|
|
|
18008
18036
|
});
|
|
18009
18037
|
}
|
|
18010
18038
|
};
|
|
18011
|
-
const checkClassNode = (node, objectKeys = false) => {
|
|
18012
|
-
if (node === null) return;
|
|
18013
|
-
switch (node.type) {
|
|
18014
|
-
case AST_NODE_TYPES87.Literal:
|
|
18015
|
-
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
18016
|
-
break;
|
|
18017
|
-
case AST_NODE_TYPES87.TemplateLiteral:
|
|
18018
|
-
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
18019
|
-
break;
|
|
18020
|
-
case AST_NODE_TYPES87.ArrayExpression:
|
|
18021
|
-
for (const element of node.elements) {
|
|
18022
|
-
if (element !== null && element.type !== AST_NODE_TYPES87.SpreadElement) checkClassNode(element, objectKeys);
|
|
18023
|
-
}
|
|
18024
|
-
break;
|
|
18025
|
-
case AST_NODE_TYPES87.ObjectExpression:
|
|
18026
|
-
checkClassProperties(node, objectKeys);
|
|
18027
|
-
break;
|
|
18028
|
-
case AST_NODE_TYPES87.ConditionalExpression:
|
|
18029
|
-
checkClassNode(node.consequent, objectKeys);
|
|
18030
|
-
checkClassNode(node.alternate, objectKeys);
|
|
18031
|
-
break;
|
|
18032
|
-
case AST_NODE_TYPES87.LogicalExpression:
|
|
18033
|
-
checkClassNode(node.right, objectKeys);
|
|
18034
|
-
break;
|
|
18035
|
-
default:
|
|
18036
|
-
break;
|
|
18037
|
-
}
|
|
18038
|
-
};
|
|
18039
18039
|
function checkClassProperties(node, objectKeys) {
|
|
18040
18040
|
for (const property of node.properties) {
|
|
18041
18041
|
if (property.type !== AST_NODE_TYPES87.Property) continue;
|
|
@@ -18469,80 +18469,6 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18469
18469
|
return {};
|
|
18470
18470
|
}
|
|
18471
18471
|
const { sourceCode } = context;
|
|
18472
|
-
function parseAssertion(statement) {
|
|
18473
|
-
if (statement.type !== AST_NODE_TYPES88.ExpressionStatement) {
|
|
18474
|
-
return null;
|
|
18475
|
-
}
|
|
18476
|
-
const call = statement.expression;
|
|
18477
|
-
if (call.type !== AST_NODE_TYPES88.CallExpression) {
|
|
18478
|
-
return null;
|
|
18479
|
-
}
|
|
18480
|
-
const callee = call.callee;
|
|
18481
|
-
if (callee.type !== AST_NODE_TYPES88.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES88.Identifier) {
|
|
18482
|
-
return null;
|
|
18483
|
-
}
|
|
18484
|
-
const matcher = callee.property.name;
|
|
18485
|
-
const expectCall = callee.object;
|
|
18486
|
-
if (expectCall.type !== AST_NODE_TYPES88.CallExpression || expectCall.callee.type !== AST_NODE_TYPES88.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
18487
|
-
return null;
|
|
18488
|
-
}
|
|
18489
|
-
const actual = expectCall.arguments[0];
|
|
18490
|
-
if (!isTestExpect(expectCall.callee)) return null;
|
|
18491
|
-
if (actual === void 0 || actual.type !== AST_NODE_TYPES88.MemberExpression || actual.optional) {
|
|
18492
|
-
return null;
|
|
18493
|
-
}
|
|
18494
|
-
if (!isPureReceiver(actual.object)) {
|
|
18495
|
-
return null;
|
|
18496
|
-
}
|
|
18497
|
-
let key;
|
|
18498
|
-
let receiver;
|
|
18499
|
-
if (actual.computed) {
|
|
18500
|
-
const index = literalIndex(actual.property);
|
|
18501
|
-
if (index === null) {
|
|
18502
|
-
return null;
|
|
18503
|
-
}
|
|
18504
|
-
key = { kind: "index", index };
|
|
18505
|
-
receiver = actual.object;
|
|
18506
|
-
} else {
|
|
18507
|
-
const access = propertyAccess(actual);
|
|
18508
|
-
if (access === null) return null;
|
|
18509
|
-
key = { kind: "property", path: access.path };
|
|
18510
|
-
receiver = access.receiver;
|
|
18511
|
-
}
|
|
18512
|
-
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
18513
|
-
}
|
|
18514
|
-
function assertionExpectation(statement, call, receiver, key, matcher) {
|
|
18515
|
-
const synthetic = SYNTHETIC_LITERAL_MATCHERS.get(matcher);
|
|
18516
|
-
if (synthetic !== void 0 && call.arguments.length === 0) {
|
|
18517
|
-
return { statement, receiver, key, matcher, expectedText: synthetic, expectedIsLiteral: true };
|
|
18518
|
-
}
|
|
18519
|
-
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
18520
|
-
return null;
|
|
18521
|
-
}
|
|
18522
|
-
const expected = call.arguments[0];
|
|
18523
|
-
if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES88.SpreadElement) {
|
|
18524
|
-
return null;
|
|
18525
|
-
}
|
|
18526
|
-
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
18527
|
-
return {
|
|
18528
|
-
statement,
|
|
18529
|
-
receiver,
|
|
18530
|
-
key,
|
|
18531
|
-
matcher,
|
|
18532
|
-
expectedText: literal ?? sourceCode.getText(expected),
|
|
18533
|
-
expectedIsLiteral: literal !== null
|
|
18534
|
-
};
|
|
18535
|
-
}
|
|
18536
|
-
function isTestExpect(callee) {
|
|
18537
|
-
const variable = ASTUtils45.findVariable(sourceCode.getScope(callee), callee.name);
|
|
18538
|
-
if (variable !== null && variable.defs.some((definition) => {
|
|
18539
|
-
if (definition.node.type !== AST_NODE_TYPES88.ImportSpecifier) return true;
|
|
18540
|
-
const declaration = definition.node.parent;
|
|
18541
|
-
const imported = definition.node.imported;
|
|
18542
|
-
return declaration.type !== AST_NODE_TYPES88.ImportDeclaration || !["vitest", "@jest/globals", "@playwright/test", "bun:test"].includes(String(declaration.source.value)) || (imported.type === AST_NODE_TYPES88.Identifier ? imported.name : imported.value) !== "expect";
|
|
18543
|
-
})) return false;
|
|
18544
|
-
return true;
|
|
18545
|
-
}
|
|
18546
18472
|
function reportPropertyRun(run) {
|
|
18547
18473
|
const tree = /* @__PURE__ */ new Map();
|
|
18548
18474
|
const paths = [];
|
|
@@ -18652,6 +18578,80 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18652
18578
|
}
|
|
18653
18579
|
flush();
|
|
18654
18580
|
}
|
|
18581
|
+
function parseAssertion(statement) {
|
|
18582
|
+
if (statement.type !== AST_NODE_TYPES88.ExpressionStatement) {
|
|
18583
|
+
return null;
|
|
18584
|
+
}
|
|
18585
|
+
const call = statement.expression;
|
|
18586
|
+
if (call.type !== AST_NODE_TYPES88.CallExpression) {
|
|
18587
|
+
return null;
|
|
18588
|
+
}
|
|
18589
|
+
const callee = call.callee;
|
|
18590
|
+
if (callee.type !== AST_NODE_TYPES88.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES88.Identifier) {
|
|
18591
|
+
return null;
|
|
18592
|
+
}
|
|
18593
|
+
const matcher = callee.property.name;
|
|
18594
|
+
const expectCall = callee.object;
|
|
18595
|
+
if (expectCall.type !== AST_NODE_TYPES88.CallExpression || expectCall.callee.type !== AST_NODE_TYPES88.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
18596
|
+
return null;
|
|
18597
|
+
}
|
|
18598
|
+
const actual = expectCall.arguments[0];
|
|
18599
|
+
if (!isTestExpect(expectCall.callee)) return null;
|
|
18600
|
+
if (actual === void 0 || actual.type !== AST_NODE_TYPES88.MemberExpression || actual.optional) {
|
|
18601
|
+
return null;
|
|
18602
|
+
}
|
|
18603
|
+
if (!isPureReceiver(actual.object)) {
|
|
18604
|
+
return null;
|
|
18605
|
+
}
|
|
18606
|
+
let key;
|
|
18607
|
+
let receiver;
|
|
18608
|
+
if (actual.computed) {
|
|
18609
|
+
const index = literalIndex(actual.property);
|
|
18610
|
+
if (index === null) {
|
|
18611
|
+
return null;
|
|
18612
|
+
}
|
|
18613
|
+
key = { kind: "index", index };
|
|
18614
|
+
receiver = actual.object;
|
|
18615
|
+
} else {
|
|
18616
|
+
const access = propertyAccess(actual);
|
|
18617
|
+
if (access === null) return null;
|
|
18618
|
+
key = { kind: "property", path: access.path };
|
|
18619
|
+
receiver = access.receiver;
|
|
18620
|
+
}
|
|
18621
|
+
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
18622
|
+
}
|
|
18623
|
+
function isTestExpect(callee) {
|
|
18624
|
+
const variable = ASTUtils45.findVariable(sourceCode.getScope(callee), callee.name);
|
|
18625
|
+
if (variable !== null && variable.defs.some((definition) => {
|
|
18626
|
+
if (definition.node.type !== AST_NODE_TYPES88.ImportSpecifier) return true;
|
|
18627
|
+
const declaration = definition.node.parent;
|
|
18628
|
+
const imported = definition.node.imported;
|
|
18629
|
+
return declaration.type !== AST_NODE_TYPES88.ImportDeclaration || !["vitest", "@jest/globals", "@playwright/test", "bun:test"].includes(String(declaration.source.value)) || (imported.type === AST_NODE_TYPES88.Identifier ? imported.name : imported.value) !== "expect";
|
|
18630
|
+
})) return false;
|
|
18631
|
+
return true;
|
|
18632
|
+
}
|
|
18633
|
+
function assertionExpectation(statement, call, receiver, key, matcher) {
|
|
18634
|
+
const synthetic = SYNTHETIC_LITERAL_MATCHERS.get(matcher);
|
|
18635
|
+
if (synthetic !== void 0 && call.arguments.length === 0) {
|
|
18636
|
+
return { statement, receiver, key, matcher, expectedText: synthetic, expectedIsLiteral: true };
|
|
18637
|
+
}
|
|
18638
|
+
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
18639
|
+
return null;
|
|
18640
|
+
}
|
|
18641
|
+
const expected = call.arguments[0];
|
|
18642
|
+
if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES88.SpreadElement) {
|
|
18643
|
+
return null;
|
|
18644
|
+
}
|
|
18645
|
+
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
18646
|
+
return {
|
|
18647
|
+
statement,
|
|
18648
|
+
receiver,
|
|
18649
|
+
key,
|
|
18650
|
+
matcher,
|
|
18651
|
+
expectedText: literal ?? sourceCode.getText(expected),
|
|
18652
|
+
expectedIsLiteral: literal !== null
|
|
18653
|
+
};
|
|
18654
|
+
}
|
|
18655
18655
|
return {
|
|
18656
18656
|
BlockStatement: (node) => {
|
|
18657
18657
|
checkBody(node.body);
|
|
@@ -21397,6 +21397,11 @@ var require_use_form_default_values_default = createRule({
|
|
|
21397
21397
|
const value = unwrapExpression6(node);
|
|
21398
21398
|
return value.type === AST_NODE_TYPES98.UnaryExpression && value.operator === "void" || value.type === AST_NODE_TYPES98.Identifier && value.name === "undefined" && (bindingOf(value)?.defs.length ?? 0) === 0;
|
|
21399
21399
|
};
|
|
21400
|
+
const uninitializedUseFormCall = (node) => {
|
|
21401
|
+
if (node.type !== AST_NODE_TYPES98.CallExpression || node.callee.type !== AST_NODE_TYPES98.Identifier || importedKind(node.callee) !== "useForm") return false;
|
|
21402
|
+
const options = node.arguments[0];
|
|
21403
|
+
return options?.type !== AST_NODE_TYPES98.SpreadElement && initializationState(options) === "uninitialized";
|
|
21404
|
+
};
|
|
21400
21405
|
const initializationState = (node) => {
|
|
21401
21406
|
if (node === void 0) return "uninitialized";
|
|
21402
21407
|
if (node.type !== AST_NODE_TYPES98.ObjectExpression) return "unknown";
|
|
@@ -21409,11 +21414,6 @@ var require_use_form_default_values_default = createRule({
|
|
|
21409
21414
|
}
|
|
21410
21415
|
return [...initialization.values()].some(Boolean) ? "initialized" : "uninitialized";
|
|
21411
21416
|
};
|
|
21412
|
-
const uninitializedUseFormCall = (node) => {
|
|
21413
|
-
if (node.type !== AST_NODE_TYPES98.CallExpression || node.callee.type !== AST_NODE_TYPES98.Identifier || importedKind(node.callee) !== "useForm") return false;
|
|
21414
|
-
const options = node.arguments[0];
|
|
21415
|
-
return options?.type !== AST_NODE_TYPES98.SpreadElement && initializationState(options) === "uninitialized";
|
|
21416
|
-
};
|
|
21417
21417
|
const isUninitializedForm = (node) => {
|
|
21418
21418
|
if (node.type !== AST_NODE_TYPES98.Identifier) return false;
|
|
21419
21419
|
const variable = bindingOf(node);
|
|
@@ -21645,28 +21645,13 @@ var require_zod_form_validation_default = createRule({
|
|
|
21645
21645
|
context.sourceCode.getScope(identifier),
|
|
21646
21646
|
identifier.name
|
|
21647
21647
|
);
|
|
21648
|
-
const
|
|
21649
|
-
const binding = resolvedBinding(identifier);
|
|
21650
|
-
if (binding === null || zodBindings.has(binding) || binding.defs.length !== 1) {
|
|
21651
|
-
return false;
|
|
21652
|
-
}
|
|
21653
|
-
const definition = binding.defs[0];
|
|
21654
|
-
if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES99.VariableDeclarator) {
|
|
21655
|
-
return false;
|
|
21656
|
-
}
|
|
21657
|
-
const init = definition.node.init;
|
|
21658
|
-
return init?.type === AST_NODE_TYPES99.ObjectExpression || init?.type === AST_NODE_TYPES99.ArrayExpression || init?.type === AST_NODE_TYPES99.Literal || init?.type === AST_NODE_TYPES99.ArrowFunctionExpression || init?.type === AST_NODE_TYPES99.FunctionExpression;
|
|
21659
|
-
};
|
|
21660
|
-
const isZodParseCall = (node) => {
|
|
21661
|
-
if (node.type !== AST_NODE_TYPES99.CallExpression) return false;
|
|
21648
|
+
const isFormDataGetCall = (node) => {
|
|
21662
21649
|
const callee = node.callee;
|
|
21663
|
-
if (callee.type !== AST_NODE_TYPES99.MemberExpression
|
|
21650
|
+
if (callee.type !== AST_NODE_TYPES99.MemberExpression) return false;
|
|
21651
|
+
if (callee.property.type !== AST_NODE_TYPES99.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
21664
21652
|
return false;
|
|
21665
21653
|
}
|
|
21666
|
-
|
|
21667
|
-
if (root === null) return false;
|
|
21668
|
-
const binding = resolvedBinding(root);
|
|
21669
|
-
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
21654
|
+
return isFormSourceIdentifier(callee.object);
|
|
21670
21655
|
};
|
|
21671
21656
|
const isFormSourceIdentifier = (node) => {
|
|
21672
21657
|
if (node.type !== AST_NODE_TYPES99.Identifier) return false;
|
|
@@ -21685,14 +21670,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21685
21670
|
}
|
|
21686
21671
|
return conventionalName;
|
|
21687
21672
|
};
|
|
21688
|
-
const isFormDataGetCall = (node) => {
|
|
21689
|
-
const callee = node.callee;
|
|
21690
|
-
if (callee.type !== AST_NODE_TYPES99.MemberExpression) return false;
|
|
21691
|
-
if (callee.property.type !== AST_NODE_TYPES99.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
21692
|
-
return false;
|
|
21693
|
-
}
|
|
21694
|
-
return isFormSourceIdentifier(callee.object);
|
|
21695
|
-
};
|
|
21696
21673
|
const zodParseAncestor = (node) => {
|
|
21697
21674
|
let parent = node.parent;
|
|
21698
21675
|
while (parent !== null && parent !== void 0) {
|
|
@@ -21710,6 +21687,29 @@ var require_zod_form_validation_default = createRule({
|
|
|
21710
21687
|
}
|
|
21711
21688
|
return null;
|
|
21712
21689
|
};
|
|
21690
|
+
const isZodParseCall = (node) => {
|
|
21691
|
+
if (node.type !== AST_NODE_TYPES99.CallExpression) return false;
|
|
21692
|
+
const callee = node.callee;
|
|
21693
|
+
if (callee.type !== AST_NODE_TYPES99.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES99.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
|
|
21694
|
+
return false;
|
|
21695
|
+
}
|
|
21696
|
+
const root = zodReceiverRoot(callee.object);
|
|
21697
|
+
if (root === null) return false;
|
|
21698
|
+
const binding = resolvedBinding(root);
|
|
21699
|
+
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
21700
|
+
};
|
|
21701
|
+
const isProvablyNonZodLocal = (identifier) => {
|
|
21702
|
+
const binding = resolvedBinding(identifier);
|
|
21703
|
+
if (binding === null || zodBindings.has(binding) || binding.defs.length !== 1) {
|
|
21704
|
+
return false;
|
|
21705
|
+
}
|
|
21706
|
+
const definition = binding.defs[0];
|
|
21707
|
+
if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES99.VariableDeclarator) {
|
|
21708
|
+
return false;
|
|
21709
|
+
}
|
|
21710
|
+
const init = definition.node.init;
|
|
21711
|
+
return init?.type === AST_NODE_TYPES99.ObjectExpression || init?.type === AST_NODE_TYPES99.ArrayExpression || init?.type === AST_NODE_TYPES99.Literal || init?.type === AST_NODE_TYPES99.ArrowFunctionExpression || init?.type === AST_NODE_TYPES99.FunctionExpression;
|
|
21712
|
+
};
|
|
21713
21713
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
21714
21714
|
const isInstanceofNarrowing = (node) => {
|
|
21715
21715
|
const parent = node.parent;
|
|
@@ -21738,28 +21738,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21738
21738
|
}
|
|
21739
21739
|
return null;
|
|
21740
21740
|
};
|
|
21741
|
-
const zodParseMethod = (call) => {
|
|
21742
|
-
const callee = call.callee;
|
|
21743
|
-
return callee.type === AST_NODE_TYPES99.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES99.Identifier ? callee.property.name : null;
|
|
21744
|
-
};
|
|
21745
|
-
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
21746
|
-
let current = node.parent;
|
|
21747
|
-
while (current !== void 0 && current !== statement) {
|
|
21748
|
-
if (current.type === AST_NODE_TYPES99.LogicalExpression || current.type === AST_NODE_TYPES99.ConditionalExpression) {
|
|
21749
|
-
return true;
|
|
21750
|
-
}
|
|
21751
|
-
current = current.parent;
|
|
21752
|
-
}
|
|
21753
|
-
return false;
|
|
21754
|
-
};
|
|
21755
|
-
const isAwaitedBeforeStatement = (node, statement) => {
|
|
21756
|
-
let current = node.parent;
|
|
21757
|
-
while (current !== void 0 && current !== statement) {
|
|
21758
|
-
if (current.type === AST_NODE_TYPES99.AwaitExpression) return true;
|
|
21759
|
-
current = current.parent;
|
|
21760
|
-
}
|
|
21761
|
-
return false;
|
|
21762
|
-
};
|
|
21763
21741
|
const guaranteedValidationStatement = (declarator, reference) => {
|
|
21764
21742
|
const parse2 = zodParseAncestor(reference);
|
|
21765
21743
|
if (parse2 === null) return null;
|
|
@@ -21778,6 +21756,28 @@ var require_zod_form_validation_default = createRule({
|
|
|
21778
21756
|
}
|
|
21779
21757
|
return null;
|
|
21780
21758
|
};
|
|
21759
|
+
const isAwaitedBeforeStatement = (node, statement) => {
|
|
21760
|
+
let current = node.parent;
|
|
21761
|
+
while (current !== void 0 && current !== statement) {
|
|
21762
|
+
if (current.type === AST_NODE_TYPES99.AwaitExpression) return true;
|
|
21763
|
+
current = current.parent;
|
|
21764
|
+
}
|
|
21765
|
+
return false;
|
|
21766
|
+
};
|
|
21767
|
+
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
21768
|
+
let current = node.parent;
|
|
21769
|
+
while (current !== void 0 && current !== statement) {
|
|
21770
|
+
if (current.type === AST_NODE_TYPES99.LogicalExpression || current.type === AST_NODE_TYPES99.ConditionalExpression) {
|
|
21771
|
+
return true;
|
|
21772
|
+
}
|
|
21773
|
+
current = current.parent;
|
|
21774
|
+
}
|
|
21775
|
+
return false;
|
|
21776
|
+
};
|
|
21777
|
+
const zodParseMethod = (call) => {
|
|
21778
|
+
const callee = call.callee;
|
|
21779
|
+
return callee.type === AST_NODE_TYPES99.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES99.Identifier ? callee.property.name : null;
|
|
21780
|
+
};
|
|
21781
21781
|
const isSafePrevalidationInspection = (identifier) => {
|
|
21782
21782
|
const parent = identifier.parent;
|
|
21783
21783
|
if (parent.type === AST_NODE_TYPES99.UnaryExpression && parent.operator === "typeof") {
|
|
@@ -21958,7 +21958,7 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
21958
21958
|
remediation: "Consider moving the private helper below its sole caller after reviewing initialization and reflection dependencies.",
|
|
21959
21959
|
category: "maintainability",
|
|
21960
21960
|
limitations: [
|
|
21961
|
-
"Generated and test files, cycles, dynamic or escaped references, overload targets, and helpers with multiple callers are excluded; immutable local callable aliases are followed only when every use stays in the caller.",
|
|
21961
|
+
"Generated and test files, cycles, dynamic or escaped references, overload targets, and helpers with multiple callers are excluded; immutable local callable aliases are followed only when every use stays in the caller. Function bodies include nested sibling helpers.",
|
|
21962
21962
|
"Class helpers must be private; their sole caller may be public, protected, or private.",
|
|
21963
21963
|
"Runtime class-field, static-block, computed-member, and decorator barriers are never crossed; non-hoisted module helpers also cannot cross eager execution or unrelated initialization.",
|
|
21964
21964
|
"This rule is report-only: reordering methods can change reflective property order, and moving module declarations can change initialization behavior or introduce temporal-dead-zone failures. Review module cycles and eager callers manually."
|
|
@@ -22101,8 +22101,9 @@ function localCallCount(context, node, owner) {
|
|
|
22101
22101
|
}
|
|
22102
22102
|
return count;
|
|
22103
22103
|
}
|
|
22104
|
-
function
|
|
22104
|
+
function declarationScope(context, program) {
|
|
22105
22105
|
const declarations = moduleDefinitions(program);
|
|
22106
|
+
if (declarations.length < 2) return;
|
|
22106
22107
|
const counts = /* @__PURE__ */ new Map();
|
|
22107
22108
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
22108
22109
|
const overloadNames = new Set(
|
|
@@ -22111,7 +22112,7 @@ function moduleScope(context, program) {
|
|
|
22111
22112
|
return node?.type === AST_NODE_TYPES100.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
|
|
22112
22113
|
})
|
|
22113
22114
|
);
|
|
22114
|
-
const exported = exportedNames(program);
|
|
22115
|
+
const exported = program.type === AST_NODE_TYPES100.Program ? exportedNames(program) : /* @__PURE__ */ new Set();
|
|
22115
22116
|
const scopeDefinitions = declarations.filter((node) => counts.get(node.name) === 1);
|
|
22116
22117
|
const definitions = scopeDefinitions.filter(
|
|
22117
22118
|
(definition) => !exported.has(definition.name) && !overloadNames.has(definition.name)
|
|
@@ -22122,17 +22123,17 @@ function moduleScope(context, program) {
|
|
|
22122
22123
|
for (const statement of program.body) {
|
|
22123
22124
|
runtimeBarrierPrefix.push((runtimeBarrierPrefix.at(-1) ?? 0) + (isDeferredModuleStatement(statement) ? 0 : 1));
|
|
22124
22125
|
}
|
|
22125
|
-
const statementIndex = (definition) => {
|
|
22126
|
-
let current = definition.node;
|
|
22127
|
-
while (current.parent !== void 0 && current.parent.type !== AST_NODE_TYPES100.Program) current = current.parent;
|
|
22128
|
-
return statementIndexes.get(current);
|
|
22129
|
-
};
|
|
22130
22126
|
const canMove = (helper, caller) => {
|
|
22131
22127
|
if (helper.node.type === AST_NODE_TYPES100.FunctionDeclaration) return true;
|
|
22132
22128
|
const helperIndex = statementIndex(helper);
|
|
22133
22129
|
const callerIndex = statementIndex(caller);
|
|
22134
22130
|
return helperIndex !== void 0 && callerIndex !== void 0 && runtimeBarrierPrefix[callerIndex + 1] === runtimeBarrierPrefix[helperIndex + 1];
|
|
22135
22131
|
};
|
|
22132
|
+
const statementIndex = (definition) => {
|
|
22133
|
+
let current = definition.node;
|
|
22134
|
+
while (current.parent !== void 0 && current.parent !== program) current = current.parent;
|
|
22135
|
+
return statementIndexes.get(current);
|
|
22136
|
+
};
|
|
22136
22137
|
reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
|
|
22137
22138
|
}
|
|
22138
22139
|
function moduleCallGraph(context, scopeDefinitions) {
|
|
@@ -22233,9 +22234,38 @@ function methodKey(name, isStatic2) {
|
|
|
22233
22234
|
function receiverDomain(context, object, receivers, thisIsStatic) {
|
|
22234
22235
|
const unwrapped = unwrapExpression7(object);
|
|
22235
22236
|
if (unwrapped.type === AST_NODE_TYPES100.ThisExpression) return thisIsStatic;
|
|
22236
|
-
|
|
22237
|
-
|
|
22238
|
-
|
|
22237
|
+
return externalReceiverDomain(context, unwrapped, receivers);
|
|
22238
|
+
}
|
|
22239
|
+
function externalReceiverDomain(context, object, receivers) {
|
|
22240
|
+
const origin = receiverOrigin(context, object, receivers);
|
|
22241
|
+
if (origin === null || typeof origin === "boolean") return origin;
|
|
22242
|
+
if (origin.type === AST_NODE_TYPES100.NewExpression) {
|
|
22243
|
+
return receiverOrigin(context, origin.callee, receivers) === true ? false : null;
|
|
22244
|
+
}
|
|
22245
|
+
if (origin.type === AST_NODE_TYPES100.ObjectExpression || origin.type === AST_NODE_TYPES100.ArrayExpression || origin.type === AST_NODE_TYPES100.Literal || origin.type === AST_NODE_TYPES100.ArrowFunctionExpression || origin.type === AST_NODE_TYPES100.FunctionExpression) return "unrelated";
|
|
22246
|
+
return null;
|
|
22247
|
+
}
|
|
22248
|
+
function receiverOrigin(context, object, receivers) {
|
|
22249
|
+
let current = object;
|
|
22250
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22251
|
+
while (true) {
|
|
22252
|
+
const unwrapped = unwrapExpression7(current);
|
|
22253
|
+
if (unwrapped.type !== AST_NODE_TYPES100.Identifier) return unwrapped;
|
|
22254
|
+
const variable = ASTUtils51.findVariable(context.sourceCode.getScope(unwrapped), unwrapped.name);
|
|
22255
|
+
if (variable === null) return null;
|
|
22256
|
+
const known = receivers.get(variable);
|
|
22257
|
+
if (known !== void 0) return known;
|
|
22258
|
+
const initializer = immutableInitializer(variable, seen);
|
|
22259
|
+
if (initializer === null) return null;
|
|
22260
|
+
current = initializer;
|
|
22261
|
+
}
|
|
22262
|
+
}
|
|
22263
|
+
function immutableInitializer(variable, seen) {
|
|
22264
|
+
if (seen.has(variable) || !stableVariable(variable) || variable.defs.length !== 1) return null;
|
|
22265
|
+
seen.add(variable);
|
|
22266
|
+
const definition = variable.defs[0];
|
|
22267
|
+
if (definition?.node.type !== AST_NODE_TYPES100.VariableDeclarator || definition.node.parent.type !== AST_NODE_TYPES100.VariableDeclaration || definition.node.parent.kind !== "const") return null;
|
|
22268
|
+
return definition.node.init;
|
|
22239
22269
|
}
|
|
22240
22270
|
function stableVariable(variable) {
|
|
22241
22271
|
return !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
|
|
@@ -22250,7 +22280,7 @@ function walk(node, visitorKeys, visit, nestedFunction = false) {
|
|
|
22250
22280
|
const nested = nestedFunction || isFunction(node) || node.type === AST_NODE_TYPES100.ClassDeclaration || node.type === AST_NODE_TYPES100.ClassExpression;
|
|
22251
22281
|
forEachAstChild(node, visitorKeys, (child) => walk(child, visitorKeys, visit, nested));
|
|
22252
22282
|
}
|
|
22253
|
-
function classScope(context, node,
|
|
22283
|
+
function classScope(context, node, computedReferences) {
|
|
22254
22284
|
const methods = node.body.body.filter(
|
|
22255
22285
|
(member) => member.type === AST_NODE_TYPES100.MethodDefinition
|
|
22256
22286
|
);
|
|
@@ -22307,7 +22337,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
22307
22337
|
const collectAlias = (current, nestedFunction) => {
|
|
22308
22338
|
if (nestedFunction || current.type !== AST_NODE_TYPES100.VariableDeclarator || current.init === null) return;
|
|
22309
22339
|
const domain = receiverDomain(context, current.init, receivers, method.static);
|
|
22310
|
-
if (domain === null) return;
|
|
22340
|
+
if (domain === null || domain === "unrelated") return;
|
|
22311
22341
|
if (current.id.type === AST_NODE_TYPES100.ObjectPattern) {
|
|
22312
22342
|
pinDestructuredMembers(current.id, domain);
|
|
22313
22343
|
return;
|
|
@@ -22332,11 +22362,12 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
22332
22362
|
const destructuring = receiverDestructuring(current);
|
|
22333
22363
|
if (destructuring !== null) {
|
|
22334
22364
|
const domain2 = receiverDomain(context, destructuring.value, receivers, method.static);
|
|
22335
|
-
pinDestructuredMembers(destructuring.binding, domain2);
|
|
22365
|
+
if (domain2 !== "unrelated") pinDestructuredMembers(destructuring.binding, domain2);
|
|
22336
22366
|
}
|
|
22337
22367
|
if (current.type !== AST_NODE_TYPES100.MemberExpression) return;
|
|
22338
22368
|
const domain = receiverDomain(context, current.object, receivers, method.static);
|
|
22339
22369
|
const targetName = referencedPropertyName(current);
|
|
22370
|
+
if (domain === "unrelated") return;
|
|
22340
22371
|
if (domain === null) {
|
|
22341
22372
|
pinNames(targetName);
|
|
22342
22373
|
return;
|
|
@@ -22370,11 +22401,20 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
22370
22401
|
if (member.type === AST_NODE_TYPES100.MethodDefinition || member.type === AST_NODE_TYPES100.TSAbstractMethodDefinition) continue;
|
|
22371
22402
|
walk(member, context.sourceCode.visitorKeys, (current) => {
|
|
22372
22403
|
if (current.type !== AST_NODE_TYPES100.MemberExpression) return;
|
|
22404
|
+
if (externalReceiverDomain(context, current.object, classReceivers) === "unrelated") return;
|
|
22373
22405
|
pinNames(referencedPropertyName(current));
|
|
22374
22406
|
});
|
|
22375
22407
|
}
|
|
22376
|
-
|
|
22377
|
-
|
|
22408
|
+
const externalReceivers = new Map(classReceivers);
|
|
22409
|
+
for (const variable of context.sourceCode.getDeclaredVariables(node)) {
|
|
22410
|
+
if (stableVariable(variable)) externalReceivers.set(variable, true);
|
|
22411
|
+
}
|
|
22412
|
+
for (const reference of computedReferences) {
|
|
22413
|
+
if (context.sourceCode.getAncestors(reference).includes(node)) continue;
|
|
22414
|
+
const domain = externalReceiverDomain(context, reference.object, externalReceivers);
|
|
22415
|
+
if (domain === "unrelated") continue;
|
|
22416
|
+
const name = referencedPropertyName(reference);
|
|
22417
|
+
if (name !== null || domain !== null) pinNames(name, domain);
|
|
22378
22418
|
}
|
|
22379
22419
|
const memberIndexes = new Map(node.body.body.map((member, index) => [member, index]));
|
|
22380
22420
|
const runtimeBarrierPrefix = [0];
|
|
@@ -22438,6 +22478,7 @@ var stepdown_default = createRule({
|
|
|
22438
22478
|
create(context) {
|
|
22439
22479
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
22440
22480
|
const classes = [];
|
|
22481
|
+
const functionBodies = [];
|
|
22441
22482
|
return {
|
|
22442
22483
|
ClassDeclaration: (node) => {
|
|
22443
22484
|
classes.push(node);
|
|
@@ -22445,13 +22486,17 @@ var stepdown_default = createRule({
|
|
|
22445
22486
|
ClassExpression: (node) => {
|
|
22446
22487
|
classes.push(node);
|
|
22447
22488
|
},
|
|
22489
|
+
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
|
|
22490
|
+
if (isFunction(node) && node.body?.type === AST_NODE_TYPES100.BlockStatement) functionBodies.push(node.body);
|
|
22491
|
+
},
|
|
22448
22492
|
"Program:exit": (program) => {
|
|
22449
|
-
|
|
22450
|
-
const
|
|
22493
|
+
declarationScope(context, program);
|
|
22494
|
+
for (const body2 of functionBodies) declarationScope(context, body2);
|
|
22495
|
+
const computedReferences = [];
|
|
22451
22496
|
walk(program, context.sourceCode.visitorKeys, (node) => {
|
|
22452
|
-
if (node.type === AST_NODE_TYPES100.MemberExpression && node.computed
|
|
22497
|
+
if (node.type === AST_NODE_TYPES100.MemberExpression && node.computed) computedReferences.push(node);
|
|
22453
22498
|
});
|
|
22454
|
-
for (const node of classes) classScope(context, node,
|
|
22499
|
+
for (const node of classes) classScope(context, node, computedReferences);
|
|
22455
22500
|
}
|
|
22456
22501
|
};
|
|
22457
22502
|
}
|
|
@@ -22803,6 +22848,59 @@ function importedAssertionKind(specifier) {
|
|
|
22803
22848
|
|
|
22804
22849
|
// src/rules/sole-export-matches-filename.ts
|
|
22805
22850
|
import { AST_NODE_TYPES as AST_NODE_TYPES102 } from "@typescript-eslint/utils";
|
|
22851
|
+
|
|
22852
|
+
// src/rules/_is-framework-entrypoint.ts
|
|
22853
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
22854
|
+
import { dirname as dirname3, join as join3, relative as relative2 } from "path";
|
|
22855
|
+
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]);
|
|
22856
|
+
var NEXT_COMPONENT = /^(?:src\/)?app\/(?:.*\/)?(?:page|layout|loading|not-found|template|error|global-error|default|forbidden|unauthorized)\.[jt]sx?$/u;
|
|
22857
|
+
var NEXT_ROUTE = /^(?:src\/)?app\/(?:.*\/)?route\.[jt]s$/u;
|
|
22858
|
+
function isFrameworkEntrypoint(filename, exportKey) {
|
|
22859
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
22860
|
+
if (!/(?:^|\/)(?:app|pages)\/|(?:^|\/)(?:middleware|proxy)\.[jt]s$/u.test(normalized)) return false;
|
|
22861
|
+
const owner = packageOwner(normalized);
|
|
22862
|
+
if (owner === null) return false;
|
|
22863
|
+
const path = relative2(owner.root, normalized).replaceAll("\\", "/");
|
|
22864
|
+
if (declaresFramework(owner.metadata, "next") && isNextEntrypoint(path, exportKey)) return true;
|
|
22865
|
+
return declaresFramework(owner.metadata, "astro") && isAstroEntrypoint(path, exportKey);
|
|
22866
|
+
}
|
|
22867
|
+
function isNextEntrypoint(path, exportKey) {
|
|
22868
|
+
const privateAppFolder = /^(?:src\/)?app\/(?:.*\/)?_[^/]+\//u.test(path);
|
|
22869
|
+
if (!privateAppFolder && NEXT_COMPONENT.test(path) && exportKey === "default") return true;
|
|
22870
|
+
if (!privateAppFolder && NEXT_ROUTE.test(path) && HTTP_METHODS.has(exportKey)) return true;
|
|
22871
|
+
if (/^(?:src\/)?pages\/.*\.[jt]sx?$/u.test(path) && exportKey === "default") return true;
|
|
22872
|
+
const middleware = /^(?:src\/)?(middleware|proxy)\.[jt]s$/u.exec(path);
|
|
22873
|
+
return middleware !== null && (exportKey === "default" || exportKey === middleware[1]);
|
|
22874
|
+
}
|
|
22875
|
+
function isAstroEntrypoint(path, exportKey) {
|
|
22876
|
+
return (
|
|
22877
|
+
// Astro pages implicitly export their rendered component, including when only a routing hook is explicit.
|
|
22878
|
+
/^src\/pages\/.*\.astro$/u.test(path) || /^src\/pages\/.*\.[jt]s$/u.test(path) && (HTTP_METHODS.has(exportKey) || exportKey === "ALL") || /^src\/middleware\.[jt]s$/u.test(path) && exportKey === "onRequest"
|
|
22879
|
+
);
|
|
22880
|
+
}
|
|
22881
|
+
function packageOwner(filename) {
|
|
22882
|
+
let root = dirname3(filename);
|
|
22883
|
+
while (true) {
|
|
22884
|
+
try {
|
|
22885
|
+
return { root, metadata: JSON.parse(readFileSync3(join3(root, "package.json"), "utf8")) };
|
|
22886
|
+
} catch (error) {
|
|
22887
|
+
if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") return null;
|
|
22888
|
+
}
|
|
22889
|
+
const parent = dirname3(root);
|
|
22890
|
+
if (parent === root) return null;
|
|
22891
|
+
root = parent;
|
|
22892
|
+
}
|
|
22893
|
+
}
|
|
22894
|
+
function declaresFramework(metadata, name) {
|
|
22895
|
+
if (typeof metadata !== "object" || metadata === null) return false;
|
|
22896
|
+
for (const section of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
22897
|
+
const dependencies = Reflect.get(metadata, section);
|
|
22898
|
+
if (typeof dependencies === "object" && dependencies !== null && typeof Reflect.get(dependencies, name) === "string") return true;
|
|
22899
|
+
}
|
|
22900
|
+
return false;
|
|
22901
|
+
}
|
|
22902
|
+
|
|
22903
|
+
// src/rules/sole-export-matches-filename.ts
|
|
22806
22904
|
var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
22807
22905
|
defaultLevel: "error",
|
|
22808
22906
|
summary: "Make a module filename reflect its sole named public runtime export.",
|
|
@@ -22812,7 +22910,8 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
|
22812
22910
|
limitations: [
|
|
22813
22911
|
"Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS, unresolved re-exports, and emission-dependent exports are excluded.",
|
|
22814
22912
|
"The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker. Supporting types do not exempt a sole runtime export; public runtime aliases count as distinct exports.",
|
|
22815
|
-
"Exported destructuring patterns are excluded rather than undercounted as public exports."
|
|
22913
|
+
"Exported destructuring patterns are excluded rather than undercounted as public exports.",
|
|
22914
|
+
"Next.js and Astro routing exemptions require the nearest package.json to declare the framework, a conventional entrypoint path, and its expected runtime export. Custom routing roots and pageExtensions are not inferred."
|
|
22816
22915
|
],
|
|
22817
22916
|
examples: [
|
|
22818
22917
|
{ 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 },
|
|
@@ -22822,13 +22921,6 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
|
22822
22921
|
var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
|
|
22823
22922
|
"global",
|
|
22824
22923
|
"index",
|
|
22825
|
-
"layout",
|
|
22826
|
-
"loading",
|
|
22827
|
-
"middleware",
|
|
22828
|
-
"not-found",
|
|
22829
|
-
"page",
|
|
22830
|
-
"route",
|
|
22831
|
-
"template",
|
|
22832
22924
|
"types"
|
|
22833
22925
|
]);
|
|
22834
22926
|
function stem3(filename) {
|
|
@@ -22853,7 +22945,7 @@ var sole_export_matches_filename_default = createRule({
|
|
|
22853
22945
|
create(context) {
|
|
22854
22946
|
const fileStem = stem3(context.filename);
|
|
22855
22947
|
const normalizedFilename = context.filename.replaceAll("\\", "/");
|
|
22856
|
-
if (EXCLUDED_STEMS.has(fileStem) || GENERIC_MODULE_STEMS.has(fileStem) ||
|
|
22948
|
+
if (EXCLUDED_STEMS.has(fileStem) || GENERIC_MODULE_STEMS.has(fileStem) || context.filename.endsWith(".d.ts") || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
22857
22949
|
let hasCommonJsExport = false;
|
|
22858
22950
|
return {
|
|
22859
22951
|
"CallExpression, MemberExpression"(node) {
|
|
@@ -22865,6 +22957,7 @@ var sole_export_matches_filename_default = createRule({
|
|
|
22865
22957
|
if (exports.ambiguous || exports.exports.length !== 1) return;
|
|
22866
22958
|
const only = exports.exports[0];
|
|
22867
22959
|
if (only === void 0) return;
|
|
22960
|
+
if (isFrameworkEntrypoint(normalizedFilename, only.key)) return;
|
|
22868
22961
|
if (only.name === "onRouterTransitionStart" && /(?:^|\/)instrumentation-client\.[jt]s$/u.test(normalizedFilename)) return;
|
|
22869
22962
|
if (only.name === "collections" && /(?:^|\/)src\/content\.config\.(?:ts|js|mjs)$/u.test(normalizedFilename) && program.body.some((statement) => statement.type === AST_NODE_TYPES102.ImportDeclaration && statement.source.value === "astro:content")) return;
|
|
22870
22963
|
const exportedStem = kebabCase(only.name);
|
|
@@ -23128,16 +23221,6 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23128
23221
|
const binding = resolvedBinding(identifier);
|
|
23129
23222
|
if (binding !== null) zodBindings.add(binding);
|
|
23130
23223
|
}
|
|
23131
|
-
function isZodChain(node) {
|
|
23132
|
-
const root = calleeChainRoot2(node);
|
|
23133
|
-
if (root === null) return false;
|
|
23134
|
-
const binding = resolvedBinding(root);
|
|
23135
|
-
return binding !== null && zodBindings.has(binding);
|
|
23136
|
-
}
|
|
23137
|
-
function isSchemaBinding(identifier) {
|
|
23138
|
-
const binding = resolvedBinding(identifier);
|
|
23139
|
-
return binding !== null && schemaBindings.has(binding);
|
|
23140
|
-
}
|
|
23141
23224
|
function isConfirmedSchema(expression) {
|
|
23142
23225
|
const init = unwrapExpression8(expression);
|
|
23143
23226
|
if (init.type === AST_NODE_TYPES103.Identifier) return isSchemaBinding(init);
|
|
@@ -23154,6 +23237,16 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23154
23237
|
const root = calleeChainRoot2(init.callee);
|
|
23155
23238
|
return root !== null && isSchemaBinding(root) && SCHEMA_RETURNING_METHODS.has(terminal);
|
|
23156
23239
|
}
|
|
23240
|
+
function isSchemaBinding(identifier) {
|
|
23241
|
+
const binding = resolvedBinding(identifier);
|
|
23242
|
+
return binding !== null && schemaBindings.has(binding);
|
|
23243
|
+
}
|
|
23244
|
+
function isZodChain(node) {
|
|
23245
|
+
const root = calleeChainRoot2(node);
|
|
23246
|
+
if (root === null) return false;
|
|
23247
|
+
const binding = resolvedBinding(root);
|
|
23248
|
+
return binding !== null && zodBindings.has(binding);
|
|
23249
|
+
}
|
|
23157
23250
|
if (isTestFile(context.filename) || BENCHMARK_PATH_RE2.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
23158
23251
|
return {};
|
|
23159
23252
|
}
|
|
@@ -23385,7 +23478,7 @@ var RULES = {
|
|
|
23385
23478
|
};
|
|
23386
23479
|
var meta = {
|
|
23387
23480
|
name: "@sarj/eslint-plugin",
|
|
23388
|
-
version: "16.
|
|
23481
|
+
version: "16.1.0"
|
|
23389
23482
|
};
|
|
23390
23483
|
var APPLICATION_ONLY_RULES = [];
|
|
23391
23484
|
var LIBRARY_IMPORT_POLICY = ["error", {
|