pasika 0.10.81 → 0.10.83
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 +62 -5
- package/package.json +1 -1
|
@@ -386,6 +386,17 @@ function parseModule(file) {
|
|
|
386
386
|
names.add(node.name.text);
|
|
387
387
|
} else if (ts.isElementAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === namespace && ts.isStringLiteral(node.argumentExpression)) {
|
|
388
388
|
names.add(node.argumentExpression.text);
|
|
389
|
+
} else if (ts.isVariableDeclaration(node) && ts.isObjectBindingPattern(node.name) && node.initializer && ts.isIdentifier(node.initializer) && node.initializer.text === namespace) {
|
|
390
|
+
for (const element of node.name.elements) {
|
|
391
|
+
if (element.dotDotDotToken) continue;
|
|
392
|
+
let importedName;
|
|
393
|
+
if (element.propertyName) {
|
|
394
|
+
importedName = propertyName(element.propertyName);
|
|
395
|
+
} else if (ts.isIdentifier(element.name)) {
|
|
396
|
+
importedName = element.name.text;
|
|
397
|
+
}
|
|
398
|
+
if (importedName) names.add(importedName);
|
|
399
|
+
}
|
|
389
400
|
}
|
|
390
401
|
ts.forEachChild(node, visit);
|
|
391
402
|
};
|
|
@@ -1207,6 +1218,8 @@ function isNestedInside(expectedFolder, currentFolder, componentFile) {
|
|
|
1207
1218
|
if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
|
|
1208
1219
|
const folderName = currentFolder[currentFolder.length - 1];
|
|
1209
1220
|
if (!folderName) return false;
|
|
1221
|
+
const componentName = path10.basename(componentFile, path10.extname(componentFile));
|
|
1222
|
+
if (componentName !== folderName) return false;
|
|
1210
1223
|
return fs3.existsSync(path10.join(path10.dirname(componentFile), `${folderName}.tsx`));
|
|
1211
1224
|
}
|
|
1212
1225
|
var componentPlacementRule = {
|
|
@@ -2926,7 +2939,13 @@ function parentComponentName(dirPath, folderName) {
|
|
|
2926
2939
|
if (!fs4.existsSync(componentFile)) return void 0;
|
|
2927
2940
|
try {
|
|
2928
2941
|
const exports = parseModule(componentFile).exports;
|
|
2929
|
-
|
|
2942
|
+
const classifiedComponent = exports.find((moduleExport) => moduleExport.kind === "component")?.name;
|
|
2943
|
+
if (classifiedComponent) return classifiedComponent;
|
|
2944
|
+
const normalizedFolderName = folderName.replaceAll("-", "").toLowerCase();
|
|
2945
|
+
const ownerExport = exports.find(
|
|
2946
|
+
(moduleExport) => isPascalCase4(moduleExport.name) && moduleExport.name.toLowerCase() === normalizedFolderName
|
|
2947
|
+
);
|
|
2948
|
+
return ownerExport?.name;
|
|
2930
2949
|
} catch {
|
|
2931
2950
|
return void 0;
|
|
2932
2951
|
}
|
|
@@ -2976,7 +2995,7 @@ var enforceBarrelExportsRule = {
|
|
|
2976
2995
|
if (nonParentExports.length > 0) {
|
|
2977
2996
|
context.report({
|
|
2978
2997
|
loc: { line: 1, column: 0 },
|
|
2979
|
-
message: `index.ts must not re-export
|
|
2998
|
+
message: `index.ts must not re-export nested internals: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
|
|
2980
2999
|
});
|
|
2981
3000
|
}
|
|
2982
3001
|
}
|
|
@@ -3801,6 +3820,24 @@ function sourceSegments(sourceRoot, absolutePath) {
|
|
|
3801
3820
|
}
|
|
3802
3821
|
return relativePath.split(path31.sep);
|
|
3803
3822
|
}
|
|
3823
|
+
function isWithin(root, candidate) {
|
|
3824
|
+
const relativePath = path31.relative(root, candidate);
|
|
3825
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path31.isAbsolute(relativePath);
|
|
3826
|
+
}
|
|
3827
|
+
function componentFolderAncestors(targetFile, sourceRoot) {
|
|
3828
|
+
const folders = [];
|
|
3829
|
+
let current = path31.dirname(targetFile);
|
|
3830
|
+
while (current !== sourceRoot && isWithin(sourceRoot, current)) {
|
|
3831
|
+
const folderName = path31.basename(current);
|
|
3832
|
+
if (hasComponentOwner(current, folderName) && hasExactEntry(current, "index.ts")) {
|
|
3833
|
+
folders.push(current);
|
|
3834
|
+
}
|
|
3835
|
+
const parent = path31.dirname(current);
|
|
3836
|
+
if (parent === current) break;
|
|
3837
|
+
current = parent;
|
|
3838
|
+
}
|
|
3839
|
+
return folders;
|
|
3840
|
+
}
|
|
3804
3841
|
function relativeSpecifier(filename, resolvedPath) {
|
|
3805
3842
|
const relativePath = path31.relative(path31.dirname(filename), resolvedPath).split(path31.sep).join("/");
|
|
3806
3843
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
@@ -3830,6 +3867,26 @@ var importBoundariesRule = {
|
|
|
3830
3867
|
return;
|
|
3831
3868
|
}
|
|
3832
3869
|
const importPath = source.value;
|
|
3870
|
+
const resolvedModule = resolveSpecifier(filename, importPath, sourceRoot);
|
|
3871
|
+
if (resolvedModule) {
|
|
3872
|
+
for (const componentFolder of componentFolderAncestors(resolvedModule, sourceRoot)) {
|
|
3873
|
+
if (isWithin(componentFolder, filename)) continue;
|
|
3874
|
+
const componentEntry = path31.join(componentFolder, "index.ts");
|
|
3875
|
+
if (path31.resolve(resolvedModule) === path31.resolve(componentEntry)) continue;
|
|
3876
|
+
const entrySpecifier = prefersRelative(filename, componentFolder) ? relativeSpecifier(filename, componentFolder) : aliasSpecifier(sourceRoot, componentFolder);
|
|
3877
|
+
const folderLabel = `src/${path31.relative(sourceRoot, componentFolder).split(path31.sep).join("/")}/`;
|
|
3878
|
+
const message = [
|
|
3879
|
+
`Do not import "${importPath}" across the ${folderLabel} component boundary;`,
|
|
3880
|
+
`outside consumers may import only "${entrySpecifier}".`,
|
|
3881
|
+
"Move nested internals to their CCF when they need reuse."
|
|
3882
|
+
].join(" ");
|
|
3883
|
+
context.report({
|
|
3884
|
+
node: source,
|
|
3885
|
+
message
|
|
3886
|
+
});
|
|
3887
|
+
return;
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3833
3890
|
const resolvedPath = resolveSourceImport(sourceRoot, filename, importPath);
|
|
3834
3891
|
if (!resolvedPath) {
|
|
3835
3892
|
return;
|
|
@@ -5044,7 +5101,7 @@ var ownershipIndexCache = /* @__PURE__ */ new WeakMap();
|
|
|
5044
5101
|
function normalizePath(value) {
|
|
5045
5102
|
return value.replaceAll("\\", "/").toLowerCase();
|
|
5046
5103
|
}
|
|
5047
|
-
function
|
|
5104
|
+
function isWithin2(root, file) {
|
|
5048
5105
|
const relative = path39.relative(root, file);
|
|
5049
5106
|
return relative === "" || !relative.startsWith("..") && !path39.isAbsolute(relative);
|
|
5050
5107
|
}
|
|
@@ -5186,7 +5243,7 @@ var ContractOwnershipIndex = class {
|
|
|
5186
5243
|
const normalized = normalizePath(fileName);
|
|
5187
5244
|
if (/\/typescript\/lib\/lib\.[^/]+\.d\.ts$/u.test(normalized)) return "platform";
|
|
5188
5245
|
if (normalized.includes("/node_modules/")) return "third-party";
|
|
5189
|
-
if (
|
|
5246
|
+
if (isWithin2(this.cwd, path39.resolve(fileName))) return "first-party";
|
|
5190
5247
|
return "unknown";
|
|
5191
5248
|
}
|
|
5192
5249
|
schemaOwnership(declaration) {
|
|
@@ -5200,7 +5257,7 @@ var ContractOwnershipIndex = class {
|
|
|
5200
5257
|
}
|
|
5201
5258
|
indexApiContracts() {
|
|
5202
5259
|
for (const sourceFile of this.program.getSourceFiles()) {
|
|
5203
|
-
if (sourceFile.isDeclarationFile || !
|
|
5260
|
+
if (sourceFile.isDeclarationFile || !isWithin2(this.cwd, path39.resolve(sourceFile.fileName))) continue;
|
|
5204
5261
|
const visit = (node) => {
|
|
5205
5262
|
if (ts7.isCallExpression(node) && this.isDefineApiContractCall(node)) this.indexApiContractCall(node);
|
|
5206
5263
|
ts7.forEachChild(node, visit);
|