pasika 0.10.86 → 0.10.88
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/eslint/pasika/index.js +47 -12
- package/package.json +1 -1
|
@@ -844,17 +844,21 @@ function componentFacadeTarget(context, filename) {
|
|
|
844
844
|
if (statements.length === 0 || statements.some((node) => node.type !== "ExportNamedDeclaration" || !node.source)) {
|
|
845
845
|
return void 0;
|
|
846
846
|
}
|
|
847
|
-
const
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
847
|
+
for (const statement of statements) {
|
|
848
|
+
if (statement.type !== "ExportNamedDeclaration" || typeof statement.source?.value !== "string") continue;
|
|
849
|
+
if (!statement.source.value.startsWith("./")) return void 0;
|
|
850
|
+
const componentFile = path6.resolve(path6.dirname(filename), `${statement.source.value}.tsx`);
|
|
851
|
+
if (!fs2.existsSync(componentFile)) continue;
|
|
852
|
+
const components = parseComponentInfo(fs2.readFileSync(componentFile, "utf8"), componentFile);
|
|
853
|
+
if (components.some(
|
|
854
|
+
({ name }) => statement.specifiers.some(
|
|
855
|
+
(specifier) => specifier.local.type === "Identifier" && specifier.local.name === name
|
|
856
|
+
)
|
|
857
|
+
)) {
|
|
858
|
+
return componentFile;
|
|
859
|
+
}
|
|
851
860
|
}
|
|
852
|
-
|
|
853
|
-
if (!fs2.existsSync(componentFile)) return void 0;
|
|
854
|
-
const components = parseComponentInfo(fs2.readFileSync(componentFile, "utf8"), componentFile);
|
|
855
|
-
return components.some(
|
|
856
|
-
({ name }) => exports.some((specifier) => specifier.local.type === "Identifier" && specifier.local.name === name)
|
|
857
|
-
) ? componentFile : void 0;
|
|
861
|
+
return void 0;
|
|
858
862
|
}
|
|
859
863
|
var applicationStructureRule = {
|
|
860
864
|
meta: {
|
|
@@ -5121,7 +5125,7 @@ var noMixedConcernsRule = {
|
|
|
5121
5125
|
schema: [],
|
|
5122
5126
|
type: "problem",
|
|
5123
5127
|
docs: {
|
|
5124
|
-
description: "Enforce one React component per .tsx file
|
|
5128
|
+
description: "Enforce one React component and one exported runtime value per .tsx file."
|
|
5125
5129
|
}
|
|
5126
5130
|
},
|
|
5127
5131
|
create(context) {
|
|
@@ -5130,13 +5134,44 @@ var noMixedConcernsRule = {
|
|
|
5130
5134
|
return {
|
|
5131
5135
|
"Program:exit"() {
|
|
5132
5136
|
const components = parseComponentInfo(sourceCode, context.filename, { includeNonExported: true });
|
|
5133
|
-
if (components.length
|
|
5137
|
+
if (components.length === 0) return;
|
|
5134
5138
|
for (const extra of components.slice(1)) {
|
|
5135
5139
|
context.report({
|
|
5136
5140
|
loc: { line: 1, column: 0 },
|
|
5137
5141
|
message: `File defines multiple components. "${extra.name}" is an extra component. Move it to its own file. Each component file MUST define exactly one component. See docs/next-codebase-guide/rules/no-mixed-concerns-rule.md`
|
|
5138
5142
|
});
|
|
5139
5143
|
}
|
|
5144
|
+
if (components.length > 1) return;
|
|
5145
|
+
const componentName = components[0]?.name;
|
|
5146
|
+
if (!componentName) return;
|
|
5147
|
+
for (const statement of context.sourceCode.ast.body) {
|
|
5148
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
5149
|
+
if (/^export\s+(?:type|interface)\b/.test(context.sourceCode.getText(statement))) continue;
|
|
5150
|
+
const declaration = statement.declaration;
|
|
5151
|
+
if (declaration?.type === "FunctionDeclaration" && declaration.id.name === componentName) continue;
|
|
5152
|
+
if (declaration?.type === "VariableDeclaration" && declaration.declarations.length === 1 && declaration.declarations[0]?.id.type === "Identifier" && declaration.declarations[0].id.name === componentName) {
|
|
5153
|
+
continue;
|
|
5154
|
+
}
|
|
5155
|
+
if (!declaration && statement.specifiers.every(
|
|
5156
|
+
(specifier) => /^type\b/.test(context.sourceCode.getText(specifier)) || !statement.source && specifier.local.type === "Identifier" && specifier.local.name === componentName
|
|
5157
|
+
)) {
|
|
5158
|
+
continue;
|
|
5159
|
+
}
|
|
5160
|
+
} else if (statement.type === "ExportAllDeclaration") {
|
|
5161
|
+
if (/^export\s+type\b/.test(context.sourceCode.getText(statement))) continue;
|
|
5162
|
+
} else if (statement.type === "ExportDefaultDeclaration") {
|
|
5163
|
+
if (statement.declaration.type === "Identifier" && statement.declaration.name === componentName) continue;
|
|
5164
|
+
if (statement.declaration.type === "FunctionDeclaration" && statement.declaration.id?.name === componentName) {
|
|
5165
|
+
continue;
|
|
5166
|
+
}
|
|
5167
|
+
} else {
|
|
5168
|
+
continue;
|
|
5169
|
+
}
|
|
5170
|
+
context.report({
|
|
5171
|
+
node: statement,
|
|
5172
|
+
message: `Component files must export only their own component "${componentName}". Import other values directly from their files.`
|
|
5173
|
+
});
|
|
5174
|
+
}
|
|
5140
5175
|
}
|
|
5141
5176
|
};
|
|
5142
5177
|
}
|