@sarj/eslint-plugin 15.28.1 → 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 +848 -747
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +845 -744
- package/dist/rule-examples.cjs +4 -4
- package/dist/rule-examples.js +1 -1
- 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
|
}
|
|
@@ -7503,20 +7503,9 @@ var no_vague_suppression_description_default = createRule({
|
|
|
7503
7503
|
}
|
|
7504
7504
|
});
|
|
7505
7505
|
|
|
7506
|
-
// src/rules/
|
|
7506
|
+
// src/rules/_runtime-exports.ts
|
|
7507
7507
|
import { AST_NODE_TYPES as AST_NODE_TYPES40, ASTUtils as ASTUtils16 } from "@typescript-eslint/utils";
|
|
7508
|
-
var
|
|
7509
|
-
summary: "Disallow generic module stems when one runtime export already names the responsibility.",
|
|
7510
|
-
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
7511
|
-
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
7512
|
-
category: "maintainability",
|
|
7513
|
-
limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
|
|
7514
|
-
examples: [
|
|
7515
|
-
{ id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/parse-order.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/parse-order.ts", expectedCount: 0, public: true },
|
|
7516
|
-
{ id: "generic-module-name", title: "Do not hide one export in a generic module", outcome: "match", files: [{ path: "src/utils.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/utils.ts", expectedCount: 1, public: true }
|
|
7517
|
-
]
|
|
7518
|
-
};
|
|
7519
|
-
var GENERIC_STEMS = /* @__PURE__ */ new Set([
|
|
7508
|
+
var GENERIC_MODULE_STEMS = /* @__PURE__ */ new Set([
|
|
7520
7509
|
"common",
|
|
7521
7510
|
"helper",
|
|
7522
7511
|
"helpers",
|
|
@@ -7527,164 +7516,172 @@ var GENERIC_STEMS = /* @__PURE__ */ new Set([
|
|
|
7527
7516
|
"utils"
|
|
7528
7517
|
]);
|
|
7529
7518
|
var CJS_OBJECT_EXPORT_METHODS = /* @__PURE__ */ new Set(["assign", "defineProperties", "defineProperty"]);
|
|
7530
|
-
function fileParts(filename) {
|
|
7531
|
-
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
7532
|
-
const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
|
|
7533
|
-
const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
|
|
7534
|
-
return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
|
|
7535
|
-
}
|
|
7536
|
-
function declaredNames(declaration) {
|
|
7537
|
-
if (declaration.declare === true) return [];
|
|
7538
|
-
if (declaration.type === AST_NODE_TYPES40.FunctionDeclaration || declaration.type === AST_NODE_TYPES40.ClassDeclaration || declaration.type === AST_NODE_TYPES40.TSEnumDeclaration) {
|
|
7539
|
-
if (declaration.type === AST_NODE_TYPES40.TSEnumDeclaration && declaration.const) return [];
|
|
7540
|
-
return declaration.id === null ? [] : [declaration.id.name];
|
|
7541
|
-
}
|
|
7542
|
-
if (declaration.type === AST_NODE_TYPES40.TSModuleDeclaration && declaration.id.type === AST_NODE_TYPES40.Identifier) {
|
|
7543
|
-
return [declaration.id.name];
|
|
7544
|
-
}
|
|
7545
|
-
if (declaration.type !== AST_NODE_TYPES40.VariableDeclaration) return [];
|
|
7546
|
-
return declaration.declarations.flatMap(
|
|
7547
|
-
(item) => item.id.type === AST_NODE_TYPES40.Identifier ? [item.id.name] : []
|
|
7548
|
-
);
|
|
7549
|
-
}
|
|
7550
7519
|
function runtimeExports(program) {
|
|
7551
|
-
const
|
|
7552
|
-
const
|
|
7520
|
+
const bindings = localBindings(program);
|
|
7521
|
+
const exports = /* @__PURE__ */ new Map();
|
|
7553
7522
|
let ambiguous = false;
|
|
7554
|
-
function
|
|
7555
|
-
if (
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
}
|
|
7563
|
-
|
|
7523
|
+
function add(key, name, node, emission) {
|
|
7524
|
+
if (emission === "unknown") ambiguous = true;
|
|
7525
|
+
if (emission === "runtime") exports.set(key, { key, name, node });
|
|
7526
|
+
}
|
|
7527
|
+
function collectDefault(statement) {
|
|
7528
|
+
const declaration = statement.declaration;
|
|
7529
|
+
if (declaration.type === AST_NODE_TYPES40.Identifier) {
|
|
7530
|
+
add("default", declaration.name, statement, bindings.get(declaration.name) ?? "unknown");
|
|
7531
|
+
} else if ("id" in declaration && declaration.id?.type === AST_NODE_TYPES40.Identifier) {
|
|
7532
|
+
add("default", declaration.id.name, declaration, declarationEmission(declaration));
|
|
7533
|
+
} else ambiguous = true;
|
|
7534
|
+
}
|
|
7535
|
+
function collectNamed(statement) {
|
|
7536
|
+
if (statement.exportKind === "type") return;
|
|
7564
7537
|
if (statement.source !== null) {
|
|
7565
7538
|
if (statement.specifiers.some((specifier) => specifier.exportKind !== "type")) ambiguous = true;
|
|
7566
7539
|
return;
|
|
7567
7540
|
}
|
|
7568
|
-
|
|
7569
|
-
|
|
7541
|
+
const declaration = statement.declaration;
|
|
7542
|
+
if (declaration !== null) {
|
|
7570
7543
|
if (declaration.type === AST_NODE_TYPES40.VariableDeclaration && declaration.declarations.some((item) => item.id.type !== AST_NODE_TYPES40.Identifier)) ambiguous = true;
|
|
7571
|
-
|
|
7544
|
+
const names = declarationNames(declaration);
|
|
7545
|
+
if (names.length === 0 && declarationEmission(declaration) !== "erased") ambiguous = true;
|
|
7546
|
+
for (const name of names) add(name, name, declaration, bindings.get(name) ?? "unknown");
|
|
7572
7547
|
}
|
|
7573
|
-
collectExportSpecifiers(statement);
|
|
7574
|
-
}
|
|
7575
|
-
function collectExportSpecifiers(statement) {
|
|
7576
7548
|
for (const specifier of statement.specifiers) {
|
|
7577
|
-
if (specifier.exportKind === "type"
|
|
7578
|
-
const
|
|
7549
|
+
if (specifier.exportKind === "type") continue;
|
|
7550
|
+
const key = specifier.exported.type === AST_NODE_TYPES40.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
7579
7551
|
const local = specifier.local.name;
|
|
7580
|
-
|
|
7552
|
+
add(key, key === "default" ? local : key, specifier, bindings.get(local) ?? "unknown");
|
|
7581
7553
|
}
|
|
7582
7554
|
}
|
|
7583
|
-
function collectDefaultExport(statement) {
|
|
7584
|
-
const declaration = statement.declaration;
|
|
7585
|
-
if (declaration.type === AST_NODE_TYPES40.Identifier) {
|
|
7586
|
-
if (!typeBindings.has(declaration.name)) {
|
|
7587
|
-
exports.push({ key: "default", name: declaration.name, node: statement });
|
|
7588
|
-
}
|
|
7589
|
-
} else if ((declaration.type === AST_NODE_TYPES40.FunctionDeclaration || declaration.type === AST_NODE_TYPES40.ClassDeclaration) && declaration.id !== null && declaration.declare !== true) exports.push({ key: "default", name: declaration.id.name, node: declaration });
|
|
7590
|
-
else if (declaration.type !== AST_NODE_TYPES40.TSInterfaceDeclaration && declaration.type !== AST_NODE_TYPES40.TSTypeAliasDeclaration) ambiguous = true;
|
|
7591
|
-
}
|
|
7592
7555
|
for (const statement of program.body) {
|
|
7593
|
-
|
|
7556
|
+
if (statement.type === AST_NODE_TYPES40.ExportAllDeclaration && statement.exportKind !== "type") ambiguous = true;
|
|
7557
|
+
if (statement.type === AST_NODE_TYPES40.TSExportAssignment) ambiguous = true;
|
|
7558
|
+
if (statement.type === AST_NODE_TYPES40.ExportDefaultDeclaration) collectDefault(statement);
|
|
7559
|
+
if (statement.type === AST_NODE_TYPES40.ExportNamedDeclaration) collectNamed(statement);
|
|
7594
7560
|
}
|
|
7595
|
-
|
|
7596
|
-
return { exports: [...unique.values()], ambiguous };
|
|
7561
|
+
return { exports: [...exports.values()], ambiguous };
|
|
7597
7562
|
}
|
|
7598
|
-
function
|
|
7599
|
-
const
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
if (
|
|
7604
|
-
|
|
7605
|
-
return;
|
|
7606
|
-
}
|
|
7607
|
-
if (declaration?.type === AST_NODE_TYPES40.TSEnumDeclaration && declaration.const) {
|
|
7608
|
-
names.add(declaration.id.name);
|
|
7609
|
-
return;
|
|
7610
|
-
}
|
|
7611
|
-
if (statement.type === AST_NODE_TYPES40.ImportDeclaration) {
|
|
7612
|
-
collectImportBindings(statement);
|
|
7613
|
-
return;
|
|
7614
|
-
}
|
|
7615
|
-
if (declaration?.type === AST_NODE_TYPES40.TSDeclareFunction && declaration.id !== null) {
|
|
7616
|
-
names.add(declaration.id.name);
|
|
7617
|
-
return;
|
|
7618
|
-
}
|
|
7619
|
-
if (declaration !== null && declaration.declare === true) {
|
|
7620
|
-
collectDeclaredNames(declaration);
|
|
7621
|
-
return;
|
|
7622
|
-
}
|
|
7623
|
-
if (declaration !== null && "type" in declaration) {
|
|
7624
|
-
for (const name of declaredNames(declaration)) {
|
|
7625
|
-
runtimeNames.add(name);
|
|
7626
|
-
}
|
|
7627
|
-
}
|
|
7563
|
+
function localBindings(program) {
|
|
7564
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
7565
|
+
function register(name, emission) {
|
|
7566
|
+
const previous = bindings.get(name);
|
|
7567
|
+
if (previous === "runtime" || emission === "runtime") bindings.set(name, "runtime");
|
|
7568
|
+
else if (previous === "unknown" || emission === "unknown") bindings.set(name, "unknown");
|
|
7569
|
+
else bindings.set(name, "erased");
|
|
7628
7570
|
}
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
runtimeNames.add(specifier.local.name);
|
|
7571
|
+
for (const statement of program.body) {
|
|
7572
|
+
if (statement.type === AST_NODE_TYPES40.ImportDeclaration) {
|
|
7573
|
+
for (const specifier of statement.specifiers) {
|
|
7574
|
+
const typeOnly = statement.importKind === "type" || specifier.type === AST_NODE_TYPES40.ImportSpecifier && specifier.importKind === "type";
|
|
7575
|
+
register(specifier.local.name, typeOnly ? "erased" : "unknown");
|
|
7635
7576
|
}
|
|
7577
|
+
continue;
|
|
7636
7578
|
}
|
|
7579
|
+
const declaration = statement.type === AST_NODE_TYPES40.ExportNamedDeclaration || statement.type === AST_NODE_TYPES40.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
7580
|
+
if (declaration === null) continue;
|
|
7581
|
+
for (const name of declarationNames(declaration)) register(name, declarationEmission(declaration));
|
|
7637
7582
|
}
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7583
|
+
return bindings;
|
|
7584
|
+
}
|
|
7585
|
+
function declarationNames(declaration) {
|
|
7586
|
+
if ("id" in declaration && declaration.id !== null) {
|
|
7587
|
+
let id = declaration.id;
|
|
7588
|
+
while (id.type === AST_NODE_TYPES40.TSQualifiedName) id = id.left;
|
|
7589
|
+
if (id.type === AST_NODE_TYPES40.Identifier) return [id.name];
|
|
7645
7590
|
}
|
|
7646
|
-
|
|
7647
|
-
|
|
7591
|
+
if (declaration.type !== AST_NODE_TYPES40.VariableDeclaration) return [];
|
|
7592
|
+
return declaration.declarations.flatMap((item) => item.id.type === AST_NODE_TYPES40.Identifier ? [item.id.name] : []);
|
|
7593
|
+
}
|
|
7594
|
+
function declarationEmission(declaration) {
|
|
7595
|
+
if ("declare" in declaration && declaration.declare === true) return "erased";
|
|
7596
|
+
switch (declaration.type) {
|
|
7597
|
+
case AST_NODE_TYPES40.TSInterfaceDeclaration:
|
|
7598
|
+
case AST_NODE_TYPES40.TSTypeAliasDeclaration:
|
|
7599
|
+
case AST_NODE_TYPES40.TSDeclareFunction:
|
|
7600
|
+
return "erased";
|
|
7601
|
+
case AST_NODE_TYPES40.ClassDeclaration:
|
|
7602
|
+
case AST_NODE_TYPES40.FunctionDeclaration:
|
|
7603
|
+
case AST_NODE_TYPES40.VariableDeclaration:
|
|
7604
|
+
return "runtime";
|
|
7605
|
+
case AST_NODE_TYPES40.TSEnumDeclaration:
|
|
7606
|
+
return declaration.const ? "unknown" : "runtime";
|
|
7607
|
+
case AST_NODE_TYPES40.TSModuleDeclaration:
|
|
7608
|
+
return namespaceEmission(declaration);
|
|
7609
|
+
default:
|
|
7610
|
+
return "unknown";
|
|
7648
7611
|
}
|
|
7649
|
-
return new Set([...names].filter((name) => !runtimeNames.has(name)));
|
|
7650
7612
|
}
|
|
7651
|
-
function
|
|
7652
|
-
const
|
|
7653
|
-
|
|
7613
|
+
function namespaceEmission(declaration) {
|
|
7614
|
+
const { body: body2 } = declaration;
|
|
7615
|
+
if (body2 === void 0) return "unknown";
|
|
7616
|
+
if (body2.body.length === 0) return "unknown";
|
|
7617
|
+
let ambiguous = false;
|
|
7618
|
+
for (const statement of body2.body) {
|
|
7619
|
+
if (statement.type === AST_NODE_TYPES40.ExportNamedDeclaration && statement.exportKind === "type") continue;
|
|
7620
|
+
const inner = statement.type === AST_NODE_TYPES40.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7621
|
+
const emission = inner === null ? "unknown" : declarationEmission(inner);
|
|
7622
|
+
if (emission === "runtime") return "runtime";
|
|
7623
|
+
if (emission === "unknown") ambiguous = true;
|
|
7624
|
+
}
|
|
7625
|
+
return ambiguous ? "unknown" : "erased";
|
|
7654
7626
|
}
|
|
7655
|
-
function
|
|
7656
|
-
|
|
7657
|
-
|
|
7627
|
+
function isCommonJsExportReference(node, sourceCode) {
|
|
7628
|
+
function isGlobal(node2) {
|
|
7629
|
+
const variable = ASTUtils16.findVariable(sourceCode.getScope(node2), node2.name);
|
|
7630
|
+
return variable === null || variable.defs.length === 0;
|
|
7631
|
+
}
|
|
7632
|
+
if (node.type === AST_NODE_TYPES40.MemberExpression) {
|
|
7633
|
+
return node.object.type === AST_NODE_TYPES40.Identifier && isGlobal(node.object) && (node.object.name === "exports" || node.object.name === "module" && memberPropertyName(node) === "exports");
|
|
7634
|
+
}
|
|
7635
|
+
const first = node.arguments[0];
|
|
7636
|
+
return first?.type === AST_NODE_TYPES40.Identifier && first.name === "exports" && isGlobal(first) && node.callee.type === AST_NODE_TYPES40.MemberExpression && node.callee.object.type === AST_NODE_TYPES40.Identifier && node.callee.object.name === "Object" && isGlobal(node.callee.object) && CJS_OBJECT_EXPORT_METHODS.has(memberPropertyName(node.callee) ?? "");
|
|
7658
7637
|
}
|
|
7659
7638
|
function memberPropertyName(node) {
|
|
7660
7639
|
if (!node.computed && node.property.type === AST_NODE_TYPES40.Identifier) return node.property.name;
|
|
7661
7640
|
return node.computed && node.property.type === AST_NODE_TYPES40.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
7662
7641
|
}
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
}
|
|
7642
|
+
|
|
7643
|
+
// src/rules/no-generic-single-export-module.ts
|
|
7644
|
+
var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
|
|
7645
|
+
summary: "Disallow generic module stems when one runtime export already names the responsibility.",
|
|
7646
|
+
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
7647
|
+
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
7648
|
+
category: "maintainability",
|
|
7649
|
+
limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
|
|
7650
|
+
examples: [
|
|
7651
|
+
{ id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/parse-order.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/parse-order.ts", expectedCount: 0, public: true },
|
|
7652
|
+
{ id: "generic-module-name", title: "Do not hide one export in a generic module", outcome: "match", files: [{ path: "src/utils.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/utils.ts", expectedCount: 1, public: true }
|
|
7653
|
+
]
|
|
7654
|
+
};
|
|
7655
|
+
function fileParts(filename) {
|
|
7656
|
+
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
7657
|
+
const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
|
|
7658
|
+
const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
|
|
7659
|
+
return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
|
|
7660
|
+
}
|
|
7661
|
+
function isConventionalFrameworkUtility(filename, exported) {
|
|
7662
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
7663
|
+
return exported === "cn" && /(?:^|\/)lib\/utils\.[cm]?[jt]sx?$/u.test(normalized);
|
|
7664
|
+
}
|
|
7665
|
+
var no_generic_single_export_module_default = createRule({
|
|
7666
|
+
name: "no-generic-single-export-module",
|
|
7667
|
+
documentation: NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION,
|
|
7668
|
+
meta: {
|
|
7669
|
+
type: "suggestion",
|
|
7670
|
+
docs: { description: "Disallow generic module stems when one runtime export already names the responsibility." },
|
|
7671
|
+
schema: [],
|
|
7672
|
+
messages: {
|
|
7673
|
+
genericSingleExport: "Module stem `{{stem}}` is generic and its only runtime export is `{{exported}}`; choose a responsibility-bearing module name or colocate the export with its domain."
|
|
7674
|
+
}
|
|
7673
7675
|
},
|
|
7674
7676
|
defaultOptions: [],
|
|
7675
7677
|
create(context) {
|
|
7676
7678
|
const file = fileParts(context.filename);
|
|
7677
7679
|
const { stem: stem4 } = file;
|
|
7678
|
-
if (!
|
|
7680
|
+
if (!GENERIC_MODULE_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
7679
7681
|
let hasCommonJsExport = false;
|
|
7680
7682
|
return {
|
|
7681
|
-
CallExpression(node) {
|
|
7682
|
-
|
|
7683
|
-
if (first?.type === AST_NODE_TYPES40.Identifier && first.name === "exports" && isGlobalIdentifier2(context, first) && node.callee.type === AST_NODE_TYPES40.MemberExpression && node.callee.object.type === AST_NODE_TYPES40.Identifier && node.callee.object.name === "Object" && isGlobalIdentifier2(context, node.callee.object) && memberPropertyName(node.callee) !== null && CJS_OBJECT_EXPORT_METHODS.has(memberPropertyName(node.callee))) hasCommonJsExport = true;
|
|
7684
|
-
},
|
|
7685
|
-
MemberExpression(node) {
|
|
7686
|
-
if (node.object.type === AST_NODE_TYPES40.Identifier && node.object.name === "exports" && isGlobalIdentifier2(context, node.object)) hasCommonJsExport = true;
|
|
7687
|
-
if (node.object.type === AST_NODE_TYPES40.Identifier && node.object.name === "module" && isGlobalIdentifier2(context, node.object) && memberPropertyName(node) === "exports") hasCommonJsExport = true;
|
|
7683
|
+
"CallExpression, MemberExpression"(node) {
|
|
7684
|
+
if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
|
|
7688
7685
|
},
|
|
7689
7686
|
"Program:exit"(program) {
|
|
7690
7687
|
if (hasCommonJsExport) return;
|
|
@@ -8034,6 +8031,10 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8034
8031
|
data: { name, count: String(tuple.elements.length) }
|
|
8035
8032
|
});
|
|
8036
8033
|
};
|
|
8034
|
+
const enterFunction = (node) => {
|
|
8035
|
+
functionStack.push(node);
|
|
8036
|
+
check(node);
|
|
8037
|
+
};
|
|
8037
8038
|
const check = (node) => {
|
|
8038
8039
|
if (isQueryKeyFactory(node)) return;
|
|
8039
8040
|
const annotation = node.returnType?.typeAnnotation;
|
|
@@ -8049,10 +8050,6 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8049
8050
|
}
|
|
8050
8051
|
report2(annotation, name);
|
|
8051
8052
|
};
|
|
8052
|
-
const enterFunction = (node) => {
|
|
8053
|
-
functionStack.push(node);
|
|
8054
|
-
check(node);
|
|
8055
|
-
};
|
|
8056
8053
|
const exitFunction = () => {
|
|
8057
8054
|
functionStack.pop();
|
|
8058
8055
|
};
|
|
@@ -8499,32 +8496,16 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8499
8496
|
const definition = variable.defs[0];
|
|
8500
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;
|
|
8501
8498
|
}
|
|
8502
|
-
function
|
|
8503
|
-
if (node
|
|
8504
|
-
|
|
8505
|
-
for (const property of [...node.properties].reverse()) {
|
|
8506
|
-
if (property.type !== AST_NODE_TYPES42.Property || property.computed) continue;
|
|
8507
|
-
const key = property.key;
|
|
8508
|
-
const keyName = key.type === AST_NODE_TYPES42.Identifier ? key.name : key.type === AST_NODE_TYPES42.Literal && typeof key.value === "string" ? key.value : null;
|
|
8509
|
-
if (keyName !== name) continue;
|
|
8510
|
-
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;
|
|
8511
|
-
}
|
|
8512
|
-
return null;
|
|
8513
|
-
}
|
|
8514
|
-
function isInternalApiUrl(node) {
|
|
8515
|
-
const resolved = resolveNode2(node ?? void 0);
|
|
8516
|
-
if (resolved?.type === AST_NODE_TYPES42.Literal) {
|
|
8517
|
-
return typeof resolved.value === "string" && internalApiPrefixes.some(
|
|
8518
|
-
(prefix) => resolved.value === prefix || resolved.value.startsWith(`${prefix}/`)
|
|
8519
|
-
);
|
|
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;
|
|
8520
8502
|
}
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
);
|
|
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;
|
|
8526
8507
|
}
|
|
8527
|
-
return
|
|
8508
|
+
return isMutationMethod2(propertyValue(resolveNode2(init), "method"));
|
|
8528
8509
|
}
|
|
8529
8510
|
function isMutationMethod2(node) {
|
|
8530
8511
|
const resolved = resolveNode2(node ?? void 0);
|
|
@@ -8541,16 +8522,32 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8541
8522
|
}
|
|
8542
8523
|
return resolved?.type === AST_NODE_TYPES42.LogicalExpression && resolved.operator === "||" && (isMutationMethod2(resolved.left) || isMutationMethod2(resolved.right));
|
|
8543
8524
|
}
|
|
8544
|
-
function
|
|
8545
|
-
|
|
8546
|
-
|
|
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
|
+
);
|
|
8547
8531
|
}
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
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
|
+
);
|
|
8552
8537
|
}
|
|
8553
|
-
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;
|
|
8554
8551
|
}
|
|
8555
8552
|
if (allowed.some((re) => re.test(filename))) {
|
|
8556
8553
|
return {};
|
|
@@ -9225,19 +9222,19 @@ var no_restated_jsdoc_default = createRule({
|
|
|
9225
9222
|
function enclosingDeclarationNames(node) {
|
|
9226
9223
|
let declaration = null;
|
|
9227
9224
|
while (node != null && node.type !== AST_NODE_TYPES47.Program) {
|
|
9228
|
-
declaration =
|
|
9225
|
+
declaration = declarationNames2(node);
|
|
9229
9226
|
if (declaration !== null) break;
|
|
9230
9227
|
node = node.parent ?? null;
|
|
9231
9228
|
}
|
|
9232
9229
|
return declaration;
|
|
9233
9230
|
}
|
|
9234
|
-
function
|
|
9231
|
+
function declarationNames2(node) {
|
|
9235
9232
|
switch (node.type) {
|
|
9236
9233
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
9237
9234
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
9238
9235
|
case AST_NODE_TYPES47.ExportNamedDeclaration:
|
|
9239
9236
|
case AST_NODE_TYPES47.ExportDefaultDeclaration:
|
|
9240
|
-
return node.declaration == null ? null :
|
|
9237
|
+
return node.declaration == null ? null : declarationNames2(node.declaration);
|
|
9241
9238
|
case AST_NODE_TYPES47.FunctionDeclaration:
|
|
9242
9239
|
case AST_NODE_TYPES47.TSDeclareFunction:
|
|
9243
9240
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
@@ -9649,35 +9646,30 @@ var no_secret_in_log_default = createRule({
|
|
|
9649
9646
|
create(context, [loggingOptions]) {
|
|
9650
9647
|
const matcher = createLogMatcher(loggingOptions);
|
|
9651
9648
|
const blobArmApplies = !isTestFile(context.filename);
|
|
9652
|
-
function
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
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;
|
|
9656
9656
|
}
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
const value = valueName(prop.value);
|
|
9663
|
-
if (value !== null && hasRedactionMarker(value)) return false;
|
|
9664
|
-
const name = value !== null && isSecretKeyword(value) ? value : keyName;
|
|
9665
|
-
if (name === null || !isSecretKeyword(name) || !isRawSecretValue(prop)) {
|
|
9666
|
-
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;
|
|
9667
9662
|
}
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
function reportRawBlob(node, value) {
|
|
9672
|
-
if (!blobArmApplies) {
|
|
9673
|
-
return false;
|
|
9663
|
+
if (value.type === "TemplateLiteral") {
|
|
9664
|
+
for (const expression of value.expressions) inspectLoggedValue(expression);
|
|
9665
|
+
return;
|
|
9674
9666
|
}
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
return
|
|
9667
|
+
if (value.type === "BinaryExpression" && value.operator === "+") {
|
|
9668
|
+
inspectLoggedValue(value.left);
|
|
9669
|
+
inspectLoggedValue(value.right);
|
|
9670
|
+
return;
|
|
9679
9671
|
}
|
|
9680
|
-
|
|
9672
|
+
if (!reportSecretArgument(value)) reportRawBlob(value, value);
|
|
9681
9673
|
}
|
|
9682
9674
|
function literalProperties(value) {
|
|
9683
9675
|
const effective = /* @__PURE__ */ new Map();
|
|
@@ -9702,30 +9694,35 @@ var no_secret_in_log_default = createRule({
|
|
|
9702
9694
|
}
|
|
9703
9695
|
return [...effective.values()];
|
|
9704
9696
|
}
|
|
9705
|
-
function
|
|
9706
|
-
if (
|
|
9707
|
-
|
|
9708
|
-
if (reportSecretProperty(property) || reportRawBlob(property, property.value)) continue;
|
|
9709
|
-
inspectLoggedValue(property.value);
|
|
9710
|
-
}
|
|
9711
|
-
return;
|
|
9697
|
+
function reportRawBlob(node, value) {
|
|
9698
|
+
if (!blobArmApplies) {
|
|
9699
|
+
return false;
|
|
9712
9700
|
}
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
return;
|
|
9701
|
+
const name = rawBlobValueName(value);
|
|
9702
|
+
if (name !== null) {
|
|
9703
|
+
context.report({ node, messageId: "noRawBodyInLog", data: { name } });
|
|
9704
|
+
return true;
|
|
9718
9705
|
}
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
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;
|
|
9722
9715
|
}
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
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;
|
|
9727
9723
|
}
|
|
9728
|
-
|
|
9724
|
+
context.report({ node: arg, messageId: "noSecretInLog", data: { name } });
|
|
9725
|
+
return true;
|
|
9729
9726
|
}
|
|
9730
9727
|
return {
|
|
9731
9728
|
CallExpression(node) {
|
|
@@ -10023,9 +10020,6 @@ function bindsName(param, name) {
|
|
|
10023
10020
|
}
|
|
10024
10021
|
function subtreeReadsName(node, name) {
|
|
10025
10022
|
let found = false;
|
|
10026
|
-
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10027
|
-
(param) => bindsName(param, name)
|
|
10028
|
-
);
|
|
10029
10023
|
const recurse = (current) => {
|
|
10030
10024
|
if (found) {
|
|
10031
10025
|
return;
|
|
@@ -10042,6 +10036,9 @@ function subtreeReadsName(node, name) {
|
|
|
10042
10036
|
return found;
|
|
10043
10037
|
}, (key) => !isNonReadingProperty(current, key));
|
|
10044
10038
|
};
|
|
10039
|
+
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10040
|
+
(param) => bindsName(param, name)
|
|
10041
|
+
);
|
|
10045
10042
|
recurse(node);
|
|
10046
10043
|
return found;
|
|
10047
10044
|
}
|
|
@@ -11903,14 +11900,6 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11903
11900
|
const trail = startingOn.get(member.loc.end.line);
|
|
11904
11901
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
11905
11902
|
}
|
|
11906
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
11907
|
-
if (comment.loc.end.line >= member.node.loc.start.line) return false;
|
|
11908
|
-
const body2 = commentBody(comment);
|
|
11909
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
11910
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
11911
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
11912
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
11913
|
-
}
|
|
11914
11903
|
function check(node, members) {
|
|
11915
11904
|
const judged = members.map(named).filter((member) => member !== void 0);
|
|
11916
11905
|
if (judged.length === 0) return;
|
|
@@ -11949,6 +11938,14 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11949
11938
|
data: { restated: String(restated), commented: String(commented) }
|
|
11950
11939
|
});
|
|
11951
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
|
+
}
|
|
11952
11949
|
return {
|
|
11953
11950
|
ClassBody: (node) => {
|
|
11954
11951
|
check(node, node.body);
|
|
@@ -12184,14 +12181,6 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12184
12181
|
const trail = startingOn.get(member.loc.end.line);
|
|
12185
12182
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
12186
12183
|
}
|
|
12187
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
12188
|
-
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
12189
|
-
const body2 = commentBody(comment);
|
|
12190
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
12191
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
12192
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
12193
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
12194
|
-
}
|
|
12195
12184
|
function check(node) {
|
|
12196
12185
|
const members = node.type === AST_NODE_TYPES56.TSInterfaceBody ? node.body : node.members;
|
|
12197
12186
|
const named2 = members.filter(isNamedMember);
|
|
@@ -12227,6 +12216,14 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12227
12216
|
data: { restated: String(restated), commented: String(commented) }
|
|
12228
12217
|
});
|
|
12229
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
|
+
}
|
|
12230
12227
|
return {
|
|
12231
12228
|
TSInterfaceBody: check,
|
|
12232
12229
|
TSTypeLiteral: check
|
|
@@ -12545,6 +12542,11 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12545
12542
|
const binding = resolve2(identifier);
|
|
12546
12543
|
if (binding !== null) destination.add(binding);
|
|
12547
12544
|
}
|
|
12545
|
+
function checkAssertion(node) {
|
|
12546
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12547
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12548
12550
|
function isMockTypeReference(node) {
|
|
12549
12551
|
if (node.type !== AST_NODE_TYPES58.TSTypeReference) return false;
|
|
12550
12552
|
const typeName = node.typeName;
|
|
@@ -12558,11 +12560,6 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12558
12560
|
}
|
|
12559
12561
|
return false;
|
|
12560
12562
|
}
|
|
12561
|
-
function checkAssertion(node) {
|
|
12562
|
-
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12563
|
-
context.report({ node, messageId: "unsafeMockCast" });
|
|
12564
|
-
}
|
|
12565
|
-
}
|
|
12566
12563
|
return {
|
|
12567
12564
|
ImportDeclaration(node) {
|
|
12568
12565
|
if (!MOCK_MODULES.has(node.source.value)) return;
|
|
@@ -17897,7 +17894,7 @@ var staticallyImportsExternalRenderer = (program) => program.body.some((statemen
|
|
|
17897
17894
|
var semanticForegroundRoles = (filename) => {
|
|
17898
17895
|
const packageRoot = nearestPackageRoot(dirname2(filename));
|
|
17899
17896
|
if (packageRoot === null) return /* @__PURE__ */ new Set();
|
|
17900
|
-
const candidates = CSS_DETECTION_FILES.map((
|
|
17897
|
+
const candidates = CSS_DETECTION_FILES.map((relative3) => join2(packageRoot, relative3));
|
|
17901
17898
|
const fingerprint = candidates.map(fileFingerprint2).join("|");
|
|
17902
17899
|
const cached = SEMANTIC_DECLARATIONS_CACHE.get(packageRoot);
|
|
17903
17900
|
if (cached?.fingerprint === fingerprint) return cached.value;
|
|
@@ -17980,37 +17977,6 @@ var prefer_semantic_colors_default = createRule({
|
|
|
17980
17977
|
const key = `${node.range[0]}:${node.range[1]}:${messageId}:${JSON.stringify(data)}`;
|
|
17981
17978
|
pendingReports.set(key, { node, messageId, data });
|
|
17982
17979
|
};
|
|
17983
|
-
const reportClasses = (value, node) => {
|
|
17984
|
-
const tokens = classTokens(value);
|
|
17985
|
-
for (const token of tokens) {
|
|
17986
|
-
const base = tailwindBase(token);
|
|
17987
|
-
if (RAW_PALETTE_RE.test(base)) {
|
|
17988
|
-
report2(node, "rawPalette", { class: token });
|
|
17989
|
-
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
17990
|
-
report2(node, "arbitraryColor", { class: token });
|
|
17991
|
-
}
|
|
17992
|
-
}
|
|
17993
|
-
if (!checkOpaqueForegroundPairs || isInsideSvg(node)) return;
|
|
17994
|
-
for (const token of tokens) {
|
|
17995
|
-
const prefix = tailwindVariantPrefix(token);
|
|
17996
|
-
if (prefix.split(":").includes("print")) continue;
|
|
17997
|
-
const base = tailwindBase(token);
|
|
17998
|
-
if (!OPAQUE_FOREGROUND_RE.test(base)) continue;
|
|
17999
|
-
const semanticBackground = tokens.find((candidate2) => {
|
|
18000
|
-
if (tailwindVariantPrefix(candidate2) !== prefix) return false;
|
|
18001
|
-
const match = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(candidate2));
|
|
18002
|
-
return match?.[1] !== void 0 && foregroundRoles.has(match[1]);
|
|
18003
|
-
});
|
|
18004
|
-
if (semanticBackground === void 0) continue;
|
|
18005
|
-
const role = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(semanticBackground))?.[1];
|
|
18006
|
-
if (role === void 0) continue;
|
|
18007
|
-
report2(node, "opaqueForegroundPair", {
|
|
18008
|
-
background: semanticBackground,
|
|
18009
|
-
class: token,
|
|
18010
|
-
replacement: `${prefix}text-${role}-foreground`
|
|
18011
|
-
});
|
|
18012
|
-
}
|
|
18013
|
-
};
|
|
18014
17980
|
const checkClassNode = (node, objectKeys = false) => {
|
|
18015
17981
|
if (node === null) return;
|
|
18016
17982
|
switch (node.type) {
|
|
@@ -18039,6 +18005,37 @@ var prefer_semantic_colors_default = createRule({
|
|
|
18039
18005
|
break;
|
|
18040
18006
|
}
|
|
18041
18007
|
};
|
|
18008
|
+
const reportClasses = (value, node) => {
|
|
18009
|
+
const tokens = classTokens(value);
|
|
18010
|
+
for (const token of tokens) {
|
|
18011
|
+
const base = tailwindBase(token);
|
|
18012
|
+
if (RAW_PALETTE_RE.test(base)) {
|
|
18013
|
+
report2(node, "rawPalette", { class: token });
|
|
18014
|
+
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
18015
|
+
report2(node, "arbitraryColor", { class: token });
|
|
18016
|
+
}
|
|
18017
|
+
}
|
|
18018
|
+
if (!checkOpaqueForegroundPairs || isInsideSvg(node)) return;
|
|
18019
|
+
for (const token of tokens) {
|
|
18020
|
+
const prefix = tailwindVariantPrefix(token);
|
|
18021
|
+
if (prefix.split(":").includes("print")) continue;
|
|
18022
|
+
const base = tailwindBase(token);
|
|
18023
|
+
if (!OPAQUE_FOREGROUND_RE.test(base)) continue;
|
|
18024
|
+
const semanticBackground = tokens.find((candidate2) => {
|
|
18025
|
+
if (tailwindVariantPrefix(candidate2) !== prefix) return false;
|
|
18026
|
+
const match = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(candidate2));
|
|
18027
|
+
return match?.[1] !== void 0 && foregroundRoles.has(match[1]);
|
|
18028
|
+
});
|
|
18029
|
+
if (semanticBackground === void 0) continue;
|
|
18030
|
+
const role = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(semanticBackground))?.[1];
|
|
18031
|
+
if (role === void 0) continue;
|
|
18032
|
+
report2(node, "opaqueForegroundPair", {
|
|
18033
|
+
background: semanticBackground,
|
|
18034
|
+
class: token,
|
|
18035
|
+
replacement: `${prefix}text-${role}-foreground`
|
|
18036
|
+
});
|
|
18037
|
+
}
|
|
18038
|
+
};
|
|
18042
18039
|
function checkClassProperties(node, objectKeys) {
|
|
18043
18040
|
for (const property of node.properties) {
|
|
18044
18041
|
if (property.type !== AST_NODE_TYPES87.Property) continue;
|
|
@@ -18472,80 +18469,6 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18472
18469
|
return {};
|
|
18473
18470
|
}
|
|
18474
18471
|
const { sourceCode } = context;
|
|
18475
|
-
function parseAssertion(statement) {
|
|
18476
|
-
if (statement.type !== AST_NODE_TYPES88.ExpressionStatement) {
|
|
18477
|
-
return null;
|
|
18478
|
-
}
|
|
18479
|
-
const call = statement.expression;
|
|
18480
|
-
if (call.type !== AST_NODE_TYPES88.CallExpression) {
|
|
18481
|
-
return null;
|
|
18482
|
-
}
|
|
18483
|
-
const callee = call.callee;
|
|
18484
|
-
if (callee.type !== AST_NODE_TYPES88.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES88.Identifier) {
|
|
18485
|
-
return null;
|
|
18486
|
-
}
|
|
18487
|
-
const matcher = callee.property.name;
|
|
18488
|
-
const expectCall = callee.object;
|
|
18489
|
-
if (expectCall.type !== AST_NODE_TYPES88.CallExpression || expectCall.callee.type !== AST_NODE_TYPES88.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
18490
|
-
return null;
|
|
18491
|
-
}
|
|
18492
|
-
const actual = expectCall.arguments[0];
|
|
18493
|
-
if (!isTestExpect(expectCall.callee)) return null;
|
|
18494
|
-
if (actual === void 0 || actual.type !== AST_NODE_TYPES88.MemberExpression || actual.optional) {
|
|
18495
|
-
return null;
|
|
18496
|
-
}
|
|
18497
|
-
if (!isPureReceiver(actual.object)) {
|
|
18498
|
-
return null;
|
|
18499
|
-
}
|
|
18500
|
-
let key;
|
|
18501
|
-
let receiver;
|
|
18502
|
-
if (actual.computed) {
|
|
18503
|
-
const index = literalIndex(actual.property);
|
|
18504
|
-
if (index === null) {
|
|
18505
|
-
return null;
|
|
18506
|
-
}
|
|
18507
|
-
key = { kind: "index", index };
|
|
18508
|
-
receiver = actual.object;
|
|
18509
|
-
} else {
|
|
18510
|
-
const access = propertyAccess(actual);
|
|
18511
|
-
if (access === null) return null;
|
|
18512
|
-
key = { kind: "property", path: access.path };
|
|
18513
|
-
receiver = access.receiver;
|
|
18514
|
-
}
|
|
18515
|
-
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
18516
|
-
}
|
|
18517
|
-
function assertionExpectation(statement, call, receiver, key, matcher) {
|
|
18518
|
-
const synthetic = SYNTHETIC_LITERAL_MATCHERS.get(matcher);
|
|
18519
|
-
if (synthetic !== void 0 && call.arguments.length === 0) {
|
|
18520
|
-
return { statement, receiver, key, matcher, expectedText: synthetic, expectedIsLiteral: true };
|
|
18521
|
-
}
|
|
18522
|
-
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
18523
|
-
return null;
|
|
18524
|
-
}
|
|
18525
|
-
const expected = call.arguments[0];
|
|
18526
|
-
if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES88.SpreadElement) {
|
|
18527
|
-
return null;
|
|
18528
|
-
}
|
|
18529
|
-
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
18530
|
-
return {
|
|
18531
|
-
statement,
|
|
18532
|
-
receiver,
|
|
18533
|
-
key,
|
|
18534
|
-
matcher,
|
|
18535
|
-
expectedText: literal ?? sourceCode.getText(expected),
|
|
18536
|
-
expectedIsLiteral: literal !== null
|
|
18537
|
-
};
|
|
18538
|
-
}
|
|
18539
|
-
function isTestExpect(callee) {
|
|
18540
|
-
const variable = ASTUtils45.findVariable(sourceCode.getScope(callee), callee.name);
|
|
18541
|
-
if (variable !== null && variable.defs.some((definition) => {
|
|
18542
|
-
if (definition.node.type !== AST_NODE_TYPES88.ImportSpecifier) return true;
|
|
18543
|
-
const declaration = definition.node.parent;
|
|
18544
|
-
const imported = definition.node.imported;
|
|
18545
|
-
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";
|
|
18546
|
-
})) return false;
|
|
18547
|
-
return true;
|
|
18548
|
-
}
|
|
18549
18472
|
function reportPropertyRun(run) {
|
|
18550
18473
|
const tree = /* @__PURE__ */ new Map();
|
|
18551
18474
|
const paths = [];
|
|
@@ -18655,6 +18578,80 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18655
18578
|
}
|
|
18656
18579
|
flush();
|
|
18657
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
|
+
}
|
|
18658
18655
|
return {
|
|
18659
18656
|
BlockStatement: (node) => {
|
|
18660
18657
|
checkBody(node.body);
|
|
@@ -21400,6 +21397,11 @@ var require_use_form_default_values_default = createRule({
|
|
|
21400
21397
|
const value = unwrapExpression6(node);
|
|
21401
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;
|
|
21402
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
|
+
};
|
|
21403
21405
|
const initializationState = (node) => {
|
|
21404
21406
|
if (node === void 0) return "uninitialized";
|
|
21405
21407
|
if (node.type !== AST_NODE_TYPES98.ObjectExpression) return "unknown";
|
|
@@ -21412,11 +21414,6 @@ var require_use_form_default_values_default = createRule({
|
|
|
21412
21414
|
}
|
|
21413
21415
|
return [...initialization.values()].some(Boolean) ? "initialized" : "uninitialized";
|
|
21414
21416
|
};
|
|
21415
|
-
const uninitializedUseFormCall = (node) => {
|
|
21416
|
-
if (node.type !== AST_NODE_TYPES98.CallExpression || node.callee.type !== AST_NODE_TYPES98.Identifier || importedKind(node.callee) !== "useForm") return false;
|
|
21417
|
-
const options = node.arguments[0];
|
|
21418
|
-
return options?.type !== AST_NODE_TYPES98.SpreadElement && initializationState(options) === "uninitialized";
|
|
21419
|
-
};
|
|
21420
21417
|
const isUninitializedForm = (node) => {
|
|
21421
21418
|
if (node.type !== AST_NODE_TYPES98.Identifier) return false;
|
|
21422
21419
|
const variable = bindingOf(node);
|
|
@@ -21648,28 +21645,13 @@ var require_zod_form_validation_default = createRule({
|
|
|
21648
21645
|
context.sourceCode.getScope(identifier),
|
|
21649
21646
|
identifier.name
|
|
21650
21647
|
);
|
|
21651
|
-
const
|
|
21652
|
-
const binding = resolvedBinding(identifier);
|
|
21653
|
-
if (binding === null || zodBindings.has(binding) || binding.defs.length !== 1) {
|
|
21654
|
-
return false;
|
|
21655
|
-
}
|
|
21656
|
-
const definition = binding.defs[0];
|
|
21657
|
-
if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES99.VariableDeclarator) {
|
|
21658
|
-
return false;
|
|
21659
|
-
}
|
|
21660
|
-
const init = definition.node.init;
|
|
21661
|
-
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;
|
|
21662
|
-
};
|
|
21663
|
-
const isZodParseCall = (node) => {
|
|
21664
|
-
if (node.type !== AST_NODE_TYPES99.CallExpression) return false;
|
|
21648
|
+
const isFormDataGetCall = (node) => {
|
|
21665
21649
|
const callee = node.callee;
|
|
21666
|
-
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)) {
|
|
21667
21652
|
return false;
|
|
21668
21653
|
}
|
|
21669
|
-
|
|
21670
|
-
if (root === null) return false;
|
|
21671
|
-
const binding = resolvedBinding(root);
|
|
21672
|
-
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
21654
|
+
return isFormSourceIdentifier(callee.object);
|
|
21673
21655
|
};
|
|
21674
21656
|
const isFormSourceIdentifier = (node) => {
|
|
21675
21657
|
if (node.type !== AST_NODE_TYPES99.Identifier) return false;
|
|
@@ -21688,14 +21670,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21688
21670
|
}
|
|
21689
21671
|
return conventionalName;
|
|
21690
21672
|
};
|
|
21691
|
-
const isFormDataGetCall = (node) => {
|
|
21692
|
-
const callee = node.callee;
|
|
21693
|
-
if (callee.type !== AST_NODE_TYPES99.MemberExpression) return false;
|
|
21694
|
-
if (callee.property.type !== AST_NODE_TYPES99.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
21695
|
-
return false;
|
|
21696
|
-
}
|
|
21697
|
-
return isFormSourceIdentifier(callee.object);
|
|
21698
|
-
};
|
|
21699
21673
|
const zodParseAncestor = (node) => {
|
|
21700
21674
|
let parent = node.parent;
|
|
21701
21675
|
while (parent !== null && parent !== void 0) {
|
|
@@ -21713,6 +21687,29 @@ var require_zod_form_validation_default = createRule({
|
|
|
21713
21687
|
}
|
|
21714
21688
|
return null;
|
|
21715
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
|
+
};
|
|
21716
21713
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
21717
21714
|
const isInstanceofNarrowing = (node) => {
|
|
21718
21715
|
const parent = node.parent;
|
|
@@ -21741,28 +21738,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21741
21738
|
}
|
|
21742
21739
|
return null;
|
|
21743
21740
|
};
|
|
21744
|
-
const zodParseMethod = (call) => {
|
|
21745
|
-
const callee = call.callee;
|
|
21746
|
-
return callee.type === AST_NODE_TYPES99.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES99.Identifier ? callee.property.name : null;
|
|
21747
|
-
};
|
|
21748
|
-
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
21749
|
-
let current = node.parent;
|
|
21750
|
-
while (current !== void 0 && current !== statement) {
|
|
21751
|
-
if (current.type === AST_NODE_TYPES99.LogicalExpression || current.type === AST_NODE_TYPES99.ConditionalExpression) {
|
|
21752
|
-
return true;
|
|
21753
|
-
}
|
|
21754
|
-
current = current.parent;
|
|
21755
|
-
}
|
|
21756
|
-
return false;
|
|
21757
|
-
};
|
|
21758
|
-
const isAwaitedBeforeStatement = (node, statement) => {
|
|
21759
|
-
let current = node.parent;
|
|
21760
|
-
while (current !== void 0 && current !== statement) {
|
|
21761
|
-
if (current.type === AST_NODE_TYPES99.AwaitExpression) return true;
|
|
21762
|
-
current = current.parent;
|
|
21763
|
-
}
|
|
21764
|
-
return false;
|
|
21765
|
-
};
|
|
21766
21741
|
const guaranteedValidationStatement = (declarator, reference) => {
|
|
21767
21742
|
const parse2 = zodParseAncestor(reference);
|
|
21768
21743
|
if (parse2 === null) return null;
|
|
@@ -21781,6 +21756,28 @@ var require_zod_form_validation_default = createRule({
|
|
|
21781
21756
|
}
|
|
21782
21757
|
return null;
|
|
21783
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
|
+
};
|
|
21784
21781
|
const isSafePrevalidationInspection = (identifier) => {
|
|
21785
21782
|
const parent = identifier.parent;
|
|
21786
21783
|
if (parent.type === AST_NODE_TYPES99.UnaryExpression && parent.operator === "typeof") {
|
|
@@ -21961,9 +21958,9 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
21961
21958
|
remediation: "Consider moving the private helper below its sole caller after reviewing initialization and reflection dependencies.",
|
|
21962
21959
|
category: "maintainability",
|
|
21963
21960
|
limitations: [
|
|
21964
|
-
"Generated and test files, cycles, dynamic references, overload targets, and helpers with multiple callers are excluded.",
|
|
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.",
|
|
21965
21962
|
"Class helpers must be private; their sole caller may be public, protected, or private.",
|
|
21966
|
-
"Runtime class-field, static-block, computed-member, and decorator barriers are never crossed.",
|
|
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.",
|
|
21967
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."
|
|
21968
21965
|
],
|
|
21969
21966
|
examples: [
|
|
@@ -21975,7 +21972,7 @@ function isFunction(node) {
|
|
|
21975
21972
|
return node.type === AST_NODE_TYPES100.ArrowFunctionExpression || node.type === AST_NODE_TYPES100.FunctionDeclaration || node.type === AST_NODE_TYPES100.FunctionExpression;
|
|
21976
21973
|
}
|
|
21977
21974
|
function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true) {
|
|
21978
|
-
const byName = new Map(scopeDefinitions.map((definition) => [definition.
|
|
21975
|
+
const byName = new Map(scopeDefinitions.map((definition) => [definition.key, definition]));
|
|
21979
21976
|
const cycles = cycleComponents(calls);
|
|
21980
21977
|
const callers = /* @__PURE__ */ new Map();
|
|
21981
21978
|
for (const [caller, callees] of calls) {
|
|
@@ -21987,16 +21984,16 @@ function reportMisordered(context, candidates, scopeDefinitions, calls, pinned,
|
|
|
21987
21984
|
}
|
|
21988
21985
|
}
|
|
21989
21986
|
for (const helper of candidates) {
|
|
21990
|
-
const helperCallers = [...callers.get(helper.
|
|
21991
|
-
if (pinned.has(helper.
|
|
21987
|
+
const helperCallers = [...callers.get(helper.key) ?? []];
|
|
21988
|
+
if (pinned.has(helper.key) || helperCallers.length !== 1) continue;
|
|
21992
21989
|
const callerName2 = helperCallers[0];
|
|
21993
|
-
if (callerName2 === void 0 || cycles.has(helper.
|
|
21990
|
+
if (callerName2 === void 0 || cycles.has(helper.key) && cycles.get(helper.key) === cycles.get(callerName2)) continue;
|
|
21994
21991
|
const caller = byName.get(callerName2);
|
|
21995
21992
|
if (caller === void 0 || helper.node.range[0] >= caller.node.range[0] || !canMove(helper, caller)) continue;
|
|
21996
21993
|
context.report({
|
|
21997
21994
|
node: helper.node,
|
|
21998
21995
|
messageId: "helperAboveOnlyCaller",
|
|
21999
|
-
data: { helper: helper.name, caller:
|
|
21996
|
+
data: { helper: helper.name, caller: caller.name }
|
|
22000
21997
|
});
|
|
22001
21998
|
}
|
|
22002
21999
|
}
|
|
@@ -22067,8 +22064,46 @@ function cycleComponents(graph) {
|
|
|
22067
22064
|
}
|
|
22068
22065
|
return components;
|
|
22069
22066
|
}
|
|
22070
|
-
function
|
|
22067
|
+
function isErasedExpression(node) {
|
|
22068
|
+
return node.type === AST_NODE_TYPES100.TSAsExpression || node.type === AST_NODE_TYPES100.TSTypeAssertion || node.type === AST_NODE_TYPES100.TSSatisfiesExpression || node.type === AST_NODE_TYPES100.TSNonNullExpression || node.type === AST_NODE_TYPES100.TSInstantiationExpression;
|
|
22069
|
+
}
|
|
22070
|
+
function unwrapExpression7(node) {
|
|
22071
|
+
let current = node;
|
|
22072
|
+
while (isErasedExpression(current)) current = current.expression;
|
|
22073
|
+
return current;
|
|
22074
|
+
}
|
|
22075
|
+
function wrappedExpression(node) {
|
|
22076
|
+
let current = node;
|
|
22077
|
+
while (current.parent !== void 0 && isErasedExpression(current.parent) && current.parent.expression === current) current = current.parent;
|
|
22078
|
+
return current;
|
|
22079
|
+
}
|
|
22080
|
+
function enclosingFunction5(context, node) {
|
|
22081
|
+
return [...context.sourceCode.getAncestors(node)].reverse().find(isFunction);
|
|
22082
|
+
}
|
|
22083
|
+
function localCallCount(context, node, owner) {
|
|
22084
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22085
|
+
const pending = [node];
|
|
22086
|
+
let count = 0;
|
|
22087
|
+
while (pending.length > 0) {
|
|
22088
|
+
const current = pending.pop();
|
|
22089
|
+
if (current === void 0 || enclosingFunction5(context, current) !== owner) return null;
|
|
22090
|
+
const expression = wrappedExpression(current);
|
|
22091
|
+
const parent = expression.parent;
|
|
22092
|
+
if (parent?.type === AST_NODE_TYPES100.CallExpression && parent.callee === expression) {
|
|
22093
|
+
count += 1;
|
|
22094
|
+
continue;
|
|
22095
|
+
}
|
|
22096
|
+
if (parent?.type !== AST_NODE_TYPES100.VariableDeclarator || parent.init !== expression || parent.id.type !== AST_NODE_TYPES100.Identifier || parent.parent.type !== AST_NODE_TYPES100.VariableDeclaration || parent.parent.kind !== "const") return null;
|
|
22097
|
+
const variable = context.sourceCode.getDeclaredVariables(parent)[0];
|
|
22098
|
+
if (variable === void 0 || seen.has(variable) || !stableVariable(variable)) return null;
|
|
22099
|
+
seen.add(variable);
|
|
22100
|
+
pending.push(...variable.references.filter((reference) => reference.isRead()).map((reference) => reference.identifier));
|
|
22101
|
+
}
|
|
22102
|
+
return count;
|
|
22103
|
+
}
|
|
22104
|
+
function declarationScope(context, program) {
|
|
22071
22105
|
const declarations = moduleDefinitions(program);
|
|
22106
|
+
if (declarations.length < 2) return;
|
|
22072
22107
|
const counts = /* @__PURE__ */ new Map();
|
|
22073
22108
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
22074
22109
|
const overloadNames = new Set(
|
|
@@ -22077,11 +22112,31 @@ function moduleScope(context, program) {
|
|
|
22077
22112
|
return node?.type === AST_NODE_TYPES100.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
|
|
22078
22113
|
})
|
|
22079
22114
|
);
|
|
22080
|
-
const exported = exportedNames(program);
|
|
22115
|
+
const exported = program.type === AST_NODE_TYPES100.Program ? exportedNames(program) : /* @__PURE__ */ new Set();
|
|
22081
22116
|
const scopeDefinitions = declarations.filter((node) => counts.get(node.name) === 1);
|
|
22082
22117
|
const definitions = scopeDefinitions.filter(
|
|
22083
22118
|
(definition) => !exported.has(definition.name) && !overloadNames.has(definition.name)
|
|
22084
22119
|
);
|
|
22120
|
+
const { calls, pinned } = moduleCallGraph(context, scopeDefinitions);
|
|
22121
|
+
const statementIndexes = new Map(program.body.map((statement, index) => [statement, index]));
|
|
22122
|
+
const runtimeBarrierPrefix = [0];
|
|
22123
|
+
for (const statement of program.body) {
|
|
22124
|
+
runtimeBarrierPrefix.push((runtimeBarrierPrefix.at(-1) ?? 0) + (isDeferredModuleStatement(statement) ? 0 : 1));
|
|
22125
|
+
}
|
|
22126
|
+
const canMove = (helper, caller) => {
|
|
22127
|
+
if (helper.node.type === AST_NODE_TYPES100.FunctionDeclaration) return true;
|
|
22128
|
+
const helperIndex = statementIndex(helper);
|
|
22129
|
+
const callerIndex = statementIndex(caller);
|
|
22130
|
+
return helperIndex !== void 0 && callerIndex !== void 0 && runtimeBarrierPrefix[callerIndex + 1] === runtimeBarrierPrefix[helperIndex + 1];
|
|
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
|
+
};
|
|
22137
|
+
reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
|
|
22138
|
+
}
|
|
22139
|
+
function moduleCallGraph(context, scopeDefinitions) {
|
|
22085
22140
|
const byFunction = new Map(scopeDefinitions.map((definition) => [definition.functionNode, definition]));
|
|
22086
22141
|
const calls = /* @__PURE__ */ new Map();
|
|
22087
22142
|
const pinned = /* @__PURE__ */ new Set();
|
|
@@ -22089,26 +22144,33 @@ function moduleScope(context, program) {
|
|
|
22089
22144
|
const variable = context.sourceCode.getDeclaredVariables(definition.bindingNode)[0];
|
|
22090
22145
|
for (const reference of variable?.references ?? []) {
|
|
22091
22146
|
if (reference.isWrite() && reference.init !== true) {
|
|
22092
|
-
pinned.add(definition.
|
|
22147
|
+
pinned.add(definition.key);
|
|
22093
22148
|
continue;
|
|
22094
22149
|
}
|
|
22095
22150
|
if (!reference.isRead()) continue;
|
|
22096
|
-
const
|
|
22097
|
-
|
|
22098
|
-
|
|
22099
|
-
const parent = identifier.parent;
|
|
22100
|
-
const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
|
|
22101
|
-
if (callerDefinition === void 0 || parent.type !== AST_NODE_TYPES100.CallExpression || parent.callee !== identifier) {
|
|
22102
|
-
pinned.add(definition.name);
|
|
22151
|
+
const callerDefinition = byFunction.get(enclosingFunction5(context, reference.identifier));
|
|
22152
|
+
if (callerDefinition?.functionNode === void 0) {
|
|
22153
|
+
pinned.add(definition.key);
|
|
22103
22154
|
continue;
|
|
22104
22155
|
}
|
|
22105
|
-
const
|
|
22106
|
-
|
|
22107
|
-
|
|
22108
|
-
|
|
22156
|
+
const count = localCallCount(context, reference.identifier, callerDefinition.functionNode);
|
|
22157
|
+
if (count === null) {
|
|
22158
|
+
pinned.add(definition.key);
|
|
22159
|
+
} else if (count > 0) {
|
|
22160
|
+
const callees = calls.get(callerDefinition.key) ?? /* @__PURE__ */ new Set();
|
|
22161
|
+
callees.add(definition.key);
|
|
22162
|
+
calls.set(callerDefinition.key, callees);
|
|
22163
|
+
}
|
|
22109
22164
|
}
|
|
22110
22165
|
}
|
|
22111
|
-
|
|
22166
|
+
return { calls, pinned };
|
|
22167
|
+
}
|
|
22168
|
+
function isDeferredModuleStatement(statement) {
|
|
22169
|
+
const node = statement.type === AST_NODE_TYPES100.ExportNamedDeclaration || statement.type === AST_NODE_TYPES100.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
22170
|
+
if (node === null || node.type === AST_NODE_TYPES100.FunctionDeclaration || node.type === AST_NODE_TYPES100.TSDeclareFunction || node.type === AST_NODE_TYPES100.TSInterfaceDeclaration || node.type === AST_NODE_TYPES100.TSTypeAliasDeclaration || node.type === AST_NODE_TYPES100.ImportDeclaration || node.type === AST_NODE_TYPES100.ExportAllDeclaration || node.type === AST_NODE_TYPES100.EmptyStatement) return true;
|
|
22171
|
+
return node.type === AST_NODE_TYPES100.VariableDeclaration && node.declarations.every(
|
|
22172
|
+
(declaration) => declaration.id.type === AST_NODE_TYPES100.Identifier && declaration.init !== null && isFunction(unwrapExpression7(declaration.init))
|
|
22173
|
+
);
|
|
22112
22174
|
}
|
|
22113
22175
|
function exportedNames(program) {
|
|
22114
22176
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -22142,16 +22204,18 @@ function moduleDefinitions(program) {
|
|
|
22142
22204
|
for (const statement of program.body) {
|
|
22143
22205
|
const node = statement.type === AST_NODE_TYPES100.ExportNamedDeclaration || statement.type === AST_NODE_TYPES100.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
22144
22206
|
if (node?.type === AST_NODE_TYPES100.FunctionDeclaration && node.id !== null && node.body !== null) {
|
|
22145
|
-
definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
22207
|
+
definitions.push({ key: node.id.name, name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
22146
22208
|
continue;
|
|
22147
22209
|
}
|
|
22148
|
-
if (node?.type !== AST_NODE_TYPES100.VariableDeclaration || node.kind !== "const") continue;
|
|
22210
|
+
if (node?.type !== AST_NODE_TYPES100.VariableDeclaration || node.kind !== "const" || node.declarations.length !== 1) continue;
|
|
22149
22211
|
for (const declarator of node.declarations) {
|
|
22150
|
-
|
|
22212
|
+
const initializer = declarator.init === null ? null : unwrapExpression7(declarator.init);
|
|
22213
|
+
if (declarator.id.type === AST_NODE_TYPES100.Identifier && initializer !== null && isFunction(initializer)) {
|
|
22151
22214
|
definitions.push({
|
|
22215
|
+
key: declarator.id.name,
|
|
22152
22216
|
name: declarator.id.name,
|
|
22153
22217
|
node: declarator,
|
|
22154
|
-
functionNode:
|
|
22218
|
+
functionNode: initializer,
|
|
22155
22219
|
bindingNode: declarator
|
|
22156
22220
|
});
|
|
22157
22221
|
}
|
|
@@ -22161,15 +22225,50 @@ function moduleDefinitions(program) {
|
|
|
22161
22225
|
}
|
|
22162
22226
|
function methodName2(node) {
|
|
22163
22227
|
if (node.key.type === AST_NODE_TYPES100.PrivateIdentifier) return `#${node.key.name}`;
|
|
22164
|
-
|
|
22228
|
+
if (!node.computed && node.key.type === AST_NODE_TYPES100.Identifier) return node.key.name;
|
|
22229
|
+
return node.key.type === AST_NODE_TYPES100.Literal && typeof node.key.value === "string" ? node.key.value : null;
|
|
22165
22230
|
}
|
|
22166
|
-
function
|
|
22167
|
-
|
|
22168
|
-
|
|
22169
|
-
|
|
22170
|
-
|
|
22171
|
-
if (
|
|
22172
|
-
return
|
|
22231
|
+
function methodKey(name, isStatic2) {
|
|
22232
|
+
return `${isStatic2 ? "static" : "instance"}:${name}`;
|
|
22233
|
+
}
|
|
22234
|
+
function receiverDomain(context, object, receivers, thisIsStatic) {
|
|
22235
|
+
const unwrapped = unwrapExpression7(object);
|
|
22236
|
+
if (unwrapped.type === AST_NODE_TYPES100.ThisExpression) return thisIsStatic;
|
|
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;
|
|
22269
|
+
}
|
|
22270
|
+
function stableVariable(variable) {
|
|
22271
|
+
return !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
|
|
22173
22272
|
}
|
|
22174
22273
|
function referencedPropertyName(node) {
|
|
22175
22274
|
if (node.property.type === AST_NODE_TYPES100.PrivateIdentifier) return `#${node.property.name}`;
|
|
@@ -22178,131 +22277,145 @@ function referencedPropertyName(node) {
|
|
|
22178
22277
|
}
|
|
22179
22278
|
function walk(node, visitorKeys, visit, nestedFunction = false) {
|
|
22180
22279
|
visit(node, nestedFunction);
|
|
22181
|
-
const nested = nestedFunction || isFunction(node);
|
|
22280
|
+
const nested = nestedFunction || isFunction(node) || node.type === AST_NODE_TYPES100.ClassDeclaration || node.type === AST_NODE_TYPES100.ClassExpression;
|
|
22182
22281
|
forEachAstChild(node, visitorKeys, (child) => walk(child, visitorKeys, visit, nested));
|
|
22183
22282
|
}
|
|
22184
|
-
function classScope(context, node,
|
|
22283
|
+
function classScope(context, node, computedReferences) {
|
|
22185
22284
|
const methods = node.body.body.filter(
|
|
22186
22285
|
(member) => member.type === AST_NODE_TYPES100.MethodDefinition
|
|
22187
22286
|
);
|
|
22188
22287
|
const counts = classMethodCounts(node.body, methods);
|
|
22189
|
-
const
|
|
22190
|
-
|
|
22191
|
-
|
|
22192
|
-
});
|
|
22193
|
-
const definitions = methods.flatMap((method) => {
|
|
22288
|
+
const implementations = methods.filter((method) => isFunction(method.value));
|
|
22289
|
+
const implementationCounts = classMethodCounts(node.body, implementations);
|
|
22290
|
+
const scopeDefinitions = implementations.flatMap((method) => {
|
|
22194
22291
|
const name = methodName2(method);
|
|
22195
|
-
const
|
|
22196
|
-
return name !== null &&
|
|
22292
|
+
const key = name === null ? null : methodKey(name, method.static);
|
|
22293
|
+
return name !== null && key !== null && implementationCounts.get(key) === 1 ? [{ key, name, node: method }] : [];
|
|
22197
22294
|
});
|
|
22295
|
+
const definitions = scopeDefinitions.filter(
|
|
22296
|
+
({ key, node: method }) => (method.accessibility === "private" || method.key.type === AST_NODE_TYPES100.PrivateIdentifier) && counts.get(key) === 1 && method.decorators.length === 0 && !method.computed && method.kind === "method"
|
|
22297
|
+
);
|
|
22198
22298
|
if (definitions.length === 0) return;
|
|
22199
|
-
const
|
|
22299
|
+
const methodKeys = new Set(scopeDefinitions.map((definition) => definition.key));
|
|
22200
22300
|
const calls = /* @__PURE__ */ new Map();
|
|
22201
22301
|
const pinned = /* @__PURE__ */ new Set();
|
|
22202
|
-
const
|
|
22203
|
-
|
|
22204
|
-
const
|
|
22205
|
-
|
|
22206
|
-
|
|
22207
|
-
|
|
22208
|
-
|
|
22209
|
-
|
|
22302
|
+
const classReceivers = classReceiverBindings(context, node);
|
|
22303
|
+
const pinNames = (name, domain = null) => {
|
|
22304
|
+
for (const definition of definitions) {
|
|
22305
|
+
if ((name === null || definition.name === name) && (domain === null || definition.node.static === domain)) {
|
|
22306
|
+
pinned.add(definition.key);
|
|
22307
|
+
}
|
|
22308
|
+
}
|
|
22309
|
+
};
|
|
22310
|
+
function pinDestructuredMembers(binding, domain) {
|
|
22311
|
+
for (const property of binding.properties) {
|
|
22312
|
+
if (property.type === AST_NODE_TYPES100.RestElement || property.computed) {
|
|
22313
|
+
pinNames(null, domain);
|
|
22314
|
+
} else if (property.key.type === AST_NODE_TYPES100.Identifier) {
|
|
22315
|
+
pinNames(property.key.name, domain);
|
|
22316
|
+
} else if (property.key.type === AST_NODE_TYPES100.Literal && typeof property.key.value === "string") {
|
|
22317
|
+
pinNames(property.key.value, domain);
|
|
22318
|
+
}
|
|
22319
|
+
}
|
|
22210
22320
|
}
|
|
22211
22321
|
function collectMethodCalls(method) {
|
|
22212
|
-
const
|
|
22213
|
-
if (
|
|
22214
|
-
|
|
22215
|
-
|
|
22322
|
+
const name = methodName2(method);
|
|
22323
|
+
if (name === null) {
|
|
22324
|
+
pinNames(null);
|
|
22325
|
+
return;
|
|
22326
|
+
}
|
|
22327
|
+
if (!isFunction(method.value)) return;
|
|
22328
|
+
const methodFunction = method.value;
|
|
22329
|
+
const caller = methodKey(name, method.static);
|
|
22330
|
+
const receivers = new Map(classReceivers);
|
|
22216
22331
|
const parameterDecoratorNodes = /* @__PURE__ */ new Set();
|
|
22217
22332
|
for (const parameter of method.value.params) {
|
|
22218
22333
|
for (const decorator of parameter.decorators) {
|
|
22219
22334
|
walk(decorator, context.sourceCode.visitorKeys, (current) => parameterDecoratorNodes.add(current));
|
|
22220
22335
|
}
|
|
22221
22336
|
}
|
|
22222
|
-
const thisValue = (value) => {
|
|
22223
|
-
let current = value;
|
|
22224
|
-
while (current?.type === AST_NODE_TYPES100.TSAsExpression || current?.type === AST_NODE_TYPES100.TSSatisfiesExpression || current?.type === AST_NODE_TYPES100.TSNonNullExpression) current = current.expression;
|
|
22225
|
-
return current?.type === AST_NODE_TYPES100.ThisExpression;
|
|
22226
|
-
};
|
|
22227
22337
|
const collectAlias = (current, nestedFunction) => {
|
|
22228
|
-
if (nestedFunction || current.type !== AST_NODE_TYPES100.VariableDeclarator
|
|
22229
|
-
|
|
22230
|
-
|
|
22231
|
-
|
|
22232
|
-
|
|
22233
|
-
if (binding.type === AST_NODE_TYPES100.ObjectPattern) {
|
|
22234
|
-
pinDestructuredMembers(binding);
|
|
22338
|
+
if (nestedFunction || current.type !== AST_NODE_TYPES100.VariableDeclarator || current.init === null) return;
|
|
22339
|
+
const domain = receiverDomain(context, current.init, receivers, method.static);
|
|
22340
|
+
if (domain === null || domain === "unrelated") return;
|
|
22341
|
+
if (current.id.type === AST_NODE_TYPES100.ObjectPattern) {
|
|
22342
|
+
pinDestructuredMembers(current.id, domain);
|
|
22235
22343
|
return;
|
|
22236
22344
|
}
|
|
22237
|
-
if (
|
|
22238
|
-
|
|
22239
|
-
|
|
22240
|
-
|
|
22241
|
-
methodAliases.add(variable);
|
|
22345
|
+
if (current.id.type !== AST_NODE_TYPES100.Identifier) return;
|
|
22346
|
+
if (current.parent.type !== AST_NODE_TYPES100.VariableDeclaration || current.parent.kind !== "const") {
|
|
22347
|
+
pinNames(null, domain);
|
|
22348
|
+
return;
|
|
22242
22349
|
}
|
|
22350
|
+
const variable = context.sourceCode.getDeclaredVariables(current)[0];
|
|
22351
|
+
if (variable === void 0 || !stableVariable(variable)) return;
|
|
22352
|
+
const local = variable.references.every((reference) => {
|
|
22353
|
+
if (!reference.isRead()) return true;
|
|
22354
|
+
const expression = wrappedExpression(reference.identifier);
|
|
22355
|
+
return enclosingFunction5(context, reference.identifier) === methodFunction && expression.parent?.type === AST_NODE_TYPES100.MemberExpression && expression.parent.object === expression;
|
|
22356
|
+
});
|
|
22357
|
+
if (local) receivers.set(variable, domain);
|
|
22358
|
+
else pinNames(null, domain);
|
|
22243
22359
|
};
|
|
22244
|
-
for (const
|
|
22245
|
-
walk(parameter, context.sourceCode.visitorKeys, collectAlias);
|
|
22246
|
-
}
|
|
22247
|
-
for (const statement of method.value.body.body) {
|
|
22248
|
-
walk(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
22249
|
-
}
|
|
22250
|
-
function pinDestructuredMembers(binding) {
|
|
22251
|
-
for (const property of binding.properties) {
|
|
22252
|
-
if (property.type === AST_NODE_TYPES100.RestElement) {
|
|
22253
|
-
for (const name of privateNames) pinned.add(name);
|
|
22254
|
-
} else if (property.key.type === AST_NODE_TYPES100.Identifier && privateNames.has(property.key.name)) {
|
|
22255
|
-
pinned.add(property.key.name);
|
|
22256
|
-
}
|
|
22257
|
-
}
|
|
22258
|
-
}
|
|
22360
|
+
for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
22259
22361
|
const visitCall = (current, nestedFunction) => {
|
|
22260
|
-
|
|
22261
|
-
|
|
22362
|
+
const destructuring = receiverDestructuring(current);
|
|
22363
|
+
if (destructuring !== null) {
|
|
22364
|
+
const domain2 = receiverDomain(context, destructuring.value, receivers, method.static);
|
|
22365
|
+
if (domain2 !== "unrelated") pinDestructuredMembers(destructuring.binding, domain2);
|
|
22262
22366
|
}
|
|
22263
22367
|
if (current.type !== AST_NODE_TYPES100.MemberExpression) return;
|
|
22264
|
-
const
|
|
22265
|
-
|
|
22266
|
-
|
|
22267
|
-
|
|
22368
|
+
const domain = receiverDomain(context, current.object, receivers, method.static);
|
|
22369
|
+
const targetName = referencedPropertyName(current);
|
|
22370
|
+
if (domain === "unrelated") return;
|
|
22371
|
+
if (domain === null) {
|
|
22372
|
+
pinNames(targetName);
|
|
22268
22373
|
return;
|
|
22269
22374
|
}
|
|
22270
|
-
if (
|
|
22271
|
-
|
|
22272
|
-
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
22273
|
-
pinned.add(target);
|
|
22375
|
+
if (targetName === null) {
|
|
22376
|
+
if (current.computed) pinNames(null, domain);
|
|
22274
22377
|
return;
|
|
22275
22378
|
}
|
|
22276
|
-
|
|
22379
|
+
const target = methodKey(targetName, domain);
|
|
22380
|
+
if (!methodKeys.has(target)) return;
|
|
22381
|
+
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current)) {
|
|
22277
22382
|
pinned.add(target);
|
|
22278
22383
|
return;
|
|
22279
22384
|
}
|
|
22280
|
-
const
|
|
22281
|
-
|
|
22282
|
-
|
|
22385
|
+
const count = localCallCount(context, current, methodFunction);
|
|
22386
|
+
if (count === null) {
|
|
22387
|
+
pinned.add(target);
|
|
22388
|
+
} else if (count > 0) {
|
|
22389
|
+
const callees = calls.get(caller) ?? /* @__PURE__ */ new Set();
|
|
22390
|
+
callees.add(target);
|
|
22391
|
+
calls.set(caller, callees);
|
|
22392
|
+
}
|
|
22283
22393
|
};
|
|
22284
|
-
for (const decorator of method.decorators)
|
|
22285
|
-
walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
|
|
22286
|
-
}
|
|
22394
|
+
for (const decorator of method.decorators) walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
|
|
22287
22395
|
if (method.computed) walk(method.key, context.sourceCode.visitorKeys, visitCall, true);
|
|
22288
|
-
for (const parameter of method.value.params)
|
|
22289
|
-
|
|
22290
|
-
}
|
|
22291
|
-
for (const statement of method.value.body.body) {
|
|
22292
|
-
walk(statement, context.sourceCode.visitorKeys, visitCall);
|
|
22293
|
-
}
|
|
22396
|
+
for (const parameter of method.value.params) walk(parameter, context.sourceCode.visitorKeys, visitCall);
|
|
22397
|
+
for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, visitCall);
|
|
22294
22398
|
}
|
|
22295
22399
|
for (const method of methods) collectMethodCalls(method);
|
|
22296
22400
|
for (const member of node.body.body) {
|
|
22297
22401
|
if (member.type === AST_NODE_TYPES100.MethodDefinition || member.type === AST_NODE_TYPES100.TSAbstractMethodDefinition) continue;
|
|
22298
22402
|
walk(member, context.sourceCode.visitorKeys, (current) => {
|
|
22299
22403
|
if (current.type !== AST_NODE_TYPES100.MemberExpression) return;
|
|
22300
|
-
|
|
22301
|
-
|
|
22302
|
-
if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
|
|
22404
|
+
if (externalReceiverDomain(context, current.object, classReceivers) === "unrelated") return;
|
|
22405
|
+
pinNames(referencedPropertyName(current));
|
|
22303
22406
|
});
|
|
22304
22407
|
}
|
|
22305
|
-
|
|
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);
|
|
22418
|
+
}
|
|
22306
22419
|
const memberIndexes = new Map(node.body.body.map((member, index) => [member, index]));
|
|
22307
22420
|
const runtimeBarrierPrefix = [0];
|
|
22308
22421
|
for (const member of node.body.body) {
|
|
@@ -22316,6 +22429,27 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
22316
22429
|
};
|
|
22317
22430
|
reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
|
|
22318
22431
|
}
|
|
22432
|
+
function classReceiverBindings(context, node) {
|
|
22433
|
+
const classReceivers = /* @__PURE__ */ new Map();
|
|
22434
|
+
if (node.id !== null) {
|
|
22435
|
+
const internal = ASTUtils51.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
22436
|
+
if (internal !== null && stableVariable(internal)) classReceivers.set(internal, true);
|
|
22437
|
+
}
|
|
22438
|
+
if (node.type === AST_NODE_TYPES100.ClassExpression && node.parent.type === AST_NODE_TYPES100.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES100.Identifier && node.parent.parent.type === AST_NODE_TYPES100.VariableDeclaration && node.parent.parent.kind === "const") {
|
|
22439
|
+
const outer = ASTUtils51.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
22440
|
+
if (outer !== null && stableVariable(outer)) classReceivers.set(outer, true);
|
|
22441
|
+
}
|
|
22442
|
+
return classReceivers;
|
|
22443
|
+
}
|
|
22444
|
+
function receiverDestructuring(node) {
|
|
22445
|
+
if (node.type === AST_NODE_TYPES100.VariableDeclarator && node.id.type === AST_NODE_TYPES100.ObjectPattern && node.init !== null) {
|
|
22446
|
+
return { binding: node.id, value: node.init };
|
|
22447
|
+
}
|
|
22448
|
+
if ((node.type === AST_NODE_TYPES100.AssignmentPattern || node.type === AST_NODE_TYPES100.AssignmentExpression) && node.left.type === AST_NODE_TYPES100.ObjectPattern) {
|
|
22449
|
+
return { binding: node.left, value: node.right };
|
|
22450
|
+
}
|
|
22451
|
+
return null;
|
|
22452
|
+
}
|
|
22319
22453
|
function isClassRuntimeBarrier(member) {
|
|
22320
22454
|
switch (member.type) {
|
|
22321
22455
|
case AST_NODE_TYPES100.StaticBlock:
|
|
@@ -22344,6 +22478,7 @@ var stepdown_default = createRule({
|
|
|
22344
22478
|
create(context) {
|
|
22345
22479
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
22346
22480
|
const classes = [];
|
|
22481
|
+
const functionBodies = [];
|
|
22347
22482
|
return {
|
|
22348
22483
|
ClassDeclaration: (node) => {
|
|
22349
22484
|
classes.push(node);
|
|
@@ -22351,13 +22486,17 @@ var stepdown_default = createRule({
|
|
|
22351
22486
|
ClassExpression: (node) => {
|
|
22352
22487
|
classes.push(node);
|
|
22353
22488
|
},
|
|
22489
|
+
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
|
|
22490
|
+
if (isFunction(node) && node.body?.type === AST_NODE_TYPES100.BlockStatement) functionBodies.push(node.body);
|
|
22491
|
+
},
|
|
22354
22492
|
"Program:exit": (program) => {
|
|
22355
|
-
|
|
22356
|
-
const
|
|
22493
|
+
declarationScope(context, program);
|
|
22494
|
+
for (const body2 of functionBodies) declarationScope(context, body2);
|
|
22495
|
+
const computedReferences = [];
|
|
22357
22496
|
walk(program, context.sourceCode.visitorKeys, (node) => {
|
|
22358
|
-
if (node.type === AST_NODE_TYPES100.MemberExpression && node.computed
|
|
22497
|
+
if (node.type === AST_NODE_TYPES100.MemberExpression && node.computed) computedReferences.push(node);
|
|
22359
22498
|
});
|
|
22360
|
-
for (const node of classes) classScope(context, node,
|
|
22499
|
+
for (const node of classes) classScope(context, node, computedReferences);
|
|
22361
22500
|
}
|
|
22362
22501
|
};
|
|
22363
22502
|
}
|
|
@@ -22366,12 +22505,18 @@ function classMethodCounts(body2, methods) {
|
|
|
22366
22505
|
const counts = /* @__PURE__ */ new Map();
|
|
22367
22506
|
for (const method of methods) {
|
|
22368
22507
|
const name = methodName2(method);
|
|
22369
|
-
if (name !== null)
|
|
22508
|
+
if (name !== null) {
|
|
22509
|
+
const key = methodKey(name, method.static);
|
|
22510
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
22511
|
+
}
|
|
22370
22512
|
}
|
|
22371
22513
|
for (const member of body2.body) {
|
|
22372
22514
|
if (member.type !== AST_NODE_TYPES100.TSAbstractMethodDefinition) continue;
|
|
22373
22515
|
const name = !member.computed && member.key.type === AST_NODE_TYPES100.Identifier ? member.key.name : null;
|
|
22374
|
-
if (name !== null)
|
|
22516
|
+
if (name !== null) {
|
|
22517
|
+
const key = methodKey(name, member.static);
|
|
22518
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
22519
|
+
}
|
|
22375
22520
|
}
|
|
22376
22521
|
return counts;
|
|
22377
22522
|
}
|
|
@@ -22703,16 +22848,70 @@ function importedAssertionKind(specifier) {
|
|
|
22703
22848
|
|
|
22704
22849
|
// src/rules/sole-export-matches-filename.ts
|
|
22705
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
|
|
22706
22904
|
var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
22707
|
-
defaultLevel: "
|
|
22905
|
+
defaultLevel: "error",
|
|
22708
22906
|
summary: "Make a module filename reflect its sole named public runtime export.",
|
|
22709
22907
|
rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
|
|
22710
|
-
remediation: "Name the module for the exported responsibility, using
|
|
22908
|
+
remediation: "Name the module for the exported responsibility, using the full kebab-case export name; otherwise colocate genuinely related exports.",
|
|
22711
22909
|
category: "maintainability",
|
|
22712
22910
|
limitations: [
|
|
22713
|
-
"Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS,
|
|
22714
|
-
"The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker.
|
|
22715
|
-
"Exported destructuring patterns are excluded rather than undercounted as public exports."
|
|
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.",
|
|
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.",
|
|
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."
|
|
22716
22915
|
],
|
|
22717
22916
|
examples: [
|
|
22718
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 },
|
|
@@ -22720,39 +22919,9 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
|
22720
22919
|
]
|
|
22721
22920
|
};
|
|
22722
22921
|
var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
|
|
22723
|
-
"common",
|
|
22724
22922
|
"global",
|
|
22725
|
-
"helpers",
|
|
22726
22923
|
"index",
|
|
22727
|
-
"
|
|
22728
|
-
"loading",
|
|
22729
|
-
"middleware",
|
|
22730
|
-
"misc",
|
|
22731
|
-
"not-found",
|
|
22732
|
-
"page",
|
|
22733
|
-
"route",
|
|
22734
|
-
"shared",
|
|
22735
|
-
"template",
|
|
22736
|
-
"types",
|
|
22737
|
-
"util",
|
|
22738
|
-
"utils"
|
|
22739
|
-
]);
|
|
22740
|
-
var WEAK_DOMAIN_TOKENS = /* @__PURE__ */ new Set([
|
|
22741
|
-
"adapter",
|
|
22742
|
-
"client",
|
|
22743
|
-
"config",
|
|
22744
|
-
"controller",
|
|
22745
|
-
"factory",
|
|
22746
|
-
"handler",
|
|
22747
|
-
"manager",
|
|
22748
|
-
"provider",
|
|
22749
|
-
"record",
|
|
22750
|
-
"repository",
|
|
22751
|
-
"router",
|
|
22752
|
-
"schema",
|
|
22753
|
-
"service",
|
|
22754
|
-
"store",
|
|
22755
|
-
"worker"
|
|
22924
|
+
"types"
|
|
22756
22925
|
]);
|
|
22757
22926
|
function stem3(filename) {
|
|
22758
22927
|
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
@@ -22761,34 +22930,6 @@ function stem3(filename) {
|
|
|
22761
22930
|
function kebabCase(name) {
|
|
22762
22931
|
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();
|
|
22763
22932
|
}
|
|
22764
|
-
function reflectsExportName(fileStem, exportedStem) {
|
|
22765
|
-
if (fileStem.startsWith("_")) return false;
|
|
22766
|
-
const visibleFileStem = fileStem.toLowerCase();
|
|
22767
|
-
const fileTokens = visibleFileStem.split("-").filter(Boolean);
|
|
22768
|
-
const exportTokens = exportedStem.split("-").filter(Boolean);
|
|
22769
|
-
if (fileTokens.length === 0 || exportTokens.length === 0) return false;
|
|
22770
|
-
if (fileTokens.length === 1) {
|
|
22771
|
-
const [token] = fileTokens;
|
|
22772
|
-
return token !== void 0 && token.length >= 4 && !WEAK_DOMAIN_TOKENS.has(token) && (exportTokens[0] === token || exportTokens.at(-1) === token);
|
|
22773
|
-
}
|
|
22774
|
-
const compactFile = fileTokens.join("");
|
|
22775
|
-
if (compactFile.length < 6) return false;
|
|
22776
|
-
const boundaryPhrases = /* @__PURE__ */ new Set();
|
|
22777
|
-
for (let index = 1; index <= exportTokens.length; index += 1) {
|
|
22778
|
-
boundaryPhrases.add(exportTokens.slice(0, index).join(""));
|
|
22779
|
-
boundaryPhrases.add(exportTokens.slice(-index).join(""));
|
|
22780
|
-
}
|
|
22781
|
-
return boundaryPhrases.has(compactFile);
|
|
22782
|
-
}
|
|
22783
|
-
function declarationExport(statement) {
|
|
22784
|
-
const declaration = statement.declaration;
|
|
22785
|
-
if (declaration === null || declaration.declare === true) return [];
|
|
22786
|
-
if (declaration.type === AST_NODE_TYPES102.ClassDeclaration || declaration.type === AST_NODE_TYPES102.FunctionDeclaration || declaration.type === AST_NODE_TYPES102.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
|
|
22787
|
-
if (declaration.type !== AST_NODE_TYPES102.VariableDeclaration) return [];
|
|
22788
|
-
return declaration.declarations.flatMap(
|
|
22789
|
-
(item) => item.id.type === AST_NODE_TYPES102.Identifier ? [{ name: item.id.name, node: item }] : []
|
|
22790
|
-
);
|
|
22791
|
-
}
|
|
22792
22933
|
var sole_export_matches_filename_default = createRule({
|
|
22793
22934
|
name: "sole-export-matches-filename",
|
|
22794
22935
|
documentation: SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION,
|
|
@@ -22804,64 +22945,25 @@ var sole_export_matches_filename_default = createRule({
|
|
|
22804
22945
|
create(context) {
|
|
22805
22946
|
const fileStem = stem3(context.filename);
|
|
22806
22947
|
const normalizedFilename = context.filename.replaceAll("\\", "/");
|
|
22807
|
-
if (EXCLUDED_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 {};
|
|
22949
|
+
let hasCommonJsExport = false;
|
|
22808
22950
|
return {
|
|
22951
|
+
"CallExpression, MemberExpression"(node) {
|
|
22952
|
+
if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
|
|
22953
|
+
},
|
|
22809
22954
|
"Program:exit"(program) {
|
|
22810
|
-
|
|
22811
|
-
const
|
|
22812
|
-
|
|
22813
|
-
|
|
22814
|
-
if (statement.type === AST_NODE_TYPES102.ExportDefaultDeclaration) {
|
|
22815
|
-
publicExports.add("default");
|
|
22816
|
-
const declaration = statement.declaration;
|
|
22817
|
-
if ((declaration.type === AST_NODE_TYPES102.ClassDeclaration || declaration.type === AST_NODE_TYPES102.FunctionDeclaration) && declaration.id !== null) exports.push({ name: declaration.id.name, node: declaration });
|
|
22818
|
-
else return false;
|
|
22819
|
-
}
|
|
22820
|
-
if (statement.type !== AST_NODE_TYPES102.ExportNamedDeclaration) return true;
|
|
22821
|
-
return collectNamedExport(statement);
|
|
22822
|
-
}
|
|
22823
|
-
function collectNamedExport(statement) {
|
|
22824
|
-
const declaration = statement.declaration;
|
|
22825
|
-
if (declaration !== null && "id" in declaration && declaration.id?.type === AST_NODE_TYPES102.Identifier) {
|
|
22826
|
-
publicExports.add(declaration.id.name);
|
|
22827
|
-
}
|
|
22828
|
-
if (declaration?.type === AST_NODE_TYPES102.VariableDeclaration) {
|
|
22829
|
-
if (declaration.declarations.some((item) => item.id.type !== AST_NODE_TYPES102.Identifier)) return false;
|
|
22830
|
-
for (const item of declaration.declarations) {
|
|
22831
|
-
if (item.id.type === AST_NODE_TYPES102.Identifier) publicExports.add(item.id.name);
|
|
22832
|
-
}
|
|
22833
|
-
}
|
|
22834
|
-
for (const specifier of statement.specifiers) {
|
|
22835
|
-
const exported = specifier.exported.type === AST_NODE_TYPES102.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
22836
|
-
publicExports.add(String(exported));
|
|
22837
|
-
}
|
|
22838
|
-
if (statement.exportKind === "type") return true;
|
|
22839
|
-
exports.push(...declarationExport(statement));
|
|
22840
|
-
collectRuntimeSpecifiers(statement);
|
|
22841
|
-
return true;
|
|
22842
|
-
}
|
|
22843
|
-
function collectRuntimeSpecifiers(statement) {
|
|
22844
|
-
for (const specifier of statement.specifiers) {
|
|
22845
|
-
const exported = specifier.exported.type === AST_NODE_TYPES102.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
22846
|
-
publicExports.add(String(exported));
|
|
22847
|
-
if (specifier.exportKind === "type") continue;
|
|
22848
|
-
if (exported === "default") exports.push({ name: specifier.local.name, node: specifier });
|
|
22849
|
-
else exports.push({ name: String(exported), node: specifier });
|
|
22850
|
-
}
|
|
22851
|
-
}
|
|
22852
|
-
for (const statement of program.body) {
|
|
22853
|
-
if (!collectPublicExport(statement)) return;
|
|
22854
|
-
}
|
|
22855
|
-
const unique = new Map(exports.map((item) => [item.name, item]));
|
|
22856
|
-
if (unique.size !== 1 || publicExports.size !== 1) return;
|
|
22857
|
-
const only = [...unique.values()][0];
|
|
22955
|
+
if (hasCommonJsExport) return;
|
|
22956
|
+
const exports = runtimeExports(program);
|
|
22957
|
+
if (exports.ambiguous || exports.exports.length !== 1) return;
|
|
22958
|
+
const only = exports.exports[0];
|
|
22858
22959
|
if (only === void 0) return;
|
|
22960
|
+
if (isFrameworkEntrypoint(normalizedFilename, only.key)) return;
|
|
22859
22961
|
if (only.name === "onRouterTransitionStart" && /(?:^|\/)instrumentation-client\.[jt]s$/u.test(normalizedFilename)) return;
|
|
22860
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;
|
|
22861
22963
|
const exportedStem = kebabCase(only.name);
|
|
22862
22964
|
if (exportedStem === "") return;
|
|
22863
22965
|
const expected = `${fileStem.startsWith("_") ? "_" : ""}${exportedStem}`;
|
|
22864
|
-
if (expected === fileStem.toLowerCase()
|
|
22966
|
+
if (expected === fileStem.toLowerCase()) return;
|
|
22865
22967
|
context.report({ node: only.node, messageId: "matchSoleExport", data: { exported: only.name, expected } });
|
|
22866
22968
|
}
|
|
22867
22969
|
};
|
|
@@ -23079,7 +23181,7 @@ var chainMemberNames2 = (node) => {
|
|
|
23079
23181
|
names.reverse();
|
|
23080
23182
|
return names;
|
|
23081
23183
|
};
|
|
23082
|
-
var
|
|
23184
|
+
var unwrapExpression8 = (node) => {
|
|
23083
23185
|
let current = node;
|
|
23084
23186
|
while (current.type === AST_NODE_TYPES103.TSAsExpression || current.type === AST_NODE_TYPES103.TSSatisfiesExpression || current.type === AST_NODE_TYPES103.TSNonNullExpression || current.type === AST_NODE_TYPES103.TSTypeAssertion) {
|
|
23085
23187
|
current = current.expression;
|
|
@@ -23119,18 +23221,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23119
23221
|
const binding = resolvedBinding(identifier);
|
|
23120
23222
|
if (binding !== null) zodBindings.add(binding);
|
|
23121
23223
|
}
|
|
23122
|
-
function isZodChain(node) {
|
|
23123
|
-
const root = calleeChainRoot2(node);
|
|
23124
|
-
if (root === null) return false;
|
|
23125
|
-
const binding = resolvedBinding(root);
|
|
23126
|
-
return binding !== null && zodBindings.has(binding);
|
|
23127
|
-
}
|
|
23128
|
-
function isSchemaBinding(identifier) {
|
|
23129
|
-
const binding = resolvedBinding(identifier);
|
|
23130
|
-
return binding !== null && schemaBindings.has(binding);
|
|
23131
|
-
}
|
|
23132
23224
|
function isConfirmedSchema(expression) {
|
|
23133
|
-
const init =
|
|
23225
|
+
const init = unwrapExpression8(expression);
|
|
23134
23226
|
if (init.type === AST_NODE_TYPES103.Identifier) return isSchemaBinding(init);
|
|
23135
23227
|
if (init.type !== AST_NODE_TYPES103.CallExpression || init.callee.type !== AST_NODE_TYPES103.MemberExpression) {
|
|
23136
23228
|
return false;
|
|
@@ -23145,6 +23237,16 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23145
23237
|
const root = calleeChainRoot2(init.callee);
|
|
23146
23238
|
return root !== null && isSchemaBinding(root) && SCHEMA_RETURNING_METHODS.has(terminal);
|
|
23147
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
|
+
}
|
|
23148
23250
|
if (isTestFile(context.filename) || BENCHMARK_PATH_RE2.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
23149
23251
|
return {};
|
|
23150
23252
|
}
|
|
@@ -23175,7 +23277,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23175
23277
|
}
|
|
23176
23278
|
});
|
|
23177
23279
|
|
|
23178
|
-
// src/rules/
|
|
23280
|
+
// src/rules/_renamed-rules.ts
|
|
23179
23281
|
var RENAMED_RULES = {
|
|
23180
23282
|
"jsdoc-restates-signature": "no-restated-jsdoc",
|
|
23181
23283
|
"zod-naming-convention": "require-pascal-case-zod-schema-name",
|
|
@@ -23184,7 +23286,7 @@ var RENAMED_RULES = {
|
|
|
23184
23286
|
"trailing-value-narration": "no-trailing-value-narration"
|
|
23185
23287
|
};
|
|
23186
23288
|
|
|
23187
|
-
// src/rules/_retired.ts
|
|
23289
|
+
// src/rules/_retired-rules.ts
|
|
23188
23290
|
var RETIRED_RULES = {
|
|
23189
23291
|
"ban-loose-type-guards-in-tests": {
|
|
23190
23292
|
removedIn: "5.0.0",
|
|
@@ -23376,7 +23478,7 @@ var RULES = {
|
|
|
23376
23478
|
};
|
|
23377
23479
|
var meta = {
|
|
23378
23480
|
name: "@sarj/eslint-plugin",
|
|
23379
|
-
version: "
|
|
23481
|
+
version: "16.1.0"
|
|
23380
23482
|
};
|
|
23381
23483
|
var APPLICATION_ONLY_RULES = [];
|
|
23382
23484
|
var LIBRARY_IMPORT_POLICY = ["error", {
|
|
@@ -23401,8 +23503,7 @@ var ADVISORY_RULES = [
|
|
|
23401
23503
|
"@sarj/prefer-whole-object-assertion",
|
|
23402
23504
|
"@sarj/require-camelcase-properties",
|
|
23403
23505
|
"@sarj/require-interface-for-exported-class",
|
|
23404
|
-
"@sarj/require-sql-access-class"
|
|
23405
|
-
"@sarj/sole-export-matches-filename"
|
|
23506
|
+
"@sarj/require-sql-access-class"
|
|
23406
23507
|
];
|
|
23407
23508
|
var RECOMMENDED_RULES = {
|
|
23408
23509
|
"@sarj/no-conditional-empty-object-spread": "error",
|
|
@@ -23514,7 +23615,7 @@ var RECOMMENDED_RULES = {
|
|
|
23514
23615
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
23515
23616
|
"@sarj/stepdown": "error",
|
|
23516
23617
|
"@sarj/source-coupled-test": "error",
|
|
23517
|
-
"@sarj/sole-export-matches-filename": "
|
|
23618
|
+
"@sarj/sole-export-matches-filename": "error",
|
|
23518
23619
|
"@sarj/test-phase-label-comment": "error",
|
|
23519
23620
|
"@sarj/require-pascal-case-zod-schema-name": "error"
|
|
23520
23621
|
};
|
|
@@ -23632,7 +23733,7 @@ var STRICT_RULES = {
|
|
|
23632
23733
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
23633
23734
|
"@sarj/stepdown": "error",
|
|
23634
23735
|
"@sarj/source-coupled-test": "error",
|
|
23635
|
-
"@sarj/sole-export-matches-filename": "
|
|
23736
|
+
"@sarj/sole-export-matches-filename": "error",
|
|
23636
23737
|
"@sarj/test-phase-label-comment": "error",
|
|
23637
23738
|
"@sarj/require-pascal-case-zod-schema-name": "error"
|
|
23638
23739
|
};
|
|
@@ -23655,7 +23756,7 @@ var PLUGIN = {
|
|
|
23655
23756
|
};
|
|
23656
23757
|
}
|
|
23657
23758
|
};
|
|
23658
|
-
var
|
|
23759
|
+
var src_default = PLUGIN;
|
|
23659
23760
|
export {
|
|
23660
23761
|
ADVISORY_RULES,
|
|
23661
23762
|
APPLICATION_ONLY_RULES,
|
|
@@ -23666,7 +23767,7 @@ export {
|
|
|
23666
23767
|
STRICT_RULES,
|
|
23667
23768
|
ADVISORY_RULES as advisoryRules,
|
|
23668
23769
|
APPLICATION_ONLY_RULES as applicationOnlyRules,
|
|
23669
|
-
|
|
23770
|
+
src_default as default,
|
|
23670
23771
|
publicDocumentation,
|
|
23671
23772
|
RECOMMENDED_RULES as recommendedRules,
|
|
23672
23773
|
RENAMED_RULES as renamedRules,
|