@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.cjs
CHANGED
|
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
33
|
ADVISORY_RULES: () => ADVISORY_RULES,
|
|
34
34
|
APPLICATION_ONLY_RULES: () => APPLICATION_ONLY_RULES,
|
|
35
35
|
RECOMMENDED_RULES: () => RECOMMENDED_RULES,
|
|
@@ -39,7 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
STRICT_RULES: () => STRICT_RULES,
|
|
40
40
|
advisoryRules: () => ADVISORY_RULES,
|
|
41
41
|
applicationOnlyRules: () => APPLICATION_ONLY_RULES,
|
|
42
|
-
default: () =>
|
|
42
|
+
default: () => src_default,
|
|
43
43
|
publicDocumentation: () => publicDocumentation,
|
|
44
44
|
recommendedRules: () => RECOMMENDED_RULES,
|
|
45
45
|
renamedRules: () => RENAMED_RULES,
|
|
@@ -47,7 +47,7 @@ __export(index_exports, {
|
|
|
47
47
|
rules: () => RULES,
|
|
48
48
|
strictRules: () => STRICT_RULES
|
|
49
49
|
});
|
|
50
|
-
module.exports = __toCommonJS(
|
|
50
|
+
module.exports = __toCommonJS(src_exports);
|
|
51
51
|
|
|
52
52
|
// src/rules/no-conditional-empty-object-spread.ts
|
|
53
53
|
var import_utils2 = require("@typescript-eslint/utils");
|
|
@@ -489,8 +489,8 @@ var prefer_typed_reflection_default = createRule({
|
|
|
489
489
|
const services = import_utils3.ESLintUtils.getParserServices(context);
|
|
490
490
|
if (!services.program) return {};
|
|
491
491
|
const checker = services.program.getTypeChecker();
|
|
492
|
-
const globalName = (node, name) => node.type === import_utils3.AST_NODE_TYPES.Identifier && node.name === name && !import_utils3.ASTUtils.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
493
492
|
const isReflect = (node) => globalName(node, "Reflect") || node.type === import_utils3.AST_NODE_TYPES.MemberExpression && propertyName(node) === "Reflect" && globalName(node.object, "globalThis");
|
|
493
|
+
const globalName = (node, name) => node.type === import_utils3.AST_NODE_TYPES.Identifier && node.name === name && !import_utils3.ASTUtils.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
494
494
|
const closedObject = (type) => {
|
|
495
495
|
if (type.isUnion()) return type.types.every(closedObject);
|
|
496
496
|
return knownType(type) && type.getProperties().length > 0 && checker.getIndexInfosOfType(type).length === 0;
|
|
@@ -727,6 +727,14 @@ var no_reduce_accumulator_copy_default = createRule({
|
|
|
727
727
|
const accumulator = context.sourceCode.getDeclaredVariables(callback).find((variable) => variable.identifiers.includes(parameter));
|
|
728
728
|
if (!accumulator || accumulator.references.some((reference) => reference.isWrite())) return;
|
|
729
729
|
const referencesAccumulator = (value) => value.type === import_utils5.AST_NODE_TYPES.Identifier && import_utils5.ASTUtils.findVariable(context.sourceCode.getScope(value), value.name) === accumulator;
|
|
730
|
+
const inspect = (current) => {
|
|
731
|
+
if (current !== callback.body && [import_utils5.AST_NODE_TYPES.ArrowFunctionExpression, import_utils5.AST_NODE_TYPES.FunctionExpression, import_utils5.AST_NODE_TYPES.FunctionDeclaration].some((kind) => kind === current.type)) return;
|
|
732
|
+
if (current.type === import_utils5.AST_NODE_TYPES.SpreadElement && (arraySeed && current.parent.type === import_utils5.AST_NODE_TYPES.ArrayExpression || objectSeed && current.parent.type === import_utils5.AST_NODE_TYPES.ObjectExpression) && referencesAccumulator(current.argument)) {
|
|
733
|
+
context.report({ node: current, messageId: "copy" });
|
|
734
|
+
}
|
|
735
|
+
if (current.type === import_utils5.AST_NODE_TYPES.CallExpression) inspectCall(current);
|
|
736
|
+
forEachAstChild(current, context.sourceCode.visitorKeys, inspect);
|
|
737
|
+
};
|
|
730
738
|
const inspectCall = (current) => {
|
|
731
739
|
if (current.callee.type !== import_utils5.AST_NODE_TYPES.MemberExpression) return;
|
|
732
740
|
const member = current.callee;
|
|
@@ -739,14 +747,6 @@ var no_reduce_accumulator_copy_default = createRule({
|
|
|
739
747
|
const assignCopy = objectSeed && name === "assign" && globalObject && target?.type === import_utils5.AST_NODE_TYPES.ObjectExpression && current.arguments.slice(1).some(referencesAccumulator);
|
|
740
748
|
if (directCopy || fromCopy || assignCopy) context.report({ node: current, messageId: "copy" });
|
|
741
749
|
};
|
|
742
|
-
const inspect = (current) => {
|
|
743
|
-
if (current !== callback.body && [import_utils5.AST_NODE_TYPES.ArrowFunctionExpression, import_utils5.AST_NODE_TYPES.FunctionExpression, import_utils5.AST_NODE_TYPES.FunctionDeclaration].some((kind) => kind === current.type)) return;
|
|
744
|
-
if (current.type === import_utils5.AST_NODE_TYPES.SpreadElement && (arraySeed && current.parent.type === import_utils5.AST_NODE_TYPES.ArrayExpression || objectSeed && current.parent.type === import_utils5.AST_NODE_TYPES.ObjectExpression) && referencesAccumulator(current.argument)) {
|
|
745
|
-
context.report({ node: current, messageId: "copy" });
|
|
746
|
-
}
|
|
747
|
-
if (current.type === import_utils5.AST_NODE_TYPES.CallExpression) inspectCall(current);
|
|
748
|
-
forEachAstChild(current, context.sourceCode.visitorKeys, inspect);
|
|
749
|
-
};
|
|
750
750
|
inspect(callback.body);
|
|
751
751
|
}
|
|
752
752
|
};
|
|
@@ -3650,28 +3650,6 @@ var no_cors_wildcard_with_credentials_default = createRule({
|
|
|
3650
3650
|
const scopeHeaderSets = /* @__PURE__ */ new Map();
|
|
3651
3651
|
const variableIds = /* @__PURE__ */ new WeakMap();
|
|
3652
3652
|
let nextVariableId = 0;
|
|
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
|
-
function receiverIdentity(node) {
|
|
3661
|
-
if (node.type === import_utils23.AST_NODE_TYPES.Identifier) {
|
|
3662
|
-
const variable = import_utils23.ASTUtils.findVariable(
|
|
3663
|
-
context.sourceCode.getScope(node),
|
|
3664
|
-
node.name
|
|
3665
|
-
);
|
|
3666
|
-
return variable === null ? `global:${node.name}` : `variable:${variableId(variable)}`;
|
|
3667
|
-
}
|
|
3668
|
-
if (node.type === import_utils23.AST_NODE_TYPES.ThisExpression) return "this";
|
|
3669
|
-
if (node.type === import_utils23.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils23.AST_NODE_TYPES.Identifier) {
|
|
3670
|
-
const owner = receiverIdentity(node.object);
|
|
3671
|
-
return owner === null ? null : `${owner}.${node.property.name}`;
|
|
3672
|
-
}
|
|
3673
|
-
return null;
|
|
3674
|
-
}
|
|
3675
3653
|
function recordHeaderSet(node, kind) {
|
|
3676
3654
|
if (node.callee.type !== import_utils23.AST_NODE_TYPES.MemberExpression) return;
|
|
3677
3655
|
const receiver = receiverIdentity(node.callee.object);
|
|
@@ -3693,6 +3671,28 @@ var no_cors_wildcard_with_credentials_default = createRule({
|
|
|
3693
3671
|
entry.credentialsNodes.push(node);
|
|
3694
3672
|
}
|
|
3695
3673
|
}
|
|
3674
|
+
function receiverIdentity(node) {
|
|
3675
|
+
if (node.type === import_utils23.AST_NODE_TYPES.Identifier) {
|
|
3676
|
+
const variable = import_utils23.ASTUtils.findVariable(
|
|
3677
|
+
context.sourceCode.getScope(node),
|
|
3678
|
+
node.name
|
|
3679
|
+
);
|
|
3680
|
+
return variable === null ? `global:${node.name}` : `variable:${variableId(variable)}`;
|
|
3681
|
+
}
|
|
3682
|
+
if (node.type === import_utils23.AST_NODE_TYPES.ThisExpression) return "this";
|
|
3683
|
+
if (node.type === import_utils23.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils23.AST_NODE_TYPES.Identifier) {
|
|
3684
|
+
const owner = receiverIdentity(node.object);
|
|
3685
|
+
return owner === null ? null : `${owner}.${node.property.name}`;
|
|
3686
|
+
}
|
|
3687
|
+
return null;
|
|
3688
|
+
}
|
|
3689
|
+
function variableId(variable) {
|
|
3690
|
+
const existing = variableIds.get(variable);
|
|
3691
|
+
if (existing !== void 0) return existing;
|
|
3692
|
+
const value = nextVariableId++;
|
|
3693
|
+
variableIds.set(variable, value);
|
|
3694
|
+
return value;
|
|
3695
|
+
}
|
|
3696
3696
|
return {
|
|
3697
3697
|
NewExpression(node) {
|
|
3698
3698
|
if (isCorsWildcardCredentialsCall(node)) {
|
|
@@ -4482,20 +4482,6 @@ function functionComplexity(fn, visitorKeys) {
|
|
|
4482
4482
|
function add(node, nesting, construct) {
|
|
4483
4483
|
points.push({ line: node.loc.start.line, amount: nesting + 1, construct });
|
|
4484
4484
|
}
|
|
4485
|
-
function logical(node, nesting) {
|
|
4486
|
-
let previous;
|
|
4487
|
-
function flatten(expression) {
|
|
4488
|
-
if (expression.type !== import_utils29.AST_NODE_TYPES.LogicalExpression || expression.operator === "??") {
|
|
4489
|
-
visit(expression, nesting);
|
|
4490
|
-
return;
|
|
4491
|
-
}
|
|
4492
|
-
flatten(expression.left);
|
|
4493
|
-
if (previous !== expression.operator) add(expression, 0, expression.operator);
|
|
4494
|
-
previous = expression.operator;
|
|
4495
|
-
flatten(expression.right);
|
|
4496
|
-
}
|
|
4497
|
-
flatten(node);
|
|
4498
|
-
}
|
|
4499
4485
|
function conditional(node, nesting) {
|
|
4500
4486
|
add(node, nesting, "if");
|
|
4501
4487
|
let branch = node;
|
|
@@ -4574,6 +4560,20 @@ function functionComplexity(fn, visitorKeys) {
|
|
|
4574
4560
|
}
|
|
4575
4561
|
visitChildren(node, nesting);
|
|
4576
4562
|
}
|
|
4563
|
+
function logical(node, nesting) {
|
|
4564
|
+
let previous;
|
|
4565
|
+
function flatten(expression) {
|
|
4566
|
+
if (expression.type !== import_utils29.AST_NODE_TYPES.LogicalExpression || expression.operator === "??") {
|
|
4567
|
+
visit(expression, nesting);
|
|
4568
|
+
return;
|
|
4569
|
+
}
|
|
4570
|
+
flatten(expression.left);
|
|
4571
|
+
if (previous !== expression.operator) add(expression, 0, expression.operator);
|
|
4572
|
+
previous = expression.operator;
|
|
4573
|
+
flatten(expression.right);
|
|
4574
|
+
}
|
|
4575
|
+
flatten(node);
|
|
4576
|
+
}
|
|
4577
4577
|
function visitChildren(node, nesting) {
|
|
4578
4578
|
forEachAstChild(node, visitorKeys, (child) => visit(child, nesting));
|
|
4579
4579
|
}
|
|
@@ -5196,6 +5196,14 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
5196
5196
|
const callee = callback.type === import_utils31.AST_NODE_TYPES.Identifier ? callback : callback.type === import_utils31.AST_NODE_TYPES.ArrowFunctionExpression || callback.type === import_utils31.AST_NODE_TYPES.FunctionExpression ? soleCall(callback)?.callee : null;
|
|
5197
5197
|
return callee?.type === import_utils31.AST_NODE_TYPES.Identifier && bindingOf(callee) === bindingOf(parameter);
|
|
5198
5198
|
};
|
|
5199
|
+
let clientModule = null;
|
|
5200
|
+
const reportsSleepHere = () => {
|
|
5201
|
+
if (checkClientModules) {
|
|
5202
|
+
return true;
|
|
5203
|
+
}
|
|
5204
|
+
clientModule ??= isClientModule2();
|
|
5205
|
+
return !clientModule;
|
|
5206
|
+
};
|
|
5199
5207
|
function isClientModule2() {
|
|
5200
5208
|
if (/\.[cm]?[jt]sx$/.test(filename)) {
|
|
5201
5209
|
return true;
|
|
@@ -5211,14 +5219,6 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
5211
5219
|
}
|
|
5212
5220
|
return false;
|
|
5213
5221
|
}
|
|
5214
|
-
let clientModule = null;
|
|
5215
|
-
const reportsSleepHere = () => {
|
|
5216
|
-
if (checkClientModules) {
|
|
5217
|
-
return true;
|
|
5218
|
-
}
|
|
5219
|
-
clientModule ??= isClientModule2();
|
|
5220
|
-
return !clientModule;
|
|
5221
|
-
};
|
|
5222
5222
|
return {
|
|
5223
5223
|
NewExpression(node) {
|
|
5224
5224
|
if (node.callee.type !== import_utils31.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise" || !isGlobal(node.callee)) {
|
|
@@ -5648,13 +5648,6 @@ var no_detached_global_fetch_default = createRule({
|
|
|
5648
5648
|
const variable = bindingOf(identifier);
|
|
5649
5649
|
if (variable !== null && isStableAlias(variable)) aliases.add(variable);
|
|
5650
5650
|
}
|
|
5651
|
-
function isGlobalFetchMember(node) {
|
|
5652
|
-
if (!isGlobalReceiver(node.object)) return false;
|
|
5653
|
-
if (!node.computed) {
|
|
5654
|
-
return node.property.type === import_utils34.AST_NODE_TYPES.Identifier && node.property.name === "fetch";
|
|
5655
|
-
}
|
|
5656
|
-
return node.property.type === import_utils34.AST_NODE_TYPES.Literal && node.property.value === "fetch";
|
|
5657
|
-
}
|
|
5658
5651
|
function staticMemberName9(node) {
|
|
5659
5652
|
if (!node.computed) {
|
|
5660
5653
|
return node.property.type === import_utils34.AST_NODE_TYPES.Identifier ? node.property.name : null;
|
|
@@ -5683,6 +5676,13 @@ var no_detached_global_fetch_default = createRule({
|
|
|
5683
5676
|
}
|
|
5684
5677
|
return false;
|
|
5685
5678
|
}
|
|
5679
|
+
function isGlobalFetchMember(node) {
|
|
5680
|
+
if (!isGlobalReceiver(node.object)) return false;
|
|
5681
|
+
if (!node.computed) {
|
|
5682
|
+
return node.property.type === import_utils34.AST_NODE_TYPES.Identifier && node.property.name === "fetch";
|
|
5683
|
+
}
|
|
5684
|
+
return node.property.type === import_utils34.AST_NODE_TYPES.Literal && node.property.value === "fetch";
|
|
5685
|
+
}
|
|
5686
5686
|
function recordAliasFromValue(identifier, value) {
|
|
5687
5687
|
if (mayBeRawFetch(value)) recordAlias(identifier);
|
|
5688
5688
|
}
|
|
@@ -6241,17 +6241,6 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
6241
6241
|
}
|
|
6242
6242
|
return false;
|
|
6243
6243
|
}
|
|
6244
|
-
function baseKind(node) {
|
|
6245
|
-
const callee = node.callee;
|
|
6246
|
-
if (callee.type === import_utils37.AST_NODE_TYPES.Identifier) {
|
|
6247
|
-
return resolvesToTrackedImport(callee) ? constructors.get(callee.name) ?? null : null;
|
|
6248
|
-
}
|
|
6249
|
-
if (callee.type !== import_utils37.AST_NODE_TYPES.MemberExpression || callee.object.type !== import_utils37.AST_NODE_TYPES.Identifier || !namespaces.has(callee.object.name) || !resolvesToTrackedImport(callee.object)) {
|
|
6250
|
-
return null;
|
|
6251
|
-
}
|
|
6252
|
-
const name = memberName(callee);
|
|
6253
|
-
return name !== null && KINDS.has(name) ? name : null;
|
|
6254
|
-
}
|
|
6255
6244
|
function readChain(node) {
|
|
6256
6245
|
const calls = [];
|
|
6257
6246
|
let current = node;
|
|
@@ -6268,6 +6257,17 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
6268
6257
|
current = callee.object;
|
|
6269
6258
|
}
|
|
6270
6259
|
}
|
|
6260
|
+
function baseKind(node) {
|
|
6261
|
+
const callee = node.callee;
|
|
6262
|
+
if (callee.type === import_utils37.AST_NODE_TYPES.Identifier) {
|
|
6263
|
+
return resolvesToTrackedImport(callee) ? constructors.get(callee.name) ?? null : null;
|
|
6264
|
+
}
|
|
6265
|
+
if (callee.type !== import_utils37.AST_NODE_TYPES.MemberExpression || callee.object.type !== import_utils37.AST_NODE_TYPES.Identifier || !namespaces.has(callee.object.name) || !resolvesToTrackedImport(callee.object)) {
|
|
6266
|
+
return null;
|
|
6267
|
+
}
|
|
6268
|
+
const name = memberName(callee);
|
|
6269
|
+
return name !== null && KINDS.has(name) ? name : null;
|
|
6270
|
+
}
|
|
6271
6271
|
function isInsideReshapingCall(node) {
|
|
6272
6272
|
let child = node;
|
|
6273
6273
|
let parent = child.parent;
|
|
@@ -6581,30 +6581,30 @@ var no_redundant_optional_array_default_default = createRule({
|
|
|
6581
6581
|
}
|
|
6582
6582
|
return false;
|
|
6583
6583
|
}
|
|
6584
|
-
function
|
|
6584
|
+
function isArraySchemaExpression(node) {
|
|
6585
6585
|
if (node.type !== import_utils39.AST_NODE_TYPES.CallExpression) return false;
|
|
6586
6586
|
const { callee } = node;
|
|
6587
6587
|
if (callee.type === import_utils39.AST_NODE_TYPES.Identifier) {
|
|
6588
|
-
return resolvesToTrackedImport(callee);
|
|
6588
|
+
return arrayConstructors.has(callee.name) && resolvesToTrackedImport(callee);
|
|
6589
6589
|
}
|
|
6590
6590
|
if (callee.type !== import_utils39.AST_NODE_TYPES.MemberExpression) return false;
|
|
6591
|
-
|
|
6591
|
+
const method = memberName2(callee);
|
|
6592
|
+
if (method === "array" && (callee.object.type === import_utils39.AST_NODE_TYPES.Identifier ? namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object) : isZodSchemaExpression(callee.object))) {
|
|
6592
6593
|
return true;
|
|
6593
6594
|
}
|
|
6594
|
-
return
|
|
6595
|
+
return isArraySchemaExpression(callee.object);
|
|
6595
6596
|
}
|
|
6596
|
-
function
|
|
6597
|
+
function isZodSchemaExpression(node) {
|
|
6597
6598
|
if (node.type !== import_utils39.AST_NODE_TYPES.CallExpression) return false;
|
|
6598
6599
|
const { callee } = node;
|
|
6599
6600
|
if (callee.type === import_utils39.AST_NODE_TYPES.Identifier) {
|
|
6600
|
-
return
|
|
6601
|
+
return resolvesToTrackedImport(callee);
|
|
6601
6602
|
}
|
|
6602
6603
|
if (callee.type !== import_utils39.AST_NODE_TYPES.MemberExpression) return false;
|
|
6603
|
-
|
|
6604
|
-
if (method === "array" && (callee.object.type === import_utils39.AST_NODE_TYPES.Identifier ? namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object) : isZodSchemaExpression(callee.object))) {
|
|
6604
|
+
if (callee.object.type === import_utils39.AST_NODE_TYPES.Identifier && namespaces.has(callee.object.name) && resolvesToTrackedImport(callee.object)) {
|
|
6605
6605
|
return true;
|
|
6606
6606
|
}
|
|
6607
|
-
return
|
|
6607
|
+
return isZodSchemaExpression(callee.object);
|
|
6608
6608
|
}
|
|
6609
6609
|
return {
|
|
6610
6610
|
ImportDeclaration(node) {
|
|
@@ -7036,10 +7036,6 @@ var no_log_only_catch_default = createRule({
|
|
|
7036
7036
|
}
|
|
7037
7037
|
return matcher.isLoggingCall(statement.expression);
|
|
7038
7038
|
}
|
|
7039
|
-
function hasCommentDirectlyAbove(node) {
|
|
7040
|
-
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
7041
|
-
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
7042
|
-
}
|
|
7043
7039
|
function hasAdjacentRationale(node) {
|
|
7044
7040
|
const tryStatement = node.parent;
|
|
7045
7041
|
if (hasCommentDirectlyAbove(tryStatement) || hasCommentDirectlyAbove(node)) return true;
|
|
@@ -7049,6 +7045,10 @@ var no_log_only_catch_default = createRule({
|
|
|
7049
7045
|
}
|
|
7050
7046
|
return hasCommentDirectlyAbove(block.parent);
|
|
7051
7047
|
}
|
|
7048
|
+
function hasCommentDirectlyAbove(node) {
|
|
7049
|
+
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
7050
|
+
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
7051
|
+
}
|
|
7052
7052
|
if (isTestFile(filename) || BENCHMARK_DIR_RE.test(filename.replaceAll("\\", "/"))) {
|
|
7053
7053
|
return {};
|
|
7054
7054
|
}
|
|
@@ -7521,20 +7521,9 @@ var no_vague_suppression_description_default = createRule({
|
|
|
7521
7521
|
}
|
|
7522
7522
|
});
|
|
7523
7523
|
|
|
7524
|
-
// src/rules/
|
|
7524
|
+
// src/rules/_runtime-exports.ts
|
|
7525
7525
|
var import_utils47 = require("@typescript-eslint/utils");
|
|
7526
|
-
var
|
|
7527
|
-
summary: "Disallow generic module stems when one runtime export already names the responsibility.",
|
|
7528
|
-
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
7529
|
-
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
7530
|
-
category: "maintainability",
|
|
7531
|
-
limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
|
|
7532
|
-
examples: [
|
|
7533
|
-
{ 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 },
|
|
7534
|
-
{ 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 }
|
|
7535
|
-
]
|
|
7536
|
-
};
|
|
7537
|
-
var GENERIC_STEMS = /* @__PURE__ */ new Set([
|
|
7526
|
+
var GENERIC_MODULE_STEMS = /* @__PURE__ */ new Set([
|
|
7538
7527
|
"common",
|
|
7539
7528
|
"helper",
|
|
7540
7529
|
"helpers",
|
|
@@ -7545,164 +7534,172 @@ var GENERIC_STEMS = /* @__PURE__ */ new Set([
|
|
|
7545
7534
|
"utils"
|
|
7546
7535
|
]);
|
|
7547
7536
|
var CJS_OBJECT_EXPORT_METHODS = /* @__PURE__ */ new Set(["assign", "defineProperties", "defineProperty"]);
|
|
7548
|
-
function fileParts(filename) {
|
|
7549
|
-
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
7550
|
-
const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
|
|
7551
|
-
const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
|
|
7552
|
-
return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
|
|
7553
|
-
}
|
|
7554
|
-
function declaredNames(declaration) {
|
|
7555
|
-
if (declaration.declare === true) return [];
|
|
7556
|
-
if (declaration.type === import_utils47.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration) {
|
|
7557
|
-
if (declaration.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration && declaration.const) return [];
|
|
7558
|
-
return declaration.id === null ? [] : [declaration.id.name];
|
|
7559
|
-
}
|
|
7560
|
-
if (declaration.type === import_utils47.AST_NODE_TYPES.TSModuleDeclaration && declaration.id.type === import_utils47.AST_NODE_TYPES.Identifier) {
|
|
7561
|
-
return [declaration.id.name];
|
|
7562
|
-
}
|
|
7563
|
-
if (declaration.type !== import_utils47.AST_NODE_TYPES.VariableDeclaration) return [];
|
|
7564
|
-
return declaration.declarations.flatMap(
|
|
7565
|
-
(item) => item.id.type === import_utils47.AST_NODE_TYPES.Identifier ? [item.id.name] : []
|
|
7566
|
-
);
|
|
7567
|
-
}
|
|
7568
7537
|
function runtimeExports(program) {
|
|
7569
|
-
const
|
|
7570
|
-
const
|
|
7538
|
+
const bindings = localBindings(program);
|
|
7539
|
+
const exports2 = /* @__PURE__ */ new Map();
|
|
7571
7540
|
let ambiguous = false;
|
|
7572
|
-
function
|
|
7573
|
-
if (
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
}
|
|
7581
|
-
|
|
7541
|
+
function add(key, name, node, emission) {
|
|
7542
|
+
if (emission === "unknown") ambiguous = true;
|
|
7543
|
+
if (emission === "runtime") exports2.set(key, { key, name, node });
|
|
7544
|
+
}
|
|
7545
|
+
function collectDefault(statement) {
|
|
7546
|
+
const declaration = statement.declaration;
|
|
7547
|
+
if (declaration.type === import_utils47.AST_NODE_TYPES.Identifier) {
|
|
7548
|
+
add("default", declaration.name, statement, bindings.get(declaration.name) ?? "unknown");
|
|
7549
|
+
} else if ("id" in declaration && declaration.id?.type === import_utils47.AST_NODE_TYPES.Identifier) {
|
|
7550
|
+
add("default", declaration.id.name, declaration, declarationEmission(declaration));
|
|
7551
|
+
} else ambiguous = true;
|
|
7552
|
+
}
|
|
7553
|
+
function collectNamed(statement) {
|
|
7554
|
+
if (statement.exportKind === "type") return;
|
|
7582
7555
|
if (statement.source !== null) {
|
|
7583
7556
|
if (statement.specifiers.some((specifier) => specifier.exportKind !== "type")) ambiguous = true;
|
|
7584
7557
|
return;
|
|
7585
7558
|
}
|
|
7586
|
-
|
|
7587
|
-
|
|
7559
|
+
const declaration = statement.declaration;
|
|
7560
|
+
if (declaration !== null) {
|
|
7588
7561
|
if (declaration.type === import_utils47.AST_NODE_TYPES.VariableDeclaration && declaration.declarations.some((item) => item.id.type !== import_utils47.AST_NODE_TYPES.Identifier)) ambiguous = true;
|
|
7589
|
-
|
|
7562
|
+
const names = declarationNames(declaration);
|
|
7563
|
+
if (names.length === 0 && declarationEmission(declaration) !== "erased") ambiguous = true;
|
|
7564
|
+
for (const name of names) add(name, name, declaration, bindings.get(name) ?? "unknown");
|
|
7590
7565
|
}
|
|
7591
|
-
collectExportSpecifiers(statement);
|
|
7592
|
-
}
|
|
7593
|
-
function collectExportSpecifiers(statement) {
|
|
7594
7566
|
for (const specifier of statement.specifiers) {
|
|
7595
|
-
if (specifier.exportKind === "type"
|
|
7596
|
-
const
|
|
7567
|
+
if (specifier.exportKind === "type") continue;
|
|
7568
|
+
const key = specifier.exported.type === import_utils47.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
7597
7569
|
const local = specifier.local.name;
|
|
7598
|
-
|
|
7570
|
+
add(key, key === "default" ? local : key, specifier, bindings.get(local) ?? "unknown");
|
|
7599
7571
|
}
|
|
7600
7572
|
}
|
|
7601
|
-
function collectDefaultExport(statement) {
|
|
7602
|
-
const declaration = statement.declaration;
|
|
7603
|
-
if (declaration.type === import_utils47.AST_NODE_TYPES.Identifier) {
|
|
7604
|
-
if (!typeBindings.has(declaration.name)) {
|
|
7605
|
-
exports2.push({ key: "default", name: declaration.name, node: statement });
|
|
7606
|
-
}
|
|
7607
|
-
} else if ((declaration.type === import_utils47.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.ClassDeclaration) && declaration.id !== null && declaration.declare !== true) exports2.push({ key: "default", name: declaration.id.name, node: declaration });
|
|
7608
|
-
else if (declaration.type !== import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration && declaration.type !== import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration) ambiguous = true;
|
|
7609
|
-
}
|
|
7610
7573
|
for (const statement of program.body) {
|
|
7611
|
-
|
|
7574
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.ExportAllDeclaration && statement.exportKind !== "type") ambiguous = true;
|
|
7575
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.TSExportAssignment) ambiguous = true;
|
|
7576
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration) collectDefault(statement);
|
|
7577
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration) collectNamed(statement);
|
|
7612
7578
|
}
|
|
7613
|
-
|
|
7614
|
-
return { exports: [...unique.values()], ambiguous };
|
|
7579
|
+
return { exports: [...exports2.values()], ambiguous };
|
|
7615
7580
|
}
|
|
7616
|
-
function
|
|
7617
|
-
const
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
if (
|
|
7622
|
-
|
|
7623
|
-
return;
|
|
7624
|
-
}
|
|
7625
|
-
if (declaration?.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration && declaration.const) {
|
|
7626
|
-
names.add(declaration.id.name);
|
|
7627
|
-
return;
|
|
7628
|
-
}
|
|
7629
|
-
if (statement.type === import_utils47.AST_NODE_TYPES.ImportDeclaration) {
|
|
7630
|
-
collectImportBindings(statement);
|
|
7631
|
-
return;
|
|
7632
|
-
}
|
|
7633
|
-
if (declaration?.type === import_utils47.AST_NODE_TYPES.TSDeclareFunction && declaration.id !== null) {
|
|
7634
|
-
names.add(declaration.id.name);
|
|
7635
|
-
return;
|
|
7636
|
-
}
|
|
7637
|
-
if (declaration !== null && declaration.declare === true) {
|
|
7638
|
-
collectDeclaredNames(declaration);
|
|
7639
|
-
return;
|
|
7640
|
-
}
|
|
7641
|
-
if (declaration !== null && "type" in declaration) {
|
|
7642
|
-
for (const name of declaredNames(declaration)) {
|
|
7643
|
-
runtimeNames.add(name);
|
|
7644
|
-
}
|
|
7645
|
-
}
|
|
7581
|
+
function localBindings(program) {
|
|
7582
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
7583
|
+
function register(name, emission) {
|
|
7584
|
+
const previous = bindings.get(name);
|
|
7585
|
+
if (previous === "runtime" || emission === "runtime") bindings.set(name, "runtime");
|
|
7586
|
+
else if (previous === "unknown" || emission === "unknown") bindings.set(name, "unknown");
|
|
7587
|
+
else bindings.set(name, "erased");
|
|
7646
7588
|
}
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
runtimeNames.add(specifier.local.name);
|
|
7589
|
+
for (const statement of program.body) {
|
|
7590
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.ImportDeclaration) {
|
|
7591
|
+
for (const specifier of statement.specifiers) {
|
|
7592
|
+
const typeOnly = statement.importKind === "type" || specifier.type === import_utils47.AST_NODE_TYPES.ImportSpecifier && specifier.importKind === "type";
|
|
7593
|
+
register(specifier.local.name, typeOnly ? "erased" : "unknown");
|
|
7653
7594
|
}
|
|
7595
|
+
continue;
|
|
7654
7596
|
}
|
|
7597
|
+
const declaration = statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
7598
|
+
if (declaration === null) continue;
|
|
7599
|
+
for (const name of declarationNames(declaration)) register(name, declarationEmission(declaration));
|
|
7655
7600
|
}
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7601
|
+
return bindings;
|
|
7602
|
+
}
|
|
7603
|
+
function declarationNames(declaration) {
|
|
7604
|
+
if ("id" in declaration && declaration.id !== null) {
|
|
7605
|
+
let id = declaration.id;
|
|
7606
|
+
while (id.type === import_utils47.AST_NODE_TYPES.TSQualifiedName) id = id.left;
|
|
7607
|
+
if (id.type === import_utils47.AST_NODE_TYPES.Identifier) return [id.name];
|
|
7663
7608
|
}
|
|
7664
|
-
|
|
7665
|
-
|
|
7609
|
+
if (declaration.type !== import_utils47.AST_NODE_TYPES.VariableDeclaration) return [];
|
|
7610
|
+
return declaration.declarations.flatMap((item) => item.id.type === import_utils47.AST_NODE_TYPES.Identifier ? [item.id.name] : []);
|
|
7611
|
+
}
|
|
7612
|
+
function declarationEmission(declaration) {
|
|
7613
|
+
if ("declare" in declaration && declaration.declare === true) return "erased";
|
|
7614
|
+
switch (declaration.type) {
|
|
7615
|
+
case import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration:
|
|
7616
|
+
case import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration:
|
|
7617
|
+
case import_utils47.AST_NODE_TYPES.TSDeclareFunction:
|
|
7618
|
+
return "erased";
|
|
7619
|
+
case import_utils47.AST_NODE_TYPES.ClassDeclaration:
|
|
7620
|
+
case import_utils47.AST_NODE_TYPES.FunctionDeclaration:
|
|
7621
|
+
case import_utils47.AST_NODE_TYPES.VariableDeclaration:
|
|
7622
|
+
return "runtime";
|
|
7623
|
+
case import_utils47.AST_NODE_TYPES.TSEnumDeclaration:
|
|
7624
|
+
return declaration.const ? "unknown" : "runtime";
|
|
7625
|
+
case import_utils47.AST_NODE_TYPES.TSModuleDeclaration:
|
|
7626
|
+
return namespaceEmission(declaration);
|
|
7627
|
+
default:
|
|
7628
|
+
return "unknown";
|
|
7666
7629
|
}
|
|
7667
|
-
return new Set([...names].filter((name) => !runtimeNames.has(name)));
|
|
7668
7630
|
}
|
|
7669
|
-
function
|
|
7670
|
-
const
|
|
7671
|
-
|
|
7631
|
+
function namespaceEmission(declaration) {
|
|
7632
|
+
const { body: body2 } = declaration;
|
|
7633
|
+
if (body2 === void 0) return "unknown";
|
|
7634
|
+
if (body2.body.length === 0) return "unknown";
|
|
7635
|
+
let ambiguous = false;
|
|
7636
|
+
for (const statement of body2.body) {
|
|
7637
|
+
if (statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration && statement.exportKind === "type") continue;
|
|
7638
|
+
const inner = statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7639
|
+
const emission = inner === null ? "unknown" : declarationEmission(inner);
|
|
7640
|
+
if (emission === "runtime") return "runtime";
|
|
7641
|
+
if (emission === "unknown") ambiguous = true;
|
|
7642
|
+
}
|
|
7643
|
+
return ambiguous ? "unknown" : "erased";
|
|
7672
7644
|
}
|
|
7673
|
-
function
|
|
7674
|
-
|
|
7675
|
-
|
|
7645
|
+
function isCommonJsExportReference(node, sourceCode) {
|
|
7646
|
+
function isGlobal(node2) {
|
|
7647
|
+
const variable = import_utils47.ASTUtils.findVariable(sourceCode.getScope(node2), node2.name);
|
|
7648
|
+
return variable === null || variable.defs.length === 0;
|
|
7649
|
+
}
|
|
7650
|
+
if (node.type === import_utils47.AST_NODE_TYPES.MemberExpression) {
|
|
7651
|
+
return node.object.type === import_utils47.AST_NODE_TYPES.Identifier && isGlobal(node.object) && (node.object.name === "exports" || node.object.name === "module" && memberPropertyName(node) === "exports");
|
|
7652
|
+
}
|
|
7653
|
+
const first = node.arguments[0];
|
|
7654
|
+
return first?.type === import_utils47.AST_NODE_TYPES.Identifier && first.name === "exports" && isGlobal(first) && node.callee.type === import_utils47.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.callee.object.name === "Object" && isGlobal(node.callee.object) && CJS_OBJECT_EXPORT_METHODS.has(memberPropertyName(node.callee) ?? "");
|
|
7676
7655
|
}
|
|
7677
7656
|
function memberPropertyName(node) {
|
|
7678
7657
|
if (!node.computed && node.property.type === import_utils47.AST_NODE_TYPES.Identifier) return node.property.name;
|
|
7679
7658
|
return node.computed && node.property.type === import_utils47.AST_NODE_TYPES.Literal && typeof node.property.value === "string" ? node.property.value : null;
|
|
7680
7659
|
}
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
}
|
|
7660
|
+
|
|
7661
|
+
// src/rules/no-generic-single-export-module.ts
|
|
7662
|
+
var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
|
|
7663
|
+
summary: "Disallow generic module stems when one runtime export already names the responsibility.",
|
|
7664
|
+
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
7665
|
+
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
7666
|
+
category: "maintainability",
|
|
7667
|
+
limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
|
|
7668
|
+
examples: [
|
|
7669
|
+
{ 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 },
|
|
7670
|
+
{ 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 }
|
|
7671
|
+
]
|
|
7672
|
+
};
|
|
7673
|
+
function fileParts(filename) {
|
|
7674
|
+
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
7675
|
+
const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
|
|
7676
|
+
const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
|
|
7677
|
+
return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
|
|
7678
|
+
}
|
|
7679
|
+
function isConventionalFrameworkUtility(filename, exported) {
|
|
7680
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
7681
|
+
return exported === "cn" && /(?:^|\/)lib\/utils\.[cm]?[jt]sx?$/u.test(normalized);
|
|
7682
|
+
}
|
|
7683
|
+
var no_generic_single_export_module_default = createRule({
|
|
7684
|
+
name: "no-generic-single-export-module",
|
|
7685
|
+
documentation: NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION,
|
|
7686
|
+
meta: {
|
|
7687
|
+
type: "suggestion",
|
|
7688
|
+
docs: { description: "Disallow generic module stems when one runtime export already names the responsibility." },
|
|
7689
|
+
schema: [],
|
|
7690
|
+
messages: {
|
|
7691
|
+
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."
|
|
7692
|
+
}
|
|
7691
7693
|
},
|
|
7692
7694
|
defaultOptions: [],
|
|
7693
7695
|
create(context) {
|
|
7694
7696
|
const file = fileParts(context.filename);
|
|
7695
7697
|
const { stem: stem4 } = file;
|
|
7696
|
-
if (!
|
|
7698
|
+
if (!GENERIC_MODULE_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
7697
7699
|
let hasCommonJsExport = false;
|
|
7698
7700
|
return {
|
|
7699
|
-
CallExpression(node) {
|
|
7700
|
-
|
|
7701
|
-
if (first?.type === import_utils47.AST_NODE_TYPES.Identifier && first.name === "exports" && isGlobalIdentifier2(context, first) && node.callee.type === import_utils47.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils47.AST_NODE_TYPES.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;
|
|
7702
|
-
},
|
|
7703
|
-
MemberExpression(node) {
|
|
7704
|
-
if (node.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.object.name === "exports" && isGlobalIdentifier2(context, node.object)) hasCommonJsExport = true;
|
|
7705
|
-
if (node.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.object.name === "module" && isGlobalIdentifier2(context, node.object) && memberPropertyName(node) === "exports") hasCommonJsExport = true;
|
|
7701
|
+
"CallExpression, MemberExpression"(node) {
|
|
7702
|
+
if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
|
|
7706
7703
|
},
|
|
7707
7704
|
"Program:exit"(program) {
|
|
7708
7705
|
if (hasCommonJsExport) return;
|
|
@@ -8052,6 +8049,10 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8052
8049
|
data: { name, count: String(tuple.elements.length) }
|
|
8053
8050
|
});
|
|
8054
8051
|
};
|
|
8052
|
+
const enterFunction = (node) => {
|
|
8053
|
+
functionStack.push(node);
|
|
8054
|
+
check(node);
|
|
8055
|
+
};
|
|
8055
8056
|
const check = (node) => {
|
|
8056
8057
|
if (isQueryKeyFactory(node)) return;
|
|
8057
8058
|
const annotation = node.returnType?.typeAnnotation;
|
|
@@ -8067,10 +8068,6 @@ var no_positional_tuple_return_default = createRule({
|
|
|
8067
8068
|
}
|
|
8068
8069
|
report2(annotation, name);
|
|
8069
8070
|
};
|
|
8070
|
-
const enterFunction = (node) => {
|
|
8071
|
-
functionStack.push(node);
|
|
8072
|
-
check(node);
|
|
8073
|
-
};
|
|
8074
8071
|
const exitFunction = () => {
|
|
8075
8072
|
functionStack.pop();
|
|
8076
8073
|
};
|
|
@@ -8517,32 +8514,16 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8517
8514
|
const definition = variable.defs[0];
|
|
8518
8515
|
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 === import_utils51.AST_NODE_TYPES.ObjectExpression && variable.references.some((reference) => reference.identifier !== node && reference.init !== true)) ? definition.node.init : node;
|
|
8519
8516
|
}
|
|
8520
|
-
function
|
|
8521
|
-
if (node
|
|
8522
|
-
|
|
8523
|
-
for (const property of [...node.properties].reverse()) {
|
|
8524
|
-
if (property.type !== import_utils51.AST_NODE_TYPES.Property || property.computed) continue;
|
|
8525
|
-
const key = property.key;
|
|
8526
|
-
const keyName = key.type === import_utils51.AST_NODE_TYPES.Identifier ? key.name : key.type === import_utils51.AST_NODE_TYPES.Literal && typeof key.value === "string" ? key.value : null;
|
|
8527
|
-
if (keyName !== name) continue;
|
|
8528
|
-
return property.value.type === import_utils51.AST_NODE_TYPES.AssignmentPattern || property.value.type === import_utils51.AST_NODE_TYPES.ArrayPattern || property.value.type === import_utils51.AST_NODE_TYPES.ObjectPattern ? null : property.value;
|
|
8529
|
-
}
|
|
8530
|
-
return null;
|
|
8531
|
-
}
|
|
8532
|
-
function isInternalApiUrl(node) {
|
|
8533
|
-
const resolved = resolveNode2(node ?? void 0);
|
|
8534
|
-
if (resolved?.type === import_utils51.AST_NODE_TYPES.Literal) {
|
|
8535
|
-
return typeof resolved.value === "string" && internalApiPrefixes.some(
|
|
8536
|
-
(prefix) => resolved.value === prefix || resolved.value.startsWith(`${prefix}/`)
|
|
8537
|
-
);
|
|
8517
|
+
function serverActionOwns(node) {
|
|
8518
|
+
if (node.callee.type !== import_utils51.AST_NODE_TYPES.Identifier || !hasUseClientDirective || hasUseServerDirective || importsServerOnly || SERVER_ACTION_SKIP_FILE_RE.test(filename) || nonReactFramework) {
|
|
8519
|
+
return false;
|
|
8538
8520
|
}
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
);
|
|
8521
|
+
const url = node.arguments[0];
|
|
8522
|
+
const init = node.arguments[1];
|
|
8523
|
+
if (url === void 0 || url.type === import_utils51.AST_NODE_TYPES.SpreadElement || init === void 0 || init.type === import_utils51.AST_NODE_TYPES.SpreadElement || !isInternalApiUrl(url)) {
|
|
8524
|
+
return false;
|
|
8544
8525
|
}
|
|
8545
|
-
return
|
|
8526
|
+
return isMutationMethod2(propertyValue(resolveNode2(init), "method"));
|
|
8546
8527
|
}
|
|
8547
8528
|
function isMutationMethod2(node) {
|
|
8548
8529
|
const resolved = resolveNode2(node ?? void 0);
|
|
@@ -8559,16 +8540,32 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
8559
8540
|
}
|
|
8560
8541
|
return resolved?.type === import_utils51.AST_NODE_TYPES.LogicalExpression && resolved.operator === "||" && (isMutationMethod2(resolved.left) || isMutationMethod2(resolved.right));
|
|
8561
8542
|
}
|
|
8562
|
-
function
|
|
8563
|
-
|
|
8564
|
-
|
|
8543
|
+
function isInternalApiUrl(node) {
|
|
8544
|
+
const resolved = resolveNode2(node ?? void 0);
|
|
8545
|
+
if (resolved?.type === import_utils51.AST_NODE_TYPES.Literal) {
|
|
8546
|
+
return typeof resolved.value === "string" && internalApiPrefixes.some(
|
|
8547
|
+
(prefix) => resolved.value === prefix || resolved.value.startsWith(`${prefix}/`)
|
|
8548
|
+
);
|
|
8565
8549
|
}
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8550
|
+
if (resolved?.type === import_utils51.AST_NODE_TYPES.TemplateLiteral) {
|
|
8551
|
+
const prefix = resolved.quasis[0]?.value.cooked;
|
|
8552
|
+
return typeof prefix === "string" && internalApiPrefixes.some(
|
|
8553
|
+
(apiPrefix) => prefix === apiPrefix || prefix.startsWith(`${apiPrefix}/`)
|
|
8554
|
+
);
|
|
8570
8555
|
}
|
|
8571
|
-
return
|
|
8556
|
+
return resolved?.type === import_utils51.AST_NODE_TYPES.BinaryExpression && resolved.operator === "+" && isInternalApiUrl(resolved.left);
|
|
8557
|
+
}
|
|
8558
|
+
function propertyValue(node, name) {
|
|
8559
|
+
if (node?.type !== import_utils51.AST_NODE_TYPES.ObjectExpression) return null;
|
|
8560
|
+
if (node.properties.some((property) => property.type !== import_utils51.AST_NODE_TYPES.Property || property.computed)) return null;
|
|
8561
|
+
for (const property of [...node.properties].reverse()) {
|
|
8562
|
+
if (property.type !== import_utils51.AST_NODE_TYPES.Property || property.computed) continue;
|
|
8563
|
+
const key = property.key;
|
|
8564
|
+
const keyName = key.type === import_utils51.AST_NODE_TYPES.Identifier ? key.name : key.type === import_utils51.AST_NODE_TYPES.Literal && typeof key.value === "string" ? key.value : null;
|
|
8565
|
+
if (keyName !== name) continue;
|
|
8566
|
+
return property.value.type === import_utils51.AST_NODE_TYPES.AssignmentPattern || property.value.type === import_utils51.AST_NODE_TYPES.ArrayPattern || property.value.type === import_utils51.AST_NODE_TYPES.ObjectPattern ? null : property.value;
|
|
8567
|
+
}
|
|
8568
|
+
return null;
|
|
8572
8569
|
}
|
|
8573
8570
|
if (allowed.some((re) => re.test(filename))) {
|
|
8574
8571
|
return {};
|
|
@@ -9243,19 +9240,19 @@ var no_restated_jsdoc_default = createRule({
|
|
|
9243
9240
|
function enclosingDeclarationNames(node) {
|
|
9244
9241
|
let declaration = null;
|
|
9245
9242
|
while (node != null && node.type !== import_utils57.AST_NODE_TYPES.Program) {
|
|
9246
|
-
declaration =
|
|
9243
|
+
declaration = declarationNames2(node);
|
|
9247
9244
|
if (declaration !== null) break;
|
|
9248
9245
|
node = node.parent ?? null;
|
|
9249
9246
|
}
|
|
9250
9247
|
return declaration;
|
|
9251
9248
|
}
|
|
9252
|
-
function
|
|
9249
|
+
function declarationNames2(node) {
|
|
9253
9250
|
switch (node.type) {
|
|
9254
9251
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
9255
9252
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
9256
9253
|
case import_utils57.AST_NODE_TYPES.ExportNamedDeclaration:
|
|
9257
9254
|
case import_utils57.AST_NODE_TYPES.ExportDefaultDeclaration:
|
|
9258
|
-
return node.declaration == null ? null :
|
|
9255
|
+
return node.declaration == null ? null : declarationNames2(node.declaration);
|
|
9259
9256
|
case import_utils57.AST_NODE_TYPES.FunctionDeclaration:
|
|
9260
9257
|
case import_utils57.AST_NODE_TYPES.TSDeclareFunction:
|
|
9261
9258
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
@@ -9667,35 +9664,30 @@ var no_secret_in_log_default = createRule({
|
|
|
9667
9664
|
create(context, [loggingOptions]) {
|
|
9668
9665
|
const matcher = createLogMatcher(loggingOptions);
|
|
9669
9666
|
const blobArmApplies = !isTestFile(context.filename);
|
|
9670
|
-
function
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9667
|
+
function inspectLoggedValue(value) {
|
|
9668
|
+
if (value.type === "ObjectExpression") {
|
|
9669
|
+
for (const property of literalProperties(value)) {
|
|
9670
|
+
if (reportSecretProperty(property) || reportRawBlob(property, property.value)) continue;
|
|
9671
|
+
inspectLoggedValue(property.value);
|
|
9672
|
+
}
|
|
9673
|
+
return;
|
|
9674
9674
|
}
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
const value = valueName(prop.value);
|
|
9681
|
-
if (value !== null && hasRedactionMarker(value)) return false;
|
|
9682
|
-
const name = value !== null && isSecretKeyword(value) ? value : keyName;
|
|
9683
|
-
if (name === null || !isSecretKeyword(name) || !isRawSecretValue(prop)) {
|
|
9684
|
-
return false;
|
|
9675
|
+
if (value.type === "ArrayExpression") {
|
|
9676
|
+
for (const element of value.elements) {
|
|
9677
|
+
if (element !== null && element.type !== "SpreadElement") inspectLoggedValue(element);
|
|
9678
|
+
}
|
|
9679
|
+
return;
|
|
9685
9680
|
}
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
function reportRawBlob(node, value) {
|
|
9690
|
-
if (!blobArmApplies) {
|
|
9691
|
-
return false;
|
|
9681
|
+
if (value.type === "TemplateLiteral") {
|
|
9682
|
+
for (const expression of value.expressions) inspectLoggedValue(expression);
|
|
9683
|
+
return;
|
|
9692
9684
|
}
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
return
|
|
9685
|
+
if (value.type === "BinaryExpression" && value.operator === "+") {
|
|
9686
|
+
inspectLoggedValue(value.left);
|
|
9687
|
+
inspectLoggedValue(value.right);
|
|
9688
|
+
return;
|
|
9697
9689
|
}
|
|
9698
|
-
|
|
9690
|
+
if (!reportSecretArgument(value)) reportRawBlob(value, value);
|
|
9699
9691
|
}
|
|
9700
9692
|
function literalProperties(value) {
|
|
9701
9693
|
const effective = /* @__PURE__ */ new Map();
|
|
@@ -9720,30 +9712,35 @@ var no_secret_in_log_default = createRule({
|
|
|
9720
9712
|
}
|
|
9721
9713
|
return [...effective.values()];
|
|
9722
9714
|
}
|
|
9723
|
-
function
|
|
9724
|
-
if (
|
|
9725
|
-
|
|
9726
|
-
if (reportSecretProperty(property) || reportRawBlob(property, property.value)) continue;
|
|
9727
|
-
inspectLoggedValue(property.value);
|
|
9728
|
-
}
|
|
9729
|
-
return;
|
|
9715
|
+
function reportRawBlob(node, value) {
|
|
9716
|
+
if (!blobArmApplies) {
|
|
9717
|
+
return false;
|
|
9730
9718
|
}
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
return;
|
|
9719
|
+
const name = rawBlobValueName(value);
|
|
9720
|
+
if (name !== null) {
|
|
9721
|
+
context.report({ node, messageId: "noRawBodyInLog", data: { name } });
|
|
9722
|
+
return true;
|
|
9736
9723
|
}
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9724
|
+
return false;
|
|
9725
|
+
}
|
|
9726
|
+
function reportSecretProperty(prop) {
|
|
9727
|
+
const keyName = propertyKeyName2(prop);
|
|
9728
|
+
const value = valueName(prop.value);
|
|
9729
|
+
if (value !== null && hasRedactionMarker(value)) return false;
|
|
9730
|
+
const name = value !== null && isSecretKeyword(value) ? value : keyName;
|
|
9731
|
+
if (name === null || !isSecretKeyword(name) || !isRawSecretValue(prop)) {
|
|
9732
|
+
return false;
|
|
9740
9733
|
}
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9734
|
+
context.report({ node: prop, messageId: "noSecretInLog", data: { name } });
|
|
9735
|
+
return true;
|
|
9736
|
+
}
|
|
9737
|
+
function reportSecretArgument(arg) {
|
|
9738
|
+
const name = valueName(arg);
|
|
9739
|
+
if (name === null || !isSecretKeyword(name)) {
|
|
9740
|
+
return false;
|
|
9745
9741
|
}
|
|
9746
|
-
|
|
9742
|
+
context.report({ node: arg, messageId: "noSecretInLog", data: { name } });
|
|
9743
|
+
return true;
|
|
9747
9744
|
}
|
|
9748
9745
|
return {
|
|
9749
9746
|
CallExpression(node) {
|
|
@@ -10041,9 +10038,6 @@ function bindsName(param, name) {
|
|
|
10041
10038
|
}
|
|
10042
10039
|
function subtreeReadsName(node, name) {
|
|
10043
10040
|
let found = false;
|
|
10044
|
-
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10045
|
-
(param) => bindsName(param, name)
|
|
10046
|
-
);
|
|
10047
10041
|
const recurse = (current) => {
|
|
10048
10042
|
if (found) {
|
|
10049
10043
|
return;
|
|
@@ -10060,6 +10054,9 @@ function subtreeReadsName(node, name) {
|
|
|
10060
10054
|
return found;
|
|
10061
10055
|
}, (key) => !isNonReadingProperty(current, key));
|
|
10062
10056
|
};
|
|
10057
|
+
const shadowsName = (fn) => isFunctionNode(fn) && fn.params.some(
|
|
10058
|
+
(param) => bindsName(param, name)
|
|
10059
|
+
);
|
|
10063
10060
|
recurse(node);
|
|
10064
10061
|
return found;
|
|
10065
10062
|
}
|
|
@@ -11921,14 +11918,6 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11921
11918
|
const trail = startingOn.get(member.loc.end.line);
|
|
11922
11919
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
11923
11920
|
}
|
|
11924
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
11925
|
-
if (comment.loc.end.line >= member.node.loc.start.line) return false;
|
|
11926
|
-
const body2 = commentBody(comment);
|
|
11927
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
11928
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
11929
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
11930
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
11931
|
-
}
|
|
11932
11921
|
function check(node, members) {
|
|
11933
11922
|
const judged = members.map(named).filter((member) => member !== void 0);
|
|
11934
11923
|
if (judged.length === 0) return;
|
|
@@ -11967,6 +11956,14 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
11967
11956
|
data: { restated: String(restated), commented: String(commented) }
|
|
11968
11957
|
});
|
|
11969
11958
|
}
|
|
11959
|
+
function isGroupLabel(comment, member, headsRun) {
|
|
11960
|
+
if (comment.loc.end.line >= member.node.loc.start.line) return false;
|
|
11961
|
+
const body2 = commentBody(comment);
|
|
11962
|
+
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
11963
|
+
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
11964
|
+
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
11965
|
+
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
11966
|
+
}
|
|
11970
11967
|
return {
|
|
11971
11968
|
ClassBody: (node) => {
|
|
11972
11969
|
check(node, node.body);
|
|
@@ -12202,14 +12199,6 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12202
12199
|
const trail = startingOn.get(member.loc.end.line);
|
|
12203
12200
|
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
12204
12201
|
}
|
|
12205
|
-
function isGroupLabel(comment, member, headsRun) {
|
|
12206
|
-
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
12207
|
-
const body2 = commentBody(comment);
|
|
12208
|
-
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
12209
|
-
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
12210
|
-
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
12211
|
-
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
12212
|
-
}
|
|
12213
12202
|
function check(node) {
|
|
12214
12203
|
const members = node.type === import_utils71.AST_NODE_TYPES.TSInterfaceBody ? node.body : node.members;
|
|
12215
12204
|
const named2 = members.filter(isNamedMember);
|
|
@@ -12245,6 +12234,14 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
12245
12234
|
data: { restated: String(restated), commented: String(commented) }
|
|
12246
12235
|
});
|
|
12247
12236
|
}
|
|
12237
|
+
function isGroupLabel(comment, member, headsRun) {
|
|
12238
|
+
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
12239
|
+
const body2 = commentBody(comment);
|
|
12240
|
+
if (!BARE_LABEL_RE.test(body2)) return false;
|
|
12241
|
+
if (labelStems(body2) === labelStems(sourceCode.getText(member.key))) return false;
|
|
12242
|
+
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
12243
|
+
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
12244
|
+
}
|
|
12248
12245
|
return {
|
|
12249
12246
|
TSInterfaceBody: check,
|
|
12250
12247
|
TSTypeLiteral: check
|
|
@@ -12560,6 +12557,11 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12560
12557
|
const binding = resolve2(identifier);
|
|
12561
12558
|
if (binding !== null) destination.add(binding);
|
|
12562
12559
|
}
|
|
12560
|
+
function checkAssertion(node) {
|
|
12561
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12562
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
12563
|
+
}
|
|
12564
|
+
}
|
|
12563
12565
|
function isMockTypeReference(node) {
|
|
12564
12566
|
if (node.type !== import_utils73.AST_NODE_TYPES.TSTypeReference) return false;
|
|
12565
12567
|
const typeName = node.typeName;
|
|
@@ -12573,11 +12575,6 @@ var no_unsafe_mock_casting_default = createRule({
|
|
|
12573
12575
|
}
|
|
12574
12576
|
return false;
|
|
12575
12577
|
}
|
|
12576
|
-
function checkAssertion(node) {
|
|
12577
|
-
if (isMockTypeReference(node.typeAnnotation)) {
|
|
12578
|
-
context.report({ node, messageId: "unsafeMockCast" });
|
|
12579
|
-
}
|
|
12580
|
-
}
|
|
12581
12578
|
return {
|
|
12582
12579
|
ImportDeclaration(node) {
|
|
12583
12580
|
if (!MOCK_MODULES.has(node.source.value)) return;
|
|
@@ -17888,7 +17885,7 @@ var staticallyImportsExternalRenderer = (program) => program.body.some((statemen
|
|
|
17888
17885
|
var semanticForegroundRoles = (filename) => {
|
|
17889
17886
|
const packageRoot = nearestPackageRoot((0, import_path.dirname)(filename));
|
|
17890
17887
|
if (packageRoot === null) return /* @__PURE__ */ new Set();
|
|
17891
|
-
const candidates = CSS_DETECTION_FILES.map((
|
|
17888
|
+
const candidates = CSS_DETECTION_FILES.map((relative3) => (0, import_path.join)(packageRoot, relative3));
|
|
17892
17889
|
const fingerprint = candidates.map(fileFingerprint2).join("|");
|
|
17893
17890
|
const cached = SEMANTIC_DECLARATIONS_CACHE.get(packageRoot);
|
|
17894
17891
|
if (cached?.fingerprint === fingerprint) return cached.value;
|
|
@@ -17971,37 +17968,6 @@ var prefer_semantic_colors_default = createRule({
|
|
|
17971
17968
|
const key = `${node.range[0]}:${node.range[1]}:${messageId}:${JSON.stringify(data)}`;
|
|
17972
17969
|
pendingReports.set(key, { node, messageId, data });
|
|
17973
17970
|
};
|
|
17974
|
-
const reportClasses = (value, node) => {
|
|
17975
|
-
const tokens = classTokens(value);
|
|
17976
|
-
for (const token of tokens) {
|
|
17977
|
-
const base = tailwindBase(token);
|
|
17978
|
-
if (RAW_PALETTE_RE.test(base)) {
|
|
17979
|
-
report2(node, "rawPalette", { class: token });
|
|
17980
|
-
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
17981
|
-
report2(node, "arbitraryColor", { class: token });
|
|
17982
|
-
}
|
|
17983
|
-
}
|
|
17984
|
-
if (!checkOpaqueForegroundPairs || isInsideSvg(node)) return;
|
|
17985
|
-
for (const token of tokens) {
|
|
17986
|
-
const prefix = tailwindVariantPrefix(token);
|
|
17987
|
-
if (prefix.split(":").includes("print")) continue;
|
|
17988
|
-
const base = tailwindBase(token);
|
|
17989
|
-
if (!OPAQUE_FOREGROUND_RE.test(base)) continue;
|
|
17990
|
-
const semanticBackground = tokens.find((candidate2) => {
|
|
17991
|
-
if (tailwindVariantPrefix(candidate2) !== prefix) return false;
|
|
17992
|
-
const match = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(candidate2));
|
|
17993
|
-
return match?.[1] !== void 0 && foregroundRoles.has(match[1]);
|
|
17994
|
-
});
|
|
17995
|
-
if (semanticBackground === void 0) continue;
|
|
17996
|
-
const role = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(semanticBackground))?.[1];
|
|
17997
|
-
if (role === void 0) continue;
|
|
17998
|
-
report2(node, "opaqueForegroundPair", {
|
|
17999
|
-
background: semanticBackground,
|
|
18000
|
-
class: token,
|
|
18001
|
-
replacement: `${prefix}text-${role}-foreground`
|
|
18002
|
-
});
|
|
18003
|
-
}
|
|
18004
|
-
};
|
|
18005
17971
|
const checkClassNode = (node, objectKeys = false) => {
|
|
18006
17972
|
if (node === null) return;
|
|
18007
17973
|
switch (node.type) {
|
|
@@ -18030,6 +17996,37 @@ var prefer_semantic_colors_default = createRule({
|
|
|
18030
17996
|
break;
|
|
18031
17997
|
}
|
|
18032
17998
|
};
|
|
17999
|
+
const reportClasses = (value, node) => {
|
|
18000
|
+
const tokens = classTokens(value);
|
|
18001
|
+
for (const token of tokens) {
|
|
18002
|
+
const base = tailwindBase(token);
|
|
18003
|
+
if (RAW_PALETTE_RE.test(base)) {
|
|
18004
|
+
report2(node, "rawPalette", { class: token });
|
|
18005
|
+
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
18006
|
+
report2(node, "arbitraryColor", { class: token });
|
|
18007
|
+
}
|
|
18008
|
+
}
|
|
18009
|
+
if (!checkOpaqueForegroundPairs || isInsideSvg(node)) return;
|
|
18010
|
+
for (const token of tokens) {
|
|
18011
|
+
const prefix = tailwindVariantPrefix(token);
|
|
18012
|
+
if (prefix.split(":").includes("print")) continue;
|
|
18013
|
+
const base = tailwindBase(token);
|
|
18014
|
+
if (!OPAQUE_FOREGROUND_RE.test(base)) continue;
|
|
18015
|
+
const semanticBackground = tokens.find((candidate2) => {
|
|
18016
|
+
if (tailwindVariantPrefix(candidate2) !== prefix) return false;
|
|
18017
|
+
const match = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(candidate2));
|
|
18018
|
+
return match?.[1] !== void 0 && foregroundRoles.has(match[1]);
|
|
18019
|
+
});
|
|
18020
|
+
if (semanticBackground === void 0) continue;
|
|
18021
|
+
const role = SEMANTIC_BACKGROUND_RE.exec(tailwindBase(semanticBackground))?.[1];
|
|
18022
|
+
if (role === void 0) continue;
|
|
18023
|
+
report2(node, "opaqueForegroundPair", {
|
|
18024
|
+
background: semanticBackground,
|
|
18025
|
+
class: token,
|
|
18026
|
+
replacement: `${prefix}text-${role}-foreground`
|
|
18027
|
+
});
|
|
18028
|
+
}
|
|
18029
|
+
};
|
|
18033
18030
|
function checkClassProperties(node, objectKeys) {
|
|
18034
18031
|
for (const property of node.properties) {
|
|
18035
18032
|
if (property.type !== import_utils103.AST_NODE_TYPES.Property) continue;
|
|
@@ -18463,80 +18460,6 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18463
18460
|
return {};
|
|
18464
18461
|
}
|
|
18465
18462
|
const { sourceCode } = context;
|
|
18466
|
-
function parseAssertion(statement) {
|
|
18467
|
-
if (statement.type !== import_utils105.AST_NODE_TYPES.ExpressionStatement) {
|
|
18468
|
-
return null;
|
|
18469
|
-
}
|
|
18470
|
-
const call = statement.expression;
|
|
18471
|
-
if (call.type !== import_utils105.AST_NODE_TYPES.CallExpression) {
|
|
18472
|
-
return null;
|
|
18473
|
-
}
|
|
18474
|
-
const callee = call.callee;
|
|
18475
|
-
if (callee.type !== import_utils105.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils105.AST_NODE_TYPES.Identifier) {
|
|
18476
|
-
return null;
|
|
18477
|
-
}
|
|
18478
|
-
const matcher = callee.property.name;
|
|
18479
|
-
const expectCall = callee.object;
|
|
18480
|
-
if (expectCall.type !== import_utils105.AST_NODE_TYPES.CallExpression || expectCall.callee.type !== import_utils105.AST_NODE_TYPES.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
18481
|
-
return null;
|
|
18482
|
-
}
|
|
18483
|
-
const actual = expectCall.arguments[0];
|
|
18484
|
-
if (!isTestExpect(expectCall.callee)) return null;
|
|
18485
|
-
if (actual === void 0 || actual.type !== import_utils105.AST_NODE_TYPES.MemberExpression || actual.optional) {
|
|
18486
|
-
return null;
|
|
18487
|
-
}
|
|
18488
|
-
if (!isPureReceiver(actual.object)) {
|
|
18489
|
-
return null;
|
|
18490
|
-
}
|
|
18491
|
-
let key;
|
|
18492
|
-
let receiver;
|
|
18493
|
-
if (actual.computed) {
|
|
18494
|
-
const index = literalIndex(actual.property);
|
|
18495
|
-
if (index === null) {
|
|
18496
|
-
return null;
|
|
18497
|
-
}
|
|
18498
|
-
key = { kind: "index", index };
|
|
18499
|
-
receiver = actual.object;
|
|
18500
|
-
} else {
|
|
18501
|
-
const access = propertyAccess(actual);
|
|
18502
|
-
if (access === null) return null;
|
|
18503
|
-
key = { kind: "property", path: access.path };
|
|
18504
|
-
receiver = access.receiver;
|
|
18505
|
-
}
|
|
18506
|
-
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
18507
|
-
}
|
|
18508
|
-
function assertionExpectation(statement, call, receiver, key, matcher) {
|
|
18509
|
-
const synthetic = SYNTHETIC_LITERAL_MATCHERS.get(matcher);
|
|
18510
|
-
if (synthetic !== void 0 && call.arguments.length === 0) {
|
|
18511
|
-
return { statement, receiver, key, matcher, expectedText: synthetic, expectedIsLiteral: true };
|
|
18512
|
-
}
|
|
18513
|
-
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
18514
|
-
return null;
|
|
18515
|
-
}
|
|
18516
|
-
const expected = call.arguments[0];
|
|
18517
|
-
if (call.arguments.length !== 1 || expected === void 0 || expected.type === import_utils105.AST_NODE_TYPES.SpreadElement) {
|
|
18518
|
-
return null;
|
|
18519
|
-
}
|
|
18520
|
-
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
18521
|
-
return {
|
|
18522
|
-
statement,
|
|
18523
|
-
receiver,
|
|
18524
|
-
key,
|
|
18525
|
-
matcher,
|
|
18526
|
-
expectedText: literal ?? sourceCode.getText(expected),
|
|
18527
|
-
expectedIsLiteral: literal !== null
|
|
18528
|
-
};
|
|
18529
|
-
}
|
|
18530
|
-
function isTestExpect(callee) {
|
|
18531
|
-
const variable = import_utils105.ASTUtils.findVariable(sourceCode.getScope(callee), callee.name);
|
|
18532
|
-
if (variable !== null && variable.defs.some((definition) => {
|
|
18533
|
-
if (definition.node.type !== import_utils105.AST_NODE_TYPES.ImportSpecifier) return true;
|
|
18534
|
-
const declaration = definition.node.parent;
|
|
18535
|
-
const imported = definition.node.imported;
|
|
18536
|
-
return declaration.type !== import_utils105.AST_NODE_TYPES.ImportDeclaration || !["vitest", "@jest/globals", "@playwright/test", "bun:test"].includes(String(declaration.source.value)) || (imported.type === import_utils105.AST_NODE_TYPES.Identifier ? imported.name : imported.value) !== "expect";
|
|
18537
|
-
})) return false;
|
|
18538
|
-
return true;
|
|
18539
|
-
}
|
|
18540
18463
|
function reportPropertyRun(run) {
|
|
18541
18464
|
const tree = /* @__PURE__ */ new Map();
|
|
18542
18465
|
const paths = [];
|
|
@@ -18646,6 +18569,80 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
18646
18569
|
}
|
|
18647
18570
|
flush();
|
|
18648
18571
|
}
|
|
18572
|
+
function parseAssertion(statement) {
|
|
18573
|
+
if (statement.type !== import_utils105.AST_NODE_TYPES.ExpressionStatement) {
|
|
18574
|
+
return null;
|
|
18575
|
+
}
|
|
18576
|
+
const call = statement.expression;
|
|
18577
|
+
if (call.type !== import_utils105.AST_NODE_TYPES.CallExpression) {
|
|
18578
|
+
return null;
|
|
18579
|
+
}
|
|
18580
|
+
const callee = call.callee;
|
|
18581
|
+
if (callee.type !== import_utils105.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils105.AST_NODE_TYPES.Identifier) {
|
|
18582
|
+
return null;
|
|
18583
|
+
}
|
|
18584
|
+
const matcher = callee.property.name;
|
|
18585
|
+
const expectCall = callee.object;
|
|
18586
|
+
if (expectCall.type !== import_utils105.AST_NODE_TYPES.CallExpression || expectCall.callee.type !== import_utils105.AST_NODE_TYPES.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
18587
|
+
return null;
|
|
18588
|
+
}
|
|
18589
|
+
const actual = expectCall.arguments[0];
|
|
18590
|
+
if (!isTestExpect(expectCall.callee)) return null;
|
|
18591
|
+
if (actual === void 0 || actual.type !== import_utils105.AST_NODE_TYPES.MemberExpression || actual.optional) {
|
|
18592
|
+
return null;
|
|
18593
|
+
}
|
|
18594
|
+
if (!isPureReceiver(actual.object)) {
|
|
18595
|
+
return null;
|
|
18596
|
+
}
|
|
18597
|
+
let key;
|
|
18598
|
+
let receiver;
|
|
18599
|
+
if (actual.computed) {
|
|
18600
|
+
const index = literalIndex(actual.property);
|
|
18601
|
+
if (index === null) {
|
|
18602
|
+
return null;
|
|
18603
|
+
}
|
|
18604
|
+
key = { kind: "index", index };
|
|
18605
|
+
receiver = actual.object;
|
|
18606
|
+
} else {
|
|
18607
|
+
const access = propertyAccess(actual);
|
|
18608
|
+
if (access === null) return null;
|
|
18609
|
+
key = { kind: "property", path: access.path };
|
|
18610
|
+
receiver = access.receiver;
|
|
18611
|
+
}
|
|
18612
|
+
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
18613
|
+
}
|
|
18614
|
+
function isTestExpect(callee) {
|
|
18615
|
+
const variable = import_utils105.ASTUtils.findVariable(sourceCode.getScope(callee), callee.name);
|
|
18616
|
+
if (variable !== null && variable.defs.some((definition) => {
|
|
18617
|
+
if (definition.node.type !== import_utils105.AST_NODE_TYPES.ImportSpecifier) return true;
|
|
18618
|
+
const declaration = definition.node.parent;
|
|
18619
|
+
const imported = definition.node.imported;
|
|
18620
|
+
return declaration.type !== import_utils105.AST_NODE_TYPES.ImportDeclaration || !["vitest", "@jest/globals", "@playwright/test", "bun:test"].includes(String(declaration.source.value)) || (imported.type === import_utils105.AST_NODE_TYPES.Identifier ? imported.name : imported.value) !== "expect";
|
|
18621
|
+
})) return false;
|
|
18622
|
+
return true;
|
|
18623
|
+
}
|
|
18624
|
+
function assertionExpectation(statement, call, receiver, key, matcher) {
|
|
18625
|
+
const synthetic = SYNTHETIC_LITERAL_MATCHERS.get(matcher);
|
|
18626
|
+
if (synthetic !== void 0 && call.arguments.length === 0) {
|
|
18627
|
+
return { statement, receiver, key, matcher, expectedText: synthetic, expectedIsLiteral: true };
|
|
18628
|
+
}
|
|
18629
|
+
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
18630
|
+
return null;
|
|
18631
|
+
}
|
|
18632
|
+
const expected = call.arguments[0];
|
|
18633
|
+
if (call.arguments.length !== 1 || expected === void 0 || expected.type === import_utils105.AST_NODE_TYPES.SpreadElement) {
|
|
18634
|
+
return null;
|
|
18635
|
+
}
|
|
18636
|
+
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
18637
|
+
return {
|
|
18638
|
+
statement,
|
|
18639
|
+
receiver,
|
|
18640
|
+
key,
|
|
18641
|
+
matcher,
|
|
18642
|
+
expectedText: literal ?? sourceCode.getText(expected),
|
|
18643
|
+
expectedIsLiteral: literal !== null
|
|
18644
|
+
};
|
|
18645
|
+
}
|
|
18649
18646
|
return {
|
|
18650
18647
|
BlockStatement: (node) => {
|
|
18651
18648
|
checkBody(node.body);
|
|
@@ -21385,6 +21382,11 @@ var require_use_form_default_values_default = createRule({
|
|
|
21385
21382
|
const value = unwrapExpression6(node);
|
|
21386
21383
|
return value.type === import_utils115.AST_NODE_TYPES.UnaryExpression && value.operator === "void" || value.type === import_utils115.AST_NODE_TYPES.Identifier && value.name === "undefined" && (bindingOf(value)?.defs.length ?? 0) === 0;
|
|
21387
21384
|
};
|
|
21385
|
+
const uninitializedUseFormCall = (node) => {
|
|
21386
|
+
if (node.type !== import_utils115.AST_NODE_TYPES.CallExpression || node.callee.type !== import_utils115.AST_NODE_TYPES.Identifier || importedKind(node.callee) !== "useForm") return false;
|
|
21387
|
+
const options = node.arguments[0];
|
|
21388
|
+
return options?.type !== import_utils115.AST_NODE_TYPES.SpreadElement && initializationState(options) === "uninitialized";
|
|
21389
|
+
};
|
|
21388
21390
|
const initializationState = (node) => {
|
|
21389
21391
|
if (node === void 0) return "uninitialized";
|
|
21390
21392
|
if (node.type !== import_utils115.AST_NODE_TYPES.ObjectExpression) return "unknown";
|
|
@@ -21397,11 +21399,6 @@ var require_use_form_default_values_default = createRule({
|
|
|
21397
21399
|
}
|
|
21398
21400
|
return [...initialization.values()].some(Boolean) ? "initialized" : "uninitialized";
|
|
21399
21401
|
};
|
|
21400
|
-
const uninitializedUseFormCall = (node) => {
|
|
21401
|
-
if (node.type !== import_utils115.AST_NODE_TYPES.CallExpression || node.callee.type !== import_utils115.AST_NODE_TYPES.Identifier || importedKind(node.callee) !== "useForm") return false;
|
|
21402
|
-
const options = node.arguments[0];
|
|
21403
|
-
return options?.type !== import_utils115.AST_NODE_TYPES.SpreadElement && initializationState(options) === "uninitialized";
|
|
21404
|
-
};
|
|
21405
21402
|
const isUninitializedForm = (node) => {
|
|
21406
21403
|
if (node.type !== import_utils115.AST_NODE_TYPES.Identifier) return false;
|
|
21407
21404
|
const variable = bindingOf(node);
|
|
@@ -21630,28 +21627,13 @@ var require_zod_form_validation_default = createRule({
|
|
|
21630
21627
|
context.sourceCode.getScope(identifier),
|
|
21631
21628
|
identifier.name
|
|
21632
21629
|
);
|
|
21633
|
-
const
|
|
21634
|
-
const binding = resolvedBinding(identifier);
|
|
21635
|
-
if (binding === null || zodBindings.has(binding) || binding.defs.length !== 1) {
|
|
21636
|
-
return false;
|
|
21637
|
-
}
|
|
21638
|
-
const definition = binding.defs[0];
|
|
21639
|
-
if (definition?.type !== "Variable" || definition.node.type !== import_utils117.AST_NODE_TYPES.VariableDeclarator) {
|
|
21640
|
-
return false;
|
|
21641
|
-
}
|
|
21642
|
-
const init = definition.node.init;
|
|
21643
|
-
return init?.type === import_utils117.AST_NODE_TYPES.ObjectExpression || init?.type === import_utils117.AST_NODE_TYPES.ArrayExpression || init?.type === import_utils117.AST_NODE_TYPES.Literal || init?.type === import_utils117.AST_NODE_TYPES.ArrowFunctionExpression || init?.type === import_utils117.AST_NODE_TYPES.FunctionExpression;
|
|
21644
|
-
};
|
|
21645
|
-
const isZodParseCall = (node) => {
|
|
21646
|
-
if (node.type !== import_utils117.AST_NODE_TYPES.CallExpression) return false;
|
|
21630
|
+
const isFormDataGetCall = (node) => {
|
|
21647
21631
|
const callee = node.callee;
|
|
21648
|
-
if (callee.type !== import_utils117.AST_NODE_TYPES.MemberExpression
|
|
21632
|
+
if (callee.type !== import_utils117.AST_NODE_TYPES.MemberExpression) return false;
|
|
21633
|
+
if (callee.property.type !== import_utils117.AST_NODE_TYPES.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
21649
21634
|
return false;
|
|
21650
21635
|
}
|
|
21651
|
-
|
|
21652
|
-
if (root === null) return false;
|
|
21653
|
-
const binding = resolvedBinding(root);
|
|
21654
|
-
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
21636
|
+
return isFormSourceIdentifier(callee.object);
|
|
21655
21637
|
};
|
|
21656
21638
|
const isFormSourceIdentifier = (node) => {
|
|
21657
21639
|
if (node.type !== import_utils117.AST_NODE_TYPES.Identifier) return false;
|
|
@@ -21670,14 +21652,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21670
21652
|
}
|
|
21671
21653
|
return conventionalName;
|
|
21672
21654
|
};
|
|
21673
|
-
const isFormDataGetCall = (node) => {
|
|
21674
|
-
const callee = node.callee;
|
|
21675
|
-
if (callee.type !== import_utils117.AST_NODE_TYPES.MemberExpression) return false;
|
|
21676
|
-
if (callee.property.type !== import_utils117.AST_NODE_TYPES.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
|
|
21677
|
-
return false;
|
|
21678
|
-
}
|
|
21679
|
-
return isFormSourceIdentifier(callee.object);
|
|
21680
|
-
};
|
|
21681
21655
|
const zodParseAncestor = (node) => {
|
|
21682
21656
|
let parent = node.parent;
|
|
21683
21657
|
while (parent !== null && parent !== void 0) {
|
|
@@ -21695,6 +21669,29 @@ var require_zod_form_validation_default = createRule({
|
|
|
21695
21669
|
}
|
|
21696
21670
|
return null;
|
|
21697
21671
|
};
|
|
21672
|
+
const isZodParseCall = (node) => {
|
|
21673
|
+
if (node.type !== import_utils117.AST_NODE_TYPES.CallExpression) return false;
|
|
21674
|
+
const callee = node.callee;
|
|
21675
|
+
if (callee.type !== import_utils117.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils117.AST_NODE_TYPES.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
|
|
21676
|
+
return false;
|
|
21677
|
+
}
|
|
21678
|
+
const root = zodReceiverRoot(callee.object);
|
|
21679
|
+
if (root === null) return false;
|
|
21680
|
+
const binding = resolvedBinding(root);
|
|
21681
|
+
return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
|
|
21682
|
+
};
|
|
21683
|
+
const isProvablyNonZodLocal = (identifier) => {
|
|
21684
|
+
const binding = resolvedBinding(identifier);
|
|
21685
|
+
if (binding === null || zodBindings.has(binding) || binding.defs.length !== 1) {
|
|
21686
|
+
return false;
|
|
21687
|
+
}
|
|
21688
|
+
const definition = binding.defs[0];
|
|
21689
|
+
if (definition?.type !== "Variable" || definition.node.type !== import_utils117.AST_NODE_TYPES.VariableDeclarator) {
|
|
21690
|
+
return false;
|
|
21691
|
+
}
|
|
21692
|
+
const init = definition.node.init;
|
|
21693
|
+
return init?.type === import_utils117.AST_NODE_TYPES.ObjectExpression || init?.type === import_utils117.AST_NODE_TYPES.ArrayExpression || init?.type === import_utils117.AST_NODE_TYPES.Literal || init?.type === import_utils117.AST_NODE_TYPES.ArrowFunctionExpression || init?.type === import_utils117.AST_NODE_TYPES.FunctionExpression;
|
|
21694
|
+
};
|
|
21698
21695
|
const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
|
|
21699
21696
|
const isInstanceofNarrowing = (node) => {
|
|
21700
21697
|
const parent = node.parent;
|
|
@@ -21723,28 +21720,6 @@ var require_zod_form_validation_default = createRule({
|
|
|
21723
21720
|
}
|
|
21724
21721
|
return null;
|
|
21725
21722
|
};
|
|
21726
|
-
const zodParseMethod = (call) => {
|
|
21727
|
-
const callee = call.callee;
|
|
21728
|
-
return callee.type === import_utils117.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils117.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
21729
|
-
};
|
|
21730
|
-
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
21731
|
-
let current = node.parent;
|
|
21732
|
-
while (current !== void 0 && current !== statement) {
|
|
21733
|
-
if (current.type === import_utils117.AST_NODE_TYPES.LogicalExpression || current.type === import_utils117.AST_NODE_TYPES.ConditionalExpression) {
|
|
21734
|
-
return true;
|
|
21735
|
-
}
|
|
21736
|
-
current = current.parent;
|
|
21737
|
-
}
|
|
21738
|
-
return false;
|
|
21739
|
-
};
|
|
21740
|
-
const isAwaitedBeforeStatement = (node, statement) => {
|
|
21741
|
-
let current = node.parent;
|
|
21742
|
-
while (current !== void 0 && current !== statement) {
|
|
21743
|
-
if (current.type === import_utils117.AST_NODE_TYPES.AwaitExpression) return true;
|
|
21744
|
-
current = current.parent;
|
|
21745
|
-
}
|
|
21746
|
-
return false;
|
|
21747
|
-
};
|
|
21748
21723
|
const guaranteedValidationStatement = (declarator, reference) => {
|
|
21749
21724
|
const parse2 = zodParseAncestor(reference);
|
|
21750
21725
|
if (parse2 === null) return null;
|
|
@@ -21763,6 +21738,28 @@ var require_zod_form_validation_default = createRule({
|
|
|
21763
21738
|
}
|
|
21764
21739
|
return null;
|
|
21765
21740
|
};
|
|
21741
|
+
const isAwaitedBeforeStatement = (node, statement) => {
|
|
21742
|
+
let current = node.parent;
|
|
21743
|
+
while (current !== void 0 && current !== statement) {
|
|
21744
|
+
if (current.type === import_utils117.AST_NODE_TYPES.AwaitExpression) return true;
|
|
21745
|
+
current = current.parent;
|
|
21746
|
+
}
|
|
21747
|
+
return false;
|
|
21748
|
+
};
|
|
21749
|
+
const hasConditionalAncestorBeforeStatement = (node, statement) => {
|
|
21750
|
+
let current = node.parent;
|
|
21751
|
+
while (current !== void 0 && current !== statement) {
|
|
21752
|
+
if (current.type === import_utils117.AST_NODE_TYPES.LogicalExpression || current.type === import_utils117.AST_NODE_TYPES.ConditionalExpression) {
|
|
21753
|
+
return true;
|
|
21754
|
+
}
|
|
21755
|
+
current = current.parent;
|
|
21756
|
+
}
|
|
21757
|
+
return false;
|
|
21758
|
+
};
|
|
21759
|
+
const zodParseMethod = (call) => {
|
|
21760
|
+
const callee = call.callee;
|
|
21761
|
+
return callee.type === import_utils117.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils117.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
21762
|
+
};
|
|
21766
21763
|
const isSafePrevalidationInspection = (identifier) => {
|
|
21767
21764
|
const parent = identifier.parent;
|
|
21768
21765
|
if (parent.type === import_utils117.AST_NODE_TYPES.UnaryExpression && parent.operator === "typeof") {
|
|
@@ -21943,9 +21940,9 @@ var STEPDOWN_DOCUMENTATION = {
|
|
|
21943
21940
|
remediation: "Consider moving the private helper below its sole caller after reviewing initialization and reflection dependencies.",
|
|
21944
21941
|
category: "maintainability",
|
|
21945
21942
|
limitations: [
|
|
21946
|
-
"Generated and test files, cycles, dynamic references, overload targets, and helpers with multiple callers are excluded.",
|
|
21943
|
+
"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.",
|
|
21947
21944
|
"Class helpers must be private; their sole caller may be public, protected, or private.",
|
|
21948
|
-
"Runtime class-field, static-block, computed-member, and decorator barriers are never crossed.",
|
|
21945
|
+
"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.",
|
|
21949
21946
|
"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."
|
|
21950
21947
|
],
|
|
21951
21948
|
examples: [
|
|
@@ -21957,7 +21954,7 @@ function isFunction(node) {
|
|
|
21957
21954
|
return node.type === import_utils119.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils119.AST_NODE_TYPES.FunctionExpression;
|
|
21958
21955
|
}
|
|
21959
21956
|
function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true) {
|
|
21960
|
-
const byName = new Map(scopeDefinitions.map((definition) => [definition.
|
|
21957
|
+
const byName = new Map(scopeDefinitions.map((definition) => [definition.key, definition]));
|
|
21961
21958
|
const cycles = cycleComponents(calls);
|
|
21962
21959
|
const callers = /* @__PURE__ */ new Map();
|
|
21963
21960
|
for (const [caller, callees] of calls) {
|
|
@@ -21969,16 +21966,16 @@ function reportMisordered(context, candidates, scopeDefinitions, calls, pinned,
|
|
|
21969
21966
|
}
|
|
21970
21967
|
}
|
|
21971
21968
|
for (const helper of candidates) {
|
|
21972
|
-
const helperCallers = [...callers.get(helper.
|
|
21973
|
-
if (pinned.has(helper.
|
|
21969
|
+
const helperCallers = [...callers.get(helper.key) ?? []];
|
|
21970
|
+
if (pinned.has(helper.key) || helperCallers.length !== 1) continue;
|
|
21974
21971
|
const callerName2 = helperCallers[0];
|
|
21975
|
-
if (callerName2 === void 0 || cycles.has(helper.
|
|
21972
|
+
if (callerName2 === void 0 || cycles.has(helper.key) && cycles.get(helper.key) === cycles.get(callerName2)) continue;
|
|
21976
21973
|
const caller = byName.get(callerName2);
|
|
21977
21974
|
if (caller === void 0 || helper.node.range[0] >= caller.node.range[0] || !canMove(helper, caller)) continue;
|
|
21978
21975
|
context.report({
|
|
21979
21976
|
node: helper.node,
|
|
21980
21977
|
messageId: "helperAboveOnlyCaller",
|
|
21981
|
-
data: { helper: helper.name, caller:
|
|
21978
|
+
data: { helper: helper.name, caller: caller.name }
|
|
21982
21979
|
});
|
|
21983
21980
|
}
|
|
21984
21981
|
}
|
|
@@ -22049,8 +22046,46 @@ function cycleComponents(graph) {
|
|
|
22049
22046
|
}
|
|
22050
22047
|
return components;
|
|
22051
22048
|
}
|
|
22052
|
-
function
|
|
22049
|
+
function isErasedExpression(node) {
|
|
22050
|
+
return node.type === import_utils119.AST_NODE_TYPES.TSAsExpression || node.type === import_utils119.AST_NODE_TYPES.TSTypeAssertion || node.type === import_utils119.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils119.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils119.AST_NODE_TYPES.TSInstantiationExpression;
|
|
22051
|
+
}
|
|
22052
|
+
function unwrapExpression7(node) {
|
|
22053
|
+
let current = node;
|
|
22054
|
+
while (isErasedExpression(current)) current = current.expression;
|
|
22055
|
+
return current;
|
|
22056
|
+
}
|
|
22057
|
+
function wrappedExpression(node) {
|
|
22058
|
+
let current = node;
|
|
22059
|
+
while (current.parent !== void 0 && isErasedExpression(current.parent) && current.parent.expression === current) current = current.parent;
|
|
22060
|
+
return current;
|
|
22061
|
+
}
|
|
22062
|
+
function enclosingFunction5(context, node) {
|
|
22063
|
+
return [...context.sourceCode.getAncestors(node)].reverse().find(isFunction);
|
|
22064
|
+
}
|
|
22065
|
+
function localCallCount(context, node, owner) {
|
|
22066
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22067
|
+
const pending = [node];
|
|
22068
|
+
let count = 0;
|
|
22069
|
+
while (pending.length > 0) {
|
|
22070
|
+
const current = pending.pop();
|
|
22071
|
+
if (current === void 0 || enclosingFunction5(context, current) !== owner) return null;
|
|
22072
|
+
const expression = wrappedExpression(current);
|
|
22073
|
+
const parent = expression.parent;
|
|
22074
|
+
if (parent?.type === import_utils119.AST_NODE_TYPES.CallExpression && parent.callee === expression) {
|
|
22075
|
+
count += 1;
|
|
22076
|
+
continue;
|
|
22077
|
+
}
|
|
22078
|
+
if (parent?.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator || parent.init !== expression || parent.id.type !== import_utils119.AST_NODE_TYPES.Identifier || parent.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || parent.parent.kind !== "const") return null;
|
|
22079
|
+
const variable = context.sourceCode.getDeclaredVariables(parent)[0];
|
|
22080
|
+
if (variable === void 0 || seen.has(variable) || !stableVariable(variable)) return null;
|
|
22081
|
+
seen.add(variable);
|
|
22082
|
+
pending.push(...variable.references.filter((reference) => reference.isRead()).map((reference) => reference.identifier));
|
|
22083
|
+
}
|
|
22084
|
+
return count;
|
|
22085
|
+
}
|
|
22086
|
+
function declarationScope(context, program) {
|
|
22053
22087
|
const declarations = moduleDefinitions(program);
|
|
22088
|
+
if (declarations.length < 2) return;
|
|
22054
22089
|
const counts = /* @__PURE__ */ new Map();
|
|
22055
22090
|
for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
|
|
22056
22091
|
const overloadNames = new Set(
|
|
@@ -22059,11 +22094,31 @@ function moduleScope(context, program) {
|
|
|
22059
22094
|
return node?.type === import_utils119.AST_NODE_TYPES.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
|
|
22060
22095
|
})
|
|
22061
22096
|
);
|
|
22062
|
-
const exported = exportedNames(program);
|
|
22097
|
+
const exported = program.type === import_utils119.AST_NODE_TYPES.Program ? exportedNames(program) : /* @__PURE__ */ new Set();
|
|
22063
22098
|
const scopeDefinitions = declarations.filter((node) => counts.get(node.name) === 1);
|
|
22064
22099
|
const definitions = scopeDefinitions.filter(
|
|
22065
22100
|
(definition) => !exported.has(definition.name) && !overloadNames.has(definition.name)
|
|
22066
22101
|
);
|
|
22102
|
+
const { calls, pinned } = moduleCallGraph(context, scopeDefinitions);
|
|
22103
|
+
const statementIndexes = new Map(program.body.map((statement, index) => [statement, index]));
|
|
22104
|
+
const runtimeBarrierPrefix = [0];
|
|
22105
|
+
for (const statement of program.body) {
|
|
22106
|
+
runtimeBarrierPrefix.push((runtimeBarrierPrefix.at(-1) ?? 0) + (isDeferredModuleStatement(statement) ? 0 : 1));
|
|
22107
|
+
}
|
|
22108
|
+
const canMove = (helper, caller) => {
|
|
22109
|
+
if (helper.node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration) return true;
|
|
22110
|
+
const helperIndex = statementIndex(helper);
|
|
22111
|
+
const callerIndex = statementIndex(caller);
|
|
22112
|
+
return helperIndex !== void 0 && callerIndex !== void 0 && runtimeBarrierPrefix[callerIndex + 1] === runtimeBarrierPrefix[helperIndex + 1];
|
|
22113
|
+
};
|
|
22114
|
+
const statementIndex = (definition) => {
|
|
22115
|
+
let current = definition.node;
|
|
22116
|
+
while (current.parent !== void 0 && current.parent !== program) current = current.parent;
|
|
22117
|
+
return statementIndexes.get(current);
|
|
22118
|
+
};
|
|
22119
|
+
reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
|
|
22120
|
+
}
|
|
22121
|
+
function moduleCallGraph(context, scopeDefinitions) {
|
|
22067
22122
|
const byFunction = new Map(scopeDefinitions.map((definition) => [definition.functionNode, definition]));
|
|
22068
22123
|
const calls = /* @__PURE__ */ new Map();
|
|
22069
22124
|
const pinned = /* @__PURE__ */ new Set();
|
|
@@ -22071,26 +22126,33 @@ function moduleScope(context, program) {
|
|
|
22071
22126
|
const variable = context.sourceCode.getDeclaredVariables(definition.bindingNode)[0];
|
|
22072
22127
|
for (const reference of variable?.references ?? []) {
|
|
22073
22128
|
if (reference.isWrite() && reference.init !== true) {
|
|
22074
|
-
pinned.add(definition.
|
|
22129
|
+
pinned.add(definition.key);
|
|
22075
22130
|
continue;
|
|
22076
22131
|
}
|
|
22077
22132
|
if (!reference.isRead()) continue;
|
|
22078
|
-
const
|
|
22079
|
-
|
|
22080
|
-
|
|
22081
|
-
const parent = identifier.parent;
|
|
22082
|
-
const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
|
|
22083
|
-
if (callerDefinition === void 0 || parent.type !== import_utils119.AST_NODE_TYPES.CallExpression || parent.callee !== identifier) {
|
|
22084
|
-
pinned.add(definition.name);
|
|
22133
|
+
const callerDefinition = byFunction.get(enclosingFunction5(context, reference.identifier));
|
|
22134
|
+
if (callerDefinition?.functionNode === void 0) {
|
|
22135
|
+
pinned.add(definition.key);
|
|
22085
22136
|
continue;
|
|
22086
22137
|
}
|
|
22087
|
-
const
|
|
22088
|
-
|
|
22089
|
-
|
|
22090
|
-
|
|
22138
|
+
const count = localCallCount(context, reference.identifier, callerDefinition.functionNode);
|
|
22139
|
+
if (count === null) {
|
|
22140
|
+
pinned.add(definition.key);
|
|
22141
|
+
} else if (count > 0) {
|
|
22142
|
+
const callees = calls.get(callerDefinition.key) ?? /* @__PURE__ */ new Set();
|
|
22143
|
+
callees.add(definition.key);
|
|
22144
|
+
calls.set(callerDefinition.key, callees);
|
|
22145
|
+
}
|
|
22091
22146
|
}
|
|
22092
22147
|
}
|
|
22093
|
-
|
|
22148
|
+
return { calls, pinned };
|
|
22149
|
+
}
|
|
22150
|
+
function isDeferredModuleStatement(statement) {
|
|
22151
|
+
const node = statement.type === import_utils119.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils119.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
22152
|
+
if (node === null || node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils119.AST_NODE_TYPES.TSDeclareFunction || node.type === import_utils119.AST_NODE_TYPES.TSInterfaceDeclaration || node.type === import_utils119.AST_NODE_TYPES.TSTypeAliasDeclaration || node.type === import_utils119.AST_NODE_TYPES.ImportDeclaration || node.type === import_utils119.AST_NODE_TYPES.ExportAllDeclaration || node.type === import_utils119.AST_NODE_TYPES.EmptyStatement) return true;
|
|
22153
|
+
return node.type === import_utils119.AST_NODE_TYPES.VariableDeclaration && node.declarations.every(
|
|
22154
|
+
(declaration) => declaration.id.type === import_utils119.AST_NODE_TYPES.Identifier && declaration.init !== null && isFunction(unwrapExpression7(declaration.init))
|
|
22155
|
+
);
|
|
22094
22156
|
}
|
|
22095
22157
|
function exportedNames(program) {
|
|
22096
22158
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -22124,16 +22186,18 @@ function moduleDefinitions(program) {
|
|
|
22124
22186
|
for (const statement of program.body) {
|
|
22125
22187
|
const node = statement.type === import_utils119.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils119.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
22126
22188
|
if (node?.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && node.body !== null) {
|
|
22127
|
-
definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
22189
|
+
definitions.push({ key: node.id.name, name: node.id.name, node, functionNode: node, bindingNode: node });
|
|
22128
22190
|
continue;
|
|
22129
22191
|
}
|
|
22130
|
-
if (node?.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const") continue;
|
|
22192
|
+
if (node?.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const" || node.declarations.length !== 1) continue;
|
|
22131
22193
|
for (const declarator of node.declarations) {
|
|
22132
|
-
|
|
22194
|
+
const initializer = declarator.init === null ? null : unwrapExpression7(declarator.init);
|
|
22195
|
+
if (declarator.id.type === import_utils119.AST_NODE_TYPES.Identifier && initializer !== null && isFunction(initializer)) {
|
|
22133
22196
|
definitions.push({
|
|
22197
|
+
key: declarator.id.name,
|
|
22134
22198
|
name: declarator.id.name,
|
|
22135
22199
|
node: declarator,
|
|
22136
|
-
functionNode:
|
|
22200
|
+
functionNode: initializer,
|
|
22137
22201
|
bindingNode: declarator
|
|
22138
22202
|
});
|
|
22139
22203
|
}
|
|
@@ -22143,15 +22207,50 @@ function moduleDefinitions(program) {
|
|
|
22143
22207
|
}
|
|
22144
22208
|
function methodName2(node) {
|
|
22145
22209
|
if (node.key.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) return `#${node.key.name}`;
|
|
22146
|
-
|
|
22210
|
+
if (!node.computed && node.key.type === import_utils119.AST_NODE_TYPES.Identifier) return node.key.name;
|
|
22211
|
+
return node.key.type === import_utils119.AST_NODE_TYPES.Literal && typeof node.key.value === "string" ? node.key.value : null;
|
|
22147
22212
|
}
|
|
22148
|
-
function
|
|
22149
|
-
|
|
22150
|
-
|
|
22151
|
-
|
|
22152
|
-
|
|
22153
|
-
if (
|
|
22154
|
-
return
|
|
22213
|
+
function methodKey(name, isStatic2) {
|
|
22214
|
+
return `${isStatic2 ? "static" : "instance"}:${name}`;
|
|
22215
|
+
}
|
|
22216
|
+
function receiverDomain(context, object, receivers, thisIsStatic) {
|
|
22217
|
+
const unwrapped = unwrapExpression7(object);
|
|
22218
|
+
if (unwrapped.type === import_utils119.AST_NODE_TYPES.ThisExpression) return thisIsStatic;
|
|
22219
|
+
return externalReceiverDomain(context, unwrapped, receivers);
|
|
22220
|
+
}
|
|
22221
|
+
function externalReceiverDomain(context, object, receivers) {
|
|
22222
|
+
const origin = receiverOrigin(context, object, receivers);
|
|
22223
|
+
if (origin === null || typeof origin === "boolean") return origin;
|
|
22224
|
+
if (origin.type === import_utils119.AST_NODE_TYPES.NewExpression) {
|
|
22225
|
+
return receiverOrigin(context, origin.callee, receivers) === true ? false : null;
|
|
22226
|
+
}
|
|
22227
|
+
if (origin.type === import_utils119.AST_NODE_TYPES.ObjectExpression || origin.type === import_utils119.AST_NODE_TYPES.ArrayExpression || origin.type === import_utils119.AST_NODE_TYPES.Literal || origin.type === import_utils119.AST_NODE_TYPES.ArrowFunctionExpression || origin.type === import_utils119.AST_NODE_TYPES.FunctionExpression) return "unrelated";
|
|
22228
|
+
return null;
|
|
22229
|
+
}
|
|
22230
|
+
function receiverOrigin(context, object, receivers) {
|
|
22231
|
+
let current = object;
|
|
22232
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22233
|
+
while (true) {
|
|
22234
|
+
const unwrapped = unwrapExpression7(current);
|
|
22235
|
+
if (unwrapped.type !== import_utils119.AST_NODE_TYPES.Identifier) return unwrapped;
|
|
22236
|
+
const variable = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(unwrapped), unwrapped.name);
|
|
22237
|
+
if (variable === null) return null;
|
|
22238
|
+
const known = receivers.get(variable);
|
|
22239
|
+
if (known !== void 0) return known;
|
|
22240
|
+
const initializer = immutableInitializer(variable, seen);
|
|
22241
|
+
if (initializer === null) return null;
|
|
22242
|
+
current = initializer;
|
|
22243
|
+
}
|
|
22244
|
+
}
|
|
22245
|
+
function immutableInitializer(variable, seen) {
|
|
22246
|
+
if (seen.has(variable) || !stableVariable(variable) || variable.defs.length !== 1) return null;
|
|
22247
|
+
seen.add(variable);
|
|
22248
|
+
const definition = variable.defs[0];
|
|
22249
|
+
if (definition?.node.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator || definition.node.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || definition.node.parent.kind !== "const") return null;
|
|
22250
|
+
return definition.node.init;
|
|
22251
|
+
}
|
|
22252
|
+
function stableVariable(variable) {
|
|
22253
|
+
return !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
|
|
22155
22254
|
}
|
|
22156
22255
|
function referencedPropertyName(node) {
|
|
22157
22256
|
if (node.property.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) return `#${node.property.name}`;
|
|
@@ -22160,131 +22259,145 @@ function referencedPropertyName(node) {
|
|
|
22160
22259
|
}
|
|
22161
22260
|
function walk(node, visitorKeys, visit, nestedFunction = false) {
|
|
22162
22261
|
visit(node, nestedFunction);
|
|
22163
|
-
const nested = nestedFunction || isFunction(node);
|
|
22262
|
+
const nested = nestedFunction || isFunction(node) || node.type === import_utils119.AST_NODE_TYPES.ClassDeclaration || node.type === import_utils119.AST_NODE_TYPES.ClassExpression;
|
|
22164
22263
|
forEachAstChild(node, visitorKeys, (child) => walk(child, visitorKeys, visit, nested));
|
|
22165
22264
|
}
|
|
22166
|
-
function classScope(context, node,
|
|
22265
|
+
function classScope(context, node, computedReferences) {
|
|
22167
22266
|
const methods = node.body.body.filter(
|
|
22168
22267
|
(member) => member.type === import_utils119.AST_NODE_TYPES.MethodDefinition
|
|
22169
22268
|
);
|
|
22170
22269
|
const counts = classMethodCounts(node.body, methods);
|
|
22171
|
-
const
|
|
22172
|
-
|
|
22173
|
-
|
|
22174
|
-
});
|
|
22175
|
-
const definitions = methods.flatMap((method) => {
|
|
22270
|
+
const implementations = methods.filter((method) => isFunction(method.value));
|
|
22271
|
+
const implementationCounts = classMethodCounts(node.body, implementations);
|
|
22272
|
+
const scopeDefinitions = implementations.flatMap((method) => {
|
|
22176
22273
|
const name = methodName2(method);
|
|
22177
|
-
const
|
|
22178
|
-
return name !== null &&
|
|
22274
|
+
const key = name === null ? null : methodKey(name, method.static);
|
|
22275
|
+
return name !== null && key !== null && implementationCounts.get(key) === 1 ? [{ key, name, node: method }] : [];
|
|
22179
22276
|
});
|
|
22277
|
+
const definitions = scopeDefinitions.filter(
|
|
22278
|
+
({ key, node: method }) => (method.accessibility === "private" || method.key.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) && counts.get(key) === 1 && method.decorators.length === 0 && !method.computed && method.kind === "method"
|
|
22279
|
+
);
|
|
22180
22280
|
if (definitions.length === 0) return;
|
|
22181
|
-
const
|
|
22281
|
+
const methodKeys = new Set(scopeDefinitions.map((definition) => definition.key));
|
|
22182
22282
|
const calls = /* @__PURE__ */ new Map();
|
|
22183
22283
|
const pinned = /* @__PURE__ */ new Set();
|
|
22184
|
-
const
|
|
22185
|
-
|
|
22186
|
-
const
|
|
22187
|
-
|
|
22188
|
-
|
|
22189
|
-
|
|
22190
|
-
|
|
22191
|
-
|
|
22284
|
+
const classReceivers = classReceiverBindings(context, node);
|
|
22285
|
+
const pinNames = (name, domain = null) => {
|
|
22286
|
+
for (const definition of definitions) {
|
|
22287
|
+
if ((name === null || definition.name === name) && (domain === null || definition.node.static === domain)) {
|
|
22288
|
+
pinned.add(definition.key);
|
|
22289
|
+
}
|
|
22290
|
+
}
|
|
22291
|
+
};
|
|
22292
|
+
function pinDestructuredMembers(binding, domain) {
|
|
22293
|
+
for (const property of binding.properties) {
|
|
22294
|
+
if (property.type === import_utils119.AST_NODE_TYPES.RestElement || property.computed) {
|
|
22295
|
+
pinNames(null, domain);
|
|
22296
|
+
} else if (property.key.type === import_utils119.AST_NODE_TYPES.Identifier) {
|
|
22297
|
+
pinNames(property.key.name, domain);
|
|
22298
|
+
} else if (property.key.type === import_utils119.AST_NODE_TYPES.Literal && typeof property.key.value === "string") {
|
|
22299
|
+
pinNames(property.key.value, domain);
|
|
22300
|
+
}
|
|
22301
|
+
}
|
|
22192
22302
|
}
|
|
22193
22303
|
function collectMethodCalls(method) {
|
|
22194
|
-
const
|
|
22195
|
-
if (
|
|
22196
|
-
|
|
22197
|
-
|
|
22304
|
+
const name = methodName2(method);
|
|
22305
|
+
if (name === null) {
|
|
22306
|
+
pinNames(null);
|
|
22307
|
+
return;
|
|
22308
|
+
}
|
|
22309
|
+
if (!isFunction(method.value)) return;
|
|
22310
|
+
const methodFunction = method.value;
|
|
22311
|
+
const caller = methodKey(name, method.static);
|
|
22312
|
+
const receivers = new Map(classReceivers);
|
|
22198
22313
|
const parameterDecoratorNodes = /* @__PURE__ */ new Set();
|
|
22199
22314
|
for (const parameter of method.value.params) {
|
|
22200
22315
|
for (const decorator of parameter.decorators) {
|
|
22201
22316
|
walk(decorator, context.sourceCode.visitorKeys, (current) => parameterDecoratorNodes.add(current));
|
|
22202
22317
|
}
|
|
22203
22318
|
}
|
|
22204
|
-
const thisValue = (value) => {
|
|
22205
|
-
let current = value;
|
|
22206
|
-
while (current?.type === import_utils119.AST_NODE_TYPES.TSAsExpression || current?.type === import_utils119.AST_NODE_TYPES.TSSatisfiesExpression || current?.type === import_utils119.AST_NODE_TYPES.TSNonNullExpression) current = current.expression;
|
|
22207
|
-
return current?.type === import_utils119.AST_NODE_TYPES.ThisExpression;
|
|
22208
|
-
};
|
|
22209
22319
|
const collectAlias = (current, nestedFunction) => {
|
|
22210
|
-
if (nestedFunction || current.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator
|
|
22211
|
-
|
|
22212
|
-
|
|
22213
|
-
|
|
22214
|
-
|
|
22215
|
-
if (binding.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
|
|
22216
|
-
pinDestructuredMembers(binding);
|
|
22320
|
+
if (nestedFunction || current.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator || current.init === null) return;
|
|
22321
|
+
const domain = receiverDomain(context, current.init, receivers, method.static);
|
|
22322
|
+
if (domain === null || domain === "unrelated") return;
|
|
22323
|
+
if (current.id.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
|
|
22324
|
+
pinDestructuredMembers(current.id, domain);
|
|
22217
22325
|
return;
|
|
22218
22326
|
}
|
|
22219
|
-
if (
|
|
22220
|
-
|
|
22221
|
-
|
|
22222
|
-
|
|
22223
|
-
methodAliases.add(variable);
|
|
22327
|
+
if (current.id.type !== import_utils119.AST_NODE_TYPES.Identifier) return;
|
|
22328
|
+
if (current.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || current.parent.kind !== "const") {
|
|
22329
|
+
pinNames(null, domain);
|
|
22330
|
+
return;
|
|
22224
22331
|
}
|
|
22332
|
+
const variable = context.sourceCode.getDeclaredVariables(current)[0];
|
|
22333
|
+
if (variable === void 0 || !stableVariable(variable)) return;
|
|
22334
|
+
const local = variable.references.every((reference) => {
|
|
22335
|
+
if (!reference.isRead()) return true;
|
|
22336
|
+
const expression = wrappedExpression(reference.identifier);
|
|
22337
|
+
return enclosingFunction5(context, reference.identifier) === methodFunction && expression.parent?.type === import_utils119.AST_NODE_TYPES.MemberExpression && expression.parent.object === expression;
|
|
22338
|
+
});
|
|
22339
|
+
if (local) receivers.set(variable, domain);
|
|
22340
|
+
else pinNames(null, domain);
|
|
22225
22341
|
};
|
|
22226
|
-
for (const
|
|
22227
|
-
walk(parameter, context.sourceCode.visitorKeys, collectAlias);
|
|
22228
|
-
}
|
|
22229
|
-
for (const statement of method.value.body.body) {
|
|
22230
|
-
walk(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
22231
|
-
}
|
|
22232
|
-
function pinDestructuredMembers(binding) {
|
|
22233
|
-
for (const property of binding.properties) {
|
|
22234
|
-
if (property.type === import_utils119.AST_NODE_TYPES.RestElement) {
|
|
22235
|
-
for (const name of privateNames) pinned.add(name);
|
|
22236
|
-
} else if (property.key.type === import_utils119.AST_NODE_TYPES.Identifier && privateNames.has(property.key.name)) {
|
|
22237
|
-
pinned.add(property.key.name);
|
|
22238
|
-
}
|
|
22239
|
-
}
|
|
22240
|
-
}
|
|
22342
|
+
for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, collectAlias);
|
|
22241
22343
|
const visitCall = (current, nestedFunction) => {
|
|
22242
|
-
|
|
22243
|
-
|
|
22344
|
+
const destructuring = receiverDestructuring(current);
|
|
22345
|
+
if (destructuring !== null) {
|
|
22346
|
+
const domain2 = receiverDomain(context, destructuring.value, receivers, method.static);
|
|
22347
|
+
if (domain2 !== "unrelated") pinDestructuredMembers(destructuring.binding, domain2);
|
|
22244
22348
|
}
|
|
22245
22349
|
if (current.type !== import_utils119.AST_NODE_TYPES.MemberExpression) return;
|
|
22246
|
-
const
|
|
22247
|
-
|
|
22248
|
-
|
|
22249
|
-
|
|
22350
|
+
const domain = receiverDomain(context, current.object, receivers, method.static);
|
|
22351
|
+
const targetName = referencedPropertyName(current);
|
|
22352
|
+
if (domain === "unrelated") return;
|
|
22353
|
+
if (domain === null) {
|
|
22354
|
+
pinNames(targetName);
|
|
22250
22355
|
return;
|
|
22251
22356
|
}
|
|
22252
|
-
if (
|
|
22253
|
-
|
|
22254
|
-
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
22255
|
-
pinned.add(target);
|
|
22357
|
+
if (targetName === null) {
|
|
22358
|
+
if (current.computed) pinNames(null, domain);
|
|
22256
22359
|
return;
|
|
22257
22360
|
}
|
|
22258
|
-
|
|
22361
|
+
const target = methodKey(targetName, domain);
|
|
22362
|
+
if (!methodKeys.has(target)) return;
|
|
22363
|
+
if (current.computed || nestedFunction || parameterDecoratorNodes.has(current)) {
|
|
22259
22364
|
pinned.add(target);
|
|
22260
22365
|
return;
|
|
22261
22366
|
}
|
|
22262
|
-
const
|
|
22263
|
-
|
|
22264
|
-
|
|
22367
|
+
const count = localCallCount(context, current, methodFunction);
|
|
22368
|
+
if (count === null) {
|
|
22369
|
+
pinned.add(target);
|
|
22370
|
+
} else if (count > 0) {
|
|
22371
|
+
const callees = calls.get(caller) ?? /* @__PURE__ */ new Set();
|
|
22372
|
+
callees.add(target);
|
|
22373
|
+
calls.set(caller, callees);
|
|
22374
|
+
}
|
|
22265
22375
|
};
|
|
22266
|
-
for (const decorator of method.decorators)
|
|
22267
|
-
walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
|
|
22268
|
-
}
|
|
22376
|
+
for (const decorator of method.decorators) walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
|
|
22269
22377
|
if (method.computed) walk(method.key, context.sourceCode.visitorKeys, visitCall, true);
|
|
22270
|
-
for (const parameter of method.value.params)
|
|
22271
|
-
|
|
22272
|
-
}
|
|
22273
|
-
for (const statement of method.value.body.body) {
|
|
22274
|
-
walk(statement, context.sourceCode.visitorKeys, visitCall);
|
|
22275
|
-
}
|
|
22378
|
+
for (const parameter of method.value.params) walk(parameter, context.sourceCode.visitorKeys, visitCall);
|
|
22379
|
+
for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, visitCall);
|
|
22276
22380
|
}
|
|
22277
22381
|
for (const method of methods) collectMethodCalls(method);
|
|
22278
22382
|
for (const member of node.body.body) {
|
|
22279
22383
|
if (member.type === import_utils119.AST_NODE_TYPES.MethodDefinition || member.type === import_utils119.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
|
|
22280
22384
|
walk(member, context.sourceCode.visitorKeys, (current) => {
|
|
22281
22385
|
if (current.type !== import_utils119.AST_NODE_TYPES.MemberExpression) return;
|
|
22282
|
-
|
|
22283
|
-
|
|
22284
|
-
if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
|
|
22386
|
+
if (externalReceiverDomain(context, current.object, classReceivers) === "unrelated") return;
|
|
22387
|
+
pinNames(referencedPropertyName(current));
|
|
22285
22388
|
});
|
|
22286
22389
|
}
|
|
22287
|
-
|
|
22390
|
+
const externalReceivers = new Map(classReceivers);
|
|
22391
|
+
for (const variable of context.sourceCode.getDeclaredVariables(node)) {
|
|
22392
|
+
if (stableVariable(variable)) externalReceivers.set(variable, true);
|
|
22393
|
+
}
|
|
22394
|
+
for (const reference of computedReferences) {
|
|
22395
|
+
if (context.sourceCode.getAncestors(reference).includes(node)) continue;
|
|
22396
|
+
const domain = externalReceiverDomain(context, reference.object, externalReceivers);
|
|
22397
|
+
if (domain === "unrelated") continue;
|
|
22398
|
+
const name = referencedPropertyName(reference);
|
|
22399
|
+
if (name !== null || domain !== null) pinNames(name, domain);
|
|
22400
|
+
}
|
|
22288
22401
|
const memberIndexes = new Map(node.body.body.map((member, index) => [member, index]));
|
|
22289
22402
|
const runtimeBarrierPrefix = [0];
|
|
22290
22403
|
for (const member of node.body.body) {
|
|
@@ -22298,6 +22411,27 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
22298
22411
|
};
|
|
22299
22412
|
reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
|
|
22300
22413
|
}
|
|
22414
|
+
function classReceiverBindings(context, node) {
|
|
22415
|
+
const classReceivers = /* @__PURE__ */ new Map();
|
|
22416
|
+
if (node.id !== null) {
|
|
22417
|
+
const internal = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
22418
|
+
if (internal !== null && stableVariable(internal)) classReceivers.set(internal, true);
|
|
22419
|
+
}
|
|
22420
|
+
if (node.type === import_utils119.AST_NODE_TYPES.ClassExpression && node.parent.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils119.AST_NODE_TYPES.Identifier && node.parent.parent.type === import_utils119.AST_NODE_TYPES.VariableDeclaration && node.parent.parent.kind === "const") {
|
|
22421
|
+
const outer = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
22422
|
+
if (outer !== null && stableVariable(outer)) classReceivers.set(outer, true);
|
|
22423
|
+
}
|
|
22424
|
+
return classReceivers;
|
|
22425
|
+
}
|
|
22426
|
+
function receiverDestructuring(node) {
|
|
22427
|
+
if (node.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && node.id.type === import_utils119.AST_NODE_TYPES.ObjectPattern && node.init !== null) {
|
|
22428
|
+
return { binding: node.id, value: node.init };
|
|
22429
|
+
}
|
|
22430
|
+
if ((node.type === import_utils119.AST_NODE_TYPES.AssignmentPattern || node.type === import_utils119.AST_NODE_TYPES.AssignmentExpression) && node.left.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
|
|
22431
|
+
return { binding: node.left, value: node.right };
|
|
22432
|
+
}
|
|
22433
|
+
return null;
|
|
22434
|
+
}
|
|
22301
22435
|
function isClassRuntimeBarrier(member) {
|
|
22302
22436
|
switch (member.type) {
|
|
22303
22437
|
case import_utils119.AST_NODE_TYPES.StaticBlock:
|
|
@@ -22326,6 +22460,7 @@ var stepdown_default = createRule({
|
|
|
22326
22460
|
create(context) {
|
|
22327
22461
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
22328
22462
|
const classes = [];
|
|
22463
|
+
const functionBodies = [];
|
|
22329
22464
|
return {
|
|
22330
22465
|
ClassDeclaration: (node) => {
|
|
22331
22466
|
classes.push(node);
|
|
@@ -22333,13 +22468,17 @@ var stepdown_default = createRule({
|
|
|
22333
22468
|
ClassExpression: (node) => {
|
|
22334
22469
|
classes.push(node);
|
|
22335
22470
|
},
|
|
22471
|
+
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
|
|
22472
|
+
if (isFunction(node) && node.body?.type === import_utils119.AST_NODE_TYPES.BlockStatement) functionBodies.push(node.body);
|
|
22473
|
+
},
|
|
22336
22474
|
"Program:exit": (program) => {
|
|
22337
|
-
|
|
22338
|
-
const
|
|
22475
|
+
declarationScope(context, program);
|
|
22476
|
+
for (const body2 of functionBodies) declarationScope(context, body2);
|
|
22477
|
+
const computedReferences = [];
|
|
22339
22478
|
walk(program, context.sourceCode.visitorKeys, (node) => {
|
|
22340
|
-
if (node.type === import_utils119.AST_NODE_TYPES.MemberExpression && node.computed
|
|
22479
|
+
if (node.type === import_utils119.AST_NODE_TYPES.MemberExpression && node.computed) computedReferences.push(node);
|
|
22341
22480
|
});
|
|
22342
|
-
for (const node of classes) classScope(context, node,
|
|
22481
|
+
for (const node of classes) classScope(context, node, computedReferences);
|
|
22343
22482
|
}
|
|
22344
22483
|
};
|
|
22345
22484
|
}
|
|
@@ -22348,12 +22487,18 @@ function classMethodCounts(body2, methods) {
|
|
|
22348
22487
|
const counts = /* @__PURE__ */ new Map();
|
|
22349
22488
|
for (const method of methods) {
|
|
22350
22489
|
const name = methodName2(method);
|
|
22351
|
-
if (name !== null)
|
|
22490
|
+
if (name !== null) {
|
|
22491
|
+
const key = methodKey(name, method.static);
|
|
22492
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
22493
|
+
}
|
|
22352
22494
|
}
|
|
22353
22495
|
for (const member of body2.body) {
|
|
22354
22496
|
if (member.type !== import_utils119.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
|
|
22355
22497
|
const name = !member.computed && member.key.type === import_utils119.AST_NODE_TYPES.Identifier ? member.key.name : null;
|
|
22356
|
-
if (name !== null)
|
|
22498
|
+
if (name !== null) {
|
|
22499
|
+
const key = methodKey(name, member.static);
|
|
22500
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
22501
|
+
}
|
|
22357
22502
|
}
|
|
22358
22503
|
return counts;
|
|
22359
22504
|
}
|
|
@@ -22685,16 +22830,70 @@ function importedAssertionKind(specifier) {
|
|
|
22685
22830
|
|
|
22686
22831
|
// src/rules/sole-export-matches-filename.ts
|
|
22687
22832
|
var import_utils121 = require("@typescript-eslint/utils");
|
|
22833
|
+
|
|
22834
|
+
// src/rules/_is-framework-entrypoint.ts
|
|
22835
|
+
var import_node_fs2 = require("fs");
|
|
22836
|
+
var import_node_path2 = require("path");
|
|
22837
|
+
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]);
|
|
22838
|
+
var NEXT_COMPONENT = /^(?:src\/)?app\/(?:.*\/)?(?:page|layout|loading|not-found|template|error|global-error|default|forbidden|unauthorized)\.[jt]sx?$/u;
|
|
22839
|
+
var NEXT_ROUTE = /^(?:src\/)?app\/(?:.*\/)?route\.[jt]s$/u;
|
|
22840
|
+
function isFrameworkEntrypoint(filename, exportKey) {
|
|
22841
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
22842
|
+
if (!/(?:^|\/)(?:app|pages)\/|(?:^|\/)(?:middleware|proxy)\.[jt]s$/u.test(normalized)) return false;
|
|
22843
|
+
const owner = packageOwner(normalized);
|
|
22844
|
+
if (owner === null) return false;
|
|
22845
|
+
const path = (0, import_node_path2.relative)(owner.root, normalized).replaceAll("\\", "/");
|
|
22846
|
+
if (declaresFramework(owner.metadata, "next") && isNextEntrypoint(path, exportKey)) return true;
|
|
22847
|
+
return declaresFramework(owner.metadata, "astro") && isAstroEntrypoint(path, exportKey);
|
|
22848
|
+
}
|
|
22849
|
+
function isNextEntrypoint(path, exportKey) {
|
|
22850
|
+
const privateAppFolder = /^(?:src\/)?app\/(?:.*\/)?_[^/]+\//u.test(path);
|
|
22851
|
+
if (!privateAppFolder && NEXT_COMPONENT.test(path) && exportKey === "default") return true;
|
|
22852
|
+
if (!privateAppFolder && NEXT_ROUTE.test(path) && HTTP_METHODS.has(exportKey)) return true;
|
|
22853
|
+
if (/^(?:src\/)?pages\/.*\.[jt]sx?$/u.test(path) && exportKey === "default") return true;
|
|
22854
|
+
const middleware = /^(?:src\/)?(middleware|proxy)\.[jt]s$/u.exec(path);
|
|
22855
|
+
return middleware !== null && (exportKey === "default" || exportKey === middleware[1]);
|
|
22856
|
+
}
|
|
22857
|
+
function isAstroEntrypoint(path, exportKey) {
|
|
22858
|
+
return (
|
|
22859
|
+
// Astro pages implicitly export their rendered component, including when only a routing hook is explicit.
|
|
22860
|
+
/^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"
|
|
22861
|
+
);
|
|
22862
|
+
}
|
|
22863
|
+
function packageOwner(filename) {
|
|
22864
|
+
let root = (0, import_node_path2.dirname)(filename);
|
|
22865
|
+
while (true) {
|
|
22866
|
+
try {
|
|
22867
|
+
return { root, metadata: JSON.parse((0, import_node_fs2.readFileSync)((0, import_node_path2.join)(root, "package.json"), "utf8")) };
|
|
22868
|
+
} catch (error) {
|
|
22869
|
+
if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") return null;
|
|
22870
|
+
}
|
|
22871
|
+
const parent = (0, import_node_path2.dirname)(root);
|
|
22872
|
+
if (parent === root) return null;
|
|
22873
|
+
root = parent;
|
|
22874
|
+
}
|
|
22875
|
+
}
|
|
22876
|
+
function declaresFramework(metadata, name) {
|
|
22877
|
+
if (typeof metadata !== "object" || metadata === null) return false;
|
|
22878
|
+
for (const section of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
22879
|
+
const dependencies = Reflect.get(metadata, section);
|
|
22880
|
+
if (typeof dependencies === "object" && dependencies !== null && typeof Reflect.get(dependencies, name) === "string") return true;
|
|
22881
|
+
}
|
|
22882
|
+
return false;
|
|
22883
|
+
}
|
|
22884
|
+
|
|
22885
|
+
// src/rules/sole-export-matches-filename.ts
|
|
22688
22886
|
var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
22689
|
-
defaultLevel: "
|
|
22887
|
+
defaultLevel: "error",
|
|
22690
22888
|
summary: "Make a module filename reflect its sole named public runtime export.",
|
|
22691
22889
|
rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
|
|
22692
|
-
remediation: "Name the module for the exported responsibility, using
|
|
22890
|
+
remediation: "Name the module for the exported responsibility, using the full kebab-case export name; otherwise colocate genuinely related exports.",
|
|
22693
22891
|
category: "maintainability",
|
|
22694
22892
|
limitations: [
|
|
22695
|
-
"Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS,
|
|
22696
|
-
"The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker.
|
|
22697
|
-
"Exported destructuring patterns are excluded rather than undercounted as public exports."
|
|
22893
|
+
"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.",
|
|
22894
|
+
"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.",
|
|
22895
|
+
"Exported destructuring patterns are excluded rather than undercounted as public exports.",
|
|
22896
|
+
"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."
|
|
22698
22897
|
],
|
|
22699
22898
|
examples: [
|
|
22700
22899
|
{ 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 },
|
|
@@ -22702,39 +22901,9 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
|
|
|
22702
22901
|
]
|
|
22703
22902
|
};
|
|
22704
22903
|
var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
|
|
22705
|
-
"common",
|
|
22706
22904
|
"global",
|
|
22707
|
-
"helpers",
|
|
22708
22905
|
"index",
|
|
22709
|
-
"
|
|
22710
|
-
"loading",
|
|
22711
|
-
"middleware",
|
|
22712
|
-
"misc",
|
|
22713
|
-
"not-found",
|
|
22714
|
-
"page",
|
|
22715
|
-
"route",
|
|
22716
|
-
"shared",
|
|
22717
|
-
"template",
|
|
22718
|
-
"types",
|
|
22719
|
-
"util",
|
|
22720
|
-
"utils"
|
|
22721
|
-
]);
|
|
22722
|
-
var WEAK_DOMAIN_TOKENS = /* @__PURE__ */ new Set([
|
|
22723
|
-
"adapter",
|
|
22724
|
-
"client",
|
|
22725
|
-
"config",
|
|
22726
|
-
"controller",
|
|
22727
|
-
"factory",
|
|
22728
|
-
"handler",
|
|
22729
|
-
"manager",
|
|
22730
|
-
"provider",
|
|
22731
|
-
"record",
|
|
22732
|
-
"repository",
|
|
22733
|
-
"router",
|
|
22734
|
-
"schema",
|
|
22735
|
-
"service",
|
|
22736
|
-
"store",
|
|
22737
|
-
"worker"
|
|
22906
|
+
"types"
|
|
22738
22907
|
]);
|
|
22739
22908
|
function stem3(filename) {
|
|
22740
22909
|
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
@@ -22743,34 +22912,6 @@ function stem3(filename) {
|
|
|
22743
22912
|
function kebabCase(name) {
|
|
22744
22913
|
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();
|
|
22745
22914
|
}
|
|
22746
|
-
function reflectsExportName(fileStem, exportedStem) {
|
|
22747
|
-
if (fileStem.startsWith("_")) return false;
|
|
22748
|
-
const visibleFileStem = fileStem.toLowerCase();
|
|
22749
|
-
const fileTokens = visibleFileStem.split("-").filter(Boolean);
|
|
22750
|
-
const exportTokens = exportedStem.split("-").filter(Boolean);
|
|
22751
|
-
if (fileTokens.length === 0 || exportTokens.length === 0) return false;
|
|
22752
|
-
if (fileTokens.length === 1) {
|
|
22753
|
-
const [token] = fileTokens;
|
|
22754
|
-
return token !== void 0 && token.length >= 4 && !WEAK_DOMAIN_TOKENS.has(token) && (exportTokens[0] === token || exportTokens.at(-1) === token);
|
|
22755
|
-
}
|
|
22756
|
-
const compactFile = fileTokens.join("");
|
|
22757
|
-
if (compactFile.length < 6) return false;
|
|
22758
|
-
const boundaryPhrases = /* @__PURE__ */ new Set();
|
|
22759
|
-
for (let index = 1; index <= exportTokens.length; index += 1) {
|
|
22760
|
-
boundaryPhrases.add(exportTokens.slice(0, index).join(""));
|
|
22761
|
-
boundaryPhrases.add(exportTokens.slice(-index).join(""));
|
|
22762
|
-
}
|
|
22763
|
-
return boundaryPhrases.has(compactFile);
|
|
22764
|
-
}
|
|
22765
|
-
function declarationExport(statement) {
|
|
22766
|
-
const declaration = statement.declaration;
|
|
22767
|
-
if (declaration === null || declaration.declare === true) return [];
|
|
22768
|
-
if (declaration.type === import_utils121.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
|
|
22769
|
-
if (declaration.type !== import_utils121.AST_NODE_TYPES.VariableDeclaration) return [];
|
|
22770
|
-
return declaration.declarations.flatMap(
|
|
22771
|
-
(item) => item.id.type === import_utils121.AST_NODE_TYPES.Identifier ? [{ name: item.id.name, node: item }] : []
|
|
22772
|
-
);
|
|
22773
|
-
}
|
|
22774
22915
|
var sole_export_matches_filename_default = createRule({
|
|
22775
22916
|
name: "sole-export-matches-filename",
|
|
22776
22917
|
documentation: SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION,
|
|
@@ -22786,64 +22927,25 @@ var sole_export_matches_filename_default = createRule({
|
|
|
22786
22927
|
create(context) {
|
|
22787
22928
|
const fileStem = stem3(context.filename);
|
|
22788
22929
|
const normalizedFilename = context.filename.replaceAll("\\", "/");
|
|
22789
|
-
if (EXCLUDED_STEMS.has(fileStem) ||
|
|
22930
|
+
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 {};
|
|
22931
|
+
let hasCommonJsExport = false;
|
|
22790
22932
|
return {
|
|
22933
|
+
"CallExpression, MemberExpression"(node) {
|
|
22934
|
+
if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
|
|
22935
|
+
},
|
|
22791
22936
|
"Program:exit"(program) {
|
|
22792
|
-
|
|
22793
|
-
const
|
|
22794
|
-
|
|
22795
|
-
|
|
22796
|
-
if (statement.type === import_utils121.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
|
22797
|
-
publicExports.add("default");
|
|
22798
|
-
const declaration = statement.declaration;
|
|
22799
|
-
if ((declaration.type === import_utils121.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.FunctionDeclaration) && declaration.id !== null) exports2.push({ name: declaration.id.name, node: declaration });
|
|
22800
|
-
else return false;
|
|
22801
|
-
}
|
|
22802
|
-
if (statement.type !== import_utils121.AST_NODE_TYPES.ExportNamedDeclaration) return true;
|
|
22803
|
-
return collectNamedExport(statement);
|
|
22804
|
-
}
|
|
22805
|
-
function collectNamedExport(statement) {
|
|
22806
|
-
const declaration = statement.declaration;
|
|
22807
|
-
if (declaration !== null && "id" in declaration && declaration.id?.type === import_utils121.AST_NODE_TYPES.Identifier) {
|
|
22808
|
-
publicExports.add(declaration.id.name);
|
|
22809
|
-
}
|
|
22810
|
-
if (declaration?.type === import_utils121.AST_NODE_TYPES.VariableDeclaration) {
|
|
22811
|
-
if (declaration.declarations.some((item) => item.id.type !== import_utils121.AST_NODE_TYPES.Identifier)) return false;
|
|
22812
|
-
for (const item of declaration.declarations) {
|
|
22813
|
-
if (item.id.type === import_utils121.AST_NODE_TYPES.Identifier) publicExports.add(item.id.name);
|
|
22814
|
-
}
|
|
22815
|
-
}
|
|
22816
|
-
for (const specifier of statement.specifiers) {
|
|
22817
|
-
const exported = specifier.exported.type === import_utils121.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
22818
|
-
publicExports.add(String(exported));
|
|
22819
|
-
}
|
|
22820
|
-
if (statement.exportKind === "type") return true;
|
|
22821
|
-
exports2.push(...declarationExport(statement));
|
|
22822
|
-
collectRuntimeSpecifiers(statement);
|
|
22823
|
-
return true;
|
|
22824
|
-
}
|
|
22825
|
-
function collectRuntimeSpecifiers(statement) {
|
|
22826
|
-
for (const specifier of statement.specifiers) {
|
|
22827
|
-
const exported = specifier.exported.type === import_utils121.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
|
|
22828
|
-
publicExports.add(String(exported));
|
|
22829
|
-
if (specifier.exportKind === "type") continue;
|
|
22830
|
-
if (exported === "default") exports2.push({ name: specifier.local.name, node: specifier });
|
|
22831
|
-
else exports2.push({ name: String(exported), node: specifier });
|
|
22832
|
-
}
|
|
22833
|
-
}
|
|
22834
|
-
for (const statement of program.body) {
|
|
22835
|
-
if (!collectPublicExport(statement)) return;
|
|
22836
|
-
}
|
|
22837
|
-
const unique = new Map(exports2.map((item) => [item.name, item]));
|
|
22838
|
-
if (unique.size !== 1 || publicExports.size !== 1) return;
|
|
22839
|
-
const only = [...unique.values()][0];
|
|
22937
|
+
if (hasCommonJsExport) return;
|
|
22938
|
+
const exports2 = runtimeExports(program);
|
|
22939
|
+
if (exports2.ambiguous || exports2.exports.length !== 1) return;
|
|
22940
|
+
const only = exports2.exports[0];
|
|
22840
22941
|
if (only === void 0) return;
|
|
22942
|
+
if (isFrameworkEntrypoint(normalizedFilename, only.key)) return;
|
|
22841
22943
|
if (only.name === "onRouterTransitionStart" && /(?:^|\/)instrumentation-client\.[jt]s$/u.test(normalizedFilename)) return;
|
|
22842
22944
|
if (only.name === "collections" && /(?:^|\/)src\/content\.config\.(?:ts|js|mjs)$/u.test(normalizedFilename) && program.body.some((statement) => statement.type === import_utils121.AST_NODE_TYPES.ImportDeclaration && statement.source.value === "astro:content")) return;
|
|
22843
22945
|
const exportedStem = kebabCase(only.name);
|
|
22844
22946
|
if (exportedStem === "") return;
|
|
22845
22947
|
const expected = `${fileStem.startsWith("_") ? "_" : ""}${exportedStem}`;
|
|
22846
|
-
if (expected === fileStem.toLowerCase()
|
|
22948
|
+
if (expected === fileStem.toLowerCase()) return;
|
|
22847
22949
|
context.report({ node: only.node, messageId: "matchSoleExport", data: { exported: only.name, expected } });
|
|
22848
22950
|
}
|
|
22849
22951
|
};
|
|
@@ -23058,7 +23160,7 @@ var chainMemberNames2 = (node) => {
|
|
|
23058
23160
|
names.reverse();
|
|
23059
23161
|
return names;
|
|
23060
23162
|
};
|
|
23061
|
-
var
|
|
23163
|
+
var unwrapExpression8 = (node) => {
|
|
23062
23164
|
let current = node;
|
|
23063
23165
|
while (current.type === import_utils122.AST_NODE_TYPES.TSAsExpression || current.type === import_utils122.AST_NODE_TYPES.TSSatisfiesExpression || current.type === import_utils122.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils122.AST_NODE_TYPES.TSTypeAssertion) {
|
|
23064
23166
|
current = current.expression;
|
|
@@ -23098,18 +23200,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23098
23200
|
const binding = resolvedBinding(identifier);
|
|
23099
23201
|
if (binding !== null) zodBindings.add(binding);
|
|
23100
23202
|
}
|
|
23101
|
-
function isZodChain(node) {
|
|
23102
|
-
const root = calleeChainRoot2(node);
|
|
23103
|
-
if (root === null) return false;
|
|
23104
|
-
const binding = resolvedBinding(root);
|
|
23105
|
-
return binding !== null && zodBindings.has(binding);
|
|
23106
|
-
}
|
|
23107
|
-
function isSchemaBinding(identifier) {
|
|
23108
|
-
const binding = resolvedBinding(identifier);
|
|
23109
|
-
return binding !== null && schemaBindings.has(binding);
|
|
23110
|
-
}
|
|
23111
23203
|
function isConfirmedSchema(expression) {
|
|
23112
|
-
const init =
|
|
23204
|
+
const init = unwrapExpression8(expression);
|
|
23113
23205
|
if (init.type === import_utils122.AST_NODE_TYPES.Identifier) return isSchemaBinding(init);
|
|
23114
23206
|
if (init.type !== import_utils122.AST_NODE_TYPES.CallExpression || init.callee.type !== import_utils122.AST_NODE_TYPES.MemberExpression) {
|
|
23115
23207
|
return false;
|
|
@@ -23124,6 +23216,16 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23124
23216
|
const root = calleeChainRoot2(init.callee);
|
|
23125
23217
|
return root !== null && isSchemaBinding(root) && SCHEMA_RETURNING_METHODS.has(terminal);
|
|
23126
23218
|
}
|
|
23219
|
+
function isSchemaBinding(identifier) {
|
|
23220
|
+
const binding = resolvedBinding(identifier);
|
|
23221
|
+
return binding !== null && schemaBindings.has(binding);
|
|
23222
|
+
}
|
|
23223
|
+
function isZodChain(node) {
|
|
23224
|
+
const root = calleeChainRoot2(node);
|
|
23225
|
+
if (root === null) return false;
|
|
23226
|
+
const binding = resolvedBinding(root);
|
|
23227
|
+
return binding !== null && zodBindings.has(binding);
|
|
23228
|
+
}
|
|
23127
23229
|
if (isTestFile(context.filename) || BENCHMARK_PATH_RE2.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
23128
23230
|
return {};
|
|
23129
23231
|
}
|
|
@@ -23154,7 +23256,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
23154
23256
|
}
|
|
23155
23257
|
});
|
|
23156
23258
|
|
|
23157
|
-
// src/rules/
|
|
23259
|
+
// src/rules/_renamed-rules.ts
|
|
23158
23260
|
var RENAMED_RULES = {
|
|
23159
23261
|
"jsdoc-restates-signature": "no-restated-jsdoc",
|
|
23160
23262
|
"zod-naming-convention": "require-pascal-case-zod-schema-name",
|
|
@@ -23163,7 +23265,7 @@ var RENAMED_RULES = {
|
|
|
23163
23265
|
"trailing-value-narration": "no-trailing-value-narration"
|
|
23164
23266
|
};
|
|
23165
23267
|
|
|
23166
|
-
// src/rules/_retired.ts
|
|
23268
|
+
// src/rules/_retired-rules.ts
|
|
23167
23269
|
var RETIRED_RULES = {
|
|
23168
23270
|
"ban-loose-type-guards-in-tests": {
|
|
23169
23271
|
removedIn: "5.0.0",
|
|
@@ -23355,7 +23457,7 @@ var RULES = {
|
|
|
23355
23457
|
};
|
|
23356
23458
|
var meta = {
|
|
23357
23459
|
name: "@sarj/eslint-plugin",
|
|
23358
|
-
version: "
|
|
23460
|
+
version: "16.1.0"
|
|
23359
23461
|
};
|
|
23360
23462
|
var APPLICATION_ONLY_RULES = [];
|
|
23361
23463
|
var LIBRARY_IMPORT_POLICY = ["error", {
|
|
@@ -23380,8 +23482,7 @@ var ADVISORY_RULES = [
|
|
|
23380
23482
|
"@sarj/prefer-whole-object-assertion",
|
|
23381
23483
|
"@sarj/require-camelcase-properties",
|
|
23382
23484
|
"@sarj/require-interface-for-exported-class",
|
|
23383
|
-
"@sarj/require-sql-access-class"
|
|
23384
|
-
"@sarj/sole-export-matches-filename"
|
|
23485
|
+
"@sarj/require-sql-access-class"
|
|
23385
23486
|
];
|
|
23386
23487
|
var RECOMMENDED_RULES = {
|
|
23387
23488
|
"@sarj/no-conditional-empty-object-spread": "error",
|
|
@@ -23493,7 +23594,7 @@ var RECOMMENDED_RULES = {
|
|
|
23493
23594
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
23494
23595
|
"@sarj/stepdown": "error",
|
|
23495
23596
|
"@sarj/source-coupled-test": "error",
|
|
23496
|
-
"@sarj/sole-export-matches-filename": "
|
|
23597
|
+
"@sarj/sole-export-matches-filename": "error",
|
|
23497
23598
|
"@sarj/test-phase-label-comment": "error",
|
|
23498
23599
|
"@sarj/require-pascal-case-zod-schema-name": "error"
|
|
23499
23600
|
};
|
|
@@ -23611,7 +23712,7 @@ var STRICT_RULES = {
|
|
|
23611
23712
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
23612
23713
|
"@sarj/stepdown": "error",
|
|
23613
23714
|
"@sarj/source-coupled-test": "error",
|
|
23614
|
-
"@sarj/sole-export-matches-filename": "
|
|
23715
|
+
"@sarj/sole-export-matches-filename": "error",
|
|
23615
23716
|
"@sarj/test-phase-label-comment": "error",
|
|
23616
23717
|
"@sarj/require-pascal-case-zod-schema-name": "error"
|
|
23617
23718
|
};
|
|
@@ -23634,7 +23735,7 @@ var PLUGIN = {
|
|
|
23634
23735
|
};
|
|
23635
23736
|
}
|
|
23636
23737
|
};
|
|
23637
|
-
var
|
|
23738
|
+
var src_default = PLUGIN;
|
|
23638
23739
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23639
23740
|
0 && (module.exports = {
|
|
23640
23741
|
ADVISORY_RULES,
|