pasika 0.10.7 → 0.10.10

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.
@@ -1524,7 +1524,8 @@ var enforceBarrelExportsRule = {
1524
1524
  const filename = context.filename;
1525
1525
  if (!filename) return {};
1526
1526
  const baseName = path9.basename(filename);
1527
- if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
1527
+ const isIndexFile = baseName === "index.ts";
1528
+ if (!isIndexFile) return {};
1528
1529
  const dirPath = path9.dirname(filename);
1529
1530
  const folderName = path9.basename(dirPath);
1530
1531
  const parentFolderName = path9.basename(path9.dirname(dirPath));
@@ -1565,10 +1566,11 @@ var enforceBarrelExportsRule = {
1565
1566
  };
1566
1567
 
1567
1568
  // eslint/rules/component-placement.ts
1568
- import fs2 from "fs";
1569
+ import fs3 from "fs";
1569
1570
  import path11 from "path";
1570
1571
 
1571
1572
  // eslint/project/ccf.ts
1573
+ import fs2 from "fs";
1572
1574
  import path10 from "path";
1573
1575
  var SUPPORT_FOLDERS2 = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
1574
1576
  function segmentsOf(file, sourceRoot) {
@@ -1623,14 +1625,24 @@ function resolveComponentPlacement(componentFile, index) {
1623
1625
  return { countedConsumers: counted, expectedFolder: shared, reason: "ccf" };
1624
1626
  }
1625
1627
  var formatFolder = (folder) => `src/${folder.join("/")}/`;
1628
+ function isValidComponentFolder(folder, sourceRoot) {
1629
+ const name = folder[folder.length - 1];
1630
+ if (!name || SUPPORT_FOLDERS2.has(name)) return false;
1631
+ const folderPath = path10.join(sourceRoot, ...folder);
1632
+ return fs2.existsSync(path10.join(folderPath, `${name}.tsx`)) && fs2.existsSync(path10.join(folderPath, "index.ts"));
1633
+ }
1626
1634
  function owningFolderOf(consumer, sourceRoot) {
1627
- return outOfSupportFolders(folderSegmentsOf(consumer, sourceRoot));
1635
+ const result = outOfSupportFolders(folderSegmentsOf(consumer, sourceRoot));
1636
+ const [topLevel] = result;
1637
+ let minimumDepth = result.length;
1638
+ if (topLevel === "features") minimumDepth = 2;
1639
+ if (topLevel === "compositions" || topLevel === "shared") minimumDepth = 1;
1640
+ while (result.length > minimumDepth && !isValidComponentFolder(result, sourceRoot)) result.pop();
1641
+ return result;
1628
1642
  }
1629
1643
  var configModuleOf = (segments) => isConfigModule(segments) && segments.length >= 3 ? segments[1] : void 0;
1630
- function resolveSupportPlacement(supportFile, supportFolder, index) {
1631
- const consumers = [...index.consumers.get(supportFile) ?? []].filter(
1632
- (consumer) => isPlacingConsumer(consumer, index.sourceRoot)
1633
- );
1644
+ function resolveSupportPlacement(supportFile, supportFolder, index, importedBy = index.consumers.get(supportFile) ?? []) {
1645
+ const consumers = [...importedBy].filter((consumer) => isPlacingConsumer(consumer, index.sourceRoot));
1634
1646
  if (consumers.length === 0) return void 0;
1635
1647
  const consumerSegments = consumers.map((consumer) => segmentsOf(consumer, index.sourceRoot));
1636
1648
  const configModules = new Set(consumerSegments.map((segments) => configModuleOf(segments)));
@@ -1670,7 +1682,7 @@ function isNestedInside(expectedFolder, currentFolder, componentFile) {
1670
1682
  if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
1671
1683
  const folderName = currentFolder[currentFolder.length - 1];
1672
1684
  if (!folderName) return false;
1673
- return fs2.existsSync(path11.join(path11.dirname(componentFile), `${folderName}.tsx`));
1685
+ return fs3.existsSync(path11.join(path11.dirname(componentFile), `${folderName}.tsx`));
1674
1686
  }
1675
1687
  var componentPlacementRule = {
1676
1688
  meta: {
@@ -1722,6 +1734,12 @@ var componentPlacementRule = {
1722
1734
  // eslint/rules/support-file-placement.ts
1723
1735
  import path12 from "path";
1724
1736
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
1737
+ var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
1738
+ ["constants", "constant"],
1739
+ ["schemas", "schema"],
1740
+ ["types", "type"],
1741
+ ["utils", "function"]
1742
+ ]);
1725
1743
  var REASON_TEXT2 = {
1726
1744
  "config-module": "every file that imports it belongs to that configuration module",
1727
1745
  ccf: "that is the closest folder its consumers share",
@@ -1745,6 +1763,33 @@ var supportFilePlacementRule = {
1745
1763
  if (supportFolder === void 0 || !SUPPORT_FOLDERS2.has(supportFolder)) return {};
1746
1764
  const index = getProjectIndex(sourceRoot);
1747
1765
  if (!index) return {};
1766
+ const groupedExportKind = EXPORT_KIND_BY_SUPPORT_FOLDER.get(supportFolder);
1767
+ if (groupedExportKind !== void 0) {
1768
+ const utilityExports = index.modules.get(supportFile)?.exports.filter((entry) => entry.kind === groupedExportKind) ?? [];
1769
+ const placements = utilityExports.map((entry) => ({
1770
+ name: entry.name,
1771
+ placement: resolveSupportPlacement(
1772
+ supportFile,
1773
+ supportFolder,
1774
+ index,
1775
+ index.symbolConsumers.get(symbolKey(supportFile, entry.name))
1776
+ )
1777
+ })).filter(
1778
+ (entry) => entry.placement !== void 0
1779
+ );
1780
+ const folders = new Set(placements.map((entry) => formatFolder(entry.placement.expectedFolder)));
1781
+ if (folders.size > 1) {
1782
+ return {
1783
+ Program(node) {
1784
+ context.report({
1785
+ node,
1786
+ loc: { line: 1, column: 0 },
1787
+ message: `Split ${supportFolder} exports with different CCFs: ${placements.map((entry) => `${entry.name} \u2192 ${formatFolder(entry.placement.expectedFolder)}`).join(", ")}.`
1788
+ });
1789
+ }
1790
+ };
1791
+ }
1792
+ }
1748
1793
  const placement = resolveSupportPlacement(supportFile, supportFolder, index);
1749
1794
  if (!placement || sameFolder2(currentFolder, placement.expectedFolder)) return {};
1750
1795
  if (isConfigModule(segmentsOf(supportFile, sourceRoot)) && CONFIG_OWNED_FOLDERS.has(supportFolder)) {
@@ -1763,7 +1808,7 @@ var supportFilePlacementRule = {
1763
1808
  };
1764
1809
 
1765
1810
  // eslint/rules/application-structure.ts
1766
- import fs3 from "fs";
1811
+ import fs4 from "fs";
1767
1812
  import path13 from "path";
1768
1813
  var MODULE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
1769
1814
  var ROUTING_FILES = /* @__PURE__ */ new Set([
@@ -1830,6 +1875,9 @@ function componentFolderStart(segments) {
1830
1875
  if (segments[0] === "compositions" || segments[0] === "shared") return 1;
1831
1876
  return -1;
1832
1877
  }
1878
+ function hasComponentBarrel(folderPath) {
1879
+ return fs4.existsSync(path13.join(folderPath, "index.ts"));
1880
+ }
1833
1881
  function componentFolderViolation(segments, sourceRoot) {
1834
1882
  const start = componentFolderStart(segments);
1835
1883
  if (start < 0) return void 0;
@@ -1838,10 +1886,10 @@ function componentFolderViolation(segments, sourceRoot) {
1838
1886
  if (!folder || SUPPORT_FOLDERS2.has(folder)) continue;
1839
1887
  const folderPath = path13.join(sourceRoot, ...segments.slice(0, depth + 1));
1840
1888
  const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
1841
- if (!fs3.existsSync(path13.join(folderPath, `${folder}.tsx`))) {
1889
+ if (!fs4.existsSync(path13.join(folderPath, `${folder}.tsx`))) {
1842
1890
  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.`;
1843
1891
  }
1844
- if (!fs3.existsSync(path13.join(folderPath, "index.ts"))) {
1892
+ if (!hasComponentBarrel(folderPath)) {
1845
1893
  return `A component folder must have an index.ts that named-re-exports its component; add index.ts to ${label}.`;
1846
1894
  }
1847
1895
  }
@@ -1887,7 +1935,7 @@ var applicationStructureRule = {
1887
1935
  );
1888
1936
  }
1889
1937
  const moduleRoot = configModuleRoot(filename, sourceRoot);
1890
- if (moduleRoot && !fs3.existsSync(path13.join(moduleRoot, "index.ts"))) {
1938
+ if (moduleRoot && !fs4.existsSync(path13.join(moduleRoot, "index.ts"))) {
1891
1939
  return report2(
1892
1940
  context,
1893
1941
  `Add src/config/${path13.basename(moduleRoot)}/index.ts as the configuration module entry point.`
@@ -2082,7 +2130,7 @@ function toKebabCase(value) {
2082
2130
  }
2083
2131
 
2084
2132
  // eslint/rules/support-folder-shape.ts
2085
- import fs4 from "fs";
2133
+ import fs5 from "fs";
2086
2134
  import path16 from "path";
2087
2135
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
2088
2136
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
@@ -2103,7 +2151,7 @@ var supportFolderShapeRule = {
2103
2151
  const directory = path16.dirname(filename);
2104
2152
  let entries;
2105
2153
  try {
2106
- entries = fs4.readdirSync(directory);
2154
+ entries = fs5.readdirSync(directory);
2107
2155
  } catch {
2108
2156
  return {};
2109
2157
  }
@@ -4766,7 +4814,7 @@ var sourceUnderSrcRule = {
4766
4814
  };
4767
4815
 
4768
4816
  // eslint/rules/zirka-baseline.ts
4769
- import fs5 from "fs";
4817
+ import fs6 from "fs";
4770
4818
  import path44 from "path";
4771
4819
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
4772
4820
  var PRETTIER_CONFIGS = [
@@ -4805,12 +4853,12 @@ var zirkaBaselineRule = {
4805
4853
  );
4806
4854
  }
4807
4855
  const tsconfigPath = path44.join(projectRoot, "tsconfig.json");
4808
- if (!fs5.existsSync(tsconfigPath)) {
4856
+ if (!fs6.existsSync(tsconfigPath)) {
4809
4857
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
4810
4858
  } else {
4811
4859
  let extendsValue;
4812
4860
  try {
4813
- const parsed = JSON.parse(fs5.readFileSync(tsconfigPath, "utf8"));
4861
+ const parsed = JSON.parse(fs6.readFileSync(tsconfigPath, "utf8"));
4814
4862
  extendsValue = typeof parsed === "object" && parsed !== null && "extends" in parsed ? parsed.extends : void 0;
4815
4863
  } catch {
4816
4864
  report3(
@@ -4822,13 +4870,13 @@ var zirkaBaselineRule = {
4822
4870
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
4823
4871
  }
4824
4872
  }
4825
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(path44.join(projectRoot, name)));
4873
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs6.existsSync(path44.join(projectRoot, name)));
4826
4874
  if (!prettierConfigFile) {
4827
4875
  report3(
4828
4876
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
4829
4877
  );
4830
4878
  } else {
4831
- const content = fs5.readFileSync(path44.join(projectRoot, prettierConfigFile), "utf8");
4879
+ const content = fs6.readFileSync(path44.join(projectRoot, prettierConfigFile), "utf8");
4832
4880
  if (!content.includes("zirka")) {
4833
4881
  report3(
4834
4882
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.7",
3
+ "version": "0.10.10",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",