pasika 0.4.1 → 0.4.2

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.
@@ -478,6 +478,397 @@ var noArbitraryTailwindRule = {
478
478
  }
479
479
  };
480
480
 
481
+ // eslint/rules/unknown-utility.ts
482
+ import { readdirSync, readFileSync, statSync } from "fs";
483
+ import path4 from "path";
484
+ var PREFIX_NAMESPACES = {
485
+ bg: ["color"],
486
+ text: ["color", "text"],
487
+ border: ["color"],
488
+ ring: ["color"],
489
+ fill: ["color"],
490
+ stroke: ["color"],
491
+ accent: ["color"],
492
+ caret: ["color"],
493
+ decoration: ["color"],
494
+ outline: ["color"],
495
+ divide: ["color"],
496
+ from: ["color"],
497
+ via: ["color"],
498
+ to: ["color"],
499
+ shadow: ["color", "shadow"],
500
+ rounded: ["radius"],
501
+ font: ["font"],
502
+ tracking: ["tracking"],
503
+ leading: ["leading"],
504
+ opacity: ["opacity"],
505
+ z: ["z"],
506
+ blur: ["blur"],
507
+ "backdrop-blur": ["blur"],
508
+ "ring-offset": ["color"]
509
+ };
510
+ var PREFIX_BUILTINS = {
511
+ bg: [
512
+ "none",
513
+ "cover",
514
+ "contain",
515
+ "auto",
516
+ "fixed",
517
+ "local",
518
+ "scroll",
519
+ "center",
520
+ "top",
521
+ "bottom",
522
+ "left",
523
+ "right",
524
+ "left-top",
525
+ "left-bottom",
526
+ "right-top",
527
+ "right-bottom",
528
+ "repeat",
529
+ "no-repeat",
530
+ "repeat-x",
531
+ "repeat-y",
532
+ "repeat-round",
533
+ "repeat-space",
534
+ "clip-border",
535
+ "clip-padding",
536
+ "clip-content",
537
+ "clip-text",
538
+ "origin-border",
539
+ "origin-padding",
540
+ "origin-content",
541
+ "gradient-to-t",
542
+ "gradient-to-tr",
543
+ "gradient-to-r",
544
+ "gradient-to-br",
545
+ "gradient-to-b",
546
+ "gradient-to-bl",
547
+ "gradient-to-l",
548
+ "gradient-to-tl",
549
+ "linear-to-t",
550
+ "linear-to-tr",
551
+ "linear-to-r",
552
+ "linear-to-br",
553
+ "linear-to-b",
554
+ "linear-to-bl",
555
+ "linear-to-l",
556
+ "linear-to-tl"
557
+ ],
558
+ text: [
559
+ "left",
560
+ "center",
561
+ "right",
562
+ "justify",
563
+ "start",
564
+ "end",
565
+ "wrap",
566
+ "nowrap",
567
+ "balance",
568
+ "pretty",
569
+ "ellipsis",
570
+ "clip",
571
+ "truncate",
572
+ "uppercase",
573
+ "lowercase",
574
+ "capitalize",
575
+ "normal-case",
576
+ "underline",
577
+ "overline",
578
+ "line-through",
579
+ "no-underline"
580
+ ],
581
+ border: [
582
+ "solid",
583
+ "dashed",
584
+ "dotted",
585
+ "double",
586
+ "hidden",
587
+ "none",
588
+ "collapse",
589
+ "separate",
590
+ "x",
591
+ "y",
592
+ "t",
593
+ "r",
594
+ "b",
595
+ "l",
596
+ "s",
597
+ "e"
598
+ ],
599
+ ring: ["inset"],
600
+ divide: ["x", "y", "reverse"],
601
+ from: ["t", "r", "b", "l", "tr", "tl", "br", "bl", "top", "right", "bottom", "left"],
602
+ via: ["t", "r", "b", "l", "tr", "tl", "br", "bl", "top", "right", "bottom", "left"],
603
+ to: ["t", "r", "b", "l", "tr", "tl", "br", "bl", "top", "right", "bottom", "left"],
604
+ fill: ["none"],
605
+ stroke: ["none"],
606
+ accent: ["auto"],
607
+ decoration: ["solid", "double", "dotted", "dashed", "wavy", "none"],
608
+ outline: ["none", "hidden", "dashed", "dotted", "double", "solid"],
609
+ font: ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black"]
610
+ };
611
+ var DEFAULT_TOKENS = {
612
+ text: ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl", "8xl", "9xl"],
613
+ radius: ["none", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "full"],
614
+ font: ["sans", "serif", "mono"],
615
+ shadow: ["2xs", "xs", "sm", "md", "lg", "xl", "2xl", "inner", "none"],
616
+ tracking: ["tighter", "tight", "normal", "wide", "wider", "widest"],
617
+ leading: ["none", "tight", "snug", "normal", "relaxed", "loose"],
618
+ opacity: [
619
+ "0",
620
+ "5",
621
+ "10",
622
+ "15",
623
+ "20",
624
+ "25",
625
+ "30",
626
+ "35",
627
+ "40",
628
+ "45",
629
+ "50",
630
+ "55",
631
+ "60",
632
+ "65",
633
+ "70",
634
+ "75",
635
+ "80",
636
+ "85",
637
+ "90",
638
+ "95",
639
+ "100"
640
+ ],
641
+ z: ["0", "10", "20", "30", "40", "50", "auto"],
642
+ blur: ["none", "xs", "sm", "md", "lg", "xl", "2xl", "3xl"],
643
+ animate: ["none", "spin", "ping", "pulse", "bounce"],
644
+ ease: ["linear", "in", "out", "in-out"],
645
+ aspect: ["auto", "video", "square"]
646
+ };
647
+ var DEFAULT_PALETTE_FAMILIES = /* @__PURE__ */ new Set([
648
+ "red",
649
+ "orange",
650
+ "amber",
651
+ "yellow",
652
+ "lime",
653
+ "green",
654
+ "emerald",
655
+ "teal",
656
+ "cyan",
657
+ "sky",
658
+ "blue",
659
+ "indigo",
660
+ "violet",
661
+ "purple",
662
+ "fuchsia",
663
+ "pink",
664
+ "rose",
665
+ "slate",
666
+ "gray",
667
+ "zinc",
668
+ "neutral",
669
+ "stone"
670
+ ]);
671
+ var DEFAULT_PALETTE_SHADES = /* @__PURE__ */ new Set(["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"]);
672
+ var DEFAULT_COLOR_SPECIALS = /* @__PURE__ */ new Set(["white", "black", "transparent", "current", "inherit"]);
673
+ var NUMERIC_TOKEN_RE = /^-?(?:\d+\.?\d*|\.\d+)(?:%|px|rem|em)?$/;
674
+ var SIDE_WIDTH_TOKEN_RE = /^(?:x|y|t|r|b|l|s|e)-(?:\d+\.?\d*|\.\d+)(?:%|px|rem|em)?$/;
675
+ var OFFSET_TOKEN_RE = /^offset-(?:\d+\.?\d*|\.\d+)(?:%|px|rem|em)?$/;
676
+ function stylesheetFiles(dir) {
677
+ let entries;
678
+ try {
679
+ entries = readdirSync(dir);
680
+ } catch {
681
+ return [];
682
+ }
683
+ return entries.flatMap((entry) => {
684
+ if (entry.startsWith(".") || entry === "node_modules") return [];
685
+ const entryPath = path4.join(dir, entry);
686
+ let stats;
687
+ try {
688
+ stats = statSync(entryPath);
689
+ } catch {
690
+ return [];
691
+ }
692
+ if (stats.isDirectory()) return stylesheetFiles(entryPath);
693
+ return path4.extname(entry) === ".css" ? [entryPath] : [];
694
+ });
695
+ }
696
+ function themeBlocks(css2) {
697
+ const blocks = [];
698
+ let index = 0;
699
+ while (index < css2.length) {
700
+ const match = /@theme(?:\s+inline)?\s*\{/.exec(css2.slice(index));
701
+ if (!match) break;
702
+ const open = index + match.index + match[0].length - 1;
703
+ let depth = 1;
704
+ let cursor = open + 1;
705
+ for (; cursor < css2.length && depth > 0; cursor++) {
706
+ if (css2[cursor] === "{") depth++;
707
+ else if (css2[cursor] === "}") depth--;
708
+ }
709
+ blocks.push(css2.slice(open + 1, cursor - 1));
710
+ index = cursor;
711
+ }
712
+ return blocks;
713
+ }
714
+ function readInventory(files) {
715
+ const utilities = /* @__PURE__ */ new Set();
716
+ const utilityPrefixes = /* @__PURE__ */ new Set();
717
+ const themeTokensByNamespace = /* @__PURE__ */ new Map();
718
+ let defaultsReset = false;
719
+ for (const file of files) {
720
+ let css2;
721
+ try {
722
+ css2 = readFileSync(file, "utf8");
723
+ } catch {
724
+ continue;
725
+ }
726
+ for (const name of css2.matchAll(/@utility\s+(?<utilityName>[a-zA-Z0-9_-]+)/g)) {
727
+ const utilityName = name.groups?.utilityName;
728
+ if (!utilityName) continue;
729
+ utilities.add(utilityName);
730
+ const dash = utilityName.indexOf("-");
731
+ if (dash > 0) utilityPrefixes.add(utilityName.slice(0, dash));
732
+ }
733
+ for (const block of themeBlocks(css2)) {
734
+ if (/--\*\s*:\s*initial\b/.test(block)) defaultsReset = true;
735
+ for (const decl of block.matchAll(/--(?<namespace>[a-z][a-z0-9]*)-(?<token>[a-z0-9][a-z0-9_-]*)\s*:/g)) {
736
+ const namespace = decl.groups?.namespace;
737
+ const token = decl.groups?.token;
738
+ if (!namespace || !token) continue;
739
+ let set = themeTokensByNamespace.get(namespace);
740
+ if (!set) {
741
+ set = /* @__PURE__ */ new Set();
742
+ themeTokensByNamespace.set(namespace, set);
743
+ }
744
+ set.add(token);
745
+ }
746
+ }
747
+ }
748
+ return { utilities, utilityPrefixes, themeTokens: themeTokensByNamespace, defaultsReset };
749
+ }
750
+ function isColorToken(token, inventory) {
751
+ if (inventory.themeTokens.get("color")?.has(token)) return true;
752
+ if (inventory.defaultsReset) return false;
753
+ if (DEFAULT_COLOR_SPECIALS.has(token)) return true;
754
+ const hyphen = token.lastIndexOf("-");
755
+ if (hyphen === -1) return false;
756
+ return DEFAULT_PALETTE_FAMILIES.has(token.slice(0, hyphen)) && DEFAULT_PALETTE_SHADES.has(token.slice(hyphen + 1));
757
+ }
758
+ function isKnown(className, inventory) {
759
+ if (className.includes("[") || className.includes("(")) return true;
760
+ const base = className.replace(/!+$/, "").split("/")[0] ?? "";
761
+ const segments = base.split(":");
762
+ const utility = segments[segments.length - 1] ?? "";
763
+ if (!utility.includes("-")) return true;
764
+ const dash = utility.indexOf("-");
765
+ const firstTwo = utility.split("-").slice(0, 2).join("-");
766
+ const compound = PREFIX_NAMESPACES[firstTwo] ? firstTwo : void 0;
767
+ const prefix = compound ?? utility.slice(0, dash);
768
+ const token = compound ? utility.slice(compound.length + 1) : utility.slice(dash + 1);
769
+ if (!token) return true;
770
+ if (inventory.utilities.has(utility)) return true;
771
+ const namespaces = PREFIX_NAMESPACES[prefix];
772
+ if (!namespaces) {
773
+ const projectTokens = inventory.themeTokens.get(prefix);
774
+ if (projectTokens) {
775
+ if (projectTokens.has(token)) return true;
776
+ if (!inventory.defaultsReset && DEFAULT_TOKENS[prefix]?.includes(token)) return true;
777
+ return false;
778
+ }
779
+ return !inventory.utilityPrefixes.has(prefix);
780
+ }
781
+ if (NUMERIC_TOKEN_RE.test(token) || SIDE_WIDTH_TOKEN_RE.test(token) || OFFSET_TOKEN_RE.test(token)) return true;
782
+ if (PREFIX_BUILTINS[prefix]?.includes(token)) return true;
783
+ for (const namespace of namespaces) {
784
+ if (namespace === "color") {
785
+ if (isColorToken(token, inventory)) return true;
786
+ continue;
787
+ }
788
+ if (inventory.themeTokens.get(namespace)?.has(token)) return true;
789
+ if (!inventory.defaultsReset && DEFAULT_TOKENS[namespace]?.includes(token)) return true;
790
+ }
791
+ return false;
792
+ }
793
+ var CLASS_HELPERS2 = /* @__PURE__ */ new Set(["cn", "clsx", "twMerge", "twJoin"]);
794
+ var unknownUtilityRule = {
795
+ meta: {
796
+ schema: [],
797
+ type: "problem",
798
+ docs: {
799
+ description: "Require component class names to be a custom utility, theme-generated utility, or built-in."
800
+ }
801
+ },
802
+ create(context) {
803
+ const sourceRoot2 = path4.resolve("src");
804
+ let inventory;
805
+ try {
806
+ if (!statSync(sourceRoot2).isDirectory()) return {};
807
+ inventory = readInventory(stylesheetFiles(sourceRoot2));
808
+ } catch {
809
+ return {};
810
+ }
811
+ function reportUnknownClasses(node, value) {
812
+ const seen = /* @__PURE__ */ new Set();
813
+ for (const candidate of value.split(/\s+/)) {
814
+ if (!candidate || seen.has(candidate)) continue;
815
+ seen.add(candidate);
816
+ if (!isKnown(candidate, inventory)) {
817
+ context.report({
818
+ node,
819
+ message: `Utility class "${candidate}" is not a custom @utility, a theme-generated utility, or a built-in Tailwind utility.`
820
+ });
821
+ }
822
+ }
823
+ }
824
+ function checkExpression(node, expression) {
825
+ if (!expression) return;
826
+ if (expression.type === "Literal") {
827
+ if (typeof expression.value === "string") reportUnknownClasses(node, expression.value);
828
+ return;
829
+ }
830
+ if (expression.type === "TemplateLiteral") {
831
+ for (const quasi of expression.quasis) reportUnknownClasses(node, quasi.value.raw);
832
+ return;
833
+ }
834
+ if (expression.type === "LogicalExpression") {
835
+ checkExpression(node, expression.left);
836
+ checkExpression(node, expression.right);
837
+ return;
838
+ }
839
+ if (expression.type === "ConditionalExpression") {
840
+ checkExpression(node, expression.consequent);
841
+ checkExpression(node, expression.alternate);
842
+ return;
843
+ }
844
+ if (expression.type === "ArrayExpression") {
845
+ for (const element of expression.elements) checkExpression(node, element);
846
+ return;
847
+ }
848
+ if (expression.type === "ObjectExpression") {
849
+ for (const property of expression.properties) {
850
+ if (property.type === "Property") checkExpression(node, property.key);
851
+ }
852
+ }
853
+ }
854
+ return {
855
+ JSXAttribute(node) {
856
+ const attributeName = node.name?.name;
857
+ if (attributeName !== "className" && attributeName !== "class") return;
858
+ const value = node.value;
859
+ if (!value) return;
860
+ checkExpression(node, value.type === "JSXExpressionContainer" ? value.expression : value);
861
+ },
862
+ CallExpression(node) {
863
+ if (node.callee.type !== "Identifier" || !CLASS_HELPERS2.has(node.callee.name)) return;
864
+ for (const argument of node.arguments) {
865
+ checkExpression(node, argument);
866
+ }
867
+ }
868
+ };
869
+ }
870
+ };
871
+
481
872
  // eslint/rules/enforce-cn-merge.ts
482
873
  function classCount(str) {
483
874
  return str.split(/\s+/).filter(Boolean).length;
@@ -653,7 +1044,7 @@ var enforceCvaVariantPropsRule = {
653
1044
  };
654
1045
 
655
1046
  // eslint/rules/enforce-barrel-exports.ts
656
- import path4 from "path";
1047
+ import path5 from "path";
657
1048
  import fs from "fs";
658
1049
  function isPascalCase3(str) {
659
1050
  return /^[A-Z][A-Za-z0-9]*$/.test(str);
@@ -673,14 +1064,14 @@ var enforceBarrelExportsRule = {
673
1064
  create(context) {
674
1065
  const filename = context.filename;
675
1066
  if (!filename) return {};
676
- const baseName = path4.basename(filename);
1067
+ const baseName = path5.basename(filename);
677
1068
  if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
678
- const dirPath = path4.dirname(filename);
679
- const folderName = path4.basename(dirPath);
680
- const parentFolderName = path4.basename(path4.dirname(dirPath));
1069
+ const dirPath = path5.dirname(filename);
1070
+ const folderName = path5.basename(dirPath);
1071
+ const parentFolderName = path5.basename(path5.dirname(dirPath));
681
1072
  if (SUPPORT_FOLDERS.has(folderName)) return {};
682
1073
  if (!isPascalCase3(folderName) && !isKebabCase2(folderName)) return {};
683
- const matchingTsx = fs.existsSync(path4.join(dirPath, `${folderName}.tsx`)) ? folderName : null;
1074
+ const matchingTsx = fs.existsSync(path5.join(dirPath, `${folderName}.tsx`)) ? folderName : null;
684
1075
  if (!matchingTsx) return {};
685
1076
  if (!isPascalCase3(parentFolderName) && !isKebabCase2(parentFolderName)) return {};
686
1077
  const reExportedNames = /* @__PURE__ */ new Set();
@@ -715,15 +1106,15 @@ var enforceBarrelExportsRule = {
715
1106
  };
716
1107
 
717
1108
  // eslint/rules/component-placement.ts
718
- import path8 from "path";
1109
+ import path9 from "path";
719
1110
 
720
1111
  // eslint/project/index.ts
721
- import { readdirSync, statSync } from "fs";
722
- import path6 from "path";
1112
+ import { readdirSync as readdirSync2, statSync as statSync2 } from "fs";
1113
+ import path7 from "path";
723
1114
 
724
1115
  // eslint/project/parse-module.ts
725
- import path5 from "path";
726
- import { readFileSync } from "fs";
1116
+ import path6 from "path";
1117
+ import { readFileSync as readFileSync2 } from "fs";
727
1118
  import ts2 from "typescript";
728
1119
  var isPascalCase4 = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
729
1120
  var isHookName = (name) => /^use[A-Z]/.test(name);
@@ -760,7 +1151,7 @@ function classifyValue(name, initializer, isTsx) {
760
1151
  return "constant";
761
1152
  }
762
1153
  function parseModule(file) {
763
- const text = readFileSync(file, "utf8");
1154
+ const text = readFileSync2(file, "utf8");
764
1155
  const isTsx = file.endsWith(".tsx") || file.endsWith(".jsx");
765
1156
  const sourceFile = ts2.createSourceFile(file, text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
766
1157
  const imports = [];
@@ -823,7 +1214,7 @@ function parseModule(file) {
823
1214
  exports.push({ name: statement.name.text, kind: "type", line: lineOf(sourceFile, statement) });
824
1215
  }
825
1216
  }
826
- return { file: path5.resolve(file), imports, exports };
1217
+ return { file: path6.resolve(file), imports, exports };
827
1218
  }
828
1219
 
829
1220
  // eslint/project/index.ts
@@ -834,28 +1225,28 @@ var symbolKey = (file, name) => `${file}\0${name}`;
834
1225
  function listSourceFiles(dir) {
835
1226
  let entries;
836
1227
  try {
837
- entries = readdirSync(dir);
1228
+ entries = readdirSync2(dir);
838
1229
  } catch {
839
1230
  return [];
840
1231
  }
841
1232
  return entries.flatMap((entry) => {
842
1233
  if (entry.startsWith(".") || entry === "node_modules") return [];
843
- const entryPath = path6.join(dir, entry);
1234
+ const entryPath = path7.join(dir, entry);
844
1235
  let stats;
845
1236
  try {
846
- stats = statSync(entryPath);
1237
+ stats = statSync2(entryPath);
847
1238
  } catch {
848
1239
  return [];
849
1240
  }
850
1241
  if (stats.isDirectory()) return listSourceFiles(entryPath);
851
- return MODULE_EXTENSIONS.includes(path6.extname(entry)) ? [entryPath] : [];
1242
+ return MODULE_EXTENSIONS.includes(path7.extname(entry)) ? [entryPath] : [];
852
1243
  });
853
1244
  }
854
1245
  function fingerprint(files) {
855
1246
  let total = 0;
856
1247
  for (const file of files) {
857
1248
  try {
858
- total += statSync(file).mtimeMs;
1249
+ total += statSync2(file).mtimeMs;
859
1250
  } catch {
860
1251
  }
861
1252
  }
@@ -864,20 +1255,20 @@ function fingerprint(files) {
864
1255
  function resolveSpecifier(fromFile, specifier, sourceRoot2) {
865
1256
  let base;
866
1257
  if (specifier.startsWith("@/")) {
867
- base = path6.resolve(sourceRoot2, specifier.slice(2));
1258
+ base = path7.resolve(sourceRoot2, specifier.slice(2));
868
1259
  } else if (specifier.startsWith(".")) {
869
- base = path6.resolve(path6.dirname(fromFile), specifier);
1260
+ base = path7.resolve(path7.dirname(fromFile), specifier);
870
1261
  } else {
871
1262
  return void 0;
872
1263
  }
873
1264
  const candidates = [
874
1265
  base,
875
1266
  ...MODULE_EXTENSIONS.map((extension) => `${base}${extension}`),
876
- ...INDEX_BASENAMES.map((name) => path6.join(base, name))
1267
+ ...INDEX_BASENAMES.map((name) => path7.join(base, name))
877
1268
  ];
878
1269
  for (const candidate of candidates) {
879
1270
  try {
880
- if (statSync(candidate).isFile()) return candidate;
1271
+ if (statSync2(candidate).isFile()) return candidate;
881
1272
  } catch {
882
1273
  }
883
1274
  }
@@ -917,7 +1308,7 @@ function getProjectIndex(sourceRoot2) {
917
1308
  return cache.index;
918
1309
  }
919
1310
  try {
920
- if (!statSync(sourceRoot2).isDirectory()) return void 0;
1311
+ if (!statSync2(sourceRoot2).isDirectory()) return void 0;
921
1312
  } catch {
922
1313
  return void 0;
923
1314
  }
@@ -933,11 +1324,11 @@ function getProjectIndex(sourceRoot2) {
933
1324
  }
934
1325
 
935
1326
  // eslint/project/ccf.ts
936
- import path7 from "path";
1327
+ import path8 from "path";
937
1328
  var SUPPORT_FOLDERS2 = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
938
1329
  function segmentsOf(file, sourceRoot2) {
939
- const relative = path7.relative(sourceRoot2, file);
940
- return relative.startsWith("..") ? [] : relative.split(path7.sep);
1330
+ const relative = path8.relative(sourceRoot2, file);
1331
+ return relative.startsWith("..") ? [] : relative.split(path8.sep);
941
1332
  }
942
1333
  function folderSegmentsOf(file, sourceRoot2) {
943
1334
  return segmentsOf(file, sourceRoot2).slice(0, -1);
@@ -1016,7 +1407,7 @@ function resolveSupportPlacement(supportFile, supportFolder, index) {
1016
1407
  }
1017
1408
  function describeConsumers(consumers, sourceRoot2) {
1018
1409
  const shown = 3;
1019
- const names = consumers.map((consumer) => path7.relative(path7.dirname(sourceRoot2), consumer).split(path7.sep).join("/")).sort((left, right) => left.localeCompare(right));
1410
+ const names = consumers.map((consumer) => path8.relative(path8.dirname(sourceRoot2), consumer).split(path8.sep).join("/")).sort((left, right) => left.localeCompare(right));
1020
1411
  if (names.length <= shown) return names.join(", ");
1021
1412
  return `${names.slice(0, shown).join(", ")} and ${String(names.length - shown)} more`;
1022
1413
  }
@@ -1039,10 +1430,10 @@ var componentPlacementRule = {
1039
1430
  create(context) {
1040
1431
  const filename = context.filename;
1041
1432
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
1042
- const sourceRoot2 = path8.resolve("src");
1433
+ const sourceRoot2 = path9.resolve("src");
1043
1434
  const index = getProjectIndex(sourceRoot2);
1044
1435
  if (!index) return {};
1045
- const componentFile = path8.resolve(filename);
1436
+ const componentFile = path9.resolve(filename);
1046
1437
  const segments = segmentsOf(componentFile, sourceRoot2);
1047
1438
  if (segments.length === 0) return {};
1048
1439
  if (isUnderApp(segments) || isConfigModule(segments)) return {};
@@ -1075,7 +1466,7 @@ var componentPlacementRule = {
1075
1466
  };
1076
1467
 
1077
1468
  // eslint/rules/support-file-placement.ts
1078
- import path9 from "path";
1469
+ import path10 from "path";
1079
1470
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
1080
1471
  var REASON_TEXT2 = {
1081
1472
  "app-consumer": "a file under src/app/ imports it, so it belongs to the app-wide support folder",
@@ -1094,8 +1485,8 @@ var supportFilePlacementRule = {
1094
1485
  }
1095
1486
  },
1096
1487
  create(context) {
1097
- const sourceRoot2 = path9.resolve("src");
1098
- const supportFile = path9.resolve(context.filename);
1488
+ const sourceRoot2 = path10.resolve("src");
1489
+ const supportFile = path10.resolve(context.filename);
1099
1490
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot2);
1100
1491
  const supportFolder = currentFolder[currentFolder.length - 1];
1101
1492
  if (supportFolder === void 0 || !SUPPORT_FOLDERS2.has(supportFolder)) return {};
@@ -1120,7 +1511,7 @@ var supportFilePlacementRule = {
1120
1511
 
1121
1512
  // eslint/rules/application-structure.ts
1122
1513
  import fs2 from "fs";
1123
- import path10 from "path";
1514
+ import path11 from "path";
1124
1515
  var MODULE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
1125
1516
  var ROUTING_FILES = /* @__PURE__ */ new Set([
1126
1517
  "default",
@@ -1149,7 +1540,7 @@ function report2(context, message) {
1149
1540
  };
1150
1541
  }
1151
1542
  function isCodeFile(filename) {
1152
- return MODULE_EXTENSIONS2.has(path10.extname(filename));
1543
+ return MODULE_EXTENSIONS2.has(path11.extname(filename));
1153
1544
  }
1154
1545
  function isRootSupportFolder(folder) {
1155
1546
  return SUPPORT_FOLDERS2.has(folder);
@@ -1170,7 +1561,7 @@ function expectedSupportFolder(kinds) {
1170
1561
  function configModuleRoot(filename, sourceRoot2) {
1171
1562
  const segments = segmentsOf(filename, sourceRoot2);
1172
1563
  if (segments[0] !== "config" || segments.length < 3) return void 0;
1173
- return path10.join(sourceRoot2, "config", segments[1] ?? "");
1564
+ return path11.join(sourceRoot2, "config", segments[1] ?? "");
1174
1565
  }
1175
1566
  function componentFolderStart(segments) {
1176
1567
  if (segments[0] === "features") return 2;
@@ -1183,12 +1574,12 @@ function componentFolderViolation(segments, sourceRoot2) {
1183
1574
  for (let depth = segments.length - 2; depth >= start; depth -= 1) {
1184
1575
  const folder = segments[depth];
1185
1576
  if (!folder || SUPPORT_FOLDERS2.has(folder)) continue;
1186
- const folderPath = path10.join(sourceRoot2, ...segments.slice(0, depth + 1));
1577
+ const folderPath = path11.join(sourceRoot2, ...segments.slice(0, depth + 1));
1187
1578
  const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
1188
- if (!fs2.existsSync(path10.join(folderPath, `${folder}.tsx`))) {
1579
+ if (!fs2.existsSync(path11.join(folderPath, `${folder}.tsx`))) {
1189
1580
  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.`;
1190
1581
  }
1191
- if (!fs2.existsSync(path10.join(folderPath, "index.ts"))) {
1582
+ if (!fs2.existsSync(path11.join(folderPath, "index.ts"))) {
1192
1583
  return `A component folder must have an index.ts that named-re-exports its component; add index.ts to ${label}.`;
1193
1584
  }
1194
1585
  }
@@ -1203,8 +1594,8 @@ var applicationStructureRule = {
1203
1594
  }
1204
1595
  },
1205
1596
  create(context) {
1206
- const filename = path10.resolve(context.filename);
1207
- const sourceRoot2 = path10.resolve("src");
1597
+ const filename = path11.resolve(context.filename);
1598
+ const sourceRoot2 = path11.resolve("src");
1208
1599
  const segments = segmentsOf(filename, sourceRoot2);
1209
1600
  if (segments.length === 0) return {};
1210
1601
  const [topLevel, secondLevel] = segments;
@@ -1234,42 +1625,42 @@ var applicationStructureRule = {
1234
1625
  );
1235
1626
  }
1236
1627
  const moduleRoot = configModuleRoot(filename, sourceRoot2);
1237
- if (moduleRoot && !fs2.existsSync(path10.join(moduleRoot, "index.ts"))) {
1628
+ if (moduleRoot && !fs2.existsSync(path11.join(moduleRoot, "index.ts"))) {
1238
1629
  return report2(
1239
1630
  context,
1240
- `Add src/config/${path10.basename(moduleRoot)}/index.ts as the configuration module entry point.`
1631
+ `Add src/config/${path11.basename(moduleRoot)}/index.ts as the configuration module entry point.`
1241
1632
  );
1242
1633
  }
1243
- if (moduleRoot && segments.length === 3 && path10.basename(filename) !== "index.ts") {
1634
+ if (moduleRoot && segments.length === 3 && path11.basename(filename) !== "index.ts") {
1244
1635
  const kinds2 = exportedKinds(filename);
1245
1636
  const expected2 = expectedSupportFolder(kinds2);
1246
1637
  if (expected2 !== void 0) {
1247
1638
  return report2(
1248
1639
  context,
1249
- `Move this configuration support file into src/config/${path10.basename(moduleRoot)}/${expected2}/.`
1640
+ `Move this configuration support file into src/config/${path11.basename(moduleRoot)}/${expected2}/.`
1250
1641
  );
1251
1642
  }
1252
1643
  }
1253
1644
  }
1254
1645
  if (topLevel === "app" && isCodeFile(filename)) {
1255
- const basename = path10.basename(filename, path10.extname(filename));
1256
- const currentFolder2 = path10.basename(path10.dirname(filename));
1646
+ const basename = path11.basename(filename, path11.extname(filename));
1647
+ const currentFolder2 = path11.basename(path11.dirname(filename));
1257
1648
  if (SUPPORT_FOLDERS2.has(currentFolder2)) {
1258
1649
  return report2(
1259
1650
  context,
1260
1651
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
1261
1652
  );
1262
1653
  }
1263
- if (!ROUTING_FILES.has(basename) && path10.extname(filename) !== ".css") {
1654
+ if (!ROUTING_FILES.has(basename) && path11.extname(filename) !== ".css") {
1264
1655
  return report2(
1265
1656
  context,
1266
1657
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
1267
1658
  );
1268
1659
  }
1269
1660
  }
1270
- const currentFolder = path10.basename(path10.dirname(filename));
1661
+ const currentFolder = path11.basename(path11.dirname(filename));
1271
1662
  const kinds = exportedKinds(filename);
1272
- const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path10.basename(filename) === "index.ts";
1663
+ const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path11.basename(filename) === "index.ts";
1273
1664
  if (isConfigModuleRoot) return {};
1274
1665
  if (!SUPPORT_FOLDERS2.has(currentFolder)) {
1275
1666
  const expected2 = expectedSupportFolder(kinds);
@@ -1286,7 +1677,7 @@ var applicationStructureRule = {
1286
1677
  if (kinds.has("component")) {
1287
1678
  return report2(
1288
1679
  context,
1289
- `A support folder must not contain a component; move ${path10.basename(filename)} beside ${currentFolder}/.`
1680
+ `A support folder must not contain a component; move ${path11.basename(filename)} beside ${currentFolder}/.`
1290
1681
  );
1291
1682
  }
1292
1683
  const expected = expectedSupportFolder(kinds);
@@ -1303,7 +1694,7 @@ var applicationStructureRule = {
1303
1694
  };
1304
1695
 
1305
1696
  // eslint/rules/named-exports.ts
1306
- import path11 from "path";
1697
+ import path12 from "path";
1307
1698
  var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
1308
1699
  "default",
1309
1700
  "error",
@@ -1315,9 +1706,9 @@ var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
1315
1706
  "template"
1316
1707
  ]);
1317
1708
  function isFrameworkDefaultExportFile(filename) {
1318
- const normalized = filename.replaceAll(path11.sep, "/");
1709
+ const normalized = filename.replaceAll(path12.sep, "/");
1319
1710
  if (!normalized.includes("/src/app/")) return false;
1320
- const basename = path11.basename(filename, path11.extname(filename));
1711
+ const basename = path12.basename(filename, path12.extname(filename));
1321
1712
  return FRAMEWORK_DEFAULT_EXPORT_FILES.has(basename);
1322
1713
  }
1323
1714
  var namedExportsRule = {
@@ -1342,7 +1733,7 @@ var namedExportsRule = {
1342
1733
  };
1343
1734
 
1344
1735
  // eslint/rules/data-testid-case.ts
1345
- import path12 from "path";
1736
+ import path13 from "path";
1346
1737
  var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
1347
1738
  "page",
1348
1739
  "layout",
@@ -1366,9 +1757,9 @@ var dataTestIdCaseRule = {
1366
1757
  }
1367
1758
  },
1368
1759
  create(context) {
1369
- const filename = path12.resolve(context.filename);
1760
+ const filename = path13.resolve(context.filename);
1370
1761
  if (!filename.endsWith(".tsx")) return {};
1371
- const base = path12.basename(filename, path12.extname(filename));
1762
+ const base = path13.basename(filename, path13.extname(filename));
1372
1763
  if (NEXT_ROUTING_FILES2.has(base)) return {};
1373
1764
  const text = context.sourceCode.text;
1374
1765
  const components = parseComponentInfo(text, filename);
@@ -1410,7 +1801,7 @@ function toKebabCase(value) {
1410
1801
 
1411
1802
  // eslint/rules/support-folder-shape.ts
1412
1803
  import fs3 from "fs";
1413
- import path13 from "path";
1804
+ import path14 from "path";
1414
1805
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
1415
1806
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
1416
1807
  var supportFolderShapeRule = {
@@ -1422,12 +1813,12 @@ var supportFolderShapeRule = {
1422
1813
  }
1423
1814
  },
1424
1815
  create(context) {
1425
- const filename = path13.resolve(context.filename);
1426
- const baseName = path13.basename(filename);
1816
+ const filename = path14.resolve(context.filename);
1817
+ const baseName = path14.basename(filename);
1427
1818
  if (!INDEX_NAMES.has(baseName)) return {};
1428
- const folder = path13.basename(path13.dirname(filename));
1819
+ const folder = path14.basename(path14.dirname(filename));
1429
1820
  if (!SUPPORT_FOLDERS3.has(folder)) return {};
1430
- const directory = path13.dirname(filename);
1821
+ const directory = path14.dirname(filename);
1431
1822
  let entries;
1432
1823
  try {
1433
1824
  entries = fs3.readdirSync(directory);
@@ -1445,7 +1836,7 @@ var supportFolderShapeRule = {
1445
1836
  const exportPattern = /export\s+(?:\{[^}]*\}|\*[^;]*)\s+from\s+["'](?<specifier>\.[^"']+)["']/g;
1446
1837
  for (const match of source.matchAll(exportPattern)) {
1447
1838
  const specifier = match.groups?.specifier;
1448
- if (specifier) exportedFiles.add(path13.basename(specifier));
1839
+ if (specifier) exportedFiles.add(path14.basename(specifier));
1449
1840
  }
1450
1841
  const missing = siblingModules.filter((entry) => {
1451
1842
  const stem = entry.replace(/\.(?:[cm]?tsx?|jsx?)$/, "");
@@ -1462,7 +1853,7 @@ var supportFolderShapeRule = {
1462
1853
  };
1463
1854
 
1464
1855
  // eslint/rules/import-through-index.ts
1465
- import path14 from "path";
1856
+ import path15 from "path";
1466
1857
  var importThroughIndexRule = {
1467
1858
  meta: {
1468
1859
  schema: [],
@@ -1472,7 +1863,7 @@ var importThroughIndexRule = {
1472
1863
  }
1473
1864
  },
1474
1865
  create(context) {
1475
- const filename = path14.resolve(context.filename);
1866
+ const filename = path15.resolve(context.filename);
1476
1867
  const sourceRoot2 = sourceRootOf(filename);
1477
1868
  return {
1478
1869
  Program(node) {
@@ -1484,7 +1875,7 @@ var importThroughIndexRule = {
1484
1875
  (segment) => ["constants", "types", "schemas"].includes(segment)
1485
1876
  );
1486
1877
  const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
1487
- if (!supportFolder || path14.basename(target).startsWith("index.")) continue;
1878
+ if (!supportFolder || path15.basename(target).startsWith("index.")) continue;
1488
1879
  const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
1489
1880
  const expected = `@/${folderIndex.join("/")}`;
1490
1881
  context.report({
@@ -1506,13 +1897,13 @@ function importSpecifiers(source) {
1506
1897
  return specifiers;
1507
1898
  }
1508
1899
  function sourceRootOf(filename) {
1509
- const marker = `${path14.sep}src${path14.sep}`;
1900
+ const marker = `${path15.sep}src${path15.sep}`;
1510
1901
  const srcIndex = filename.lastIndexOf(marker);
1511
- return srcIndex >= 0 ? filename.slice(0, srcIndex + marker.length - 1) : path14.resolve("src");
1902
+ return srcIndex >= 0 ? filename.slice(0, srcIndex + marker.length - 1) : path15.resolve("src");
1512
1903
  }
1513
1904
 
1514
1905
  // eslint/rules/util-file-name.ts
1515
- import path15 from "path";
1906
+ import path16 from "path";
1516
1907
  function toKebabCase2(value) {
1517
1908
  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();
1518
1909
  }
@@ -1525,7 +1916,7 @@ var utilFileNameRule = {
1525
1916
  }
1526
1917
  },
1527
1918
  create(context) {
1528
- const filename = path15.resolve(context.filename);
1919
+ const filename = path16.resolve(context.filename);
1529
1920
  const segments = filename.replace(/\\/g, "/").split("/");
1530
1921
  if (!segments.includes("utils")) return {};
1531
1922
  let module;
@@ -1539,13 +1930,13 @@ var utilFileNameRule = {
1539
1930
  const functionName = functions[0]?.name;
1540
1931
  if (!functionName) return {};
1541
1932
  const expected = toKebabCase2(functionName);
1542
- const actual = path15.basename(filename, path15.extname(filename));
1933
+ const actual = path16.basename(filename, path16.extname(filename));
1543
1934
  if (!expected || actual === expected) return {};
1544
1935
  return {
1545
1936
  Program(node) {
1546
1937
  context.report({
1547
1938
  node,
1548
- message: `A utility file exporting ${functionName} must be named ${expected}.${path15.extname(filename).slice(1)}.`
1939
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path16.extname(filename).slice(1)}.`
1549
1940
  });
1550
1941
  }
1551
1942
  };
@@ -1553,7 +1944,7 @@ var utilFileNameRule = {
1553
1944
  };
1554
1945
 
1555
1946
  // eslint/rules/no-util-barrel.ts
1556
- import path16 from "path";
1947
+ import path17 from "path";
1557
1948
  var noUtilBarrelRule = {
1558
1949
  meta: {
1559
1950
  schema: [],
@@ -1563,7 +1954,7 @@ var noUtilBarrelRule = {
1563
1954
  }
1564
1955
  },
1565
1956
  create(context) {
1566
- const filename = path16.resolve(context.filename);
1957
+ const filename = path17.resolve(context.filename);
1567
1958
  const sourceRoot2 = sourceRootOf2(filename);
1568
1959
  return {
1569
1960
  Program(node) {
@@ -1572,7 +1963,7 @@ var noUtilBarrelRule = {
1572
1963
  if (!target) continue;
1573
1964
  const segments = target.replace(/\\/g, "/").split("/");
1574
1965
  const utilsIndex = segments.lastIndexOf("utils");
1575
- if (utilsIndex < 0 || !path16.basename(target).startsWith("index.")) continue;
1966
+ if (utilsIndex < 0 || !path17.basename(target).startsWith("index.")) continue;
1576
1967
  context.report({
1577
1968
  node,
1578
1969
  message: `Import utilities directly instead of through "${specifier}". See docs/code-organization-guide/rules/utilities-rule.md`
@@ -1592,9 +1983,9 @@ function importSpecifiers2(source) {
1592
1983
  return specifiers;
1593
1984
  }
1594
1985
  function sourceRootOf2(filename) {
1595
- const marker = `${path16.sep}src${path16.sep}`;
1986
+ const marker = `${path17.sep}src${path17.sep}`;
1596
1987
  const srcIndex = filename.lastIndexOf(marker);
1597
- return srcIndex >= 0 ? filename.slice(0, srcIndex + marker.length - 1) : path16.resolve("src");
1988
+ return srcIndex >= 0 ? filename.slice(0, srcIndex + marker.length - 1) : path17.resolve("src");
1598
1989
  }
1599
1990
 
1600
1991
  // eslint/rules/jsx-hygiene.ts
@@ -1970,12 +2361,12 @@ var cvaBooleanVariantsRule = {
1970
2361
  };
1971
2362
 
1972
2363
  // eslint/rules/cross-feature-import.ts
1973
- import path17 from "path";
2364
+ import path18 from "path";
1974
2365
  var FEATURES_SEGMENT = "features";
1975
2366
  function featureNameOf(resolvedPath, sourceRoot2) {
1976
- const relative = path17.relative(sourceRoot2, resolvedPath);
2367
+ const relative = path18.relative(sourceRoot2, resolvedPath);
1977
2368
  if (relative.startsWith("..")) return void 0;
1978
- const segments = relative.split(path17.sep);
2369
+ const segments = relative.split(path18.sep);
1979
2370
  if (segments[0] !== FEATURES_SEGMENT || segments.length < 2) return void 0;
1980
2371
  return segments[1];
1981
2372
  }
@@ -1990,10 +2381,10 @@ var crossFeatureImportRule = {
1990
2381
  create(context) {
1991
2382
  const filename = context.filename;
1992
2383
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
1993
- const sourceRoot2 = path17.resolve("src");
1994
- const fileRelative = path17.relative(sourceRoot2, filename);
2384
+ const sourceRoot2 = path18.resolve("src");
2385
+ const fileRelative = path18.relative(sourceRoot2, filename);
1995
2386
  if (fileRelative.startsWith("..")) return {};
1996
- const fileSegments = fileRelative.split(path17.sep);
2387
+ const fileSegments = fileRelative.split(path18.sep);
1997
2388
  const isInCompositions = fileSegments[0] === "compositions";
1998
2389
  const isInApp = fileSegments[0] === "app";
1999
2390
  const isConfig = fileSegments[0] === "config";
@@ -2007,9 +2398,9 @@ var crossFeatureImportRule = {
2007
2398
  if (typeof source.value !== "string") return;
2008
2399
  let resolved;
2009
2400
  if (source.value.startsWith("@/")) {
2010
- resolved = path17.resolve(sourceRoot2, source.value.slice(2));
2401
+ resolved = path18.resolve(sourceRoot2, source.value.slice(2));
2011
2402
  } else if (source.value.startsWith(".")) {
2012
- resolved = path17.resolve(path17.dirname(filename), source.value);
2403
+ resolved = path18.resolve(path18.dirname(filename), source.value);
2013
2404
  }
2014
2405
  if (!resolved) return;
2015
2406
  const feature = featureNameOf(resolved, sourceRoot2);
@@ -2028,7 +2419,7 @@ var crossFeatureImportRule = {
2028
2419
  };
2029
2420
 
2030
2421
  // eslint/rules/pure-function-extract.ts
2031
- import path18 from "path";
2422
+ import path19 from "path";
2032
2423
  function isComponentLikeName(name) {
2033
2424
  return /^[A-Z]/.test(name);
2034
2425
  }
@@ -2056,10 +2447,10 @@ var pureFunctionExtractRule = {
2056
2447
  create(context) {
2057
2448
  const filename = context.filename;
2058
2449
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2059
- const sourceRoot2 = path18.resolve("src");
2060
- const relative = path18.relative(sourceRoot2, filename);
2450
+ const sourceRoot2 = path19.resolve("src");
2451
+ const relative = path19.relative(sourceRoot2, filename);
2061
2452
  if (relative.startsWith("..")) return {};
2062
- const segments = relative.split(path18.sep);
2453
+ const segments = relative.split(path19.sep);
2063
2454
  if (segments[0] === "utils") return {};
2064
2455
  if (segments[0] === "app") return {};
2065
2456
  const supportFolders = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
@@ -2099,7 +2490,7 @@ var pureFunctionExtractRule = {
2099
2490
  };
2100
2491
 
2101
2492
  // eslint/rules/hook-complexity.ts
2102
- import path19 from "path";
2493
+ import path20 from "path";
2103
2494
  import ts4 from "typescript";
2104
2495
  var REACT_HOOKS = /* @__PURE__ */ new Set([
2105
2496
  "useState",
@@ -2151,10 +2542,10 @@ var hookComplexityRule = {
2151
2542
  },
2152
2543
  create(context) {
2153
2544
  const filename = context.filename;
2154
- const sourceRoot2 = path19.resolve("src");
2155
- const relative = path19.relative(sourceRoot2, filename);
2545
+ const sourceRoot2 = path20.resolve("src");
2546
+ const relative = path20.relative(sourceRoot2, filename);
2156
2547
  if (relative.startsWith("..")) return {};
2157
- const segments = relative.split(path19.sep);
2548
+ const segments = relative.split(path20.sep);
2158
2549
  const sourceText = context.sourceCode.text;
2159
2550
  function checkHook(node, name, body, exported) {
2160
2551
  if (!exported) return;
@@ -2196,9 +2587,9 @@ var hookComplexityRule = {
2196
2587
  };
2197
2588
 
2198
2589
  // eslint/rules/locale-dotted-path.ts
2199
- import path20 from "path";
2590
+ import path21 from "path";
2200
2591
  function isInLocalesDir(filename) {
2201
- const segments = path20.resolve(filename).split(path20.sep);
2592
+ const segments = path21.resolve(filename).split(path21.sep);
2202
2593
  const srcIdx = segments.lastIndexOf("src");
2203
2594
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
2204
2595
  }
@@ -2247,9 +2638,9 @@ var localeDottedPathRule = {
2247
2638
  };
2248
2639
 
2249
2640
  // eslint/rules/locales-location.ts
2250
- import path21 from "path";
2641
+ import path22 from "path";
2251
2642
  function isLocalesFile(filename) {
2252
- const segments = path21.resolve(filename).split(path21.sep);
2643
+ const segments = path22.resolve(filename).split(path22.sep);
2253
2644
  const srcIdx = segments.lastIndexOf("src");
2254
2645
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
2255
2646
  }
@@ -2268,7 +2659,7 @@ var localesLocationRule = {
2268
2659
  create(context) {
2269
2660
  if (isLocalesFile(context.filename)) return {};
2270
2661
  const filename = context.filename;
2271
- const segments = path21.resolve(filename).split(path21.sep);
2662
+ const segments = path22.resolve(filename).split(path22.sep);
2272
2663
  const srcIdx = segments.lastIndexOf("src");
2273
2664
  if (srcIdx === -1) return {};
2274
2665
  const folder = segments[srcIdx + 1];
@@ -2290,7 +2681,7 @@ var localesLocationRule = {
2290
2681
  };
2291
2682
 
2292
2683
  // eslint/rules/hook-extraction.ts
2293
- import path22 from "path";
2684
+ import path23 from "path";
2294
2685
  var hookExtractionRule = {
2295
2686
  meta: {
2296
2687
  schema: [],
@@ -2300,8 +2691,8 @@ var hookExtractionRule = {
2300
2691
  }
2301
2692
  },
2302
2693
  create(context) {
2303
- const sourceRoot2 = path22.resolve("src");
2304
- const file = path22.resolve(context.filename);
2694
+ const sourceRoot2 = path23.resolve("src");
2695
+ const file = path23.resolve(context.filename);
2305
2696
  const segments = segmentsOf(file, sourceRoot2);
2306
2697
  if (segments.length === 0) return {};
2307
2698
  const index = getProjectIndex(sourceRoot2);
@@ -2327,7 +2718,7 @@ var hookExtractionRule = {
2327
2718
  };
2328
2719
 
2329
2720
  // eslint/rules/value-extraction.ts
2330
- import path23 from "path";
2721
+ import path24 from "path";
2331
2722
  var valueExtractionRule = {
2332
2723
  meta: {
2333
2724
  schema: [],
@@ -2337,8 +2728,8 @@ var valueExtractionRule = {
2337
2728
  }
2338
2729
  },
2339
2730
  create(context) {
2340
- const sourceRoot2 = path23.resolve("src");
2341
- const file = path23.resolve(context.filename);
2731
+ const sourceRoot2 = path24.resolve("src");
2732
+ const file = path24.resolve(context.filename);
2342
2733
  const segments = segmentsOf(file, sourceRoot2);
2343
2734
  if (segments.length === 0 || segments[0] !== "app") return {};
2344
2735
  const index = getProjectIndex(sourceRoot2);
@@ -2359,7 +2750,7 @@ var valueExtractionRule = {
2359
2750
  };
2360
2751
 
2361
2752
  // eslint/rules/config-extraction.ts
2362
- import path24 from "path";
2753
+ import path25 from "path";
2363
2754
  var configExtractionRule = {
2364
2755
  meta: {
2365
2756
  schema: [],
@@ -2369,8 +2760,8 @@ var configExtractionRule = {
2369
2760
  }
2370
2761
  },
2371
2762
  create(context) {
2372
- const sourceRoot2 = path24.resolve("src");
2373
- const file = path24.resolve(context.filename);
2763
+ const sourceRoot2 = path25.resolve("src");
2764
+ const file = path25.resolve(context.filename);
2374
2765
  const segments = segmentsOf(file, sourceRoot2);
2375
2766
  if (segments.length < 3 || segments[0] !== "config") return {};
2376
2767
  if (SUPPORT_FOLDERS2.has(segments[2] ?? "")) return {};
@@ -2408,7 +2799,7 @@ var configExtractionRule = {
2408
2799
  };
2409
2800
 
2410
2801
  // eslint/rules/component-nesting.ts
2411
- import path25 from "path";
2802
+ import path26 from "path";
2412
2803
  var componentNestingRule = {
2413
2804
  meta: {
2414
2805
  schema: [],
@@ -2418,8 +2809,8 @@ var componentNestingRule = {
2418
2809
  }
2419
2810
  },
2420
2811
  create(context) {
2421
- const sourceRoot2 = path25.resolve("src");
2422
- const file = path25.resolve(context.filename);
2812
+ const sourceRoot2 = path26.resolve("src");
2813
+ const file = path26.resolve(context.filename);
2423
2814
  const segments = segmentsOf(file, sourceRoot2);
2424
2815
  if (segments.length !== 4 || segments[0] !== "features") return {};
2425
2816
  const index = getProjectIndex(sourceRoot2);
@@ -2452,7 +2843,7 @@ var componentNestingRule = {
2452
2843
  };
2453
2844
 
2454
2845
  // eslint/rules/stay-flat.ts
2455
- import path26 from "path";
2846
+ import path27 from "path";
2456
2847
  var stayFlatRule = {
2457
2848
  meta: {
2458
2849
  schema: [],
@@ -2462,8 +2853,8 @@ var stayFlatRule = {
2462
2853
  }
2463
2854
  },
2464
2855
  create(context) {
2465
- const sourceRoot2 = path26.resolve("src");
2466
- const file = path26.resolve(context.filename);
2856
+ const sourceRoot2 = path27.resolve("src");
2857
+ const file = path27.resolve(context.filename);
2467
2858
  const segments = segmentsOf(file, sourceRoot2);
2468
2859
  if (segments.length !== 3 || segments[0] !== "features") return {};
2469
2860
  const index = getProjectIndex(sourceRoot2);
@@ -2503,7 +2894,7 @@ var stayFlatRule = {
2503
2894
  };
2504
2895
 
2505
2896
  // eslint/rules/type-extraction.ts
2506
- import path27 from "path";
2897
+ import path28 from "path";
2507
2898
  var typeExtractionRule = {
2508
2899
  meta: {
2509
2900
  schema: [],
@@ -2513,8 +2904,8 @@ var typeExtractionRule = {
2513
2904
  }
2514
2905
  },
2515
2906
  create(context) {
2516
- const sourceRoot2 = path27.resolve("src");
2517
- const file = path27.resolve(context.filename);
2907
+ const sourceRoot2 = path28.resolve("src");
2908
+ const file = path28.resolve(context.filename);
2518
2909
  const segments = segmentsOf(file, sourceRoot2);
2519
2910
  if (segments.length === 0) return {};
2520
2911
  const index = getProjectIndex(sourceRoot2);
@@ -2560,8 +2951,8 @@ var typeExtractionRule = {
2560
2951
  };
2561
2952
 
2562
2953
  // eslint/rules/locale-placement.ts
2563
- import path28 from "path";
2564
- import { readFileSync as readFileSync2 } from "fs";
2954
+ import path29 from "path";
2955
+ import { readFileSync as readFileSync3 } from "fs";
2565
2956
  import ts5 from "typescript";
2566
2957
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
2567
2958
  var camelCase = (name) => name.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase());
@@ -2607,8 +2998,8 @@ var localePlacementRule = {
2607
2998
  }
2608
2999
  },
2609
3000
  create(context) {
2610
- const sourceRoot2 = path28.resolve("src");
2611
- const file = path28.resolve(context.filename);
3001
+ const sourceRoot2 = path29.resolve("src");
3002
+ const file = path29.resolve(context.filename);
2612
3003
  const segments = segmentsOf(file, sourceRoot2);
2613
3004
  if (segments.length === 0) return {};
2614
3005
  const index = getProjectIndex(sourceRoot2);
@@ -2618,7 +3009,7 @@ var localePlacementRule = {
2618
3009
  return candidateSegments.length === 2 && candidateSegments[0] === "locales" && candidateSegments[1]?.startsWith("index.");
2619
3010
  });
2620
3011
  if (!localesFile || file !== localesFile) return {};
2621
- const placement = localePlacement(readFileSync2(localesFile, "utf8"));
3012
+ const placement = localePlacement(readFileSync3(localesFile, "utf8"));
2622
3013
  if (!placement) return {};
2623
3014
  const keyReaders = /* @__PURE__ */ new Map();
2624
3015
  const keyFeatures = /* @__PURE__ */ new Map();
@@ -2630,7 +3021,7 @@ var localePlacementRule = {
2630
3021
  );
2631
3022
  if (!importsLocales) continue;
2632
3023
  const candidateSegments = segmentsOf(candidateFile, sourceRoot2);
2633
- for (const match of readFileSync2(candidateFile, "utf8").matchAll(LOCALE_ACCESS)) {
3024
+ for (const match of readFileSync3(candidateFile, "utf8").matchAll(LOCALE_ACCESS)) {
2634
3025
  const key = match.groups?.key;
2635
3026
  if (key === void 0) continue;
2636
3027
  const readers = keyReaders.get(key) ?? /* @__PURE__ */ new Set();
@@ -2686,7 +3077,7 @@ var localePlacementRule = {
2686
3077
  };
2687
3078
 
2688
3079
  // eslint/rules/sole-state-owner.ts
2689
- import path29 from "path";
3080
+ import path30 from "path";
2690
3081
  import ts6 from "typescript";
2691
3082
  function findStateHooks(node) {
2692
3083
  const hooks = [];
@@ -2766,7 +3157,7 @@ var soleStateOwnerRule = {
2766
3157
  }
2767
3158
  },
2768
3159
  create(context) {
2769
- const filename = path29.resolve(context.filename);
3160
+ const filename = path30.resolve(context.filename);
2770
3161
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2771
3162
  const text = context.sourceCode.text;
2772
3163
  const components = parseComponentInfo(text, filename);
@@ -2845,7 +3236,7 @@ function usesOutsideJsx(declaration, hook, children) {
2845
3236
  }
2846
3237
 
2847
3238
  // eslint/rules/locale-key-shape.ts
2848
- import path30 from "path";
3239
+ import path31 from "path";
2849
3240
  var MAX_KEY_LENGTH = 30;
2850
3241
  var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
2851
3242
  "Button",
@@ -2894,7 +3285,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
2894
3285
  ]);
2895
3286
  var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
2896
3287
  function isLocalesFile2(filename) {
2897
- const segments = path30.resolve(filename).split(path30.sep);
3288
+ const segments = path31.resolve(filename).split(path31.sep);
2898
3289
  const srcIdx = segments.lastIndexOf("src");
2899
3290
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
2900
3291
  }
@@ -2957,8 +3348,8 @@ var localeKeyShapeRule = {
2957
3348
  };
2958
3349
 
2959
3350
  // eslint/rules/shared-style-dedup.ts
2960
- import path31 from "path";
2961
- import { readFileSync as readFileSync3, statSync as statSync2 } from "fs";
3351
+ import path32 from "path";
3352
+ import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
2962
3353
  var CLASS_NAME = /className="(?<classes>[^"]+)"/g;
2963
3354
  var comboCache;
2964
3355
  function combosFor(index) {
@@ -2966,7 +3357,7 @@ function combosFor(index) {
2966
3357
  let fingerprint2 = "";
2967
3358
  for (const file of files) {
2968
3359
  try {
2969
- fingerprint2 += String(statSync2(file).mtimeMs);
3360
+ fingerprint2 += String(statSync3(file).mtimeMs);
2970
3361
  } catch {
2971
3362
  fingerprint2 += "0";
2972
3363
  }
@@ -2976,7 +3367,7 @@ function combosFor(index) {
2976
3367
  }
2977
3368
  const combos = /* @__PURE__ */ new Map();
2978
3369
  for (const file of files) {
2979
- const text = readFileSync3(file, "utf8");
3370
+ const text = readFileSync4(file, "utf8");
2980
3371
  for (const match of text.matchAll(CLASS_NAME)) {
2981
3372
  const classes = (match.groups?.classes ?? "").split(/\s+/).filter(Boolean);
2982
3373
  if (classes.length < 2) continue;
@@ -2998,8 +3389,8 @@ var sharedStyleDedupRule = {
2998
3389
  }
2999
3390
  },
3000
3391
  create(context) {
3001
- const sourceRoot2 = path31.resolve("src");
3002
- const file = path31.resolve(context.filename);
3392
+ const sourceRoot2 = path32.resolve("src");
3393
+ const file = path32.resolve(context.filename);
3003
3394
  const segments = segmentsOf(file, sourceRoot2);
3004
3395
  if (segments.length === 0) return {};
3005
3396
  const index = getProjectIndex(sourceRoot2);
@@ -3203,7 +3594,7 @@ var zodSchemaValidationRule = {
3203
3594
  };
3204
3595
 
3205
3596
  // eslint/rules/source-under-src.ts
3206
- import path32 from "path";
3597
+ import path33 from "path";
3207
3598
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
3208
3599
  ".agents",
3209
3600
  ".cache",
@@ -3244,14 +3635,14 @@ var sourceUnderSrcRule = {
3244
3635
  }
3245
3636
  },
3246
3637
  create(context) {
3247
- const filename = path32.resolve(context.filename);
3638
+ const filename = path33.resolve(context.filename);
3248
3639
  if (!MODULE_EXTENSION.test(filename)) return {};
3249
- const relative = path32.relative(process.cwd(), filename).replace(/\\/g, "/");
3640
+ const relative = path33.relative(process.cwd(), filename).replace(/\\/g, "/");
3250
3641
  if (relative === "src" || relative.startsWith("src/")) return {};
3251
3642
  const topLevel = relative.split("/")[0] ?? "";
3252
3643
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
3253
3644
  if (!relative.includes("/")) {
3254
- const basename = path32.basename(filename);
3645
+ const basename = path33.basename(filename);
3255
3646
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
3256
3647
  }
3257
3648
  return {
@@ -3268,7 +3659,7 @@ var sourceUnderSrcRule = {
3268
3659
 
3269
3660
  // eslint/rules/zirka-baseline.ts
3270
3661
  import fs4 from "fs";
3271
- import path33 from "path";
3662
+ import path34 from "path";
3272
3663
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
3273
3664
  var PRETTIER_CONFIGS = [
3274
3665
  "prettier.config.mjs",
@@ -3287,10 +3678,10 @@ var zirkaBaselineRule = {
3287
3678
  }
3288
3679
  },
3289
3680
  create(context) {
3290
- const filename = path33.resolve(context.filename);
3291
- const basename = path33.basename(filename);
3681
+ const filename = path34.resolve(context.filename);
3682
+ const basename = path34.basename(filename);
3292
3683
  if (!ESLINT_CONFIG.test(basename)) return {};
3293
- const projectRoot = path33.dirname(filename);
3684
+ const projectRoot = path34.dirname(filename);
3294
3685
  const report3 = (message) => {
3295
3686
  context.report({
3296
3687
  node: context.sourceCode.ast,
@@ -3305,7 +3696,7 @@ var zirkaBaselineRule = {
3305
3696
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
3306
3697
  );
3307
3698
  }
3308
- const tsconfigPath = path33.join(projectRoot, "tsconfig.json");
3699
+ const tsconfigPath = path34.join(projectRoot, "tsconfig.json");
3309
3700
  if (!fs4.existsSync(tsconfigPath)) {
3310
3701
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
3311
3702
  } else {
@@ -3323,13 +3714,13 @@ var zirkaBaselineRule = {
3323
3714
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
3324
3715
  }
3325
3716
  }
3326
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs4.existsSync(path33.join(projectRoot, name)));
3717
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs4.existsSync(path34.join(projectRoot, name)));
3327
3718
  if (!prettierConfigFile) {
3328
3719
  report3(
3329
3720
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
3330
3721
  );
3331
3722
  } else {
3332
- const content = fs4.readFileSync(path33.join(projectRoot, prettierConfigFile), "utf8");
3723
+ const content = fs4.readFileSync(path34.join(projectRoot, prettierConfigFile), "utf8");
3333
3724
  if (!content.includes("zirka")) {
3334
3725
  report3(
3335
3726
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -3399,7 +3790,7 @@ var docKindSuffixRule = {
3399
3790
  };
3400
3791
 
3401
3792
  // eslint/rules/documentation/title-matches-file-name.ts
3402
- import path34 from "path";
3793
+ import path35 from "path";
3403
3794
  function toExpectedFileName(title) {
3404
3795
  return `${title.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.md`;
3405
3796
  }
@@ -3419,7 +3810,7 @@ var titleMatchesFileNameRule = {
3419
3810
  if (!filename.endsWith(".md")) return;
3420
3811
  const title = getTextContent(node).trim();
3421
3812
  const expectedFileName = toExpectedFileName(title);
3422
- const actualFileName = path34.basename(filename);
3813
+ const actualFileName = path35.basename(filename);
3423
3814
  if (!title) {
3424
3815
  context.report({
3425
3816
  node,
@@ -3826,7 +4217,7 @@ var referenceBlockHeadingsRule = {
3826
4217
  };
3827
4218
 
3828
4219
  // eslint/rules/documentation/support-document-placement.ts
3829
- import path35 from "path";
4220
+ import path36 from "path";
3830
4221
  var supportDocumentPlacementRule = {
3831
4222
  meta: {
3832
4223
  type: "problem",
@@ -3840,7 +4231,7 @@ var supportDocumentPlacementRule = {
3840
4231
  root(node) {
3841
4232
  const filename = getFilename(context);
3842
4233
  if (!filename.endsWith(".md")) return;
3843
- const parentFolder = path35.basename(path35.dirname(filename));
4234
+ const parentFolder = path36.basename(path36.dirname(filename));
3844
4235
  if (filename.endsWith("-rule.md") && parentFolder !== "rules") {
3845
4236
  context.report({
3846
4237
  node,
@@ -3883,11 +4274,11 @@ var noTemplatePromptRule = {
3883
4274
  };
3884
4275
 
3885
4276
  // eslint/rules/documentation/guide-folder-entry-point.ts
3886
- import path37 from "path";
4277
+ import path38 from "path";
3887
4278
 
3888
4279
  // eslint/rules/documentation/project-index.ts
3889
- import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync3 } from "fs";
3890
- import path36 from "path";
4280
+ import { readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
4281
+ import path37 from "path";
3891
4282
  var KIND_BY_SUFFIX = [
3892
4283
  ["-rule.md", "rule"],
3893
4284
  ["-guide.md", "guide"],
@@ -3895,16 +4286,16 @@ var KIND_BY_SUFFIX = [
3895
4286
  ["-policy.md", "policy"]
3896
4287
  ];
3897
4288
  function listMarkdownFiles(dir) {
3898
- return readdirSync2(dir).flatMap((entry) => {
3899
- const entryPath = path36.join(dir, entry);
3900
- if (statSync3(entryPath).isDirectory()) {
4289
+ return readdirSync3(dir).flatMap((entry) => {
4290
+ const entryPath = path37.join(dir, entry);
4291
+ if (statSync4(entryPath).isDirectory()) {
3901
4292
  return entry.startsWith("_") ? [] : listMarkdownFiles(entryPath);
3902
4293
  }
3903
4294
  return entry.endsWith(".md") ? [entryPath] : [];
3904
4295
  });
3905
4296
  }
3906
4297
  function extractTitle(filePath) {
3907
- const content = readFileSync4(filePath, "utf8");
4298
+ const content = readFileSync5(filePath, "utf8");
3908
4299
  const match = /^# (?<title>.+)$/m.exec(content);
3909
4300
  return match?.groups?.title?.trim() ?? "";
3910
4301
  }
@@ -3914,11 +4305,11 @@ function getProjectDocs(docsRoot) {
3914
4305
  if (cached) return cached;
3915
4306
  const files = listMarkdownFiles(docsRoot);
3916
4307
  const docs = files.sort((a, b) => a.localeCompare(b)).map((filePath) => {
3917
- const fileName = path36.basename(filePath);
4308
+ const fileName = path37.basename(filePath);
3918
4309
  const kind = KIND_BY_SUFFIX.find(([suffix]) => fileName.endsWith(suffix))?.[1];
3919
4310
  return {
3920
4311
  filePath,
3921
- doc: path36.relative(docsRoot, filePath).split(path36.sep).join("/"),
4312
+ doc: path37.relative(docsRoot, filePath).split(path37.sep).join("/"),
3922
4313
  fileName,
3923
4314
  kind,
3924
4315
  title: extractTitle(filePath)
@@ -3928,12 +4319,12 @@ function getProjectDocs(docsRoot) {
3928
4319
  return docs;
3929
4320
  }
3930
4321
  function findDocsRoot(filePath) {
3931
- let dir = path36.dirname(filePath);
4322
+ let dir = path37.dirname(filePath);
3932
4323
  for (; ; ) {
3933
- if (path36.basename(dir) === "docs" && statSync3(dir).isDirectory()) {
4324
+ if (path37.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
3934
4325
  return dir;
3935
4326
  }
3936
- const parent = path36.dirname(dir);
4327
+ const parent = path37.dirname(dir);
3937
4328
  if (parent === dir) return void 0;
3938
4329
  dir = parent;
3939
4330
  }
@@ -3957,13 +4348,13 @@ var guideFolderEntryPointRule = {
3957
4348
  if (!docsRoot) return;
3958
4349
  const docs = getProjectDocs(docsRoot);
3959
4350
  const guideFolders = new Set(
3960
- docs.filter((doc) => ["rules", "references"].includes(path37.basename(path37.dirname(doc.filePath)))).map((doc) => path37.dirname(path37.dirname(doc.filePath))).filter((folder) => path37.resolve(folder) !== path37.resolve(docsRoot))
4351
+ docs.filter((doc) => ["rules", "references"].includes(path38.basename(path38.dirname(doc.filePath)))).map((doc) => path38.dirname(path38.dirname(doc.filePath))).filter((folder) => path38.resolve(folder) !== path38.resolve(docsRoot))
3961
4352
  );
3962
- const currentDir = path37.dirname(filename);
4353
+ const currentDir = path38.dirname(filename);
3963
4354
  if (guideFolders.has(currentDir)) {
3964
- const expectedEntryPoint = `${path37.basename(currentDir)}.md`;
4355
+ const expectedEntryPoint = `${path38.basename(currentDir)}.md`;
3965
4356
  const hasEntryPoint = docs.some(
3966
- (doc) => doc.kind === "guide" && path37.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
4357
+ (doc) => doc.kind === "guide" && path38.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
3967
4358
  );
3968
4359
  if (!hasEntryPoint) {
3969
4360
  context.report({
@@ -4187,10 +4578,10 @@ var noNestedHowToRule = {
4187
4578
  };
4188
4579
 
4189
4580
  // eslint/rules/documentation/glossary-term-linking.ts
4190
- import { readFileSync as readFileSync5 } from "fs";
4191
- import path38 from "path";
4581
+ import { readFileSync as readFileSync6 } from "fs";
4582
+ import path39 from "path";
4192
4583
  function extractGlossaryTerms(filePath) {
4193
- const content = readFileSync5(filePath, "utf8");
4584
+ const content = readFileSync6(filePath, "utf8");
4194
4585
  const terms = [];
4195
4586
  const headingPattern = /^## (?<term>.+)$/gm;
4196
4587
  let match;
@@ -4242,9 +4633,9 @@ var glossaryTermLinkingRule = {
4242
4633
  const docsRoot = findDocsRoot(filename);
4243
4634
  if (!docsRoot) return;
4244
4635
  const docs = getProjectDocs(docsRoot);
4245
- const guideDir = path38.dirname(filename);
4636
+ const guideDir = path39.dirname(filename);
4246
4637
  const guideReferences = docs.filter(
4247
- (doc) => doc.kind === "reference" && path38.dirname(doc.filePath) === guideDir
4638
+ (doc) => doc.kind === "reference" && path39.dirname(doc.filePath) === guideDir
4248
4639
  );
4249
4640
  if (guideReferences.length === 0) return;
4250
4641
  const glossaryTerms = [];
@@ -4269,7 +4660,7 @@ var glossaryTermLinkingRule = {
4269
4660
 
4270
4661
  // eslint/rules/documentation/guide-mentions-documents.ts
4271
4662
  import { existsSync } from "fs";
4272
- import path39 from "path";
4663
+ import path40 from "path";
4273
4664
  function visitSteps3(node, check) {
4274
4665
  if (node.type === "list" && node.ordered) {
4275
4666
  for (const child of node.children) check(child);
@@ -4302,12 +4693,12 @@ var guideMentionsDocumentsRule = {
4302
4693
  if (!filename.endsWith("-guide.md")) return;
4303
4694
  const docsRoot = findDocsRoot(filename);
4304
4695
  if (!docsRoot) return;
4305
- const guideDir = path39.dirname(filename);
4306
- if (path39.basename(filename, ".md") !== path39.basename(guideDir)) return;
4696
+ const guideDir = path40.dirname(filename);
4697
+ if (path40.basename(filename, ".md") !== path40.basename(guideDir)) return;
4307
4698
  const docs = getProjectDocs(docsRoot);
4308
4699
  const owned = docs.filter((doc) => {
4309
- const parent = path39.dirname(doc.filePath);
4310
- return parent === path39.join(guideDir, "rules") || parent === path39.join(guideDir, "references");
4700
+ const parent = path40.dirname(doc.filePath);
4701
+ return parent === path40.join(guideDir, "rules") || parent === path40.join(guideDir, "references");
4311
4702
  });
4312
4703
  const allLinks = [];
4313
4704
  collectMarkdownLinks(node, allLinks);
@@ -4334,7 +4725,7 @@ var guideMentionsDocumentsRule = {
4334
4725
  for (const link of allLinks) {
4335
4726
  const target = linkTarget(link.url);
4336
4727
  if (!target.endsWith(".md")) continue;
4337
- const resolved = path39.normalize(path39.join(guideDir, target));
4728
+ const resolved = path40.normalize(path40.join(guideDir, target));
4338
4729
  if (!existsSync(resolved)) {
4339
4730
  context.report({
4340
4731
  node: link,
@@ -4839,6 +5230,83 @@ var globalStylesheetRule = {
4839
5230
  }
4840
5231
  };
4841
5232
 
5233
+ // eslint/rules/tailwind/unused-utility.ts
5234
+ import { readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
5235
+ import path41 from "path";
5236
+ var SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".css"];
5237
+ function sourceFiles(dir) {
5238
+ let entries;
5239
+ try {
5240
+ entries = readdirSync4(dir);
5241
+ } catch {
5242
+ return [];
5243
+ }
5244
+ return entries.flatMap((entry) => {
5245
+ if (entry.startsWith(".") || entry === "node_modules") return [];
5246
+ const entryPath = path41.join(dir, entry);
5247
+ let stats;
5248
+ try {
5249
+ stats = statSync5(entryPath);
5250
+ } catch {
5251
+ return [];
5252
+ }
5253
+ if (stats.isDirectory()) return sourceFiles(entryPath);
5254
+ return SOURCE_EXTENSIONS.includes(path41.extname(entry)) ? [entryPath] : [];
5255
+ });
5256
+ }
5257
+ function usagePattern(name) {
5258
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5259
+ return new RegExp(`(?<![\\w-])${escaped}(?![\\w-])`);
5260
+ }
5261
+ var unusedUtilityRule = {
5262
+ meta: {
5263
+ schema: [],
5264
+ type: "problem",
5265
+ docs: {
5266
+ description: "Require every custom @utility to be referenced by the repository's source."
5267
+ }
5268
+ },
5269
+ create(context) {
5270
+ const sourceRoot2 = path41.resolve("src");
5271
+ let files;
5272
+ try {
5273
+ if (!statSync5(sourceRoot2).isDirectory()) return {};
5274
+ files = sourceFiles(sourceRoot2);
5275
+ } catch {
5276
+ return {};
5277
+ }
5278
+ const texts = /* @__PURE__ */ new Map();
5279
+ const textOf = (file) => {
5280
+ let text = texts.get(file);
5281
+ if (text === void 0) {
5282
+ try {
5283
+ text = readFileSync7(file, "utf8");
5284
+ } catch {
5285
+ text = "";
5286
+ }
5287
+ texts.set(file, text);
5288
+ }
5289
+ return text;
5290
+ };
5291
+ return {
5292
+ "StyleSheet:exit"(node) {
5293
+ for (const utility of atrulesNamed(node, "utility")) {
5294
+ const name = preludeIdentifiers(utility)[0];
5295
+ if (!name) continue;
5296
+ const pattern = usagePattern(name);
5297
+ const definition = `@utility ${name}`;
5298
+ const used = files.some((file) => pattern.test(textOf(file).replaceAll(definition, "")));
5299
+ if (used) continue;
5300
+ context.report({
5301
+ node: utility,
5302
+ message: `Custom utility "${name}" is never used by the repository's source; remove it or use it.`
5303
+ });
5304
+ }
5305
+ }
5306
+ };
5307
+ }
5308
+ };
5309
+
4842
5310
  // eslint/rules/tailwind/index.ts
4843
5311
  var tailwindRules = {
4844
5312
  "theme-reset": themeResetRule,
@@ -4851,7 +5319,8 @@ var tailwindRules = {
4851
5319
  "surface-utility": surfaceUtilityRule,
4852
5320
  "theme-variable-namespace": themeVariableNamespaceRule,
4853
5321
  "global-css-location": globalCssLocationRule,
4854
- "global-stylesheet": globalStylesheetRule
5322
+ "global-stylesheet": globalStylesheetRule,
5323
+ "unused-utility": unusedUtilityRule
4855
5324
  };
4856
5325
 
4857
5326
  // eslint/rules/package-json/exact-version.ts
@@ -4998,8 +5467,8 @@ var nextPackageJsonRules = {
4998
5467
  };
4999
5468
 
5000
5469
  // eslint/rules/husky/husky-hook.ts
5001
- import { existsSync as existsSync2, readFileSync as readFileSync6 } from "fs";
5002
- import path40 from "path";
5470
+ import { existsSync as existsSync2, readFileSync as readFileSync8 } from "fs";
5471
+ import path42 from "path";
5003
5472
  function memberName4(member) {
5004
5473
  return member.name.type === "String" ? member.name.value : member.name.name;
5005
5474
  }
@@ -5018,7 +5487,7 @@ var huskyHookRule = {
5018
5487
  if (root.type !== "Object") return;
5019
5488
  const scriptName = context.filename;
5020
5489
  if (!scriptName.endsWith("package.json")) return;
5021
- const hookPath = path40.join(process.cwd(), ".husky", "pre-commit");
5490
+ const hookPath = path42.join(process.cwd(), ".husky", "pre-commit");
5022
5491
  if (!existsSync2(hookPath)) {
5023
5492
  context.report({
5024
5493
  node,
@@ -5026,7 +5495,7 @@ var huskyHookRule = {
5026
5495
  });
5027
5496
  return;
5028
5497
  }
5029
- const content = readFileSync6(hookPath, "utf8");
5498
+ const content = readFileSync8(hookPath, "utf8");
5030
5499
  if (!content.includes("lint-staged")) {
5031
5500
  context.report({ node, message: ".husky/pre-commit must run lint-staged." });
5032
5501
  }
@@ -5057,8 +5526,8 @@ var huskyRules = {
5057
5526
  };
5058
5527
 
5059
5528
  // eslint/rules/vulyk/vulyk-docs.ts
5060
- import { existsSync as existsSync3, readFileSync as readFileSync7 } from "fs";
5061
- import path41 from "path";
5529
+ import { existsSync as existsSync3, readFileSync as readFileSync9 } from "fs";
5530
+ import path43 from "path";
5062
5531
  var PASIKA_REPO = "Bredansky/pasika";
5063
5532
  var vulykDocsRule = {
5064
5533
  meta: {
@@ -5072,8 +5541,8 @@ var vulykDocsRule = {
5072
5541
  return {
5073
5542
  Document(node) {
5074
5543
  if (!context.filename.endsWith("package.json")) return;
5075
- const projectRoot = path41.dirname(path41.resolve(context.filename));
5076
- const configPath = path41.join(projectRoot, "vulyk.config.ts");
5544
+ const projectRoot = path43.dirname(path43.resolve(context.filename));
5545
+ const configPath = path43.join(projectRoot, "vulyk.config.ts");
5077
5546
  if (!existsSync3(configPath)) {
5078
5547
  context.report({
5079
5548
  node,
@@ -5081,14 +5550,14 @@ var vulykDocsRule = {
5081
5550
  });
5082
5551
  return;
5083
5552
  }
5084
- const config = readFileSync7(configPath, "utf8");
5553
+ const config = readFileSync9(configPath, "utf8");
5085
5554
  if (!config.includes(PASIKA_REPO)) {
5086
5555
  context.report({
5087
5556
  node,
5088
5557
  message: "vulyk.config.ts must track the framework's docs from the pasika repository."
5089
5558
  });
5090
5559
  }
5091
- const agentsPath = path41.join(projectRoot, "AGENTS.md");
5560
+ const agentsPath = path43.join(projectRoot, "AGENTS.md");
5092
5561
  if (!existsSync3(agentsPath)) {
5093
5562
  context.report({
5094
5563
  node,
@@ -5132,6 +5601,7 @@ var nextjsAppRules = {
5132
5601
  "ui-state": uiStateRule,
5133
5602
  "no-mixed-concerns": noMixedConcernsRule,
5134
5603
  "no-arbitrary-tailwind": noArbitraryTailwindRule,
5604
+ "unknown-utility": unknownUtilityRule,
5135
5605
  "enforce-cn-merge": enforceCnMergeRule,
5136
5606
  "cn-helper": cnHelperRule,
5137
5607
  "enforce-cva-variant-props": enforceCvaVariantPropsRule,