pasika 0.5.5 → 0.5.7
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 +37 -18
- package/package.json +1 -1
|
@@ -1355,6 +1355,16 @@ function isKebabCase2(str) {
|
|
|
1355
1355
|
return /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(str);
|
|
1356
1356
|
}
|
|
1357
1357
|
var SUPPORT_FOLDERS = /* @__PURE__ */ new Set(["types", "schemas", "hooks", "constants", "utils", "config", "locales"]);
|
|
1358
|
+
function parentComponentName(dirPath, folderName) {
|
|
1359
|
+
const componentFile = path9.join(dirPath, `${folderName}.tsx`);
|
|
1360
|
+
if (!fs.existsSync(componentFile)) return void 0;
|
|
1361
|
+
try {
|
|
1362
|
+
const exports = parseModule(componentFile).exports;
|
|
1363
|
+
return exports.find((moduleExport) => moduleExport.kind === "component")?.name;
|
|
1364
|
+
} catch {
|
|
1365
|
+
return void 0;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1358
1368
|
var enforceBarrelExportsRule = {
|
|
1359
1369
|
meta: {
|
|
1360
1370
|
schema: [],
|
|
@@ -1373,8 +1383,8 @@ var enforceBarrelExportsRule = {
|
|
|
1373
1383
|
const parentFolderName = path9.basename(path9.dirname(dirPath));
|
|
1374
1384
|
if (SUPPORT_FOLDERS.has(folderName)) return {};
|
|
1375
1385
|
if (!isPascalCase4(folderName) && !isKebabCase2(folderName)) return {};
|
|
1376
|
-
const
|
|
1377
|
-
if (!
|
|
1386
|
+
const parentName = parentComponentName(dirPath, folderName);
|
|
1387
|
+
if (!parentName) return {};
|
|
1378
1388
|
if (!isPascalCase4(parentFolderName) && !isKebabCase2(parentFolderName)) return {};
|
|
1379
1389
|
const reExportedNames = /* @__PURE__ */ new Set();
|
|
1380
1390
|
return {
|
|
@@ -1388,18 +1398,18 @@ var enforceBarrelExportsRule = {
|
|
|
1388
1398
|
},
|
|
1389
1399
|
"Program:exit"() {
|
|
1390
1400
|
if (reExportedNames.size === 0) return;
|
|
1391
|
-
if (!reExportedNames.has(
|
|
1401
|
+
if (!reExportedNames.has(parentName)) {
|
|
1392
1402
|
context.report({
|
|
1393
1403
|
loc: { line: 1, column: 0 },
|
|
1394
|
-
message: `index.ts in "${folderName}/" must re-export "${
|
|
1404
|
+
message: `index.ts in "${folderName}/" must re-export "${parentName}". See docs/code-organization-guide/rules/folder-nesting-rule.md`
|
|
1395
1405
|
});
|
|
1396
1406
|
return;
|
|
1397
1407
|
}
|
|
1398
|
-
const nonParentExports = [...reExportedNames].filter((n) => n !==
|
|
1408
|
+
const nonParentExports = [...reExportedNames].filter((n) => n !== parentName);
|
|
1399
1409
|
if (nonParentExports.length > 0) {
|
|
1400
1410
|
context.report({
|
|
1401
1411
|
loc: { line: 1, column: 0 },
|
|
1402
|
-
message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${
|
|
1412
|
+
message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/code-organization-guide/rules/folder-nesting-rule.md`
|
|
1403
1413
|
});
|
|
1404
1414
|
}
|
|
1405
1415
|
}
|
|
@@ -1408,6 +1418,7 @@ var enforceBarrelExportsRule = {
|
|
|
1408
1418
|
};
|
|
1409
1419
|
|
|
1410
1420
|
// eslint/rules/component-placement.ts
|
|
1421
|
+
import fs2 from "fs";
|
|
1411
1422
|
import path11 from "path";
|
|
1412
1423
|
|
|
1413
1424
|
// eslint/project/ccf.ts
|
|
@@ -1506,6 +1517,13 @@ var REASON_TEXT = {
|
|
|
1506
1517
|
"across-layers": "its consumers span more than one layer, so no feature can own it"
|
|
1507
1518
|
};
|
|
1508
1519
|
var sameFolder = (left, right) => left.length === right.length && left.every((segment, depth) => segment === right[depth]);
|
|
1520
|
+
function isNestedInside(expectedFolder, currentFolder, componentFile) {
|
|
1521
|
+
if (currentFolder.length !== expectedFolder.length + 1) return false;
|
|
1522
|
+
if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
|
|
1523
|
+
const folderName = currentFolder[currentFolder.length - 1];
|
|
1524
|
+
if (!folderName) return false;
|
|
1525
|
+
return fs2.existsSync(path11.join(path11.dirname(componentFile), `${folderName}.tsx`));
|
|
1526
|
+
}
|
|
1509
1527
|
var componentPlacementRule = {
|
|
1510
1528
|
meta: {
|
|
1511
1529
|
schema: [],
|
|
@@ -1541,6 +1559,7 @@ var componentPlacementRule = {
|
|
|
1541
1559
|
return;
|
|
1542
1560
|
}
|
|
1543
1561
|
if (sameFolder(currentFolder, placement.expectedFolder)) return;
|
|
1562
|
+
if (isNestedInside(placement.expectedFolder, currentFolder, componentFile)) return;
|
|
1544
1563
|
const explanation = REASON_TEXT[placement.reason] ?? "that is where its consumers place it";
|
|
1545
1564
|
context.report({
|
|
1546
1565
|
node,
|
|
@@ -1597,7 +1616,7 @@ var supportFilePlacementRule = {
|
|
|
1597
1616
|
};
|
|
1598
1617
|
|
|
1599
1618
|
// eslint/rules/application-structure.ts
|
|
1600
|
-
import
|
|
1619
|
+
import fs3 from "fs";
|
|
1601
1620
|
import path13 from "path";
|
|
1602
1621
|
var MODULE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
1603
1622
|
var ROUTING_FILES = /* @__PURE__ */ new Set([
|
|
@@ -1649,7 +1668,7 @@ function exportedKinds(filename) {
|
|
|
1649
1668
|
}
|
|
1650
1669
|
}
|
|
1651
1670
|
function expectedSupportFolder(kinds) {
|
|
1652
|
-
for (const kind of ["component", "hook", "
|
|
1671
|
+
for (const kind of ["component", "hook", "schema", "function", "constant", "type"]) {
|
|
1653
1672
|
if (kinds.has(kind)) return EXPECTED_SUPPORT_FOLDER[kind];
|
|
1654
1673
|
}
|
|
1655
1674
|
return void 0;
|
|
@@ -1672,10 +1691,10 @@ function componentFolderViolation(segments, sourceRoot) {
|
|
|
1672
1691
|
if (!folder || SUPPORT_FOLDERS2.has(folder)) continue;
|
|
1673
1692
|
const folderPath = path13.join(sourceRoot, ...segments.slice(0, depth + 1));
|
|
1674
1693
|
const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
|
|
1675
|
-
if (!
|
|
1694
|
+
if (!fs3.existsSync(path13.join(folderPath, `${folder}.tsx`))) {
|
|
1676
1695
|
return `A folder that is not a support folder must be a component folder; add "${folder}.tsx" to ${label} or move its files into a support folder.`;
|
|
1677
1696
|
}
|
|
1678
|
-
if (!
|
|
1697
|
+
if (!fs3.existsSync(path13.join(folderPath, "index.ts"))) {
|
|
1679
1698
|
return `A component folder must have an index.ts that named-re-exports its component; add index.ts to ${label}.`;
|
|
1680
1699
|
}
|
|
1681
1700
|
}
|
|
@@ -1721,7 +1740,7 @@ var applicationStructureRule = {
|
|
|
1721
1740
|
);
|
|
1722
1741
|
}
|
|
1723
1742
|
const moduleRoot = configModuleRoot(filename, sourceRoot);
|
|
1724
|
-
if (moduleRoot && !
|
|
1743
|
+
if (moduleRoot && !fs3.existsSync(path13.join(moduleRoot, "index.ts"))) {
|
|
1725
1744
|
return report2(
|
|
1726
1745
|
context,
|
|
1727
1746
|
`Add src/config/${path13.basename(moduleRoot)}/index.ts as the configuration module entry point.`
|
|
@@ -1907,7 +1926,7 @@ function toKebabCase(value) {
|
|
|
1907
1926
|
}
|
|
1908
1927
|
|
|
1909
1928
|
// eslint/rules/support-folder-shape.ts
|
|
1910
|
-
import
|
|
1929
|
+
import fs4 from "fs";
|
|
1911
1930
|
import path16 from "path";
|
|
1912
1931
|
var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
|
|
1913
1932
|
var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
|
|
@@ -1928,7 +1947,7 @@ var supportFolderShapeRule = {
|
|
|
1928
1947
|
const directory = path16.dirname(filename);
|
|
1929
1948
|
let entries;
|
|
1930
1949
|
try {
|
|
1931
|
-
entries =
|
|
1950
|
+
entries = fs4.readdirSync(directory);
|
|
1932
1951
|
} catch {
|
|
1933
1952
|
return {};
|
|
1934
1953
|
}
|
|
@@ -3776,7 +3795,7 @@ var sourceUnderSrcRule = {
|
|
|
3776
3795
|
};
|
|
3777
3796
|
|
|
3778
3797
|
// eslint/rules/zirka-baseline.ts
|
|
3779
|
-
import
|
|
3798
|
+
import fs5 from "fs";
|
|
3780
3799
|
import path36 from "path";
|
|
3781
3800
|
var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
|
|
3782
3801
|
var PRETTIER_CONFIGS = [
|
|
@@ -3815,12 +3834,12 @@ var zirkaBaselineRule = {
|
|
|
3815
3834
|
);
|
|
3816
3835
|
}
|
|
3817
3836
|
const tsconfigPath = path36.join(projectRoot, "tsconfig.json");
|
|
3818
|
-
if (!
|
|
3837
|
+
if (!fs5.existsSync(tsconfigPath)) {
|
|
3819
3838
|
report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
|
|
3820
3839
|
} else {
|
|
3821
3840
|
let extendsValue;
|
|
3822
3841
|
try {
|
|
3823
|
-
const parsed = JSON.parse(
|
|
3842
|
+
const parsed = JSON.parse(fs5.readFileSync(tsconfigPath, "utf8"));
|
|
3824
3843
|
extendsValue = typeof parsed === "object" && parsed !== null && "extends" in parsed ? parsed.extends : void 0;
|
|
3825
3844
|
} catch {
|
|
3826
3845
|
report3(
|
|
@@ -3832,13 +3851,13 @@ var zirkaBaselineRule = {
|
|
|
3832
3851
|
report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
|
|
3833
3852
|
}
|
|
3834
3853
|
}
|
|
3835
|
-
const prettierConfigFile = PRETTIER_CONFIGS.find((name) =>
|
|
3854
|
+
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(path36.join(projectRoot, name)));
|
|
3836
3855
|
if (!prettierConfigFile) {
|
|
3837
3856
|
report3(
|
|
3838
3857
|
"No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
|
|
3839
3858
|
);
|
|
3840
3859
|
} else {
|
|
3841
|
-
const content =
|
|
3860
|
+
const content = fs5.readFileSync(path36.join(projectRoot, prettierConfigFile), "utf8");
|
|
3842
3861
|
if (!content.includes("zirka")) {
|
|
3843
3862
|
report3(
|
|
3844
3863
|
"The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
|