pasika 0.10.1 → 0.10.3
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/README.md +78 -201
- package/dist/chunk-7JI2V3HF.js +14 -0
- package/dist/eslint/pasika/index.d.ts +1 -0
- package/dist/eslint/pasika/index.js +335 -443
- package/dist/helpers/cn.d.ts +10 -0
- package/dist/helpers/cn.js +9 -0
- package/dist/helpers/http-error.d.ts +12 -0
- package/dist/helpers/http-error.js +6 -0
- package/dist/helpers/with-response.d.ts +27 -0
- package/dist/helpers/with-response.js +36 -0
- package/dist/helpers/zod-fetch.d.ts +25 -0
- package/dist/helpers/zod-fetch.js +43 -0
- package/package.json +39 -2
|
@@ -1390,78 +1390,41 @@ var enforceCnMergeRule = {
|
|
|
1390
1390
|
};
|
|
1391
1391
|
|
|
1392
1392
|
// eslint/rules/cn-helper.ts
|
|
1393
|
-
import path9 from "path";
|
|
1394
1393
|
var HELPER = "cn";
|
|
1394
|
+
var ENTRY = "pasika/cn";
|
|
1395
1395
|
var DOC = "docs/pasika-adoption-guide/rules/cn-helper-rule.md";
|
|
1396
|
-
var
|
|
1396
|
+
var DECLARED = `A file must not declare its own ${HELPER}; import it from ${ENTRY}. See ${DOC}`;
|
|
1397
|
+
var IMPORTED = `${HELPER} must be imported from ${ENTRY}. See ${DOC}`;
|
|
1397
1398
|
function isNamed(node, name) {
|
|
1398
1399
|
return node?.type === "Identifier" && node.name === name;
|
|
1399
1400
|
}
|
|
1400
|
-
function isCallTo(node, callee) {
|
|
1401
|
-
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === callee;
|
|
1402
|
-
}
|
|
1403
|
-
function isComposition(node) {
|
|
1404
|
-
if (!isCallTo(node, "twMerge")) return false;
|
|
1405
|
-
const first = node.arguments[0];
|
|
1406
|
-
return first !== void 0 && first.type !== "SpreadElement" && isCallTo(first, "clsx");
|
|
1407
|
-
}
|
|
1408
|
-
function returnedExpression(body) {
|
|
1409
|
-
if (!body) return void 0;
|
|
1410
|
-
if (body.type !== "BlockStatement") return body;
|
|
1411
|
-
for (const statement of body.body) {
|
|
1412
|
-
if (statement.type === "ReturnStatement") return statement.argument ?? void 0;
|
|
1413
|
-
}
|
|
1414
|
-
return void 0;
|
|
1415
|
-
}
|
|
1416
|
-
function sourceRootFor(context) {
|
|
1417
|
-
return path9.join(path9.dirname(path9.resolve(context.filename)), "src");
|
|
1418
|
-
}
|
|
1419
|
-
function definesHelper(context, name) {
|
|
1420
|
-
const index = getProjectIndex(sourceRootFor(context));
|
|
1421
|
-
if (!index) return true;
|
|
1422
|
-
for (const parsed of index.modules.values()) {
|
|
1423
|
-
if (parsed.exports.some((exported) => exported.name === name)) return true;
|
|
1424
|
-
}
|
|
1425
|
-
return false;
|
|
1426
|
-
}
|
|
1427
1401
|
var cnHelperRule = {
|
|
1428
1402
|
meta: {
|
|
1429
1403
|
schema: [],
|
|
1430
1404
|
type: "problem",
|
|
1431
1405
|
docs: {
|
|
1432
|
-
description: `Require
|
|
1406
|
+
description: `Require ${HELPER} to be imported from ${ENTRY} rather than declared in the repository.`
|
|
1433
1407
|
}
|
|
1434
1408
|
},
|
|
1435
1409
|
create(context) {
|
|
1436
|
-
|
|
1437
|
-
return
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
loc: { line: 1, column: 0 },
|
|
1443
|
-
message: `A repository must define a ${HELPER} helper. See ${DOC}`
|
|
1444
|
-
});
|
|
1445
|
-
}
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1448
|
-
const check = (body, reportNode) => {
|
|
1449
|
-
if (isComposition(returnedExpression(body))) return;
|
|
1450
|
-
context.report({
|
|
1451
|
-
node: reportNode,
|
|
1452
|
-
message: `${HELPER} must return twMerge(clsx(...)). See ${DOC}`
|
|
1453
|
-
});
|
|
1410
|
+
const checkSource = (node) => {
|
|
1411
|
+
if (!node.source || node.source.value === ENTRY) return;
|
|
1412
|
+
for (const specifier of node.specifiers) {
|
|
1413
|
+
if (!isNamed(specifier.local, HELPER)) continue;
|
|
1414
|
+
context.report({ node: specifier, message: IMPORTED });
|
|
1415
|
+
}
|
|
1454
1416
|
};
|
|
1455
1417
|
return {
|
|
1456
1418
|
FunctionDeclaration(node) {
|
|
1457
|
-
if (isNamed(node.id, HELPER))
|
|
1419
|
+
if (isNamed(node.id, HELPER)) context.report({ node, message: DECLARED });
|
|
1458
1420
|
},
|
|
1459
1421
|
VariableDeclarator(node) {
|
|
1460
|
-
if (
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1422
|
+
if (isNamed(node.id.type === "Identifier" ? node.id : null, HELPER)) {
|
|
1423
|
+
context.report({ node, message: DECLARED });
|
|
1424
|
+
}
|
|
1425
|
+
},
|
|
1426
|
+
ImportDeclaration: checkSource,
|
|
1427
|
+
ExportNamedDeclaration: checkSource
|
|
1465
1428
|
};
|
|
1466
1429
|
}
|
|
1467
1430
|
};
|
|
@@ -1530,7 +1493,7 @@ var enforceCvaVariantPropsRule = {
|
|
|
1530
1493
|
};
|
|
1531
1494
|
|
|
1532
1495
|
// eslint/rules/enforce-barrel-exports.ts
|
|
1533
|
-
import
|
|
1496
|
+
import path9 from "path";
|
|
1534
1497
|
import fs from "fs";
|
|
1535
1498
|
function isPascalCase4(str) {
|
|
1536
1499
|
return /^[A-Z][A-Za-z0-9]*$/.test(str);
|
|
@@ -1540,7 +1503,7 @@ function isKebabCase2(str) {
|
|
|
1540
1503
|
}
|
|
1541
1504
|
var SUPPORT_FOLDERS = /* @__PURE__ */ new Set(["types", "schemas", "hooks", "constants", "utils", "config", "locales"]);
|
|
1542
1505
|
function parentComponentName(dirPath, folderName) {
|
|
1543
|
-
const componentFile =
|
|
1506
|
+
const componentFile = path9.join(dirPath, `${folderName}.tsx`);
|
|
1544
1507
|
if (!fs.existsSync(componentFile)) return void 0;
|
|
1545
1508
|
try {
|
|
1546
1509
|
const exports = parseModule(componentFile).exports;
|
|
@@ -1560,11 +1523,11 @@ var enforceBarrelExportsRule = {
|
|
|
1560
1523
|
create(context) {
|
|
1561
1524
|
const filename = context.filename;
|
|
1562
1525
|
if (!filename) return {};
|
|
1563
|
-
const baseName =
|
|
1526
|
+
const baseName = path9.basename(filename);
|
|
1564
1527
|
if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
|
|
1565
|
-
const dirPath =
|
|
1566
|
-
const folderName =
|
|
1567
|
-
const parentFolderName =
|
|
1528
|
+
const dirPath = path9.dirname(filename);
|
|
1529
|
+
const folderName = path9.basename(dirPath);
|
|
1530
|
+
const parentFolderName = path9.basename(path9.dirname(dirPath));
|
|
1568
1531
|
if (SUPPORT_FOLDERS.has(folderName)) return {};
|
|
1569
1532
|
if (!isPascalCase4(folderName) && !isKebabCase2(folderName)) return {};
|
|
1570
1533
|
const parentName = parentComponentName(dirPath, folderName);
|
|
@@ -1603,14 +1566,14 @@ var enforceBarrelExportsRule = {
|
|
|
1603
1566
|
|
|
1604
1567
|
// eslint/rules/component-placement.ts
|
|
1605
1568
|
import fs2 from "fs";
|
|
1606
|
-
import
|
|
1569
|
+
import path11 from "path";
|
|
1607
1570
|
|
|
1608
1571
|
// eslint/project/ccf.ts
|
|
1609
|
-
import
|
|
1572
|
+
import path10 from "path";
|
|
1610
1573
|
var SUPPORT_FOLDERS2 = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
|
|
1611
1574
|
function segmentsOf(file, sourceRoot) {
|
|
1612
|
-
const relative =
|
|
1613
|
-
return relative.startsWith("..") ? [] : relative.split(
|
|
1575
|
+
const relative = path10.relative(sourceRoot, file);
|
|
1576
|
+
return relative.startsWith("..") ? [] : relative.split(path10.sep);
|
|
1614
1577
|
}
|
|
1615
1578
|
function folderSegmentsOf(file, sourceRoot) {
|
|
1616
1579
|
return segmentsOf(file, sourceRoot).slice(0, -1);
|
|
@@ -1690,7 +1653,7 @@ function resolveSupportPlacement(supportFile, supportFolder, index) {
|
|
|
1690
1653
|
}
|
|
1691
1654
|
function describeConsumers(consumers, sourceRoot) {
|
|
1692
1655
|
const shown = 3;
|
|
1693
|
-
const names = consumers.map((consumer) =>
|
|
1656
|
+
const names = consumers.map((consumer) => path10.relative(path10.dirname(sourceRoot), consumer).split(path10.sep).join("/")).sort((left, right) => left.localeCompare(right));
|
|
1694
1657
|
if (names.length <= shown) return names.join(", ");
|
|
1695
1658
|
return `${names.slice(0, shown).join(", ")} and ${String(names.length - shown)} more`;
|
|
1696
1659
|
}
|
|
@@ -1707,7 +1670,7 @@ function isNestedInside(expectedFolder, currentFolder, componentFile) {
|
|
|
1707
1670
|
if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
|
|
1708
1671
|
const folderName = currentFolder[currentFolder.length - 1];
|
|
1709
1672
|
if (!folderName) return false;
|
|
1710
|
-
return fs2.existsSync(
|
|
1673
|
+
return fs2.existsSync(path11.join(path11.dirname(componentFile), `${folderName}.tsx`));
|
|
1711
1674
|
}
|
|
1712
1675
|
var componentPlacementRule = {
|
|
1713
1676
|
meta: {
|
|
@@ -1723,7 +1686,7 @@ var componentPlacementRule = {
|
|
|
1723
1686
|
const sourceRoot = sourceRootOf(context);
|
|
1724
1687
|
const index = getProjectIndex(sourceRoot);
|
|
1725
1688
|
if (!index) return {};
|
|
1726
|
-
const componentFile =
|
|
1689
|
+
const componentFile = path11.resolve(filename);
|
|
1727
1690
|
const segments = segmentsOf(componentFile, sourceRoot);
|
|
1728
1691
|
if (segments.length === 0) return {};
|
|
1729
1692
|
if (isUnderApp(segments) || isConfigModule(segments)) return {};
|
|
@@ -1757,7 +1720,7 @@ var componentPlacementRule = {
|
|
|
1757
1720
|
};
|
|
1758
1721
|
|
|
1759
1722
|
// eslint/rules/support-file-placement.ts
|
|
1760
|
-
import
|
|
1723
|
+
import path12 from "path";
|
|
1761
1724
|
var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
|
|
1762
1725
|
var REASON_TEXT2 = {
|
|
1763
1726
|
"config-module": "every file that imports it belongs to that configuration module",
|
|
@@ -1776,7 +1739,7 @@ var supportFilePlacementRule = {
|
|
|
1776
1739
|
},
|
|
1777
1740
|
create(context) {
|
|
1778
1741
|
const sourceRoot = sourceRootOf(context);
|
|
1779
|
-
const supportFile =
|
|
1742
|
+
const supportFile = path12.resolve(context.filename);
|
|
1780
1743
|
const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
|
|
1781
1744
|
const supportFolder = currentFolder[currentFolder.length - 1];
|
|
1782
1745
|
if (supportFolder === void 0 || !SUPPORT_FOLDERS2.has(supportFolder)) return {};
|
|
@@ -1801,7 +1764,7 @@ var supportFilePlacementRule = {
|
|
|
1801
1764
|
|
|
1802
1765
|
// eslint/rules/application-structure.ts
|
|
1803
1766
|
import fs3 from "fs";
|
|
1804
|
-
import
|
|
1767
|
+
import path13 from "path";
|
|
1805
1768
|
var MODULE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
1806
1769
|
var ROUTING_FILES = /* @__PURE__ */ new Set([
|
|
1807
1770
|
"default",
|
|
@@ -1839,7 +1802,7 @@ function report2(context, message) {
|
|
|
1839
1802
|
};
|
|
1840
1803
|
}
|
|
1841
1804
|
function isCodeFile(filename) {
|
|
1842
|
-
return MODULE_EXTENSIONS2.has(
|
|
1805
|
+
return MODULE_EXTENSIONS2.has(path13.extname(filename));
|
|
1843
1806
|
}
|
|
1844
1807
|
function isRootSupportFolder(folder) {
|
|
1845
1808
|
return SUPPORT_FOLDERS2.has(folder);
|
|
@@ -1860,7 +1823,7 @@ function expectedSupportFolder(kinds) {
|
|
|
1860
1823
|
function configModuleRoot(filename, sourceRoot) {
|
|
1861
1824
|
const segments = segmentsOf(filename, sourceRoot);
|
|
1862
1825
|
if (segments[0] !== "config" || segments.length < 3) return void 0;
|
|
1863
|
-
return
|
|
1826
|
+
return path13.join(sourceRoot, "config", segments[1] ?? "");
|
|
1864
1827
|
}
|
|
1865
1828
|
function componentFolderStart(segments) {
|
|
1866
1829
|
if (segments[0] === "features") return 2;
|
|
@@ -1873,12 +1836,12 @@ function componentFolderViolation(segments, sourceRoot) {
|
|
|
1873
1836
|
for (let depth = segments.length - 2; depth >= start; depth -= 1) {
|
|
1874
1837
|
const folder = segments[depth];
|
|
1875
1838
|
if (!folder || SUPPORT_FOLDERS2.has(folder)) continue;
|
|
1876
|
-
const folderPath =
|
|
1839
|
+
const folderPath = path13.join(sourceRoot, ...segments.slice(0, depth + 1));
|
|
1877
1840
|
const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
|
|
1878
|
-
if (!fs3.existsSync(
|
|
1841
|
+
if (!fs3.existsSync(path13.join(folderPath, `${folder}.tsx`))) {
|
|
1879
1842
|
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.`;
|
|
1880
1843
|
}
|
|
1881
|
-
if (!fs3.existsSync(
|
|
1844
|
+
if (!fs3.existsSync(path13.join(folderPath, "index.ts"))) {
|
|
1882
1845
|
return `A component folder must have an index.ts that named-re-exports its component; add index.ts to ${label}.`;
|
|
1883
1846
|
}
|
|
1884
1847
|
}
|
|
@@ -1893,7 +1856,7 @@ var applicationStructureRule = {
|
|
|
1893
1856
|
}
|
|
1894
1857
|
},
|
|
1895
1858
|
create(context) {
|
|
1896
|
-
const filename =
|
|
1859
|
+
const filename = path13.resolve(context.filename);
|
|
1897
1860
|
const sourceRoot = sourceRootOf(context);
|
|
1898
1861
|
const segments = segmentsOf(filename, sourceRoot);
|
|
1899
1862
|
if (segments.length === 0) return {};
|
|
@@ -1924,43 +1887,43 @@ var applicationStructureRule = {
|
|
|
1924
1887
|
);
|
|
1925
1888
|
}
|
|
1926
1889
|
const moduleRoot = configModuleRoot(filename, sourceRoot);
|
|
1927
|
-
if (moduleRoot && !fs3.existsSync(
|
|
1890
|
+
if (moduleRoot && !fs3.existsSync(path13.join(moduleRoot, "index.ts"))) {
|
|
1928
1891
|
return report2(
|
|
1929
1892
|
context,
|
|
1930
|
-
`Add src/config/${
|
|
1893
|
+
`Add src/config/${path13.basename(moduleRoot)}/index.ts as the configuration module entry point.`
|
|
1931
1894
|
);
|
|
1932
1895
|
}
|
|
1933
|
-
if (moduleRoot && segments.length === 3 &&
|
|
1896
|
+
if (moduleRoot && segments.length === 3 && path13.basename(filename) !== "index.ts") {
|
|
1934
1897
|
const kinds2 = exportedKinds(filename);
|
|
1935
1898
|
const expected2 = expectedSupportFolder(kinds2);
|
|
1936
1899
|
if (expected2 !== void 0) {
|
|
1937
1900
|
return report2(
|
|
1938
1901
|
context,
|
|
1939
|
-
`Move this configuration support file into src/config/${
|
|
1902
|
+
`Move this configuration support file into src/config/${path13.basename(moduleRoot)}/${expected2}/.`
|
|
1940
1903
|
);
|
|
1941
1904
|
}
|
|
1942
1905
|
}
|
|
1943
1906
|
}
|
|
1944
1907
|
if (topLevel === "app" && isCodeFile(filename)) {
|
|
1945
|
-
const basename =
|
|
1946
|
-
const currentFolder2 =
|
|
1908
|
+
const basename = path13.basename(filename, path13.extname(filename));
|
|
1909
|
+
const currentFolder2 = path13.basename(path13.dirname(filename));
|
|
1947
1910
|
if (SUPPORT_FOLDERS2.has(currentFolder2)) {
|
|
1948
1911
|
return report2(
|
|
1949
1912
|
context,
|
|
1950
1913
|
"src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
|
|
1951
1914
|
);
|
|
1952
1915
|
}
|
|
1953
|
-
if (!ROUTING_FILES.has(basename) &&
|
|
1916
|
+
if (!ROUTING_FILES.has(basename) && path13.extname(filename) !== ".css") {
|
|
1954
1917
|
return report2(
|
|
1955
1918
|
context,
|
|
1956
1919
|
"src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
|
|
1957
1920
|
);
|
|
1958
1921
|
}
|
|
1959
|
-
if (ROUTING_FILES.has(basename) ||
|
|
1922
|
+
if (ROUTING_FILES.has(basename) || path13.extname(filename) === ".css") return {};
|
|
1960
1923
|
}
|
|
1961
|
-
const currentFolder =
|
|
1924
|
+
const currentFolder = path13.basename(path13.dirname(filename));
|
|
1962
1925
|
const kinds = exportedKinds(filename);
|
|
1963
|
-
const isConfigModuleRoot = topLevel === "config" && segments.length === 3 &&
|
|
1926
|
+
const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path13.basename(filename) === "index.ts";
|
|
1964
1927
|
if (isConfigModuleRoot) return {};
|
|
1965
1928
|
if (!SUPPORT_FOLDERS2.has(currentFolder)) {
|
|
1966
1929
|
const expected2 = expectedSupportFolder(kinds);
|
|
@@ -1977,7 +1940,7 @@ var applicationStructureRule = {
|
|
|
1977
1940
|
if (kinds.has("component")) {
|
|
1978
1941
|
return report2(
|
|
1979
1942
|
context,
|
|
1980
|
-
`A support folder must not contain a component; move ${
|
|
1943
|
+
`A support folder must not contain a component; move ${path13.basename(filename)} beside ${currentFolder}/.`
|
|
1981
1944
|
);
|
|
1982
1945
|
}
|
|
1983
1946
|
const expected = expectedSupportFolder(kinds);
|
|
@@ -1994,7 +1957,7 @@ var applicationStructureRule = {
|
|
|
1994
1957
|
};
|
|
1995
1958
|
|
|
1996
1959
|
// eslint/rules/named-exports.ts
|
|
1997
|
-
import
|
|
1960
|
+
import path14 from "path";
|
|
1998
1961
|
var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
|
|
1999
1962
|
// App Router routing files
|
|
2000
1963
|
"default",
|
|
@@ -2016,9 +1979,9 @@ var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
|
|
|
2016
1979
|
"twitter-image"
|
|
2017
1980
|
]);
|
|
2018
1981
|
function isFrameworkDefaultExportFile(filename) {
|
|
2019
|
-
const normalized = filename.replaceAll(
|
|
1982
|
+
const normalized = filename.replaceAll(path14.sep, "/");
|
|
2020
1983
|
if (!normalized.includes("/src/app/")) return false;
|
|
2021
|
-
const basename =
|
|
1984
|
+
const basename = path14.basename(filename, path14.extname(filename));
|
|
2022
1985
|
return FRAMEWORK_DEFAULT_EXPORT_FILES.has(basename);
|
|
2023
1986
|
}
|
|
2024
1987
|
var namedExportsRule = {
|
|
@@ -2043,7 +2006,7 @@ var namedExportsRule = {
|
|
|
2043
2006
|
};
|
|
2044
2007
|
|
|
2045
2008
|
// eslint/rules/data-testid-case.ts
|
|
2046
|
-
import
|
|
2009
|
+
import path15 from "path";
|
|
2047
2010
|
var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
|
|
2048
2011
|
"default",
|
|
2049
2012
|
"error",
|
|
@@ -2076,9 +2039,9 @@ var dataTestIdCaseRule = {
|
|
|
2076
2039
|
}
|
|
2077
2040
|
},
|
|
2078
2041
|
create(context) {
|
|
2079
|
-
const filename =
|
|
2042
|
+
const filename = path15.resolve(context.filename);
|
|
2080
2043
|
if (!filename.endsWith(".tsx")) return {};
|
|
2081
|
-
const base =
|
|
2044
|
+
const base = path15.basename(filename, path15.extname(filename));
|
|
2082
2045
|
if (NEXT_ROUTING_FILES2.has(base)) return {};
|
|
2083
2046
|
const text = context.sourceCode.text;
|
|
2084
2047
|
const components = parseComponentInfo(text, filename);
|
|
@@ -2120,7 +2083,7 @@ function toKebabCase(value) {
|
|
|
2120
2083
|
|
|
2121
2084
|
// eslint/rules/support-folder-shape.ts
|
|
2122
2085
|
import fs4 from "fs";
|
|
2123
|
-
import
|
|
2086
|
+
import path16 from "path";
|
|
2124
2087
|
var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
|
|
2125
2088
|
var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
|
|
2126
2089
|
var supportFolderShapeRule = {
|
|
@@ -2132,12 +2095,12 @@ var supportFolderShapeRule = {
|
|
|
2132
2095
|
}
|
|
2133
2096
|
},
|
|
2134
2097
|
create(context) {
|
|
2135
|
-
const filename =
|
|
2136
|
-
const baseName =
|
|
2098
|
+
const filename = path16.resolve(context.filename);
|
|
2099
|
+
const baseName = path16.basename(filename);
|
|
2137
2100
|
if (!INDEX_NAMES.has(baseName)) return {};
|
|
2138
|
-
const folder =
|
|
2101
|
+
const folder = path16.basename(path16.dirname(filename));
|
|
2139
2102
|
if (!SUPPORT_FOLDERS3.has(folder)) return {};
|
|
2140
|
-
const directory =
|
|
2103
|
+
const directory = path16.dirname(filename);
|
|
2141
2104
|
let entries;
|
|
2142
2105
|
try {
|
|
2143
2106
|
entries = fs4.readdirSync(directory);
|
|
@@ -2154,7 +2117,7 @@ var supportFolderShapeRule = {
|
|
|
2154
2117
|
const exportPattern = /export\s+(?:\{[^}]*\}|\*[^;]*)\s+from\s+["'](?<specifier>\.[^"']+)["']/g;
|
|
2155
2118
|
for (const match of source.matchAll(exportPattern)) {
|
|
2156
2119
|
const specifier = match.groups?.specifier;
|
|
2157
|
-
if (specifier) exportedFiles.add(
|
|
2120
|
+
if (specifier) exportedFiles.add(path16.basename(specifier));
|
|
2158
2121
|
}
|
|
2159
2122
|
const hasAnyReExport = exportedFiles.size > 0;
|
|
2160
2123
|
const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
|
|
@@ -2181,7 +2144,7 @@ var supportFolderShapeRule = {
|
|
|
2181
2144
|
};
|
|
2182
2145
|
|
|
2183
2146
|
// eslint/rules/constant-casing.ts
|
|
2184
|
-
import
|
|
2147
|
+
import path17 from "path";
|
|
2185
2148
|
var NEXTJS_ROUTE_HANDLER_NAMES = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
2186
2149
|
function isScreamingSnakeCase(name) {
|
|
2187
2150
|
return /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/.test(name);
|
|
@@ -2195,9 +2158,9 @@ var constantCasingRule = {
|
|
|
2195
2158
|
}
|
|
2196
2159
|
},
|
|
2197
2160
|
create(context) {
|
|
2198
|
-
const filename =
|
|
2161
|
+
const filename = path17.resolve(context.filename);
|
|
2199
2162
|
const sourceRoot = sourceRootOf(context);
|
|
2200
|
-
if (!filename.startsWith(sourceRoot +
|
|
2163
|
+
if (!filename.startsWith(sourceRoot + path17.sep)) return {};
|
|
2201
2164
|
return {
|
|
2202
2165
|
VariableDeclarator(node) {
|
|
2203
2166
|
if (node.id.type !== "Identifier") return;
|
|
@@ -2219,7 +2182,7 @@ var constantCasingRule = {
|
|
|
2219
2182
|
};
|
|
2220
2183
|
|
|
2221
2184
|
// eslint/rules/prefer-enum.ts
|
|
2222
|
-
import
|
|
2185
|
+
import path18 from "path";
|
|
2223
2186
|
function isConstAssertion(node) {
|
|
2224
2187
|
const typeAnnotation = node.typeAnnotation;
|
|
2225
2188
|
return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
|
|
@@ -2238,9 +2201,9 @@ var preferEnumRule = {
|
|
|
2238
2201
|
}
|
|
2239
2202
|
},
|
|
2240
2203
|
create(context) {
|
|
2241
|
-
const filename =
|
|
2204
|
+
const filename = path18.resolve(context.filename);
|
|
2242
2205
|
const sourceRoot = sourceRootOf(context);
|
|
2243
|
-
if (!filename.startsWith(sourceRoot +
|
|
2206
|
+
if (!filename.startsWith(sourceRoot + path18.sep)) return {};
|
|
2244
2207
|
return {
|
|
2245
2208
|
TSAsExpression(node) {
|
|
2246
2209
|
if (!isConstAssertion(node)) return;
|
|
@@ -2258,7 +2221,7 @@ var preferEnumRule = {
|
|
|
2258
2221
|
};
|
|
2259
2222
|
|
|
2260
2223
|
// eslint/rules/import-through-index.ts
|
|
2261
|
-
import
|
|
2224
|
+
import path19 from "path";
|
|
2262
2225
|
var importThroughIndexRule = {
|
|
2263
2226
|
meta: {
|
|
2264
2227
|
schema: [],
|
|
@@ -2268,7 +2231,7 @@ var importThroughIndexRule = {
|
|
|
2268
2231
|
}
|
|
2269
2232
|
},
|
|
2270
2233
|
create(context) {
|
|
2271
|
-
const filename =
|
|
2234
|
+
const filename = path19.resolve(context.filename);
|
|
2272
2235
|
const sourceRoot = sourceRootOf2(context, filename);
|
|
2273
2236
|
return {
|
|
2274
2237
|
Program(node) {
|
|
@@ -2280,7 +2243,7 @@ var importThroughIndexRule = {
|
|
|
2280
2243
|
(segment) => ["constants", "types", "schemas"].includes(segment)
|
|
2281
2244
|
);
|
|
2282
2245
|
const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
|
|
2283
|
-
if (!supportFolder ||
|
|
2246
|
+
if (!supportFolder || path19.basename(target).startsWith("index.")) continue;
|
|
2284
2247
|
const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
|
|
2285
2248
|
const expected = `@/${folderIndex.join("/")}`;
|
|
2286
2249
|
context.report({
|
|
@@ -2302,14 +2265,14 @@ function importSpecifiers(source) {
|
|
|
2302
2265
|
return specifiers;
|
|
2303
2266
|
}
|
|
2304
2267
|
function sourceRootOf2(context, filename) {
|
|
2305
|
-
const marker = `${
|
|
2268
|
+
const marker = `${path19.sep}src${path19.sep}`;
|
|
2306
2269
|
const srcIndex = filename.lastIndexOf(marker);
|
|
2307
2270
|
if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
|
|
2308
|
-
return
|
|
2271
|
+
return path19.resolve(context.cwd ?? process.cwd(), "src");
|
|
2309
2272
|
}
|
|
2310
2273
|
|
|
2311
2274
|
// eslint/rules/util-file-name.ts
|
|
2312
|
-
import
|
|
2275
|
+
import path20 from "path";
|
|
2313
2276
|
function toKebabCase2(value) {
|
|
2314
2277
|
return value.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower>-$<upper>").replace(/(?<first>[A-Z])(?<rest>[A-Z][a-z])/g, "$<first>-$<rest>").toLowerCase();
|
|
2315
2278
|
}
|
|
@@ -2322,7 +2285,7 @@ var utilFileNameRule = {
|
|
|
2322
2285
|
}
|
|
2323
2286
|
},
|
|
2324
2287
|
create(context) {
|
|
2325
|
-
const filename =
|
|
2288
|
+
const filename = path20.resolve(context.filename);
|
|
2326
2289
|
const segments = filename.replace(/\\/g, "/").split("/");
|
|
2327
2290
|
if (!segments.includes("utils")) return {};
|
|
2328
2291
|
let module;
|
|
@@ -2336,13 +2299,13 @@ var utilFileNameRule = {
|
|
|
2336
2299
|
const functionName = functions[0]?.name;
|
|
2337
2300
|
if (!functionName) return {};
|
|
2338
2301
|
const expected = toKebabCase2(functionName);
|
|
2339
|
-
const actual =
|
|
2302
|
+
const actual = path20.basename(filename, path20.extname(filename));
|
|
2340
2303
|
if (!expected || actual === expected) return {};
|
|
2341
2304
|
return {
|
|
2342
2305
|
Program(node) {
|
|
2343
2306
|
context.report({
|
|
2344
2307
|
node,
|
|
2345
|
-
message: `A utility file exporting ${functionName} must be named ${expected}.${
|
|
2308
|
+
message: `A utility file exporting ${functionName} must be named ${expected}.${path20.extname(filename).slice(1)}.`
|
|
2346
2309
|
});
|
|
2347
2310
|
}
|
|
2348
2311
|
};
|
|
@@ -2350,7 +2313,7 @@ var utilFileNameRule = {
|
|
|
2350
2313
|
};
|
|
2351
2314
|
|
|
2352
2315
|
// eslint/rules/no-util-barrel.ts
|
|
2353
|
-
import
|
|
2316
|
+
import path21 from "path";
|
|
2354
2317
|
var noUtilBarrelRule = {
|
|
2355
2318
|
meta: {
|
|
2356
2319
|
schema: [],
|
|
@@ -2360,7 +2323,7 @@ var noUtilBarrelRule = {
|
|
|
2360
2323
|
}
|
|
2361
2324
|
},
|
|
2362
2325
|
create(context) {
|
|
2363
|
-
const filename =
|
|
2326
|
+
const filename = path21.resolve(context.filename);
|
|
2364
2327
|
const sourceRoot = sourceRootOf3(context, filename);
|
|
2365
2328
|
return {
|
|
2366
2329
|
Program(node) {
|
|
@@ -2369,7 +2332,7 @@ var noUtilBarrelRule = {
|
|
|
2369
2332
|
if (!target) continue;
|
|
2370
2333
|
const segments = target.replace(/\\/g, "/").split("/");
|
|
2371
2334
|
const utilsIndex = segments.lastIndexOf("utils");
|
|
2372
|
-
if (utilsIndex < 0 || !
|
|
2335
|
+
if (utilsIndex < 0 || !path21.basename(target).startsWith("index.")) continue;
|
|
2373
2336
|
context.report({
|
|
2374
2337
|
node,
|
|
2375
2338
|
message: `Import utilities directly instead of through "${specifier}". See docs/next-codebase-guide/rules/utilities-rule.md`
|
|
@@ -2389,10 +2352,10 @@ function importSpecifiers2(source) {
|
|
|
2389
2352
|
return specifiers;
|
|
2390
2353
|
}
|
|
2391
2354
|
function sourceRootOf3(context, filename) {
|
|
2392
|
-
const marker = `${
|
|
2355
|
+
const marker = `${path21.sep}src${path21.sep}`;
|
|
2393
2356
|
const srcIndex = filename.lastIndexOf(marker);
|
|
2394
2357
|
if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
|
|
2395
|
-
return
|
|
2358
|
+
return path21.resolve(context.cwd ?? process.cwd(), "src");
|
|
2396
2359
|
}
|
|
2397
2360
|
|
|
2398
2361
|
// eslint/rules/jsx-hygiene.ts
|
|
@@ -2485,7 +2448,7 @@ var jsxHygieneRule = {
|
|
|
2485
2448
|
};
|
|
2486
2449
|
|
|
2487
2450
|
// eslint/rules/interactive-component.ts
|
|
2488
|
-
import
|
|
2451
|
+
import path22 from "path";
|
|
2489
2452
|
var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
2490
2453
|
"a",
|
|
2491
2454
|
"button",
|
|
@@ -2640,8 +2603,8 @@ var interactiveComponentRule = {
|
|
|
2640
2603
|
},
|
|
2641
2604
|
create(context) {
|
|
2642
2605
|
if (!context.filename.endsWith(".tsx") && !context.filename.endsWith(".jsx")) return {};
|
|
2643
|
-
const filename =
|
|
2644
|
-
const base =
|
|
2606
|
+
const filename = path22.resolve(context.filename);
|
|
2607
|
+
const base = path22.basename(filename, path22.extname(filename));
|
|
2645
2608
|
if (NEXT_ROUTING_FILES3.has(base)) return {};
|
|
2646
2609
|
return {
|
|
2647
2610
|
JSXElement(node) {
|
|
@@ -2892,12 +2855,12 @@ var cvaBooleanVariantsRule = {
|
|
|
2892
2855
|
};
|
|
2893
2856
|
|
|
2894
2857
|
// eslint/rules/cross-feature-import.ts
|
|
2895
|
-
import
|
|
2858
|
+
import path23 from "path";
|
|
2896
2859
|
var FEATURES_SEGMENT = "features";
|
|
2897
2860
|
function featureNameOf(resolvedPath, sourceRoot) {
|
|
2898
|
-
const relative =
|
|
2861
|
+
const relative = path23.relative(sourceRoot, resolvedPath);
|
|
2899
2862
|
if (relative.startsWith("..")) return void 0;
|
|
2900
|
-
const segments = relative.split(
|
|
2863
|
+
const segments = relative.split(path23.sep);
|
|
2901
2864
|
if (segments[0] !== FEATURES_SEGMENT || segments.length < 2) return void 0;
|
|
2902
2865
|
return segments[1];
|
|
2903
2866
|
}
|
|
@@ -2913,9 +2876,9 @@ var crossFeatureImportRule = {
|
|
|
2913
2876
|
const filename = context.filename;
|
|
2914
2877
|
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
|
|
2915
2878
|
const sourceRoot = sourceRootOf(context);
|
|
2916
|
-
const fileRelative =
|
|
2879
|
+
const fileRelative = path23.relative(sourceRoot, filename);
|
|
2917
2880
|
if (fileRelative.startsWith("..")) return {};
|
|
2918
|
-
const fileSegments = fileRelative.split(
|
|
2881
|
+
const fileSegments = fileRelative.split(path23.sep);
|
|
2919
2882
|
const isInCompositions = fileSegments[0] === "compositions";
|
|
2920
2883
|
const isInApp = fileSegments[0] === "app";
|
|
2921
2884
|
const isConfig = fileSegments[0] === "config";
|
|
@@ -2929,9 +2892,9 @@ var crossFeatureImportRule = {
|
|
|
2929
2892
|
if (typeof source.value !== "string") return;
|
|
2930
2893
|
let resolved;
|
|
2931
2894
|
if (source.value.startsWith("@/")) {
|
|
2932
|
-
resolved =
|
|
2895
|
+
resolved = path23.resolve(sourceRoot, source.value.slice(2));
|
|
2933
2896
|
} else if (source.value.startsWith(".")) {
|
|
2934
|
-
resolved =
|
|
2897
|
+
resolved = path23.resolve(path23.dirname(filename), source.value);
|
|
2935
2898
|
}
|
|
2936
2899
|
if (!resolved) return;
|
|
2937
2900
|
const feature = featureNameOf(resolved, sourceRoot);
|
|
@@ -2950,7 +2913,7 @@ var crossFeatureImportRule = {
|
|
|
2950
2913
|
};
|
|
2951
2914
|
|
|
2952
2915
|
// eslint/rules/pure-function-extract.ts
|
|
2953
|
-
import
|
|
2916
|
+
import path24 from "path";
|
|
2954
2917
|
var ROUTE_HANDLER_EXPORT_NAMES = /* @__PURE__ */ new Set([
|
|
2955
2918
|
"GET",
|
|
2956
2919
|
"POST",
|
|
@@ -2994,12 +2957,12 @@ var pureFunctionExtractRule = {
|
|
|
2994
2957
|
},
|
|
2995
2958
|
create(context) {
|
|
2996
2959
|
const filename = context.filename;
|
|
2997
|
-
const isRouteFile =
|
|
2960
|
+
const isRouteFile = path24.basename(filename) === "route.ts";
|
|
2998
2961
|
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx") && !isRouteFile) return {};
|
|
2999
2962
|
const sourceRoot = sourceRootOf(context);
|
|
3000
|
-
const relative =
|
|
2963
|
+
const relative = path24.relative(sourceRoot, filename);
|
|
3001
2964
|
if (relative.startsWith("..")) return {};
|
|
3002
|
-
const segments = relative.split(
|
|
2965
|
+
const segments = relative.split(path24.sep);
|
|
3003
2966
|
if (segments[0] === "utils") return {};
|
|
3004
2967
|
if (segments[0] === "app" && !isRouteFile) return {};
|
|
3005
2968
|
const supportFolders = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
|
|
@@ -3046,7 +3009,7 @@ var pureFunctionExtractRule = {
|
|
|
3046
3009
|
};
|
|
3047
3010
|
|
|
3048
3011
|
// eslint/rules/root-support-placement.ts
|
|
3049
|
-
import
|
|
3012
|
+
import path25 from "path";
|
|
3050
3013
|
function isSupportFolder(value) {
|
|
3051
3014
|
return value === "utils" || value === "types" || value === "schemas" || value === "constants";
|
|
3052
3015
|
}
|
|
@@ -3079,7 +3042,7 @@ var rootSupportPlacementRule = {
|
|
|
3079
3042
|
},
|
|
3080
3043
|
create(context) {
|
|
3081
3044
|
const sourceRoot = sourceRootOf(context);
|
|
3082
|
-
const file =
|
|
3045
|
+
const file = path25.resolve(context.filename);
|
|
3083
3046
|
const segments = segmentsOf(file, sourceRoot);
|
|
3084
3047
|
const folderSegments = folderSegmentsOf(file, sourceRoot);
|
|
3085
3048
|
const supportFolder = folderSegments[folderSegments.length - 1];
|
|
@@ -3119,7 +3082,7 @@ var rootSupportPlacementRule = {
|
|
|
3119
3082
|
};
|
|
3120
3083
|
|
|
3121
3084
|
// eslint/rules/route-handler-shape.ts
|
|
3122
|
-
import
|
|
3085
|
+
import path26 from "path";
|
|
3123
3086
|
import ts4 from "typescript";
|
|
3124
3087
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
3125
3088
|
var REQUIRED_BOUNDARY = "withResponse";
|
|
@@ -3196,11 +3159,11 @@ var routeHandlerShapeRule = {
|
|
|
3196
3159
|
schema: [],
|
|
3197
3160
|
type: "problem",
|
|
3198
3161
|
docs: {
|
|
3199
|
-
description: "Require a route.ts handler to be wrapped in withResponse, with no try, loop, or if of its own, and every function it calls imported rather than declared in route.ts."
|
|
3162
|
+
description: "Require a route.ts handler to be wrapped in withResponse, written there as a function, with no try, loop, or if of its own, and every function it calls imported rather than declared in route.ts."
|
|
3200
3163
|
}
|
|
3201
3164
|
},
|
|
3202
3165
|
create(context) {
|
|
3203
|
-
if (
|
|
3166
|
+
if (path26.basename(context.filename) !== "route.ts") return {};
|
|
3204
3167
|
const sourceText = context.sourceCode.text;
|
|
3205
3168
|
function reportUnwrapped(node, name) {
|
|
3206
3169
|
context.report({
|
|
@@ -3216,7 +3179,13 @@ var routeHandlerShapeRule = {
|
|
|
3216
3179
|
return;
|
|
3217
3180
|
}
|
|
3218
3181
|
const handler = findHandler(init);
|
|
3219
|
-
if (!handler?.body)
|
|
3182
|
+
if (!handler?.body) {
|
|
3183
|
+
context.report({
|
|
3184
|
+
node,
|
|
3185
|
+
message: `Handler "${name}" must be written as a function inside withResponse, not passed as a reference. See docs/next-codebase-guide/rules/route-handler-rule.md`
|
|
3186
|
+
});
|
|
3187
|
+
return;
|
|
3188
|
+
}
|
|
3220
3189
|
const { kinds, calledNames } = analyzeHandlerBody(handler.body, sourceText);
|
|
3221
3190
|
for (const kind of kinds) {
|
|
3222
3191
|
context.report({
|
|
@@ -3254,7 +3223,7 @@ var routeHandlerShapeRule = {
|
|
|
3254
3223
|
|
|
3255
3224
|
// eslint/rules/http-error-usage.ts
|
|
3256
3225
|
import { readFileSync as readFileSync4 } from "fs";
|
|
3257
|
-
import
|
|
3226
|
+
import path27 from "path";
|
|
3258
3227
|
import ts5 from "typescript";
|
|
3259
3228
|
var HTTP_ERROR = "HttpError";
|
|
3260
3229
|
var ROUTE_FILE = "route.ts";
|
|
@@ -3298,13 +3267,13 @@ function parentClassOf(file, name) {
|
|
|
3298
3267
|
return void 0;
|
|
3299
3268
|
}
|
|
3300
3269
|
function importedFrom(file, name, sourceRoot, index) {
|
|
3301
|
-
const module = index.modules.get(
|
|
3270
|
+
const module = index.modules.get(path27.resolve(file));
|
|
3302
3271
|
const moduleImport = module?.imports.find((entry) => entry.names.includes(name));
|
|
3303
3272
|
if (!moduleImport) return void 0;
|
|
3304
3273
|
return resolveSpecifier(file, moduleImport.specifier, sourceRoot);
|
|
3305
3274
|
}
|
|
3306
3275
|
function isHttpErrorClass(file, name, sourceRoot, index) {
|
|
3307
|
-
let currentFile =
|
|
3276
|
+
let currentFile = path27.resolve(file);
|
|
3308
3277
|
let currentName = name;
|
|
3309
3278
|
for (let depth = 0; depth <= HERITAGE_DEPTH; depth += 1) {
|
|
3310
3279
|
if (currentName === HTTP_ERROR) return true;
|
|
@@ -3325,7 +3294,7 @@ function pipelineFiles(sourceRoot) {
|
|
|
3325
3294
|
if (!index) return void 0;
|
|
3326
3295
|
if (pipelineCache?.index === index) return pipelineCache.files;
|
|
3327
3296
|
const files = /* @__PURE__ */ new Set();
|
|
3328
|
-
const queue = [...index.modules.keys()].filter((file) =>
|
|
3297
|
+
const queue = [...index.modules.keys()].filter((file) => path27.basename(file) === ROUTE_FILE);
|
|
3329
3298
|
while (queue.length > 0) {
|
|
3330
3299
|
const file = queue.pop();
|
|
3331
3300
|
if (file === void 0 || files.has(file)) continue;
|
|
@@ -3348,7 +3317,7 @@ var httpErrorUsageRule = {
|
|
|
3348
3317
|
},
|
|
3349
3318
|
create(context) {
|
|
3350
3319
|
const sourceRoot = sourceRootOf(context);
|
|
3351
|
-
const file =
|
|
3320
|
+
const file = path27.resolve(context.filename);
|
|
3352
3321
|
let delegated;
|
|
3353
3322
|
function inPipeline() {
|
|
3354
3323
|
delegated ??= pipelineFiles(sourceRoot)?.has(file) ?? false;
|
|
@@ -3382,171 +3351,98 @@ var httpErrorUsageRule = {
|
|
|
3382
3351
|
};
|
|
3383
3352
|
|
|
3384
3353
|
// eslint/rules/with-response-helper.ts
|
|
3385
|
-
import path29 from "path";
|
|
3386
|
-
import ts6 from "typescript";
|
|
3387
3354
|
var HELPER2 = "withResponse";
|
|
3355
|
+
var ENTRY2 = "pasika/with-response";
|
|
3388
3356
|
var DOC3 = "docs/pasika-adoption-guide/rules/with-response-helper-rule.md";
|
|
3389
|
-
var
|
|
3390
|
-
var
|
|
3391
|
-
"awaitsHandler",
|
|
3392
|
-
"validatesWithSchema",
|
|
3393
|
-
"checksHttpError",
|
|
3394
|
-
"answersWithNullData",
|
|
3395
|
-
"usesErrorStatus",
|
|
3396
|
-
"rethrows"
|
|
3397
|
-
];
|
|
3398
|
-
var BEAT_MESSAGES = {
|
|
3399
|
-
awaitsHandler: "must await the handler",
|
|
3400
|
-
validatesWithSchema: "must validate the handler's returned data through the response schema",
|
|
3401
|
-
checksHttpError: "must check the caught error with instanceof HttpError",
|
|
3402
|
-
answersWithNullData: "must answer a thrown HttpError with { data: null, message }",
|
|
3403
|
-
usesErrorStatus: "must answer at the caught error's status",
|
|
3404
|
-
rethrows: "must rethrow a caught error that is not an HttpError"
|
|
3405
|
-
};
|
|
3357
|
+
var DECLARED2 = `A repository must not declare its own ${HELPER2}; import it from ${ENTRY2}. See ${DOC3}`;
|
|
3358
|
+
var IMPORTED2 = `${HELPER2} must be imported from ${ENTRY2}. See ${DOC3}`;
|
|
3406
3359
|
function isNamed2(node, name) {
|
|
3407
3360
|
return node?.type === "Identifier" && node.name === name;
|
|
3408
3361
|
}
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
for (const parsed of index.modules.values()) {
|
|
3416
|
-
if (parsed.exports.some((exported) => exported.name === name)) return true;
|
|
3417
|
-
}
|
|
3418
|
-
return false;
|
|
3419
|
-
}
|
|
3420
|
-
function contains(node, check) {
|
|
3421
|
-
let found = false;
|
|
3422
|
-
const visit = (current) => {
|
|
3423
|
-
if (found) return;
|
|
3424
|
-
if (check(current)) {
|
|
3425
|
-
found = true;
|
|
3426
|
-
return;
|
|
3427
|
-
}
|
|
3428
|
-
ts6.forEachChild(current, visit);
|
|
3429
|
-
};
|
|
3430
|
-
visit(node);
|
|
3431
|
-
return found;
|
|
3432
|
-
}
|
|
3433
|
-
function findTryStatement(node) {
|
|
3434
|
-
let found;
|
|
3435
|
-
const visit = (current) => {
|
|
3436
|
-
if (found) return;
|
|
3437
|
-
if (ts6.isTryStatement(current)) {
|
|
3438
|
-
found = current;
|
|
3439
|
-
return;
|
|
3362
|
+
var withResponseHelperRule = {
|
|
3363
|
+
meta: {
|
|
3364
|
+
schema: [],
|
|
3365
|
+
type: "problem",
|
|
3366
|
+
docs: {
|
|
3367
|
+
description: `Require ${HELPER2} to be imported from ${ENTRY2} rather than declared in the repository.`
|
|
3440
3368
|
}
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
}
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3369
|
+
},
|
|
3370
|
+
create(context) {
|
|
3371
|
+
const checkSource = (node) => {
|
|
3372
|
+
if (!node.source || node.source.value === ENTRY2) return;
|
|
3373
|
+
for (const specifier of node.specifiers) {
|
|
3374
|
+
if (!isNamed2(specifier.local, HELPER2)) continue;
|
|
3375
|
+
context.report({ node: specifier, message: IMPORTED2 });
|
|
3376
|
+
}
|
|
3377
|
+
};
|
|
3378
|
+
return {
|
|
3379
|
+
FunctionDeclaration(node) {
|
|
3380
|
+
if (isNamed2(node.id, HELPER2)) context.report({ node, message: DECLARED2 });
|
|
3381
|
+
},
|
|
3382
|
+
VariableDeclarator(node) {
|
|
3383
|
+
if (isNamed2(node.id.type === "Identifier" ? node.id : null, HELPER2)) {
|
|
3384
|
+
context.report({ node, message: DECLARED2 });
|
|
3385
|
+
}
|
|
3386
|
+
},
|
|
3387
|
+
ImportDeclaration: checkSource,
|
|
3388
|
+
ExportNamedDeclaration: checkSource
|
|
3389
|
+
};
|
|
3458
3390
|
}
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3391
|
+
};
|
|
3392
|
+
|
|
3393
|
+
// eslint/rules/zod-fetch-helper.ts
|
|
3394
|
+
var HELPER3 = "zodFetch";
|
|
3395
|
+
var ENTRY3 = "pasika/zod-fetch";
|
|
3396
|
+
var DOC4 = "docs/pasika-adoption-guide/rules/zod-fetch-helper-rule.md";
|
|
3397
|
+
var FETCHED = `fetch must not be called; make the request through ${HELPER3} from ${ENTRY3}. See ${DOC4}`;
|
|
3398
|
+
var DECLARED3 = `A file must not declare its own ${HELPER3}; import it from ${ENTRY3}. See ${DOC4}`;
|
|
3399
|
+
var IMPORTED3 = `${HELPER3} must be imported from ${ENTRY3}. See ${DOC4}`;
|
|
3400
|
+
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
|
|
3401
|
+
function isNamed3(node, name) {
|
|
3402
|
+
return node?.type === "Identifier" && node.name === name;
|
|
3467
3403
|
}
|
|
3468
|
-
function
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
function collectBeats(text, schemaName, handlerName) {
|
|
3472
|
-
const beats = {
|
|
3473
|
-
awaitsHandler: false,
|
|
3474
|
-
validatesWithSchema: false,
|
|
3475
|
-
checksHttpError: false,
|
|
3476
|
-
answersWithNullData: false,
|
|
3477
|
-
usesErrorStatus: false,
|
|
3478
|
-
rethrows: false
|
|
3479
|
-
};
|
|
3480
|
-
const sourceFile = ts6.createSourceFile("with-response.ts", text, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TS);
|
|
3481
|
-
const tryStatement = findTryStatement(sourceFile);
|
|
3482
|
-
if (!tryStatement) return beats;
|
|
3483
|
-
beats.awaitsHandler = contains(tryStatement.tryBlock, awaitsHandlerCall(handlerName));
|
|
3484
|
-
beats.validatesWithSchema = contains(tryStatement.tryBlock, parsesThroughSchema(schemaName));
|
|
3485
|
-
const catchClause = tryStatement.catchClause;
|
|
3486
|
-
if (!catchClause) return beats;
|
|
3487
|
-
const errorName = catchClause.variableDeclaration?.name;
|
|
3488
|
-
const caughtName = errorName && ts6.isIdentifier(errorName) ? errorName.text : void 0;
|
|
3489
|
-
beats.checksHttpError = contains(catchClause.block, checksHttpError);
|
|
3490
|
-
beats.answersWithNullData = contains(catchClause.block, answersWithNullData);
|
|
3491
|
-
beats.usesErrorStatus = contains(catchClause.block, readsErrorStatus(caughtName));
|
|
3492
|
-
beats.rethrows = contains(catchClause.block, ts6.isThrowStatement);
|
|
3493
|
-
return beats;
|
|
3494
|
-
}
|
|
3495
|
-
function parameterNames(node) {
|
|
3496
|
-
if (node.type !== "FunctionDeclaration" && node.type !== "FunctionExpression" && node.type !== "ArrowFunctionExpression") {
|
|
3497
|
-
return [];
|
|
3498
|
-
}
|
|
3499
|
-
return node.params.map((parameter) => parameter.type === "Identifier" ? parameter.name : void 0);
|
|
3404
|
+
function callsFetch(callee) {
|
|
3405
|
+
if (isNamed3(callee, "fetch")) return true;
|
|
3406
|
+
return callee.type === "MemberExpression" && !callee.computed && isNamed3(callee.property, "fetch") && callee.object.type === "Identifier" && GLOBAL_OBJECTS.has(callee.object.name);
|
|
3500
3407
|
}
|
|
3501
|
-
var
|
|
3408
|
+
var zodFetchHelperRule = {
|
|
3502
3409
|
meta: {
|
|
3503
3410
|
schema: [],
|
|
3504
3411
|
type: "problem",
|
|
3505
3412
|
docs: {
|
|
3506
|
-
description: `Require
|
|
3413
|
+
description: `Require every request to go through the ${HELPER3} imported from ${ENTRY3}, the only caller of fetch.`
|
|
3507
3414
|
}
|
|
3508
3415
|
},
|
|
3509
3416
|
create(context) {
|
|
3510
|
-
|
|
3511
|
-
return
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
node: context.sourceCode.ast,
|
|
3516
|
-
loc: { line: 1, column: 0 },
|
|
3517
|
-
message: `A repository must define a ${HELPER2} helper. See ${DOC3}`
|
|
3518
|
-
});
|
|
3519
|
-
}
|
|
3520
|
-
};
|
|
3521
|
-
}
|
|
3522
|
-
const check = (node, parameters) => {
|
|
3523
|
-
const [start, end] = node.range ?? [0, context.sourceCode.text.length];
|
|
3524
|
-
const beats = collectBeats(context.sourceCode.text.slice(start, end), parameters[0], parameters[1]);
|
|
3525
|
-
for (const beat of BEAT_KEYS) {
|
|
3526
|
-
if (beats[beat]) continue;
|
|
3527
|
-
context.report({
|
|
3528
|
-
node,
|
|
3529
|
-
message: `${HELPER2} ${BEAT_MESSAGES[beat]}. See ${DOC3}`
|
|
3530
|
-
});
|
|
3417
|
+
const checkSource = (node) => {
|
|
3418
|
+
if (!node.source || node.source.value === ENTRY3) return;
|
|
3419
|
+
for (const specifier of node.specifiers) {
|
|
3420
|
+
if (!isNamed3(specifier.local, HELPER3)) continue;
|
|
3421
|
+
context.report({ node: specifier, message: IMPORTED3 });
|
|
3531
3422
|
}
|
|
3532
3423
|
};
|
|
3533
3424
|
return {
|
|
3425
|
+
CallExpression(node) {
|
|
3426
|
+
if (!callsFetch(node.callee)) return;
|
|
3427
|
+
context.report({ node, message: FETCHED });
|
|
3428
|
+
},
|
|
3534
3429
|
FunctionDeclaration(node) {
|
|
3535
|
-
if (
|
|
3430
|
+
if (isNamed3(node.id, HELPER3)) context.report({ node, message: DECLARED3 });
|
|
3536
3431
|
},
|
|
3537
3432
|
VariableDeclarator(node) {
|
|
3538
|
-
if (
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3433
|
+
if (isNamed3(node.id.type === "Identifier" ? node.id : null, HELPER3)) {
|
|
3434
|
+
context.report({ node, message: DECLARED3 });
|
|
3435
|
+
}
|
|
3436
|
+
},
|
|
3437
|
+
ImportDeclaration: checkSource,
|
|
3438
|
+
ExportNamedDeclaration: checkSource
|
|
3543
3439
|
};
|
|
3544
3440
|
}
|
|
3545
3441
|
};
|
|
3546
3442
|
|
|
3547
3443
|
// eslint/rules/hook-complexity.ts
|
|
3548
|
-
import
|
|
3549
|
-
import
|
|
3444
|
+
import path28 from "path";
|
|
3445
|
+
import ts6 from "typescript";
|
|
3550
3446
|
var REACT_HOOKS = /* @__PURE__ */ new Set([
|
|
3551
3447
|
"useState",
|
|
3552
3448
|
"useEffect",
|
|
@@ -3574,26 +3470,26 @@ function isHookName3(name) {
|
|
|
3574
3470
|
return /^use[A-Z]/.test(name);
|
|
3575
3471
|
}
|
|
3576
3472
|
function calledMethodName(node) {
|
|
3577
|
-
return
|
|
3473
|
+
return ts6.isPropertyAccessExpression(node.expression) ? node.expression.name.text : void 0;
|
|
3578
3474
|
}
|
|
3579
3475
|
function calledOnObjectName(node) {
|
|
3580
|
-
if (!
|
|
3476
|
+
if (!ts6.isPropertyAccessExpression(node.expression)) return void 0;
|
|
3581
3477
|
const object = node.expression.expression;
|
|
3582
|
-
return
|
|
3478
|
+
return ts6.isIdentifier(object) ? object.text : void 0;
|
|
3583
3479
|
}
|
|
3584
3480
|
function calledHookName(node) {
|
|
3585
|
-
return
|
|
3481
|
+
return ts6.isCallExpression(node) && ts6.isIdentifier(node.expression) && REACT_HOOKS.has(node.expression.text) ? node.expression.text : void 0;
|
|
3586
3482
|
}
|
|
3587
3483
|
function sideEffectCategoryOf(node) {
|
|
3588
|
-
if (
|
|
3589
|
-
if (
|
|
3484
|
+
if (ts6.isAwaitExpression(node)) return "externalIO";
|
|
3485
|
+
if (ts6.isNewExpression(node) && ts6.isIdentifier(node.expression) && DOM_CONSTRUCTORS.has(node.expression.text)) {
|
|
3590
3486
|
return "domManipulation";
|
|
3591
3487
|
}
|
|
3592
|
-
if (
|
|
3488
|
+
if (ts6.isPropertyAccessExpression(node) && DOM_PROPERTIES.has(node.name.text)) {
|
|
3593
3489
|
return "domManipulation";
|
|
3594
3490
|
}
|
|
3595
|
-
if (
|
|
3596
|
-
if (
|
|
3491
|
+
if (ts6.isCallExpression(node)) {
|
|
3492
|
+
if (ts6.isIdentifier(node.expression) && node.expression.text === "fetch") return "externalIO";
|
|
3597
3493
|
const method = calledMethodName(node);
|
|
3598
3494
|
if (method && SUBSCRIPTION_METHODS.has(method)) return "subscription";
|
|
3599
3495
|
if (method && LIFECYCLE_METHODS.has(method)) return "lifecycle";
|
|
@@ -3606,12 +3502,12 @@ function sideEffectCategoryOf(node) {
|
|
|
3606
3502
|
function computeExtractionScore(body, sourceText) {
|
|
3607
3503
|
const start = body.range?.[0] ?? 0;
|
|
3608
3504
|
const end = body.range?.[1] ?? sourceText.length;
|
|
3609
|
-
const sourceFile =
|
|
3505
|
+
const sourceFile = ts6.createSourceFile(
|
|
3610
3506
|
"hook.ts",
|
|
3611
3507
|
sourceText.slice(start, end),
|
|
3612
|
-
|
|
3508
|
+
ts6.ScriptTarget.Latest,
|
|
3613
3509
|
true,
|
|
3614
|
-
|
|
3510
|
+
ts6.ScriptKind.TS
|
|
3615
3511
|
);
|
|
3616
3512
|
const hookNames = /* @__PURE__ */ new Set();
|
|
3617
3513
|
const sideEffectCategories = /* @__PURE__ */ new Set();
|
|
@@ -3620,7 +3516,7 @@ function computeExtractionScore(body, sourceText) {
|
|
|
3620
3516
|
if (hookName) hookNames.add(hookName);
|
|
3621
3517
|
const sideEffect = sideEffectCategoryOf(node);
|
|
3622
3518
|
if (sideEffect) sideEffectCategories.add(sideEffect);
|
|
3623
|
-
|
|
3519
|
+
ts6.forEachChild(node, visit);
|
|
3624
3520
|
};
|
|
3625
3521
|
visit(sourceFile);
|
|
3626
3522
|
const hookDiversityPoint = hookNames.size >= 2 ? 1 : 0;
|
|
@@ -3637,9 +3533,9 @@ var hookComplexityRule = {
|
|
|
3637
3533
|
create(context) {
|
|
3638
3534
|
const filename = context.filename;
|
|
3639
3535
|
const sourceRoot = sourceRootOf(context);
|
|
3640
|
-
const relative =
|
|
3536
|
+
const relative = path28.relative(sourceRoot, filename);
|
|
3641
3537
|
if (relative.startsWith("..")) return {};
|
|
3642
|
-
const segments = relative.split(
|
|
3538
|
+
const segments = relative.split(path28.sep);
|
|
3643
3539
|
const sourceText = context.sourceCode.text;
|
|
3644
3540
|
function checkHook(node, name, body, exported) {
|
|
3645
3541
|
if (!exported) return;
|
|
@@ -3681,9 +3577,9 @@ var hookComplexityRule = {
|
|
|
3681
3577
|
};
|
|
3682
3578
|
|
|
3683
3579
|
// eslint/rules/locale-dotted-path.ts
|
|
3684
|
-
import
|
|
3580
|
+
import path29 from "path";
|
|
3685
3581
|
function isInLocalesDir(filename) {
|
|
3686
|
-
const segments =
|
|
3582
|
+
const segments = path29.resolve(filename).split(path29.sep);
|
|
3687
3583
|
const srcIdx = segments.lastIndexOf("src");
|
|
3688
3584
|
return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
|
|
3689
3585
|
}
|
|
@@ -3732,9 +3628,9 @@ var localeDottedPathRule = {
|
|
|
3732
3628
|
};
|
|
3733
3629
|
|
|
3734
3630
|
// eslint/rules/locales-location.ts
|
|
3735
|
-
import
|
|
3631
|
+
import path30 from "path";
|
|
3736
3632
|
function isLocalesFile(filename) {
|
|
3737
|
-
const segments =
|
|
3633
|
+
const segments = path30.resolve(filename).split(path30.sep);
|
|
3738
3634
|
const srcIdx = segments.lastIndexOf("src");
|
|
3739
3635
|
return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
|
|
3740
3636
|
}
|
|
@@ -3759,7 +3655,7 @@ var localesLocationRule = {
|
|
|
3759
3655
|
create(context) {
|
|
3760
3656
|
if (isLocalesFile(context.filename) || isTestFile(context.filename)) return {};
|
|
3761
3657
|
const filename = context.filename;
|
|
3762
|
-
const segments =
|
|
3658
|
+
const segments = path30.resolve(filename).split(path30.sep);
|
|
3763
3659
|
const srcIdx = segments.lastIndexOf("src");
|
|
3764
3660
|
if (srcIdx === -1) return {};
|
|
3765
3661
|
const folder = segments[srcIdx + 1];
|
|
@@ -3783,7 +3679,7 @@ var localesLocationRule = {
|
|
|
3783
3679
|
};
|
|
3784
3680
|
|
|
3785
3681
|
// eslint/rules/hook-extraction.ts
|
|
3786
|
-
import
|
|
3682
|
+
import path31 from "path";
|
|
3787
3683
|
var hookExtractionRule = {
|
|
3788
3684
|
meta: {
|
|
3789
3685
|
schema: [],
|
|
@@ -3794,7 +3690,7 @@ var hookExtractionRule = {
|
|
|
3794
3690
|
},
|
|
3795
3691
|
create(context) {
|
|
3796
3692
|
const sourceRoot = sourceRootOf(context);
|
|
3797
|
-
const file =
|
|
3693
|
+
const file = path31.resolve(context.filename);
|
|
3798
3694
|
const segments = segmentsOf(file, sourceRoot);
|
|
3799
3695
|
if (segments.length === 0) return {};
|
|
3800
3696
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -3820,7 +3716,7 @@ var hookExtractionRule = {
|
|
|
3820
3716
|
};
|
|
3821
3717
|
|
|
3822
3718
|
// eslint/rules/value-extraction.ts
|
|
3823
|
-
import
|
|
3719
|
+
import path32 from "path";
|
|
3824
3720
|
var valueExtractionRule = {
|
|
3825
3721
|
meta: {
|
|
3826
3722
|
schema: [],
|
|
@@ -3831,7 +3727,7 @@ var valueExtractionRule = {
|
|
|
3831
3727
|
},
|
|
3832
3728
|
create(context) {
|
|
3833
3729
|
const sourceRoot = sourceRootOf(context);
|
|
3834
|
-
const file =
|
|
3730
|
+
const file = path32.resolve(context.filename);
|
|
3835
3731
|
const segments = segmentsOf(file, sourceRoot);
|
|
3836
3732
|
if (segments.length === 0 || segments[0] !== "app") return {};
|
|
3837
3733
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -3852,7 +3748,7 @@ var valueExtractionRule = {
|
|
|
3852
3748
|
};
|
|
3853
3749
|
|
|
3854
3750
|
// eslint/rules/config-extraction.ts
|
|
3855
|
-
import
|
|
3751
|
+
import path33 from "path";
|
|
3856
3752
|
var configExtractionRule = {
|
|
3857
3753
|
meta: {
|
|
3858
3754
|
schema: [],
|
|
@@ -3863,7 +3759,7 @@ var configExtractionRule = {
|
|
|
3863
3759
|
},
|
|
3864
3760
|
create(context) {
|
|
3865
3761
|
const sourceRoot = sourceRootOf(context);
|
|
3866
|
-
const file =
|
|
3762
|
+
const file = path33.resolve(context.filename);
|
|
3867
3763
|
const segments = segmentsOf(file, sourceRoot);
|
|
3868
3764
|
if (segments.length < 3 || segments[0] !== "config") return {};
|
|
3869
3765
|
if (SUPPORT_FOLDERS2.has(segments[2] ?? "")) return {};
|
|
@@ -3901,7 +3797,7 @@ var configExtractionRule = {
|
|
|
3901
3797
|
};
|
|
3902
3798
|
|
|
3903
3799
|
// eslint/rules/component-nesting.ts
|
|
3904
|
-
import
|
|
3800
|
+
import path34 from "path";
|
|
3905
3801
|
var componentNestingRule = {
|
|
3906
3802
|
meta: {
|
|
3907
3803
|
schema: [],
|
|
@@ -3912,7 +3808,7 @@ var componentNestingRule = {
|
|
|
3912
3808
|
},
|
|
3913
3809
|
create(context) {
|
|
3914
3810
|
const sourceRoot = sourceRootOf(context);
|
|
3915
|
-
const file =
|
|
3811
|
+
const file = path34.resolve(context.filename);
|
|
3916
3812
|
const segments = segmentsOf(file, sourceRoot);
|
|
3917
3813
|
if (segments.length !== 4 || segments[0] !== "features") return {};
|
|
3918
3814
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -3945,7 +3841,7 @@ var componentNestingRule = {
|
|
|
3945
3841
|
};
|
|
3946
3842
|
|
|
3947
3843
|
// eslint/rules/stay-flat.ts
|
|
3948
|
-
import
|
|
3844
|
+
import path35 from "path";
|
|
3949
3845
|
var stayFlatRule = {
|
|
3950
3846
|
meta: {
|
|
3951
3847
|
schema: [],
|
|
@@ -3956,7 +3852,7 @@ var stayFlatRule = {
|
|
|
3956
3852
|
},
|
|
3957
3853
|
create(context) {
|
|
3958
3854
|
const sourceRoot = sourceRootOf(context);
|
|
3959
|
-
const file =
|
|
3855
|
+
const file = path35.resolve(context.filename);
|
|
3960
3856
|
const segments = segmentsOf(file, sourceRoot);
|
|
3961
3857
|
if (segments.length !== 3 || segments[0] !== "features") return {};
|
|
3962
3858
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -3996,7 +3892,7 @@ var stayFlatRule = {
|
|
|
3996
3892
|
};
|
|
3997
3893
|
|
|
3998
3894
|
// eslint/rules/type-extraction.ts
|
|
3999
|
-
import
|
|
3895
|
+
import path36 from "path";
|
|
4000
3896
|
var typeExtractionRule = {
|
|
4001
3897
|
meta: {
|
|
4002
3898
|
schema: [],
|
|
@@ -4007,7 +3903,7 @@ var typeExtractionRule = {
|
|
|
4007
3903
|
},
|
|
4008
3904
|
create(context) {
|
|
4009
3905
|
const sourceRoot = sourceRootOf(context);
|
|
4010
|
-
const file =
|
|
3906
|
+
const file = path36.resolve(context.filename);
|
|
4011
3907
|
const segments = segmentsOf(file, sourceRoot);
|
|
4012
3908
|
if (segments.length === 0) return {};
|
|
4013
3909
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -4053,9 +3949,9 @@ var typeExtractionRule = {
|
|
|
4053
3949
|
};
|
|
4054
3950
|
|
|
4055
3951
|
// eslint/rules/locale-placement.ts
|
|
4056
|
-
import
|
|
3952
|
+
import path37 from "path";
|
|
4057
3953
|
import { readFileSync as readFileSync5 } from "fs";
|
|
4058
|
-
import
|
|
3954
|
+
import ts7 from "typescript";
|
|
4059
3955
|
var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
|
|
4060
3956
|
var camelCase = (name) => name.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase());
|
|
4061
3957
|
var FORCED_TOP_LEVEL = /* @__PURE__ */ new Set(["app", "shared", "compositions", "config"]);
|
|
@@ -4063,26 +3959,26 @@ function forcesTopLevel(segments) {
|
|
|
4063
3959
|
return FORCED_TOP_LEVEL.has(segments[0] ?? "") || SUPPORT_FOLDERS2.has(segments[0] ?? "");
|
|
4064
3960
|
}
|
|
4065
3961
|
function localePlacement(text) {
|
|
4066
|
-
const sourceFile =
|
|
3962
|
+
const sourceFile = ts7.createSourceFile("locales.ts", text, ts7.ScriptTarget.Latest, true, ts7.ScriptKind.TS);
|
|
4067
3963
|
for (const statement of sourceFile.statements) {
|
|
4068
|
-
if (!
|
|
4069
|
-
const isExported2 = (
|
|
4070
|
-
(modifier) => modifier.kind ===
|
|
3964
|
+
if (!ts7.isVariableStatement(statement)) continue;
|
|
3965
|
+
const isExported2 = (ts7.getModifiers(statement) ?? []).some(
|
|
3966
|
+
(modifier) => modifier.kind === ts7.SyntaxKind.ExportKeyword
|
|
4071
3967
|
);
|
|
4072
3968
|
if (!isExported2) continue;
|
|
4073
3969
|
for (const declaration of statement.declarationList.declarations) {
|
|
4074
|
-
if (!
|
|
4075
|
-
if (!declaration.initializer || !
|
|
3970
|
+
if (!ts7.isIdentifier(declaration.name) || declaration.name.text !== "locales") continue;
|
|
3971
|
+
if (!declaration.initializer || !ts7.isObjectLiteralExpression(declaration.initializer)) continue;
|
|
4076
3972
|
const placement = /* @__PURE__ */ new Map();
|
|
4077
3973
|
for (const property of declaration.initializer.properties) {
|
|
4078
|
-
if (!
|
|
3974
|
+
if (!ts7.isPropertyAssignment(property)) continue;
|
|
4079
3975
|
let name;
|
|
4080
|
-
if (
|
|
4081
|
-
else if (
|
|
3976
|
+
if (ts7.isIdentifier(property.name)) name = property.name.text;
|
|
3977
|
+
else if (ts7.isStringLiteral(property.name)) name = property.name.text;
|
|
4082
3978
|
if (name === void 0) continue;
|
|
4083
3979
|
const line = sourceFile.getLineAndCharacterOfPosition(property.getStart(sourceFile)).line + 1;
|
|
4084
3980
|
placement.set(name, {
|
|
4085
|
-
kind:
|
|
3981
|
+
kind: ts7.isObjectLiteralExpression(property.initializer) ? "nested" : "top",
|
|
4086
3982
|
line
|
|
4087
3983
|
});
|
|
4088
3984
|
}
|
|
@@ -4101,7 +3997,7 @@ var localePlacementRule = {
|
|
|
4101
3997
|
},
|
|
4102
3998
|
create(context) {
|
|
4103
3999
|
const sourceRoot = sourceRootOf(context);
|
|
4104
|
-
const file =
|
|
4000
|
+
const file = path37.resolve(context.filename);
|
|
4105
4001
|
const segments = segmentsOf(file, sourceRoot);
|
|
4106
4002
|
if (segments.length === 0) return {};
|
|
4107
4003
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -4179,39 +4075,39 @@ var localePlacementRule = {
|
|
|
4179
4075
|
};
|
|
4180
4076
|
|
|
4181
4077
|
// eslint/rules/sole-state-owner.ts
|
|
4182
|
-
import
|
|
4183
|
-
import
|
|
4078
|
+
import path38 from "path";
|
|
4079
|
+
import ts8 from "typescript";
|
|
4184
4080
|
function findStateHooks(node) {
|
|
4185
4081
|
const hooks = [];
|
|
4186
4082
|
const visit = (child) => {
|
|
4187
|
-
if (
|
|
4188
|
-
if (
|
|
4083
|
+
if (ts8.isCallExpression(child) && ts8.isIdentifier(child.expression) && child.expression.text === "useState") {
|
|
4084
|
+
if (ts8.isVariableDeclaration(child.parent)) {
|
|
4189
4085
|
const { name } = child.parent;
|
|
4190
|
-
if (
|
|
4086
|
+
if (ts8.isArrayBindingPattern(name) && name.elements.length >= 2) {
|
|
4191
4087
|
const value = name.elements[0];
|
|
4192
4088
|
const updater = name.elements[1];
|
|
4193
|
-
if (value && updater &&
|
|
4089
|
+
if (value && updater && ts8.isBindingElement(value) && ts8.isBindingElement(updater)) {
|
|
4194
4090
|
const valueName = value.name;
|
|
4195
4091
|
const updaterName = updater.name;
|
|
4196
|
-
if (
|
|
4092
|
+
if (ts8.isIdentifier(valueName) && ts8.isIdentifier(updaterName)) {
|
|
4197
4093
|
hooks.push({ value: valueName.text, updater: updaterName.text });
|
|
4198
4094
|
}
|
|
4199
4095
|
}
|
|
4200
4096
|
}
|
|
4201
4097
|
}
|
|
4202
4098
|
}
|
|
4203
|
-
|
|
4099
|
+
ts8.forEachChild(child, visit);
|
|
4204
4100
|
};
|
|
4205
4101
|
visit(node);
|
|
4206
4102
|
return hooks;
|
|
4207
4103
|
}
|
|
4208
4104
|
function isHookUsage(node, hook) {
|
|
4209
|
-
if (
|
|
4105
|
+
if (ts8.isCallExpression(node) && ts8.isIdentifier(node.expression) && node.expression.text === hook.updater) {
|
|
4210
4106
|
return "updater";
|
|
4211
4107
|
}
|
|
4212
|
-
if (
|
|
4108
|
+
if (ts8.isIdentifier(node) && node.text === hook.value) {
|
|
4213
4109
|
const parent = node.parent;
|
|
4214
|
-
if (
|
|
4110
|
+
if (ts8.isBindingElement(parent) || ts8.isPropertyAccessExpression(parent) || ts8.isShorthandPropertyAssignment(parent)) {
|
|
4215
4111
|
return void 0;
|
|
4216
4112
|
}
|
|
4217
4113
|
return "value";
|
|
@@ -4221,16 +4117,16 @@ function isHookUsage(node, hook) {
|
|
|
4221
4117
|
function topLevelJsxChildren(initial) {
|
|
4222
4118
|
if (!initial) return void 0;
|
|
4223
4119
|
let expression = initial;
|
|
4224
|
-
while (
|
|
4225
|
-
if (
|
|
4120
|
+
while (ts8.isParenthesizedExpression(expression)) expression = expression.expression;
|
|
4121
|
+
if (ts8.isJsxFragment(expression)) {
|
|
4226
4122
|
const children = expression.children.filter(
|
|
4227
|
-
(c) => !
|
|
4123
|
+
(c) => !ts8.isJsxText(c) && !ts8.isJsxSpreadAttribute(c)
|
|
4228
4124
|
);
|
|
4229
4125
|
return { root: expression, children };
|
|
4230
4126
|
}
|
|
4231
|
-
if (
|
|
4127
|
+
if (ts8.isJsxElement(expression)) {
|
|
4232
4128
|
const children = expression.children.filter(
|
|
4233
|
-
(c) => !
|
|
4129
|
+
(c) => !ts8.isJsxText(c) && !ts8.isJsxSpreadAttribute(c)
|
|
4234
4130
|
);
|
|
4235
4131
|
return { root: expression, children };
|
|
4236
4132
|
}
|
|
@@ -4244,8 +4140,8 @@ function collectUsesIn(child, hook) {
|
|
|
4244
4140
|
positions.push(node);
|
|
4245
4141
|
count += 1;
|
|
4246
4142
|
}
|
|
4247
|
-
if (
|
|
4248
|
-
|
|
4143
|
+
if (ts8.isFunctionDeclaration(node) || ts8.isClassDeclaration(node)) return;
|
|
4144
|
+
ts8.forEachChild(node, visit);
|
|
4249
4145
|
};
|
|
4250
4146
|
visit(child);
|
|
4251
4147
|
return { positions, count };
|
|
@@ -4259,7 +4155,7 @@ var soleStateOwnerRule = {
|
|
|
4259
4155
|
}
|
|
4260
4156
|
},
|
|
4261
4157
|
create(context) {
|
|
4262
|
-
const filename =
|
|
4158
|
+
const filename = path38.resolve(context.filename);
|
|
4263
4159
|
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
|
|
4264
4160
|
const text = context.sourceCode.text;
|
|
4265
4161
|
const components = parseComponentInfo(text, filename);
|
|
@@ -4284,18 +4180,18 @@ var soleStateOwnerRule = {
|
|
|
4284
4180
|
}
|
|
4285
4181
|
};
|
|
4286
4182
|
function analyzeSoleOwner(declaration, hook) {
|
|
4287
|
-
const body =
|
|
4288
|
-
if (!body || !
|
|
4183
|
+
const body = ts8.isFunctionDeclaration(declaration) ? declaration.body : void 0;
|
|
4184
|
+
if (!body || !ts8.isBlock(body)) return void 0;
|
|
4289
4185
|
const returns = [];
|
|
4290
4186
|
const visit = (node) => {
|
|
4291
|
-
if (node !== body && (
|
|
4292
|
-
if (
|
|
4293
|
-
|
|
4187
|
+
if (node !== body && (ts8.isFunctionLike(node) || ts8.isClassLike(node))) return;
|
|
4188
|
+
if (ts8.isReturnStatement(node)) returns.push(node);
|
|
4189
|
+
ts8.forEachChild(node, visit);
|
|
4294
4190
|
};
|
|
4295
4191
|
visit(body);
|
|
4296
4192
|
if (returns.length !== 1) return void 0;
|
|
4297
4193
|
const single = returns[0];
|
|
4298
|
-
if (!single?.expression || !
|
|
4194
|
+
if (!single?.expression || !ts8.isExpression(single.expression)) return void 0;
|
|
4299
4195
|
const returnExpression = single.expression;
|
|
4300
4196
|
const root = topLevelJsxChildren(returnExpression);
|
|
4301
4197
|
if (!root || root.children.length === 0) return void 0;
|
|
@@ -4318,11 +4214,11 @@ function usesOutsideJsx(declaration, hook, children) {
|
|
|
4318
4214
|
let outside = false;
|
|
4319
4215
|
const visit = (node) => {
|
|
4320
4216
|
if (outside) return;
|
|
4321
|
-
if (node !== declaration && (
|
|
4217
|
+
if (node !== declaration && (ts8.isFunctionDeclaration(node) || ts8.isClassDeclaration(node))) return;
|
|
4322
4218
|
if (isHookUsage(node, hook)) {
|
|
4323
4219
|
let current = node;
|
|
4324
4220
|
let isInJsxChild = false;
|
|
4325
|
-
while (!
|
|
4221
|
+
while (!ts8.isSourceFile(current)) {
|
|
4326
4222
|
if (children.includes(current)) {
|
|
4327
4223
|
isInJsxChild = true;
|
|
4328
4224
|
break;
|
|
@@ -4331,14 +4227,14 @@ function usesOutsideJsx(declaration, hook, children) {
|
|
|
4331
4227
|
}
|
|
4332
4228
|
if (!isInJsxChild) outside = true;
|
|
4333
4229
|
}
|
|
4334
|
-
|
|
4230
|
+
ts8.forEachChild(node, visit);
|
|
4335
4231
|
};
|
|
4336
4232
|
visit(declaration);
|
|
4337
4233
|
return outside;
|
|
4338
4234
|
}
|
|
4339
4235
|
|
|
4340
4236
|
// eslint/rules/locale-key-shape.ts
|
|
4341
|
-
import
|
|
4237
|
+
import path39 from "path";
|
|
4342
4238
|
var MAX_KEY_LENGTH = 30;
|
|
4343
4239
|
var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
|
|
4344
4240
|
"Button",
|
|
@@ -4388,7 +4284,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
|
|
|
4388
4284
|
var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
|
|
4389
4285
|
var ENGLISH = /^[A-Za-z0-9_]*$/;
|
|
4390
4286
|
function isLocalesFile2(filename) {
|
|
4391
|
-
const segments =
|
|
4287
|
+
const segments = path39.resolve(filename).split(path39.sep);
|
|
4392
4288
|
const srcIdx = segments.lastIndexOf("src");
|
|
4393
4289
|
return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
|
|
4394
4290
|
}
|
|
@@ -4459,7 +4355,7 @@ var localeKeyShapeRule = {
|
|
|
4459
4355
|
};
|
|
4460
4356
|
|
|
4461
4357
|
// eslint/rules/shared-style-dedup.ts
|
|
4462
|
-
import
|
|
4358
|
+
import path40 from "path";
|
|
4463
4359
|
import { readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
4464
4360
|
var CLASS_NAME = /className="(?<classes>[^"]+)"/g;
|
|
4465
4361
|
var comboCache;
|
|
@@ -4497,7 +4393,7 @@ var sharedStyleDedupRule = {
|
|
|
4497
4393
|
},
|
|
4498
4394
|
create(context) {
|
|
4499
4395
|
const sourceRoot = sourceRootOf(context);
|
|
4500
|
-
const file =
|
|
4396
|
+
const file = path40.resolve(context.filename);
|
|
4501
4397
|
const segments = segmentsOf(file, sourceRoot);
|
|
4502
4398
|
if (segments.length === 0) return {};
|
|
4503
4399
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -4701,7 +4597,7 @@ var zodSchemaValidationRule = {
|
|
|
4701
4597
|
};
|
|
4702
4598
|
|
|
4703
4599
|
// eslint/rules/schema-casing.ts
|
|
4704
|
-
import
|
|
4600
|
+
import path41 from "path";
|
|
4705
4601
|
function isCamelCase(name) {
|
|
4706
4602
|
return /^[a-z][a-zA-Z0-9]*$/.test(name);
|
|
4707
4603
|
}
|
|
@@ -4729,9 +4625,9 @@ var schemaCasingRule = {
|
|
|
4729
4625
|
}
|
|
4730
4626
|
},
|
|
4731
4627
|
create(context) {
|
|
4732
|
-
const filename =
|
|
4628
|
+
const filename = path41.resolve(context.filename);
|
|
4733
4629
|
const sourceRoot = sourceRootOf(context);
|
|
4734
|
-
if (!filename.startsWith(sourceRoot +
|
|
4630
|
+
if (!filename.startsWith(sourceRoot + path41.sep)) return {};
|
|
4735
4631
|
let zodLocalName;
|
|
4736
4632
|
return {
|
|
4737
4633
|
ImportDeclaration(node) {
|
|
@@ -4763,7 +4659,7 @@ var schemaCasingRule = {
|
|
|
4763
4659
|
};
|
|
4764
4660
|
|
|
4765
4661
|
// eslint/rules/component-casing.ts
|
|
4766
|
-
import
|
|
4662
|
+
import path42 from "path";
|
|
4767
4663
|
function isPascalCase6(name) {
|
|
4768
4664
|
return /^[A-Z][A-Za-z0-9]*$/.test(name);
|
|
4769
4665
|
}
|
|
@@ -4776,10 +4672,10 @@ var componentCasingRule = {
|
|
|
4776
4672
|
}
|
|
4777
4673
|
},
|
|
4778
4674
|
create(context) {
|
|
4779
|
-
const filename =
|
|
4675
|
+
const filename = path42.resolve(context.filename);
|
|
4780
4676
|
const sourceRoot = sourceRootOf(context);
|
|
4781
|
-
if (!filename.startsWith(sourceRoot +
|
|
4782
|
-
if (
|
|
4677
|
+
if (!filename.startsWith(sourceRoot + path42.sep)) return {};
|
|
4678
|
+
if (path42.extname(filename) !== ".tsx") return {};
|
|
4783
4679
|
return {
|
|
4784
4680
|
Program(node) {
|
|
4785
4681
|
for (const declaration of findJsxReturningDeclarations(context.sourceCode.text, filename)) {
|
|
@@ -4796,7 +4692,7 @@ var componentCasingRule = {
|
|
|
4796
4692
|
};
|
|
4797
4693
|
|
|
4798
4694
|
// eslint/rules/source-under-src.ts
|
|
4799
|
-
import
|
|
4695
|
+
import path43 from "path";
|
|
4800
4696
|
var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
|
|
4801
4697
|
".agents",
|
|
4802
4698
|
".cache",
|
|
@@ -4837,14 +4733,14 @@ var sourceUnderSrcRule = {
|
|
|
4837
4733
|
}
|
|
4838
4734
|
},
|
|
4839
4735
|
create(context) {
|
|
4840
|
-
const filename =
|
|
4736
|
+
const filename = path43.resolve(context.filename);
|
|
4841
4737
|
if (!MODULE_EXTENSION.test(filename)) return {};
|
|
4842
|
-
const relative =
|
|
4738
|
+
const relative = path43.relative(context.cwd, filename).replace(/\\/g, "/");
|
|
4843
4739
|
if (relative === "src" || relative.startsWith("src/")) return {};
|
|
4844
4740
|
const topLevel = relative.split("/")[0] ?? "";
|
|
4845
4741
|
if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
|
|
4846
4742
|
if (!relative.includes("/")) {
|
|
4847
|
-
const basename =
|
|
4743
|
+
const basename = path43.basename(filename);
|
|
4848
4744
|
if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
|
|
4849
4745
|
}
|
|
4850
4746
|
return {
|
|
@@ -4861,8 +4757,8 @@ var sourceUnderSrcRule = {
|
|
|
4861
4757
|
|
|
4862
4758
|
// eslint/rules/zirka-baseline.ts
|
|
4863
4759
|
import fs5 from "fs";
|
|
4864
|
-
import
|
|
4865
|
-
var
|
|
4760
|
+
import path44 from "path";
|
|
4761
|
+
var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
|
|
4866
4762
|
var PRETTIER_CONFIGS = [
|
|
4867
4763
|
"prettier.config.mjs",
|
|
4868
4764
|
"prettier.config.cjs",
|
|
@@ -4880,10 +4776,10 @@ var zirkaBaselineRule = {
|
|
|
4880
4776
|
}
|
|
4881
4777
|
},
|
|
4882
4778
|
create(context) {
|
|
4883
|
-
const filename =
|
|
4884
|
-
const basename =
|
|
4885
|
-
if (!
|
|
4886
|
-
const projectRoot =
|
|
4779
|
+
const filename = path44.resolve(context.filename);
|
|
4780
|
+
const basename = path44.basename(filename);
|
|
4781
|
+
if (!ESLINT_CONFIG.test(basename)) return {};
|
|
4782
|
+
const projectRoot = path44.dirname(filename);
|
|
4887
4783
|
const report3 = (message) => {
|
|
4888
4784
|
context.report({
|
|
4889
4785
|
node: context.sourceCode.ast,
|
|
@@ -4898,7 +4794,7 @@ var zirkaBaselineRule = {
|
|
|
4898
4794
|
'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
|
|
4899
4795
|
);
|
|
4900
4796
|
}
|
|
4901
|
-
const tsconfigPath =
|
|
4797
|
+
const tsconfigPath = path44.join(projectRoot, "tsconfig.json");
|
|
4902
4798
|
if (!fs5.existsSync(tsconfigPath)) {
|
|
4903
4799
|
report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
|
|
4904
4800
|
} else {
|
|
@@ -4916,13 +4812,13 @@ var zirkaBaselineRule = {
|
|
|
4916
4812
|
report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
|
|
4917
4813
|
}
|
|
4918
4814
|
}
|
|
4919
|
-
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(
|
|
4815
|
+
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(path44.join(projectRoot, name)));
|
|
4920
4816
|
if (!prettierConfigFile) {
|
|
4921
4817
|
report3(
|
|
4922
4818
|
"No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
|
|
4923
4819
|
);
|
|
4924
4820
|
} else {
|
|
4925
|
-
const content = fs5.readFileSync(
|
|
4821
|
+
const content = fs5.readFileSync(path44.join(projectRoot, prettierConfigFile), "utf8");
|
|
4926
4822
|
if (!content.includes("zirka")) {
|
|
4927
4823
|
report3(
|
|
4928
4824
|
"The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
|
|
@@ -5001,7 +4897,7 @@ var docKindSuffixRule = {
|
|
|
5001
4897
|
};
|
|
5002
4898
|
|
|
5003
4899
|
// eslint/rules/documentation/title-matches-file-name.ts
|
|
5004
|
-
import
|
|
4900
|
+
import path45 from "path";
|
|
5005
4901
|
function toExpectedFileName(title) {
|
|
5006
4902
|
return `${title.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
5007
4903
|
}
|
|
@@ -5021,7 +4917,7 @@ var titleMatchesFileNameRule = {
|
|
|
5021
4917
|
if (!filename.endsWith(".md")) return;
|
|
5022
4918
|
const title = getTextContent(node).trim();
|
|
5023
4919
|
const expectedFileName = toExpectedFileName(title);
|
|
5024
|
-
const actualFileName =
|
|
4920
|
+
const actualFileName = path45.basename(filename);
|
|
5025
4921
|
if (!title) {
|
|
5026
4922
|
context.report({
|
|
5027
4923
|
node,
|
|
@@ -5488,20 +5384,20 @@ var referenceMaxHeadingDepthRule = {
|
|
|
5488
5384
|
|
|
5489
5385
|
// eslint/rules/documentation/support-document-placement.ts
|
|
5490
5386
|
import { existsSync as existsSync2 } from "fs";
|
|
5491
|
-
import
|
|
5387
|
+
import path46 from "path";
|
|
5492
5388
|
function checkPlacement(filename, kind) {
|
|
5493
|
-
const parentFolder =
|
|
5389
|
+
const parentFolder = path46.basename(path46.dirname(filename));
|
|
5494
5390
|
const expectedParent = `${kind}s`;
|
|
5495
5391
|
if (parentFolder !== expectedParent) {
|
|
5496
5392
|
return `${kind} lives in "${parentFolder}/" instead of "${expectedParent}/"`;
|
|
5497
5393
|
}
|
|
5498
|
-
const guideFolderPath =
|
|
5499
|
-
const guideFolder =
|
|
5394
|
+
const guideFolderPath = path46.dirname(path46.dirname(filename));
|
|
5395
|
+
const guideFolder = path46.basename(guideFolderPath);
|
|
5500
5396
|
if (!guideFolder.endsWith("-guide")) {
|
|
5501
5397
|
return `${kind} owner folder "${guideFolder}/" does not use the "*-guide/" suffix`;
|
|
5502
5398
|
}
|
|
5503
5399
|
const entryPoint = `${guideFolder}.md`;
|
|
5504
|
-
if (!existsSync2(
|
|
5400
|
+
if (!existsSync2(path46.join(guideFolderPath, entryPoint))) {
|
|
5505
5401
|
return `${kind} owner folder "${guideFolder}/" has no "${entryPoint}" entry point`;
|
|
5506
5402
|
}
|
|
5507
5403
|
return void 0;
|
|
@@ -5560,11 +5456,11 @@ var noTemplatePromptRule = {
|
|
|
5560
5456
|
};
|
|
5561
5457
|
|
|
5562
5458
|
// eslint/rules/documentation/guide-folder-entry-point.ts
|
|
5563
|
-
import
|
|
5459
|
+
import path48 from "path";
|
|
5564
5460
|
|
|
5565
5461
|
// eslint/rules/documentation/project-index.ts
|
|
5566
5462
|
import { readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync4 } from "fs";
|
|
5567
|
-
import
|
|
5463
|
+
import path47 from "path";
|
|
5568
5464
|
var KIND_BY_SUFFIX = [
|
|
5569
5465
|
["-rule.md", "rule"],
|
|
5570
5466
|
["-guide.md", "guide"],
|
|
@@ -5573,7 +5469,7 @@ var KIND_BY_SUFFIX = [
|
|
|
5573
5469
|
];
|
|
5574
5470
|
function listMarkdownFiles(dir) {
|
|
5575
5471
|
return readdirSync3(dir).flatMap((entry) => {
|
|
5576
|
-
const entryPath =
|
|
5472
|
+
const entryPath = path47.join(dir, entry);
|
|
5577
5473
|
if (statSync4(entryPath).isDirectory()) {
|
|
5578
5474
|
return entry.startsWith("_") ? [] : listMarkdownFiles(entryPath);
|
|
5579
5475
|
}
|
|
@@ -5591,11 +5487,11 @@ function getProjectDocs(docsRoot) {
|
|
|
5591
5487
|
if (cached) return cached;
|
|
5592
5488
|
const files = listMarkdownFiles(docsRoot);
|
|
5593
5489
|
const docs = files.sort((a, b) => a.localeCompare(b)).map((filePath) => {
|
|
5594
|
-
const fileName =
|
|
5490
|
+
const fileName = path47.basename(filePath);
|
|
5595
5491
|
const kind = KIND_BY_SUFFIX.find(([suffix]) => fileName.endsWith(suffix))?.[1];
|
|
5596
5492
|
return {
|
|
5597
5493
|
filePath,
|
|
5598
|
-
doc:
|
|
5494
|
+
doc: path47.relative(docsRoot, filePath).split(path47.sep).join("/"),
|
|
5599
5495
|
fileName,
|
|
5600
5496
|
kind,
|
|
5601
5497
|
title: extractTitle(filePath)
|
|
@@ -5605,12 +5501,12 @@ function getProjectDocs(docsRoot) {
|
|
|
5605
5501
|
return docs;
|
|
5606
5502
|
}
|
|
5607
5503
|
function findDocsRoot(filePath) {
|
|
5608
|
-
let dir =
|
|
5504
|
+
let dir = path47.dirname(filePath);
|
|
5609
5505
|
for (; ; ) {
|
|
5610
|
-
if (
|
|
5506
|
+
if (path47.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
|
|
5611
5507
|
return dir;
|
|
5612
5508
|
}
|
|
5613
|
-
const parent =
|
|
5509
|
+
const parent = path47.dirname(dir);
|
|
5614
5510
|
if (parent === dir) return void 0;
|
|
5615
5511
|
dir = parent;
|
|
5616
5512
|
}
|
|
@@ -5634,13 +5530,13 @@ var guideFolderEntryPointRule = {
|
|
|
5634
5530
|
if (!docsRoot) return;
|
|
5635
5531
|
const docs = getProjectDocs(docsRoot);
|
|
5636
5532
|
const guideFolders = new Set(
|
|
5637
|
-
docs.filter((doc) => ["rules", "references"].includes(
|
|
5533
|
+
docs.filter((doc) => ["rules", "references"].includes(path48.basename(path48.dirname(doc.filePath)))).map((doc) => path48.dirname(path48.dirname(doc.filePath))).filter((folder) => path48.resolve(folder) !== path48.resolve(docsRoot))
|
|
5638
5534
|
);
|
|
5639
|
-
const currentDir =
|
|
5535
|
+
const currentDir = path48.dirname(filename);
|
|
5640
5536
|
if (guideFolders.has(currentDir)) {
|
|
5641
|
-
const expectedEntryPoint = `${
|
|
5537
|
+
const expectedEntryPoint = `${path48.basename(currentDir)}.md`;
|
|
5642
5538
|
const hasEntryPoint = docs.some(
|
|
5643
|
-
(doc) => doc.kind === "guide" &&
|
|
5539
|
+
(doc) => doc.kind === "guide" && path48.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
|
|
5644
5540
|
);
|
|
5645
5541
|
if (!hasEntryPoint) {
|
|
5646
5542
|
context.report({
|
|
@@ -5785,7 +5681,7 @@ var policySubjectHeadingsRule = {
|
|
|
5785
5681
|
|
|
5786
5682
|
// eslint/rules/documentation/guide-link-anchors.ts
|
|
5787
5683
|
import { existsSync as existsSync3, readFileSync as readFileSync8 } from "fs";
|
|
5788
|
-
import
|
|
5684
|
+
import path49 from "path";
|
|
5789
5685
|
function visitSteps2(node, check) {
|
|
5790
5686
|
if (node.type === "list" && node.ordered) {
|
|
5791
5687
|
for (const child of node.children) check(child);
|
|
@@ -5864,7 +5760,7 @@ var guideLinkAnchorsRule = {
|
|
|
5864
5760
|
for (const link of links) {
|
|
5865
5761
|
const [target = "", fragment = ""] = link.url.split("#");
|
|
5866
5762
|
if (!fragment || !isDocLink(link.url)) continue;
|
|
5867
|
-
const targetPath =
|
|
5763
|
+
const targetPath = path49.resolve(path49.dirname(filename), target);
|
|
5868
5764
|
if (!existsSync3(targetPath)) continue;
|
|
5869
5765
|
if (documentAnchors(targetPath).has(fragment.toLowerCase())) continue;
|
|
5870
5766
|
context.report({
|
|
@@ -5915,9 +5811,9 @@ var noNestedHowToRule = {
|
|
|
5915
5811
|
|
|
5916
5812
|
// eslint/rules/documentation/glossary-term-linking.ts
|
|
5917
5813
|
import { readFileSync as readFileSync9 } from "fs";
|
|
5918
|
-
import
|
|
5814
|
+
import path50 from "path";
|
|
5919
5815
|
function isGlossary(filePath) {
|
|
5920
|
-
return
|
|
5816
|
+
return path50.basename(filePath).includes("glossary");
|
|
5921
5817
|
}
|
|
5922
5818
|
function termNames(cell) {
|
|
5923
5819
|
const abbreviation = /\((?<abbreviation>[^()]+)\)/.exec(cell)?.groups?.abbreviation?.trim();
|
|
@@ -6010,10 +5906,10 @@ var glossaryTermLinkingRule = {
|
|
|
6010
5906
|
const docsRoot = findDocsRoot(filename);
|
|
6011
5907
|
if (!docsRoot) return;
|
|
6012
5908
|
const docs = getProjectDocs(docsRoot);
|
|
6013
|
-
const guideDir =
|
|
6014
|
-
const referencesDir =
|
|
5909
|
+
const guideDir = path50.dirname(filename);
|
|
5910
|
+
const referencesDir = path50.join(guideDir, "references");
|
|
6015
5911
|
const guideReferences = docs.filter(
|
|
6016
|
-
(doc) => doc.kind === "reference" &&
|
|
5912
|
+
(doc) => doc.kind === "reference" && path50.dirname(doc.filePath) === referencesDir
|
|
6017
5913
|
);
|
|
6018
5914
|
const glossaryReferences = guideReferences.filter((doc) => isGlossary(doc.filePath));
|
|
6019
5915
|
if (glossaryReferences.length === 0) return;
|
|
@@ -6030,7 +5926,7 @@ var glossaryTermLinkingRule = {
|
|
|
6030
5926
|
(section) => section.firstStepLinks.some((link) => {
|
|
6031
5927
|
const fragment = link.split("#")[1] ?? "";
|
|
6032
5928
|
if (fragment.toLowerCase() !== anchor) return false;
|
|
6033
|
-
return
|
|
5929
|
+
return path50.resolve(guideDir, linkTarget(link)) === path50.resolve(ref.filePath);
|
|
6034
5930
|
})
|
|
6035
5931
|
);
|
|
6036
5932
|
if (!anchored) {
|
|
@@ -6067,7 +5963,7 @@ var glossaryTermLinkingRule = {
|
|
|
6067
5963
|
|
|
6068
5964
|
// eslint/rules/documentation/guide-mentions-documents.ts
|
|
6069
5965
|
import { existsSync as existsSync4 } from "fs";
|
|
6070
|
-
import
|
|
5966
|
+
import path51 from "path";
|
|
6071
5967
|
function visitSteps3(node, check) {
|
|
6072
5968
|
if (node.type === "list" && node.ordered) {
|
|
6073
5969
|
for (const child of node.children) check(child);
|
|
@@ -6097,12 +5993,12 @@ var guideMentionsDocumentsRule = {
|
|
|
6097
5993
|
if (!filename.endsWith("-guide.md")) return;
|
|
6098
5994
|
const docsRoot = findDocsRoot(filename);
|
|
6099
5995
|
if (!docsRoot) return;
|
|
6100
|
-
const guideDir =
|
|
6101
|
-
if (
|
|
5996
|
+
const guideDir = path51.dirname(filename);
|
|
5997
|
+
if (path51.basename(filename, ".md") !== path51.basename(guideDir)) return;
|
|
6102
5998
|
const docs = getProjectDocs(docsRoot);
|
|
6103
5999
|
const owned = docs.filter((doc) => {
|
|
6104
|
-
const parent =
|
|
6105
|
-
return parent ===
|
|
6000
|
+
const parent = path51.dirname(doc.filePath);
|
|
6001
|
+
return parent === path51.join(guideDir, "rules") || parent === path51.join(guideDir, "references");
|
|
6106
6002
|
});
|
|
6107
6003
|
const allLinks = [];
|
|
6108
6004
|
collectMarkdownLinks(node, allLinks);
|
|
@@ -6129,7 +6025,7 @@ var guideMentionsDocumentsRule = {
|
|
|
6129
6025
|
for (const link of allLinks) {
|
|
6130
6026
|
const target = linkTarget(link.url);
|
|
6131
6027
|
if (!target.endsWith(".md")) continue;
|
|
6132
|
-
const resolved =
|
|
6028
|
+
const resolved = path51.normalize(path51.join(guideDir, target));
|
|
6133
6029
|
if (!existsSync4(resolved)) {
|
|
6134
6030
|
context.report({
|
|
6135
6031
|
node: link,
|
|
@@ -6680,11 +6576,11 @@ var themeVariableNamespaceRule = {
|
|
|
6680
6576
|
|
|
6681
6577
|
// eslint/rules/tailwind/css-entry-point.ts
|
|
6682
6578
|
import { statSync as statSync6 } from "fs";
|
|
6683
|
-
import
|
|
6579
|
+
import path54 from "path";
|
|
6684
6580
|
|
|
6685
6581
|
// eslint/rules/tailwind/source-files.ts
|
|
6686
6582
|
import { readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
|
|
6687
|
-
import
|
|
6583
|
+
import path52 from "path";
|
|
6688
6584
|
var CSS_EXTENSIONS = [".css"];
|
|
6689
6585
|
var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
6690
6586
|
var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS3, ...CSS_EXTENSIONS];
|
|
@@ -6697,7 +6593,7 @@ function findFiles(dir, extensions) {
|
|
|
6697
6593
|
}
|
|
6698
6594
|
return entries.flatMap((entry) => {
|
|
6699
6595
|
if (entry.startsWith(".") || entry === "node_modules") return [];
|
|
6700
|
-
const entryPath =
|
|
6596
|
+
const entryPath = path52.join(dir, entry);
|
|
6701
6597
|
let stats;
|
|
6702
6598
|
try {
|
|
6703
6599
|
stats = statSync5(entryPath);
|
|
@@ -6705,7 +6601,7 @@ function findFiles(dir, extensions) {
|
|
|
6705
6601
|
return [];
|
|
6706
6602
|
}
|
|
6707
6603
|
if (stats.isDirectory()) return findFiles(entryPath, extensions);
|
|
6708
|
-
return extensions.includes(
|
|
6604
|
+
return extensions.includes(path52.extname(entry)) ? [entryPath] : [];
|
|
6709
6605
|
});
|
|
6710
6606
|
}
|
|
6711
6607
|
function cachedTextReader() {
|
|
@@ -6728,7 +6624,7 @@ function escapeRegExp(text) {
|
|
|
6728
6624
|
}
|
|
6729
6625
|
|
|
6730
6626
|
// eslint/rules/tailwind/stylesheet-graph.ts
|
|
6731
|
-
import
|
|
6627
|
+
import path53 from "path";
|
|
6732
6628
|
function registersTailwind(text) {
|
|
6733
6629
|
return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
|
|
6734
6630
|
}
|
|
@@ -6742,25 +6638,25 @@ function moduleImports(text, fileName) {
|
|
|
6742
6638
|
return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
|
|
6743
6639
|
}
|
|
6744
6640
|
function resolveSpecifier2(fromFile, spec, sourceRoot) {
|
|
6745
|
-
if (spec.startsWith("/")) return
|
|
6746
|
-
if (spec.startsWith("./") || spec.startsWith("../")) return
|
|
6747
|
-
if (spec.startsWith("@/")) return
|
|
6641
|
+
if (spec.startsWith("/")) return path53.resolve(spec);
|
|
6642
|
+
if (spec.startsWith("./") || spec.startsWith("../")) return path53.resolve(path53.dirname(fromFile), spec);
|
|
6643
|
+
if (spec.startsWith("@/")) return path53.resolve(sourceRoot, spec.slice(2));
|
|
6748
6644
|
return void 0;
|
|
6749
6645
|
}
|
|
6750
6646
|
function buildStylesheetGraph(options) {
|
|
6751
6647
|
const { cssFiles, sourceRoot, textOf } = options;
|
|
6752
|
-
const cssSet = new Set(cssFiles.map((file) =>
|
|
6648
|
+
const cssSet = new Set(cssFiles.map((file) => path53.normalize(file)));
|
|
6753
6649
|
const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
|
|
6754
6650
|
const reachable = /* @__PURE__ */ new Set();
|
|
6755
6651
|
const queue = [...globals];
|
|
6756
|
-
for (const global of globals) reachable.add(
|
|
6652
|
+
for (const global of globals) reachable.add(path53.normalize(global));
|
|
6757
6653
|
while (queue.length > 0) {
|
|
6758
6654
|
const from = queue.shift();
|
|
6759
6655
|
if (!from) continue;
|
|
6760
6656
|
for (const spec of importedSpecifiers(textOf(from))) {
|
|
6761
6657
|
const target = resolveSpecifier2(from, spec, sourceRoot);
|
|
6762
6658
|
if (!target) continue;
|
|
6763
|
-
const normalized =
|
|
6659
|
+
const normalized = path53.normalize(target);
|
|
6764
6660
|
if (cssSet.has(normalized) && !reachable.has(normalized)) {
|
|
6765
6661
|
reachable.add(normalized);
|
|
6766
6662
|
queue.push(normalized);
|
|
@@ -6772,7 +6668,7 @@ function buildStylesheetGraph(options) {
|
|
|
6772
6668
|
for (const spec of importedSpecifiers(textOf(global))) {
|
|
6773
6669
|
const target = resolveSpecifier2(global, spec, sourceRoot);
|
|
6774
6670
|
if (!target) continue;
|
|
6775
|
-
const normalized =
|
|
6671
|
+
const normalized = path53.normalize(target);
|
|
6776
6672
|
if (cssSet.has(normalized)) directChildren.add(normalized);
|
|
6777
6673
|
}
|
|
6778
6674
|
}
|
|
@@ -6805,7 +6701,7 @@ var cssEntryPointRule = {
|
|
|
6805
6701
|
return {
|
|
6806
6702
|
"StyleSheet:exit"(node) {
|
|
6807
6703
|
if (globals.length === 0) return;
|
|
6808
|
-
const current =
|
|
6704
|
+
const current = path54.normalize(path54.resolve(context.filename));
|
|
6809
6705
|
if (globals.includes(current)) {
|
|
6810
6706
|
if (globals.length > 1) {
|
|
6811
6707
|
context.report({
|
|
@@ -6814,7 +6710,7 @@ var cssEntryPointRule = {
|
|
|
6814
6710
|
});
|
|
6815
6711
|
return;
|
|
6816
6712
|
}
|
|
6817
|
-
const basename =
|
|
6713
|
+
const basename = path54.basename(current);
|
|
6818
6714
|
const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
|
|
6819
6715
|
if (importCount !== 1) {
|
|
6820
6716
|
context.report({
|
|
@@ -7078,6 +6974,7 @@ var lintSetupRule = {
|
|
|
7078
6974
|
|
|
7079
6975
|
// eslint/rules/package-json/nextjs-stack.ts
|
|
7080
6976
|
var NEXTJS_STACK_DEPENDENCIES = [
|
|
6977
|
+
"pasika",
|
|
7081
6978
|
"next",
|
|
7082
6979
|
"react",
|
|
7083
6980
|
"react-dom",
|
|
@@ -7143,7 +7040,7 @@ var nextjsStackRule = {
|
|
|
7143
7040
|
|
|
7144
7041
|
// eslint/rules/package-json/vitest-coverage.ts
|
|
7145
7042
|
import { existsSync as existsSync5, readFileSync as readFileSync11 } from "fs";
|
|
7146
|
-
import
|
|
7043
|
+
import path55 from "path";
|
|
7147
7044
|
function memberName4(member) {
|
|
7148
7045
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
7149
7046
|
}
|
|
@@ -7212,7 +7109,7 @@ var vitestCoverageRule = {
|
|
|
7212
7109
|
message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
|
|
7213
7110
|
});
|
|
7214
7111
|
}
|
|
7215
|
-
const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(
|
|
7112
|
+
const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path55.join(context.cwd, name)));
|
|
7216
7113
|
if (!configName) {
|
|
7217
7114
|
context.report({
|
|
7218
7115
|
node,
|
|
@@ -7220,7 +7117,7 @@ var vitestCoverageRule = {
|
|
|
7220
7117
|
});
|
|
7221
7118
|
return;
|
|
7222
7119
|
}
|
|
7223
|
-
const content = readFileSync11(
|
|
7120
|
+
const content = readFileSync11(path55.join(context.cwd, configName), "utf8");
|
|
7224
7121
|
for (const metric of THRESHOLD_METRICS) {
|
|
7225
7122
|
if (!new RegExp(`\\b${metric}\\s*:\\s*[1-9]\\d*`).test(content)) {
|
|
7226
7123
|
context.report({ node, message: `${configName} must set a coverage threshold above zero for ${metric}.` });
|
|
@@ -7267,7 +7164,7 @@ var nextjsPackageJsonRules = {
|
|
|
7267
7164
|
|
|
7268
7165
|
// eslint/rules/husky/husky-hook.ts
|
|
7269
7166
|
import { existsSync as existsSync6, readFileSync as readFileSync12 } from "fs";
|
|
7270
|
-
import
|
|
7167
|
+
import path56 from "path";
|
|
7271
7168
|
var VITEST_CONFIG_NAMES2 = [
|
|
7272
7169
|
"vitest.config.ts",
|
|
7273
7170
|
"vitest.config.mts",
|
|
@@ -7293,7 +7190,7 @@ var huskyHookRule = {
|
|
|
7293
7190
|
const root = node.body;
|
|
7294
7191
|
if (root.type !== "Object") return;
|
|
7295
7192
|
if (!context.filename.endsWith("package.json")) return;
|
|
7296
|
-
const hookPath =
|
|
7193
|
+
const hookPath = path56.join(context.cwd, ".husky", "pre-commit");
|
|
7297
7194
|
if (!existsSync6(hookPath)) {
|
|
7298
7195
|
context.report({
|
|
7299
7196
|
node,
|
|
@@ -7317,7 +7214,7 @@ var huskyHookRule = {
|
|
|
7317
7214
|
}
|
|
7318
7215
|
requireNamedScript("typecheck");
|
|
7319
7216
|
requireNamedScript("test:unit:coverage");
|
|
7320
|
-
const vitestConfigName = VITEST_CONFIG_NAMES2.find((name) => existsSync6(
|
|
7217
|
+
const vitestConfigName = VITEST_CONFIG_NAMES2.find((name) => existsSync6(path56.join(context.cwd, name)));
|
|
7321
7218
|
if (vitestConfigName !== void 0) {
|
|
7322
7219
|
const coverageIndex = content.indexOf("npm run test:unit:coverage");
|
|
7323
7220
|
const localAddIndex = content.indexOf(`git add ${vitestConfigName}`);
|
|
@@ -7331,7 +7228,7 @@ var huskyHookRule = {
|
|
|
7331
7228
|
if (!content.includes("libyear --limit-major-individual=1")) {
|
|
7332
7229
|
context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
|
|
7333
7230
|
}
|
|
7334
|
-
const suppressionsPath =
|
|
7231
|
+
const suppressionsPath = path56.join(context.cwd, "eslint-suppressions.json");
|
|
7335
7232
|
if (existsSync6(suppressionsPath)) {
|
|
7336
7233
|
requireNamedScript("lint:prune");
|
|
7337
7234
|
const pruneIndex = content.indexOf("npm run lint:prune");
|
|
@@ -7364,7 +7261,7 @@ var huskyRules = {
|
|
|
7364
7261
|
|
|
7365
7262
|
// eslint/rules/vulyk/tracked-docs.ts
|
|
7366
7263
|
import { existsSync as existsSync7, readFileSync as readFileSync13 } from "fs";
|
|
7367
|
-
import
|
|
7264
|
+
import path57 from "path";
|
|
7368
7265
|
var PASIKA_REPO = "Bredansky/pasika";
|
|
7369
7266
|
var BASE_REQUIRED_TRACKED_DOCS = [
|
|
7370
7267
|
{ name: "documentation-guide", path: "docs/documentation-guide" },
|
|
@@ -7397,8 +7294,8 @@ var trackedDocsRule = {
|
|
|
7397
7294
|
if (!context.filename.endsWith("package.json")) return;
|
|
7398
7295
|
const root = node.body;
|
|
7399
7296
|
if (root.type !== "Object") return;
|
|
7400
|
-
const projectRoot =
|
|
7401
|
-
const configPath =
|
|
7297
|
+
const projectRoot = path57.dirname(path57.resolve(context.filename));
|
|
7298
|
+
const configPath = path57.join(projectRoot, "vulyk.config.ts");
|
|
7402
7299
|
if (!existsSync7(configPath)) {
|
|
7403
7300
|
context.report({
|
|
7404
7301
|
node,
|
|
@@ -7423,7 +7320,7 @@ var trackedDocsRule = {
|
|
|
7423
7320
|
});
|
|
7424
7321
|
}
|
|
7425
7322
|
}
|
|
7426
|
-
const agentsPath =
|
|
7323
|
+
const agentsPath = path57.join(projectRoot, "AGENTS.md");
|
|
7427
7324
|
if (!existsSync7(agentsPath)) {
|
|
7428
7325
|
context.report({
|
|
7429
7326
|
node,
|
|
@@ -7524,6 +7421,7 @@ var pasikaNextjsAppRules = {
|
|
|
7524
7421
|
"route-handler-shape": routeHandlerShapeRule,
|
|
7525
7422
|
"http-error-usage": httpErrorUsageRule,
|
|
7526
7423
|
"with-response-helper": withResponseHelperRule,
|
|
7424
|
+
"zod-fetch-helper": zodFetchHelperRule,
|
|
7527
7425
|
"hook-complexity": hookComplexityRule,
|
|
7528
7426
|
"locale-dotted-path": localeDottedPathRule,
|
|
7529
7427
|
"locales-location": localesLocationRule,
|
|
@@ -7628,11 +7526,6 @@ var zirkaConfig = {
|
|
|
7628
7526
|
plugins: { pasika: pasikaPlugin },
|
|
7629
7527
|
rules: { "pasika/zirka-baseline": "error" }
|
|
7630
7528
|
};
|
|
7631
|
-
var nextjsHelperConfig = {
|
|
7632
|
-
files: ["eslint.config.{ts,mts,cts,js,mjs,cjs}"],
|
|
7633
|
-
plugins: { pasika: pasikaPlugin },
|
|
7634
|
-
rules: { "pasika/cn-helper": "error", "pasika/with-response-helper": "error" }
|
|
7635
|
-
};
|
|
7636
7529
|
var documentationConfig = {
|
|
7637
7530
|
files: ["docs/**/*.md"],
|
|
7638
7531
|
// vulyk-generated agent files are not authored docs: with per-directory
|
|
@@ -7662,7 +7555,6 @@ var pasikaNextjsAppWithDiagnostic = (preset) => {
|
|
|
7662
7555
|
var pasikaNextjsApp = pasikaNextjsAppWithDiagnostic([
|
|
7663
7556
|
...pasikaApp,
|
|
7664
7557
|
pasikaNextjsAppPackageJsonConfig,
|
|
7665
|
-
nextjsHelperConfig,
|
|
7666
7558
|
pasikaNextjsAppConfig,
|
|
7667
7559
|
tailwindStructureRules,
|
|
7668
7560
|
tailwindImportGraph
|