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.
@@ -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 ESLINT_CONFIG = /^eslint\.config\.(?:cjs|cts|js|mjs|mts|ts)$/;
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 a repository to define a ${HELPER} helper that returns twMerge(clsx(...)).`
1406
+ description: `Require ${HELPER} to be imported from ${ENTRY} rather than declared in the repository.`
1433
1407
  }
1434
1408
  },
1435
1409
  create(context) {
1436
- if (ESLINT_CONFIG.test(path9.basename(context.filename))) {
1437
- return {
1438
- Program() {
1439
- if (definesHelper(context, HELPER)) return;
1440
- context.report({
1441
- node: context.sourceCode.ast,
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)) check(node.body, node);
1419
+ if (isNamed(node.id, HELPER)) context.report({ node, message: DECLARED });
1458
1420
  },
1459
1421
  VariableDeclarator(node) {
1460
- if (!isNamed(node.id.type === "Identifier" ? node.id : null, HELPER)) return;
1461
- const init = node.init;
1462
- if (init?.type !== "ArrowFunctionExpression" && init?.type !== "FunctionExpression") return;
1463
- check(init.body, node);
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 path10 from "path";
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 = path10.join(dirPath, `${folderName}.tsx`);
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 = path10.basename(filename);
1526
+ const baseName = path9.basename(filename);
1564
1527
  if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
1565
- const dirPath = path10.dirname(filename);
1566
- const folderName = path10.basename(dirPath);
1567
- const parentFolderName = path10.basename(path10.dirname(dirPath));
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 path12 from "path";
1569
+ import path11 from "path";
1607
1570
 
1608
1571
  // eslint/project/ccf.ts
1609
- import path11 from "path";
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 = path11.relative(sourceRoot, file);
1613
- return relative.startsWith("..") ? [] : relative.split(path11.sep);
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) => path11.relative(path11.dirname(sourceRoot), consumer).split(path11.sep).join("/")).sort((left, right) => left.localeCompare(right));
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(path12.join(path12.dirname(componentFile), `${folderName}.tsx`));
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 = path12.resolve(filename);
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 path13 from "path";
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 = path13.resolve(context.filename);
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 path14 from "path";
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(path14.extname(filename));
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 path14.join(sourceRoot, "config", segments[1] ?? "");
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 = path14.join(sourceRoot, ...segments.slice(0, depth + 1));
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(path14.join(folderPath, `${folder}.tsx`))) {
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(path14.join(folderPath, "index.ts"))) {
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 = path14.resolve(context.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(path14.join(moduleRoot, "index.ts"))) {
1890
+ if (moduleRoot && !fs3.existsSync(path13.join(moduleRoot, "index.ts"))) {
1928
1891
  return report2(
1929
1892
  context,
1930
- `Add src/config/${path14.basename(moduleRoot)}/index.ts as the configuration module entry point.`
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 && path14.basename(filename) !== "index.ts") {
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/${path14.basename(moduleRoot)}/${expected2}/.`
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 = path14.basename(filename, path14.extname(filename));
1946
- const currentFolder2 = path14.basename(path14.dirname(filename));
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) && path14.extname(filename) !== ".css") {
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) || path14.extname(filename) === ".css") return {};
1922
+ if (ROUTING_FILES.has(basename) || path13.extname(filename) === ".css") return {};
1960
1923
  }
1961
- const currentFolder = path14.basename(path14.dirname(filename));
1924
+ const currentFolder = path13.basename(path13.dirname(filename));
1962
1925
  const kinds = exportedKinds(filename);
1963
- const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path14.basename(filename) === "index.ts";
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 ${path14.basename(filename)} beside ${currentFolder}/.`
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 path15 from "path";
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(path15.sep, "/");
1982
+ const normalized = filename.replaceAll(path14.sep, "/");
2020
1983
  if (!normalized.includes("/src/app/")) return false;
2021
- const basename = path15.basename(filename, path15.extname(filename));
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 path16 from "path";
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 = path16.resolve(context.filename);
2042
+ const filename = path15.resolve(context.filename);
2080
2043
  if (!filename.endsWith(".tsx")) return {};
2081
- const base = path16.basename(filename, path16.extname(filename));
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 path17 from "path";
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 = path17.resolve(context.filename);
2136
- const baseName = path17.basename(filename);
2098
+ const filename = path16.resolve(context.filename);
2099
+ const baseName = path16.basename(filename);
2137
2100
  if (!INDEX_NAMES.has(baseName)) return {};
2138
- const folder = path17.basename(path17.dirname(filename));
2101
+ const folder = path16.basename(path16.dirname(filename));
2139
2102
  if (!SUPPORT_FOLDERS3.has(folder)) return {};
2140
- const directory = path17.dirname(filename);
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(path17.basename(specifier));
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 path18 from "path";
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 = path18.resolve(context.filename);
2161
+ const filename = path17.resolve(context.filename);
2199
2162
  const sourceRoot = sourceRootOf(context);
2200
- if (!filename.startsWith(sourceRoot + path18.sep)) return {};
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 path19 from "path";
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 = path19.resolve(context.filename);
2204
+ const filename = path18.resolve(context.filename);
2242
2205
  const sourceRoot = sourceRootOf(context);
2243
- if (!filename.startsWith(sourceRoot + path19.sep)) return {};
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 path20 from "path";
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 = path20.resolve(context.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 || path20.basename(target).startsWith("index.")) continue;
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 = `${path20.sep}src${path20.sep}`;
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 path20.resolve(context.cwd ?? process.cwd(), "src");
2271
+ return path19.resolve(context.cwd ?? process.cwd(), "src");
2309
2272
  }
2310
2273
 
2311
2274
  // eslint/rules/util-file-name.ts
2312
- import path21 from "path";
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 = path21.resolve(context.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 = path21.basename(filename, path21.extname(filename));
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}.${path21.extname(filename).slice(1)}.`
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 path22 from "path";
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 = path22.resolve(context.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 || !path22.basename(target).startsWith("index.")) continue;
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 = `${path22.sep}src${path22.sep}`;
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 path22.resolve(context.cwd ?? process.cwd(), "src");
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 path23 from "path";
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 = path23.resolve(context.filename);
2644
- const base = path23.basename(filename, path23.extname(filename));
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 path24 from "path";
2858
+ import path23 from "path";
2896
2859
  var FEATURES_SEGMENT = "features";
2897
2860
  function featureNameOf(resolvedPath, sourceRoot) {
2898
- const relative = path24.relative(sourceRoot, resolvedPath);
2861
+ const relative = path23.relative(sourceRoot, resolvedPath);
2899
2862
  if (relative.startsWith("..")) return void 0;
2900
- const segments = relative.split(path24.sep);
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 = path24.relative(sourceRoot, filename);
2879
+ const fileRelative = path23.relative(sourceRoot, filename);
2917
2880
  if (fileRelative.startsWith("..")) return {};
2918
- const fileSegments = fileRelative.split(path24.sep);
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 = path24.resolve(sourceRoot, source.value.slice(2));
2895
+ resolved = path23.resolve(sourceRoot, source.value.slice(2));
2933
2896
  } else if (source.value.startsWith(".")) {
2934
- resolved = path24.resolve(path24.dirname(filename), source.value);
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 path25 from "path";
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 = path25.basename(filename) === "route.ts";
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 = path25.relative(sourceRoot, filename);
2963
+ const relative = path24.relative(sourceRoot, filename);
3001
2964
  if (relative.startsWith("..")) return {};
3002
- const segments = relative.split(path25.sep);
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 path26 from "path";
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 = path26.resolve(context.filename);
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 path27 from "path";
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 (path27.basename(context.filename) !== "route.ts") return {};
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) return;
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 path28 from "path";
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(path28.resolve(file));
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 = path28.resolve(file);
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) => path28.basename(file) === ROUTE_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 = path28.resolve(context.filename);
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 ESLINT_CONFIG2 = /^eslint\.config\.(?:cjs|cts|js|mjs|mts|ts)$/;
3390
- var BEAT_KEYS = [
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
- function sourceRootFor2(context) {
3410
- return path29.join(path29.dirname(path29.resolve(context.filename)), "src");
3411
- }
3412
- function definesHelper2(context, name) {
3413
- const index = getProjectIndex(sourceRootFor2(context));
3414
- if (!index) return true;
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
- ts6.forEachChild(current, visit);
3442
- };
3443
- visit(node);
3444
- return found;
3445
- }
3446
- function awaitsHandlerCall(handlerName) {
3447
- return (node) => ts6.isAwaitExpression(node) && ts6.isCallExpression(node.expression) && ts6.isIdentifier(node.expression.expression) && node.expression.expression.text === handlerName;
3448
- }
3449
- function parsesThroughSchema(schemaName) {
3450
- return (node) => ts6.isCallExpression(node) && ts6.isPropertyAccessExpression(node.expression) && ts6.isIdentifier(node.expression.expression) && node.expression.expression.text === schemaName && (node.expression.name.text === "parse" || node.expression.name.text === "safeParse");
3451
- }
3452
- function checksHttpError(node) {
3453
- return ts6.isBinaryExpression(node) && node.operatorToken.kind === ts6.SyntaxKind.InstanceOfKeyword && ts6.isIdentifier(node.right) && node.right.text === "HttpError";
3454
- }
3455
- function answersWithNullData(node) {
3456
- if (!ts6.isCallExpression(node) || !ts6.isPropertyAccessExpression(node.expression) || node.expression.name.text !== "json") {
3457
- return false;
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
- return node.arguments.some((argument) => {
3460
- if (!ts6.isObjectLiteralExpression(argument)) return false;
3461
- return argument.properties.some((property) => {
3462
- if (!ts6.isPropertyAssignment(property)) return false;
3463
- const name = ts6.isIdentifier(property.name) ? property.name.text : void 0;
3464
- return name === "data" && property.initializer.kind === ts6.SyntaxKind.NullKeyword;
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 readsErrorStatus(errorName) {
3469
- return (node) => ts6.isPropertyAccessExpression(node) && node.name.text === "status" && ts6.isIdentifier(node.expression) && node.expression.text === errorName;
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 withResponseHelperRule = {
3408
+ var zodFetchHelperRule = {
3502
3409
  meta: {
3503
3410
  schema: [],
3504
3411
  type: "problem",
3505
3412
  docs: {
3506
- description: `Require a repository to define a ${HELPER2} helper that validates the handler's data and maps a thrown HttpError to a response.`
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
- if (ESLINT_CONFIG2.test(path29.basename(context.filename))) {
3511
- return {
3512
- Program() {
3513
- if (definesHelper2(context, HELPER2)) return;
3514
- context.report({
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 (isNamed2(node.id, HELPER2)) check(node, parameterNames(node));
3430
+ if (isNamed3(node.id, HELPER3)) context.report({ node, message: DECLARED3 });
3536
3431
  },
3537
3432
  VariableDeclarator(node) {
3538
- if (!isNamed2(node.id.type === "Identifier" ? node.id : null, HELPER2)) return;
3539
- const init = node.init;
3540
- if (init?.type !== "ArrowFunctionExpression" && init?.type !== "FunctionExpression") return;
3541
- check(init, parameterNames(init));
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 path30 from "path";
3549
- import ts7 from "typescript";
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 ts7.isPropertyAccessExpression(node.expression) ? node.expression.name.text : void 0;
3473
+ return ts6.isPropertyAccessExpression(node.expression) ? node.expression.name.text : void 0;
3578
3474
  }
3579
3475
  function calledOnObjectName(node) {
3580
- if (!ts7.isPropertyAccessExpression(node.expression)) return void 0;
3476
+ if (!ts6.isPropertyAccessExpression(node.expression)) return void 0;
3581
3477
  const object = node.expression.expression;
3582
- return ts7.isIdentifier(object) ? object.text : void 0;
3478
+ return ts6.isIdentifier(object) ? object.text : void 0;
3583
3479
  }
3584
3480
  function calledHookName(node) {
3585
- return ts7.isCallExpression(node) && ts7.isIdentifier(node.expression) && REACT_HOOKS.has(node.expression.text) ? node.expression.text : void 0;
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 (ts7.isAwaitExpression(node)) return "externalIO";
3589
- if (ts7.isNewExpression(node) && ts7.isIdentifier(node.expression) && DOM_CONSTRUCTORS.has(node.expression.text)) {
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 (ts7.isPropertyAccessExpression(node) && DOM_PROPERTIES.has(node.name.text)) {
3488
+ if (ts6.isPropertyAccessExpression(node) && DOM_PROPERTIES.has(node.name.text)) {
3593
3489
  return "domManipulation";
3594
3490
  }
3595
- if (ts7.isCallExpression(node)) {
3596
- if (ts7.isIdentifier(node.expression) && node.expression.text === "fetch") return "externalIO";
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 = ts7.createSourceFile(
3505
+ const sourceFile = ts6.createSourceFile(
3610
3506
  "hook.ts",
3611
3507
  sourceText.slice(start, end),
3612
- ts7.ScriptTarget.Latest,
3508
+ ts6.ScriptTarget.Latest,
3613
3509
  true,
3614
- ts7.ScriptKind.TS
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
- ts7.forEachChild(node, visit);
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 = path30.relative(sourceRoot, filename);
3536
+ const relative = path28.relative(sourceRoot, filename);
3641
3537
  if (relative.startsWith("..")) return {};
3642
- const segments = relative.split(path30.sep);
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 path31 from "path";
3580
+ import path29 from "path";
3685
3581
  function isInLocalesDir(filename) {
3686
- const segments = path31.resolve(filename).split(path31.sep);
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 path32 from "path";
3631
+ import path30 from "path";
3736
3632
  function isLocalesFile(filename) {
3737
- const segments = path32.resolve(filename).split(path32.sep);
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 = path32.resolve(filename).split(path32.sep);
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 path33 from "path";
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 = path33.resolve(context.filename);
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 path34 from "path";
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 = path34.resolve(context.filename);
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 path35 from "path";
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 = path35.resolve(context.filename);
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 path36 from "path";
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 = path36.resolve(context.filename);
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 path37 from "path";
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 = path37.resolve(context.filename);
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 path38 from "path";
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 = path38.resolve(context.filename);
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 path39 from "path";
3952
+ import path37 from "path";
4057
3953
  import { readFileSync as readFileSync5 } from "fs";
4058
- import ts8 from "typescript";
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 = ts8.createSourceFile("locales.ts", text, ts8.ScriptTarget.Latest, true, ts8.ScriptKind.TS);
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 (!ts8.isVariableStatement(statement)) continue;
4069
- const isExported2 = (ts8.getModifiers(statement) ?? []).some(
4070
- (modifier) => modifier.kind === ts8.SyntaxKind.ExportKeyword
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 (!ts8.isIdentifier(declaration.name) || declaration.name.text !== "locales") continue;
4075
- if (!declaration.initializer || !ts8.isObjectLiteralExpression(declaration.initializer)) continue;
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 (!ts8.isPropertyAssignment(property)) continue;
3974
+ if (!ts7.isPropertyAssignment(property)) continue;
4079
3975
  let name;
4080
- if (ts8.isIdentifier(property.name)) name = property.name.text;
4081
- else if (ts8.isStringLiteral(property.name)) name = property.name.text;
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: ts8.isObjectLiteralExpression(property.initializer) ? "nested" : "top",
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 = path39.resolve(context.filename);
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 path40 from "path";
4183
- import ts9 from "typescript";
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 (ts9.isCallExpression(child) && ts9.isIdentifier(child.expression) && child.expression.text === "useState") {
4188
- if (ts9.isVariableDeclaration(child.parent)) {
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 (ts9.isArrayBindingPattern(name) && name.elements.length >= 2) {
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 && ts9.isBindingElement(value) && ts9.isBindingElement(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 (ts9.isIdentifier(valueName) && ts9.isIdentifier(updaterName)) {
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
- ts9.forEachChild(child, visit);
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 (ts9.isCallExpression(node) && ts9.isIdentifier(node.expression) && node.expression.text === hook.updater) {
4105
+ if (ts8.isCallExpression(node) && ts8.isIdentifier(node.expression) && node.expression.text === hook.updater) {
4210
4106
  return "updater";
4211
4107
  }
4212
- if (ts9.isIdentifier(node) && node.text === hook.value) {
4108
+ if (ts8.isIdentifier(node) && node.text === hook.value) {
4213
4109
  const parent = node.parent;
4214
- if (ts9.isBindingElement(parent) || ts9.isPropertyAccessExpression(parent) || ts9.isShorthandPropertyAssignment(parent)) {
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 (ts9.isParenthesizedExpression(expression)) expression = expression.expression;
4225
- if (ts9.isJsxFragment(expression)) {
4120
+ while (ts8.isParenthesizedExpression(expression)) expression = expression.expression;
4121
+ if (ts8.isJsxFragment(expression)) {
4226
4122
  const children = expression.children.filter(
4227
- (c) => !ts9.isJsxText(c) && !ts9.isJsxSpreadAttribute(c)
4123
+ (c) => !ts8.isJsxText(c) && !ts8.isJsxSpreadAttribute(c)
4228
4124
  );
4229
4125
  return { root: expression, children };
4230
4126
  }
4231
- if (ts9.isJsxElement(expression)) {
4127
+ if (ts8.isJsxElement(expression)) {
4232
4128
  const children = expression.children.filter(
4233
- (c) => !ts9.isJsxText(c) && !ts9.isJsxSpreadAttribute(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 (ts9.isFunctionDeclaration(node) || ts9.isClassDeclaration(node)) return;
4248
- ts9.forEachChild(node, visit);
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 = path40.resolve(context.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 = ts9.isFunctionDeclaration(declaration) ? declaration.body : void 0;
4288
- if (!body || !ts9.isBlock(body)) return void 0;
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 && (ts9.isFunctionLike(node) || ts9.isClassLike(node))) return;
4292
- if (ts9.isReturnStatement(node)) returns.push(node);
4293
- ts9.forEachChild(node, visit);
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 || !ts9.isExpression(single.expression)) return void 0;
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 && (ts9.isFunctionDeclaration(node) || ts9.isClassDeclaration(node))) return;
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 (!ts9.isSourceFile(current)) {
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
- ts9.forEachChild(node, visit);
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 path41 from "path";
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 = path41.resolve(filename).split(path41.sep);
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 path42 from "path";
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 = path42.resolve(context.filename);
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 path43 from "path";
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 = path43.resolve(context.filename);
4628
+ const filename = path41.resolve(context.filename);
4733
4629
  const sourceRoot = sourceRootOf(context);
4734
- if (!filename.startsWith(sourceRoot + path43.sep)) return {};
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 path44 from "path";
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 = path44.resolve(context.filename);
4675
+ const filename = path42.resolve(context.filename);
4780
4676
  const sourceRoot = sourceRootOf(context);
4781
- if (!filename.startsWith(sourceRoot + path44.sep)) return {};
4782
- if (path44.extname(filename) !== ".tsx") return {};
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 path45 from "path";
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 = path45.resolve(context.filename);
4736
+ const filename = path43.resolve(context.filename);
4841
4737
  if (!MODULE_EXTENSION.test(filename)) return {};
4842
- const relative = path45.relative(context.cwd, filename).replace(/\\/g, "/");
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 = path45.basename(filename);
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 path46 from "path";
4865
- var ESLINT_CONFIG3 = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
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 = path46.resolve(context.filename);
4884
- const basename = path46.basename(filename);
4885
- if (!ESLINT_CONFIG3.test(basename)) return {};
4886
- const projectRoot = path46.dirname(filename);
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 = path46.join(projectRoot, "tsconfig.json");
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(path46.join(projectRoot, name)));
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(path46.join(projectRoot, prettierConfigFile), "utf8");
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 path47 from "path";
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 = path47.basename(filename);
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 path48 from "path";
5387
+ import path46 from "path";
5492
5388
  function checkPlacement(filename, kind) {
5493
- const parentFolder = path48.basename(path48.dirname(filename));
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 = path48.dirname(path48.dirname(filename));
5499
- const guideFolder = path48.basename(guideFolderPath);
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(path48.join(guideFolderPath, entryPoint))) {
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 path50 from "path";
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 path49 from "path";
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 = path49.join(dir, entry);
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 = path49.basename(filePath);
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: path49.relative(docsRoot, filePath).split(path49.sep).join("/"),
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 = path49.dirname(filePath);
5504
+ let dir = path47.dirname(filePath);
5609
5505
  for (; ; ) {
5610
- if (path49.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
5506
+ if (path47.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
5611
5507
  return dir;
5612
5508
  }
5613
- const parent = path49.dirname(dir);
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(path50.basename(path50.dirname(doc.filePath)))).map((doc) => path50.dirname(path50.dirname(doc.filePath))).filter((folder) => path50.resolve(folder) !== path50.resolve(docsRoot))
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 = path50.dirname(filename);
5535
+ const currentDir = path48.dirname(filename);
5640
5536
  if (guideFolders.has(currentDir)) {
5641
- const expectedEntryPoint = `${path50.basename(currentDir)}.md`;
5537
+ const expectedEntryPoint = `${path48.basename(currentDir)}.md`;
5642
5538
  const hasEntryPoint = docs.some(
5643
- (doc) => doc.kind === "guide" && path50.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
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 path51 from "path";
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 = path51.resolve(path51.dirname(filename), target);
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 path52 from "path";
5814
+ import path50 from "path";
5919
5815
  function isGlossary(filePath) {
5920
- return path52.basename(filePath).includes("glossary");
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 = path52.dirname(filename);
6014
- const referencesDir = path52.join(guideDir, "references");
5909
+ const guideDir = path50.dirname(filename);
5910
+ const referencesDir = path50.join(guideDir, "references");
6015
5911
  const guideReferences = docs.filter(
6016
- (doc) => doc.kind === "reference" && path52.dirname(doc.filePath) === referencesDir
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 path52.resolve(guideDir, linkTarget(link)) === path52.resolve(ref.filePath);
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 path53 from "path";
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 = path53.dirname(filename);
6101
- if (path53.basename(filename, ".md") !== path53.basename(guideDir)) return;
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 = path53.dirname(doc.filePath);
6105
- return parent === path53.join(guideDir, "rules") || parent === path53.join(guideDir, "references");
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 = path53.normalize(path53.join(guideDir, target));
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 path56 from "path";
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 path54 from "path";
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 = path54.join(dir, entry);
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(path54.extname(entry)) ? [entryPath] : [];
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 path55 from "path";
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 path55.resolve(spec);
6746
- if (spec.startsWith("./") || spec.startsWith("../")) return path55.resolve(path55.dirname(fromFile), spec);
6747
- if (spec.startsWith("@/")) return path55.resolve(sourceRoot, spec.slice(2));
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) => path55.normalize(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(path55.normalize(global));
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 = path55.normalize(target);
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 = path55.normalize(target);
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 = path56.normalize(path56.resolve(context.filename));
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 = path56.basename(current);
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 path57 from "path";
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(path57.join(context.cwd, name)));
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(path57.join(context.cwd, configName), "utf8");
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 path58 from "path";
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 = path58.join(context.cwd, ".husky", "pre-commit");
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(path58.join(context.cwd, name)));
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 = path58.join(context.cwd, "eslint-suppressions.json");
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 path59 from "path";
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 = path59.dirname(path59.resolve(context.filename));
7401
- const configPath = path59.join(projectRoot, "vulyk.config.ts");
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 = path59.join(projectRoot, "AGENTS.md");
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