pasika 0.5.3 → 0.5.5

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.
@@ -907,6 +907,224 @@ var unknownUtilityRule = {
907
907
  }
908
908
  };
909
909
 
910
+ // eslint/rules/enforce-cn-merge.ts
911
+ import path8 from "path";
912
+
913
+ // eslint/project/index.ts
914
+ import { readdirSync as readdirSync2, statSync as statSync2 } from "fs";
915
+ import path7 from "path";
916
+
917
+ // eslint/project/parse-module.ts
918
+ import path6 from "path";
919
+ import { readFileSync as readFileSync2 } from "fs";
920
+ import ts2 from "typescript";
921
+ var isPascalCase3 = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
922
+ var isHookName = (name) => /^use[A-Z]/.test(name);
923
+ var isSchemaName = (name) => /[Ss]chema$/.test(name);
924
+ function lineOf(sourceFile, node) {
925
+ return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
926
+ }
927
+ function returnsJsx(node) {
928
+ let found = false;
929
+ const visit = (child) => {
930
+ if (found) return;
931
+ if (ts2.isJsxElement(child) || ts2.isJsxSelfClosingElement(child) || ts2.isJsxFragment(child) || ts2.isJsxOpeningFragment(child)) {
932
+ found = true;
933
+ return;
934
+ }
935
+ ts2.forEachChild(child, visit);
936
+ };
937
+ ts2.forEachChild(node, visit);
938
+ return found;
939
+ }
940
+ function classifyFunction(name, isTsx, hasJsx) {
941
+ if (isHookName(name)) return "hook";
942
+ if (isTsx && isPascalCase3(name) && hasJsx) return "component";
943
+ return "function";
944
+ }
945
+ function classifyValue(name, initializer, isTsx) {
946
+ const isFunctionLike = initializer !== void 0 && (ts2.isArrowFunction(initializer) || ts2.isFunctionExpression(initializer) || ts2.isFunctionDeclaration(initializer));
947
+ if (isHookName(name)) return "hook";
948
+ if (isSchemaName(name)) return "schema";
949
+ if (isTsx && isPascalCase3(name) && (initializer === void 0 || returnsJsx(initializer) || isFunctionLike)) {
950
+ return "component";
951
+ }
952
+ if (isFunctionLike) return "function";
953
+ return "constant";
954
+ }
955
+ function parseModule(file) {
956
+ const text = readFileSync2(file, "utf8");
957
+ const isTsx = file.endsWith(".tsx") || file.endsWith(".jsx");
958
+ const sourceFile = ts2.createSourceFile(file, text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
959
+ const imports = [];
960
+ const exports = [];
961
+ const addImport = (specifierNode, names, node) => {
962
+ if (!ts2.isStringLiteral(specifierNode)) return;
963
+ imports.push({ specifier: specifierNode.text, names, line: lineOf(sourceFile, node) });
964
+ };
965
+ for (const statement of sourceFile.statements) {
966
+ if (ts2.isImportDeclaration(statement)) {
967
+ const names = [];
968
+ const bindings = statement.importClause?.namedBindings;
969
+ if (statement.importClause?.name) names.push(statement.importClause.name.text);
970
+ if (bindings && ts2.isNamedImports(bindings)) {
971
+ for (const element of bindings.elements) names.push(element.propertyName?.text ?? element.name.text);
972
+ }
973
+ addImport(statement.moduleSpecifier, names, statement);
974
+ continue;
975
+ }
976
+ if (ts2.isExportDeclaration(statement)) {
977
+ if (statement.moduleSpecifier) {
978
+ const names = [];
979
+ if (statement.exportClause && ts2.isNamedExports(statement.exportClause)) {
980
+ for (const element of statement.exportClause.elements) {
981
+ names.push(element.propertyName?.text ?? element.name.text);
982
+ }
983
+ }
984
+ addImport(statement.moduleSpecifier, names, statement);
985
+ }
986
+ if (statement.exportClause && ts2.isNamedExports(statement.exportClause)) {
987
+ for (const element of statement.exportClause.elements) {
988
+ exports.push({ name: element.name.text, kind: "other", line: lineOf(sourceFile, element) });
989
+ }
990
+ }
991
+ continue;
992
+ }
993
+ const isExported2 = ts2.canHaveModifiers(statement) ? (ts2.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword) : false;
994
+ if (!isExported2) continue;
995
+ if (ts2.isFunctionDeclaration(statement) && statement.name) {
996
+ const name = statement.name.text;
997
+ exports.push({
998
+ name,
999
+ kind: classifyFunction(name, isTsx, returnsJsx(statement)),
1000
+ line: lineOf(sourceFile, statement)
1001
+ });
1002
+ continue;
1003
+ }
1004
+ if (ts2.isVariableStatement(statement)) {
1005
+ for (const declaration of statement.declarationList.declarations) {
1006
+ if (!ts2.isIdentifier(declaration.name)) continue;
1007
+ exports.push({
1008
+ name: declaration.name.text,
1009
+ kind: classifyValue(declaration.name.text, declaration.initializer, isTsx),
1010
+ line: lineOf(sourceFile, declaration)
1011
+ });
1012
+ }
1013
+ continue;
1014
+ }
1015
+ if (ts2.isTypeAliasDeclaration(statement) || ts2.isInterfaceDeclaration(statement)) {
1016
+ exports.push({ name: statement.name.text, kind: "type", line: lineOf(sourceFile, statement) });
1017
+ }
1018
+ }
1019
+ return { file: path6.resolve(file), imports, exports };
1020
+ }
1021
+
1022
+ // eslint/project/index.ts
1023
+ var MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
1024
+ var INDEX_BASENAMES = ["index.ts", "index.tsx", "index.mts", "index.cts", "index.js", "index.jsx"];
1025
+ var REVALIDATE_AFTER_MS = 2e3;
1026
+ var symbolKey = (file, name) => `${file}\0${name}`;
1027
+ function listSourceFiles(dir) {
1028
+ let entries;
1029
+ try {
1030
+ entries = readdirSync2(dir);
1031
+ } catch {
1032
+ return [];
1033
+ }
1034
+ return entries.flatMap((entry) => {
1035
+ if (entry.startsWith(".") || entry === "node_modules") return [];
1036
+ const entryPath = path7.join(dir, entry);
1037
+ let stats;
1038
+ try {
1039
+ stats = statSync2(entryPath);
1040
+ } catch {
1041
+ return [];
1042
+ }
1043
+ if (stats.isDirectory()) return listSourceFiles(entryPath);
1044
+ return MODULE_EXTENSIONS.includes(path7.extname(entry)) ? [entryPath] : [];
1045
+ });
1046
+ }
1047
+ function fingerprint(files) {
1048
+ let total = 0;
1049
+ for (const file of files) {
1050
+ try {
1051
+ total += statSync2(file).mtimeMs;
1052
+ } catch {
1053
+ }
1054
+ }
1055
+ return `${String(files.length)}:${String(total)}`;
1056
+ }
1057
+ function resolveSpecifier(fromFile, specifier, sourceRoot) {
1058
+ let base;
1059
+ if (specifier.startsWith("@/")) {
1060
+ base = path7.resolve(sourceRoot, specifier.slice(2));
1061
+ } else if (specifier.startsWith(".")) {
1062
+ base = path7.resolve(path7.dirname(fromFile), specifier);
1063
+ } else {
1064
+ return void 0;
1065
+ }
1066
+ const candidates = [
1067
+ base,
1068
+ ...MODULE_EXTENSIONS.map((extension) => `${base}${extension}`),
1069
+ ...INDEX_BASENAMES.map((name) => path7.join(base, name))
1070
+ ];
1071
+ for (const candidate of candidates) {
1072
+ try {
1073
+ if (statSync2(candidate).isFile()) return candidate;
1074
+ } catch {
1075
+ }
1076
+ }
1077
+ return void 0;
1078
+ }
1079
+ function build(sourceRoot, files) {
1080
+ const modules = /* @__PURE__ */ new Map();
1081
+ const consumers = /* @__PURE__ */ new Map();
1082
+ const symbolConsumers = /* @__PURE__ */ new Map();
1083
+ for (const file of files) {
1084
+ try {
1085
+ modules.set(file, parseModule(file));
1086
+ } catch {
1087
+ }
1088
+ }
1089
+ for (const [file, module] of modules) {
1090
+ for (const moduleImport of module.imports) {
1091
+ const target = resolveSpecifier(file, moduleImport.specifier, sourceRoot);
1092
+ if (!target || !modules.has(target)) continue;
1093
+ const fileConsumers = consumers.get(target) ?? /* @__PURE__ */ new Set();
1094
+ fileConsumers.add(file);
1095
+ consumers.set(target, fileConsumers);
1096
+ for (const name of moduleImport.names) {
1097
+ const key = symbolKey(target, name);
1098
+ const nameConsumers = symbolConsumers.get(key) ?? /* @__PURE__ */ new Set();
1099
+ nameConsumers.add(file);
1100
+ symbolConsumers.set(key, nameConsumers);
1101
+ }
1102
+ }
1103
+ }
1104
+ return { sourceRoot, modules, consumers, symbolConsumers };
1105
+ }
1106
+ var cache;
1107
+ function getProjectIndex(sourceRoot) {
1108
+ const now = Date.now();
1109
+ if (cache?.index.sourceRoot === sourceRoot && now - cache.checkedAt < REVALIDATE_AFTER_MS) {
1110
+ return cache.index;
1111
+ }
1112
+ try {
1113
+ if (!statSync2(sourceRoot).isDirectory()) return void 0;
1114
+ } catch {
1115
+ return void 0;
1116
+ }
1117
+ const files = listSourceFiles(sourceRoot).sort((left, right) => left.localeCompare(right));
1118
+ const currentFingerprint = fingerprint(files);
1119
+ if (cache?.index.sourceRoot === sourceRoot && cache.fingerprint === currentFingerprint) {
1120
+ cache.checkedAt = now;
1121
+ return cache.index;
1122
+ }
1123
+ const index = build(sourceRoot, files);
1124
+ cache = { index, checkedAt: now, fingerprint: currentFingerprint };
1125
+ return index;
1126
+ }
1127
+
910
1128
  // eslint/rules/enforce-cn-merge.ts
911
1129
  function classCount(str) {
912
1130
  return str.split(/\s+/).filter(Boolean).length;
@@ -935,11 +1153,22 @@ function stringArguments(node) {
935
1153
  var enforceCnMergeRule = {
936
1154
  meta: { schema: [], type: "problem", docs: { description: "Enforce cn() for conditional class merging." } },
937
1155
  create(context) {
1156
+ const packageComponents = /* @__PURE__ */ new Set();
1157
+ const index = getProjectIndex(sourceRootOf(context));
1158
+ const module = index?.modules.get(path8.resolve(context.filename));
1159
+ for (const moduleImport of module?.imports ?? []) {
1160
+ if (moduleImport.specifier.startsWith(".") || moduleImport.specifier.startsWith("@/")) continue;
1161
+ for (const name of moduleImport.names) {
1162
+ if (/^[A-Z]/.test(name)) packageComponents.add(name);
1163
+ }
1164
+ }
938
1165
  return {
939
1166
  JSXAttribute(node) {
940
1167
  const attributeName = node.name?.name ?? "";
941
1168
  const element = node.parent.parent;
942
- const isComponentProp = isComponentName(element.openingElement?.name);
1169
+ const componentName = element.openingElement?.name;
1170
+ const isComponentProp = isComponentName(componentName);
1171
+ const isPackageComponent = componentName?.type === "JSXIdentifier" && packageComponents.has(componentName.name);
943
1172
  if (isComponentProp && attributeName !== "className" && attributeName.endsWith("ClassName")) {
944
1173
  context.report({
945
1174
  node,
@@ -951,6 +1180,7 @@ var enforceCnMergeRule = {
951
1180
  const valueNode = node.value;
952
1181
  if (!valueNode) return;
953
1182
  if (isComponentProp && attributeName === "className") {
1183
+ if (isPackageComponent) return;
954
1184
  const expression = valueNode.type === "JSXExpressionContainer" ? valueNode.expression : valueNode;
955
1185
  const invalidClass = stringArguments(expression).flatMap((value) => value.split(/\s+/).filter(Boolean)).find((className) => !isOuterLayoutClass(className));
956
1186
  if (invalidClass) {
@@ -1085,322 +1315,107 @@ var enforceCvaVariantPropsRule = {
1085
1315
  }
1086
1316
  }
1087
1317
  },
1088
- TSTypeAliasDeclaration(node) {
1089
- const aliasName = node.id?.name;
1090
- if (!aliasName?.endsWith("Props")) return;
1091
- if (node.typeAnnotation?.type !== "TSTypeLiteral") return;
1092
- for (const member of node.typeAnnotation.members ?? []) {
1093
- if (member.type !== "TSPropertySignature") continue;
1094
- const keyName2 = member.key?.type === "Identifier" ? member.key.name : void 0;
1095
- if (!keyName2) continue;
1096
- const typeAnn = member.typeAnnotation?.typeAnnotation;
1097
- if (typeAnn?.type !== "TSUnionType") continue;
1098
- const allStringLiterals = (typeAnn.types ?? []).every(
1099
- (t) => t.type === "TSLiteralType" && (t.literal?.type === "StringLiteral" || t.literal?.type === "Literal" && typeof t.literal.value === "string")
1100
- );
1101
- if (allStringLiterals && (typeAnn.types?.length ?? 0) >= 2) {
1102
- for (const variantNames of cvaDefinitions.values()) {
1103
- if (variantNames.includes(keyName2)) {
1104
- context.report({
1105
- node,
1106
- message: `Variant prop "${keyName2}" duplicates CVA variant values. Use VariantProps<typeof variants> instead of manually writing union types. See docs/styling-guide/rules/component-variant-rule.md`
1107
- });
1108
- return;
1109
- }
1110
- }
1111
- }
1112
- }
1113
- }
1114
- };
1115
- }
1116
- };
1117
-
1118
- // eslint/rules/enforce-barrel-exports.ts
1119
- import path6 from "path";
1120
- import fs from "fs";
1121
- function isPascalCase3(str) {
1122
- return /^[A-Z][A-Za-z0-9]*$/.test(str);
1123
- }
1124
- function isKebabCase2(str) {
1125
- return /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(str);
1126
- }
1127
- var SUPPORT_FOLDERS = /* @__PURE__ */ new Set(["types", "schemas", "hooks", "constants", "utils", "config", "locales"]);
1128
- var enforceBarrelExportsRule = {
1129
- meta: {
1130
- schema: [],
1131
- type: "problem",
1132
- docs: {
1133
- description: "Enforce index.ts barrels only re-export the parent component."
1134
- }
1135
- },
1136
- create(context) {
1137
- const filename = context.filename;
1138
- if (!filename) return {};
1139
- const baseName = path6.basename(filename);
1140
- if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
1141
- const dirPath = path6.dirname(filename);
1142
- const folderName = path6.basename(dirPath);
1143
- const parentFolderName = path6.basename(path6.dirname(dirPath));
1144
- if (SUPPORT_FOLDERS.has(folderName)) return {};
1145
- if (!isPascalCase3(folderName) && !isKebabCase2(folderName)) return {};
1146
- const matchingTsx = fs.existsSync(path6.join(dirPath, `${folderName}.tsx`)) ? folderName : null;
1147
- if (!matchingTsx) return {};
1148
- if (!isPascalCase3(parentFolderName) && !isKebabCase2(parentFolderName)) return {};
1149
- const reExportedNames = /* @__PURE__ */ new Set();
1150
- return {
1151
- ExportNamedDeclaration(node) {
1152
- if (!node.source) return;
1153
- for (const spec of node.specifiers) {
1154
- if (spec.exported.type === "Identifier") {
1155
- reExportedNames.add(spec.exported.name);
1156
- }
1157
- }
1158
- },
1159
- "Program:exit"() {
1160
- if (reExportedNames.size === 0) return;
1161
- if (!reExportedNames.has(matchingTsx)) {
1162
- context.report({
1163
- loc: { line: 1, column: 0 },
1164
- message: `index.ts in "${folderName}/" must re-export "${matchingTsx}". See docs/code-organization-guide/rules/folder-nesting-rule.md`
1165
- });
1166
- return;
1167
- }
1168
- const nonParentExports = [...reExportedNames].filter((n) => n !== matchingTsx);
1169
- if (nonParentExports.length > 0) {
1170
- context.report({
1171
- loc: { line: 1, column: 0 },
1172
- message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${matchingTsx}" may be re-exported. See docs/code-organization-guide/rules/folder-nesting-rule.md`
1173
- });
1174
- }
1175
- }
1176
- };
1177
- }
1178
- };
1179
-
1180
- // eslint/rules/component-placement.ts
1181
- import path10 from "path";
1182
-
1183
- // eslint/project/index.ts
1184
- import { readdirSync as readdirSync2, statSync as statSync2 } from "fs";
1185
- import path8 from "path";
1186
-
1187
- // eslint/project/parse-module.ts
1188
- import path7 from "path";
1189
- import { readFileSync as readFileSync2 } from "fs";
1190
- import ts2 from "typescript";
1191
- var isPascalCase4 = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
1192
- var isHookName = (name) => /^use[A-Z]/.test(name);
1193
- var isSchemaName = (name) => /[Ss]chema$/.test(name);
1194
- function lineOf(sourceFile, node) {
1195
- return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
1196
- }
1197
- function returnsJsx(node) {
1198
- let found = false;
1199
- const visit = (child) => {
1200
- if (found) return;
1201
- if (ts2.isJsxElement(child) || ts2.isJsxSelfClosingElement(child) || ts2.isJsxFragment(child) || ts2.isJsxOpeningFragment(child)) {
1202
- found = true;
1203
- return;
1204
- }
1205
- ts2.forEachChild(child, visit);
1206
- };
1207
- ts2.forEachChild(node, visit);
1208
- return found;
1209
- }
1210
- function classifyFunction(name, isTsx, hasJsx) {
1211
- if (isHookName(name)) return "hook";
1212
- if (isTsx && isPascalCase4(name) && hasJsx) return "component";
1213
- return "function";
1214
- }
1215
- function classifyValue(name, initializer, isTsx) {
1216
- const isFunctionLike = initializer !== void 0 && (ts2.isArrowFunction(initializer) || ts2.isFunctionExpression(initializer) || ts2.isFunctionDeclaration(initializer));
1217
- if (isHookName(name)) return "hook";
1218
- if (isSchemaName(name)) return "schema";
1219
- if (isTsx && isPascalCase4(name) && (initializer === void 0 || returnsJsx(initializer) || isFunctionLike)) {
1220
- return "component";
1221
- }
1222
- if (isFunctionLike) return "function";
1223
- return "constant";
1224
- }
1225
- function parseModule(file) {
1226
- const text = readFileSync2(file, "utf8");
1227
- const isTsx = file.endsWith(".tsx") || file.endsWith(".jsx");
1228
- const sourceFile = ts2.createSourceFile(file, text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
1229
- const imports = [];
1230
- const exports = [];
1231
- const addImport = (specifierNode, names, node) => {
1232
- if (!ts2.isStringLiteral(specifierNode)) return;
1233
- imports.push({ specifier: specifierNode.text, names, line: lineOf(sourceFile, node) });
1234
- };
1235
- for (const statement of sourceFile.statements) {
1236
- if (ts2.isImportDeclaration(statement)) {
1237
- const names = [];
1238
- const bindings = statement.importClause?.namedBindings;
1239
- if (statement.importClause?.name) names.push(statement.importClause.name.text);
1240
- if (bindings && ts2.isNamedImports(bindings)) {
1241
- for (const element of bindings.elements) names.push(element.propertyName?.text ?? element.name.text);
1242
- }
1243
- addImport(statement.moduleSpecifier, names, statement);
1244
- continue;
1245
- }
1246
- if (ts2.isExportDeclaration(statement)) {
1247
- if (statement.moduleSpecifier) {
1248
- const names = [];
1249
- if (statement.exportClause && ts2.isNamedExports(statement.exportClause)) {
1250
- for (const element of statement.exportClause.elements) {
1251
- names.push(element.propertyName?.text ?? element.name.text);
1252
- }
1253
- }
1254
- addImport(statement.moduleSpecifier, names, statement);
1255
- }
1256
- if (statement.exportClause && ts2.isNamedExports(statement.exportClause)) {
1257
- for (const element of statement.exportClause.elements) {
1258
- exports.push({ name: element.name.text, kind: "other", line: lineOf(sourceFile, element) });
1259
- }
1260
- }
1261
- continue;
1262
- }
1263
- const isExported2 = ts2.canHaveModifiers(statement) ? (ts2.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword) : false;
1264
- if (!isExported2) continue;
1265
- if (ts2.isFunctionDeclaration(statement) && statement.name) {
1266
- const name = statement.name.text;
1267
- exports.push({
1268
- name,
1269
- kind: classifyFunction(name, isTsx, returnsJsx(statement)),
1270
- line: lineOf(sourceFile, statement)
1271
- });
1272
- continue;
1273
- }
1274
- if (ts2.isVariableStatement(statement)) {
1275
- for (const declaration of statement.declarationList.declarations) {
1276
- if (!ts2.isIdentifier(declaration.name)) continue;
1277
- exports.push({
1278
- name: declaration.name.text,
1279
- kind: classifyValue(declaration.name.text, declaration.initializer, isTsx),
1280
- line: lineOf(sourceFile, declaration)
1281
- });
1282
- }
1283
- continue;
1284
- }
1285
- if (ts2.isTypeAliasDeclaration(statement) || ts2.isInterfaceDeclaration(statement)) {
1286
- exports.push({ name: statement.name.text, kind: "type", line: lineOf(sourceFile, statement) });
1287
- }
1288
- }
1289
- return { file: path7.resolve(file), imports, exports };
1290
- }
1291
-
1292
- // eslint/project/index.ts
1293
- var MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
1294
- var INDEX_BASENAMES = ["index.ts", "index.tsx", "index.mts", "index.cts", "index.js", "index.jsx"];
1295
- var REVALIDATE_AFTER_MS = 2e3;
1296
- var symbolKey = (file, name) => `${file}\0${name}`;
1297
- function listSourceFiles(dir) {
1298
- let entries;
1299
- try {
1300
- entries = readdirSync2(dir);
1301
- } catch {
1302
- return [];
1303
- }
1304
- return entries.flatMap((entry) => {
1305
- if (entry.startsWith(".") || entry === "node_modules") return [];
1306
- const entryPath = path8.join(dir, entry);
1307
- let stats;
1308
- try {
1309
- stats = statSync2(entryPath);
1310
- } catch {
1311
- return [];
1312
- }
1313
- if (stats.isDirectory()) return listSourceFiles(entryPath);
1314
- return MODULE_EXTENSIONS.includes(path8.extname(entry)) ? [entryPath] : [];
1315
- });
1316
- }
1317
- function fingerprint(files) {
1318
- let total = 0;
1319
- for (const file of files) {
1320
- try {
1321
- total += statSync2(file).mtimeMs;
1322
- } catch {
1323
- }
1318
+ TSTypeAliasDeclaration(node) {
1319
+ const aliasName = node.id?.name;
1320
+ if (!aliasName?.endsWith("Props")) return;
1321
+ if (node.typeAnnotation?.type !== "TSTypeLiteral") return;
1322
+ for (const member of node.typeAnnotation.members ?? []) {
1323
+ if (member.type !== "TSPropertySignature") continue;
1324
+ const keyName2 = member.key?.type === "Identifier" ? member.key.name : void 0;
1325
+ if (!keyName2) continue;
1326
+ const typeAnn = member.typeAnnotation?.typeAnnotation;
1327
+ if (typeAnn?.type !== "TSUnionType") continue;
1328
+ const allStringLiterals = (typeAnn.types ?? []).every(
1329
+ (t) => t.type === "TSLiteralType" && (t.literal?.type === "StringLiteral" || t.literal?.type === "Literal" && typeof t.literal.value === "string")
1330
+ );
1331
+ if (allStringLiterals && (typeAnn.types?.length ?? 0) >= 2) {
1332
+ for (const variantNames of cvaDefinitions.values()) {
1333
+ if (variantNames.includes(keyName2)) {
1334
+ context.report({
1335
+ node,
1336
+ message: `Variant prop "${keyName2}" duplicates CVA variant values. Use VariantProps<typeof variants> instead of manually writing union types. See docs/styling-guide/rules/component-variant-rule.md`
1337
+ });
1338
+ return;
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+ }
1344
+ };
1324
1345
  }
1325
- return `${String(files.length)}:${String(total)}`;
1346
+ };
1347
+
1348
+ // eslint/rules/enforce-barrel-exports.ts
1349
+ import path9 from "path";
1350
+ import fs from "fs";
1351
+ function isPascalCase4(str) {
1352
+ return /^[A-Z][A-Za-z0-9]*$/.test(str);
1326
1353
  }
1327
- function resolveSpecifier(fromFile, specifier, sourceRoot) {
1328
- let base;
1329
- if (specifier.startsWith("@/")) {
1330
- base = path8.resolve(sourceRoot, specifier.slice(2));
1331
- } else if (specifier.startsWith(".")) {
1332
- base = path8.resolve(path8.dirname(fromFile), specifier);
1333
- } else {
1334
- return void 0;
1335
- }
1336
- const candidates = [
1337
- base,
1338
- ...MODULE_EXTENSIONS.map((extension) => `${base}${extension}`),
1339
- ...INDEX_BASENAMES.map((name) => path8.join(base, name))
1340
- ];
1341
- for (const candidate of candidates) {
1342
- try {
1343
- if (statSync2(candidate).isFile()) return candidate;
1344
- } catch {
1345
- }
1346
- }
1347
- return void 0;
1354
+ function isKebabCase2(str) {
1355
+ return /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(str);
1348
1356
  }
1349
- function build(sourceRoot, files) {
1350
- const modules = /* @__PURE__ */ new Map();
1351
- const consumers = /* @__PURE__ */ new Map();
1352
- const symbolConsumers = /* @__PURE__ */ new Map();
1353
- for (const file of files) {
1354
- try {
1355
- modules.set(file, parseModule(file));
1356
- } catch {
1357
+ var SUPPORT_FOLDERS = /* @__PURE__ */ new Set(["types", "schemas", "hooks", "constants", "utils", "config", "locales"]);
1358
+ var enforceBarrelExportsRule = {
1359
+ meta: {
1360
+ schema: [],
1361
+ type: "problem",
1362
+ docs: {
1363
+ description: "Enforce index.ts barrels only re-export the parent component."
1357
1364
  }
1358
- }
1359
- for (const [file, module] of modules) {
1360
- for (const moduleImport of module.imports) {
1361
- const target = resolveSpecifier(file, moduleImport.specifier, sourceRoot);
1362
- if (!target || !modules.has(target)) continue;
1363
- const fileConsumers = consumers.get(target) ?? /* @__PURE__ */ new Set();
1364
- fileConsumers.add(file);
1365
- consumers.set(target, fileConsumers);
1366
- for (const name of moduleImport.names) {
1367
- const key = symbolKey(target, name);
1368
- const nameConsumers = symbolConsumers.get(key) ?? /* @__PURE__ */ new Set();
1369
- nameConsumers.add(file);
1370
- symbolConsumers.set(key, nameConsumers);
1365
+ },
1366
+ create(context) {
1367
+ const filename = context.filename;
1368
+ if (!filename) return {};
1369
+ const baseName = path9.basename(filename);
1370
+ if (baseName !== "index.ts" && baseName !== "index.cts" && baseName !== "index.mts") return {};
1371
+ const dirPath = path9.dirname(filename);
1372
+ const folderName = path9.basename(dirPath);
1373
+ const parentFolderName = path9.basename(path9.dirname(dirPath));
1374
+ if (SUPPORT_FOLDERS.has(folderName)) return {};
1375
+ if (!isPascalCase4(folderName) && !isKebabCase2(folderName)) return {};
1376
+ const matchingTsx = fs.existsSync(path9.join(dirPath, `${folderName}.tsx`)) ? folderName : null;
1377
+ if (!matchingTsx) return {};
1378
+ if (!isPascalCase4(parentFolderName) && !isKebabCase2(parentFolderName)) return {};
1379
+ const reExportedNames = /* @__PURE__ */ new Set();
1380
+ return {
1381
+ ExportNamedDeclaration(node) {
1382
+ if (!node.source) return;
1383
+ for (const spec of node.specifiers) {
1384
+ if (spec.exported.type === "Identifier") {
1385
+ reExportedNames.add(spec.exported.name);
1386
+ }
1387
+ }
1388
+ },
1389
+ "Program:exit"() {
1390
+ if (reExportedNames.size === 0) return;
1391
+ if (!reExportedNames.has(matchingTsx)) {
1392
+ context.report({
1393
+ loc: { line: 1, column: 0 },
1394
+ message: `index.ts in "${folderName}/" must re-export "${matchingTsx}". See docs/code-organization-guide/rules/folder-nesting-rule.md`
1395
+ });
1396
+ return;
1397
+ }
1398
+ const nonParentExports = [...reExportedNames].filter((n) => n !== matchingTsx);
1399
+ if (nonParentExports.length > 0) {
1400
+ context.report({
1401
+ loc: { line: 1, column: 0 },
1402
+ message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${matchingTsx}" may be re-exported. See docs/code-organization-guide/rules/folder-nesting-rule.md`
1403
+ });
1404
+ }
1371
1405
  }
1372
- }
1373
- }
1374
- return { sourceRoot, modules, consumers, symbolConsumers };
1375
- }
1376
- var cache;
1377
- function getProjectIndex(sourceRoot) {
1378
- const now = Date.now();
1379
- if (cache?.index.sourceRoot === sourceRoot && now - cache.checkedAt < REVALIDATE_AFTER_MS) {
1380
- return cache.index;
1381
- }
1382
- try {
1383
- if (!statSync2(sourceRoot).isDirectory()) return void 0;
1384
- } catch {
1385
- return void 0;
1386
- }
1387
- const files = listSourceFiles(sourceRoot).sort((left, right) => left.localeCompare(right));
1388
- const currentFingerprint = fingerprint(files);
1389
- if (cache?.index.sourceRoot === sourceRoot && cache.fingerprint === currentFingerprint) {
1390
- cache.checkedAt = now;
1391
- return cache.index;
1406
+ };
1392
1407
  }
1393
- const index = build(sourceRoot, files);
1394
- cache = { index, checkedAt: now, fingerprint: currentFingerprint };
1395
- return index;
1396
- }
1408
+ };
1409
+
1410
+ // eslint/rules/component-placement.ts
1411
+ import path11 from "path";
1397
1412
 
1398
1413
  // eslint/project/ccf.ts
1399
- import path9 from "path";
1414
+ import path10 from "path";
1400
1415
  var SUPPORT_FOLDERS2 = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
1401
1416
  function segmentsOf(file, sourceRoot) {
1402
- const relative = path9.relative(sourceRoot, file);
1403
- return relative.startsWith("..") ? [] : relative.split(path9.sep);
1417
+ const relative = path10.relative(sourceRoot, file);
1418
+ return relative.startsWith("..") ? [] : relative.split(path10.sep);
1404
1419
  }
1405
1420
  function folderSegmentsOf(file, sourceRoot) {
1406
1421
  return segmentsOf(file, sourceRoot).slice(0, -1);
@@ -1479,7 +1494,7 @@ function resolveSupportPlacement(supportFile, supportFolder, index) {
1479
1494
  }
1480
1495
  function describeConsumers(consumers, sourceRoot) {
1481
1496
  const shown = 3;
1482
- const names = consumers.map((consumer) => path9.relative(path9.dirname(sourceRoot), consumer).split(path9.sep).join("/")).sort((left, right) => left.localeCompare(right));
1497
+ const names = consumers.map((consumer) => path10.relative(path10.dirname(sourceRoot), consumer).split(path10.sep).join("/")).sort((left, right) => left.localeCompare(right));
1483
1498
  if (names.length <= shown) return names.join(", ");
1484
1499
  return `${names.slice(0, shown).join(", ")} and ${String(names.length - shown)} more`;
1485
1500
  }
@@ -1505,7 +1520,7 @@ var componentPlacementRule = {
1505
1520
  const sourceRoot = sourceRootOf(context);
1506
1521
  const index = getProjectIndex(sourceRoot);
1507
1522
  if (!index) return {};
1508
- const componentFile = path10.resolve(filename);
1523
+ const componentFile = path11.resolve(filename);
1509
1524
  const segments = segmentsOf(componentFile, sourceRoot);
1510
1525
  if (segments.length === 0) return {};
1511
1526
  if (isUnderApp(segments) || isConfigModule(segments)) return {};
@@ -1538,7 +1553,7 @@ var componentPlacementRule = {
1538
1553
  };
1539
1554
 
1540
1555
  // eslint/rules/support-file-placement.ts
1541
- import path11 from "path";
1556
+ import path12 from "path";
1542
1557
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
1543
1558
  var REASON_TEXT2 = {
1544
1559
  "app-consumer": "a file under src/app/ imports it, so it belongs to the app-wide support folder",
@@ -1558,7 +1573,7 @@ var supportFilePlacementRule = {
1558
1573
  },
1559
1574
  create(context) {
1560
1575
  const sourceRoot = sourceRootOf(context);
1561
- const supportFile = path11.resolve(context.filename);
1576
+ const supportFile = path12.resolve(context.filename);
1562
1577
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
1563
1578
  const supportFolder = currentFolder[currentFolder.length - 1];
1564
1579
  if (supportFolder === void 0 || !SUPPORT_FOLDERS2.has(supportFolder)) return {};
@@ -1583,11 +1598,12 @@ var supportFilePlacementRule = {
1583
1598
 
1584
1599
  // eslint/rules/application-structure.ts
1585
1600
  import fs2 from "fs";
1586
- import path12 from "path";
1601
+ import path13 from "path";
1587
1602
  var MODULE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
1588
1603
  var ROUTING_FILES = /* @__PURE__ */ new Set([
1589
1604
  "default",
1590
1605
  "error",
1606
+ "global-error",
1591
1607
  "instrumentation",
1592
1608
  "layout",
1593
1609
  "loading",
@@ -1595,7 +1611,15 @@ var ROUTING_FILES = /* @__PURE__ */ new Set([
1595
1611
  "not-found",
1596
1612
  "page",
1597
1613
  "route",
1598
- "template"
1614
+ "template",
1615
+ // File conventions Next.js requires to keep their exact names in src/app/
1616
+ "apple-icon",
1617
+ "icon",
1618
+ "manifest",
1619
+ "opengraph-image",
1620
+ "robots",
1621
+ "sitemap",
1622
+ "twitter-image"
1599
1623
  ]);
1600
1624
  var EXPECTED_SUPPORT_FOLDER = {
1601
1625
  hook: "hooks",
@@ -1612,7 +1636,7 @@ function report2(context, message) {
1612
1636
  };
1613
1637
  }
1614
1638
  function isCodeFile(filename) {
1615
- return MODULE_EXTENSIONS2.has(path12.extname(filename));
1639
+ return MODULE_EXTENSIONS2.has(path13.extname(filename));
1616
1640
  }
1617
1641
  function isRootSupportFolder(folder) {
1618
1642
  return SUPPORT_FOLDERS2.has(folder);
@@ -1633,7 +1657,7 @@ function expectedSupportFolder(kinds) {
1633
1657
  function configModuleRoot(filename, sourceRoot) {
1634
1658
  const segments = segmentsOf(filename, sourceRoot);
1635
1659
  if (segments[0] !== "config" || segments.length < 3) return void 0;
1636
- return path12.join(sourceRoot, "config", segments[1] ?? "");
1660
+ return path13.join(sourceRoot, "config", segments[1] ?? "");
1637
1661
  }
1638
1662
  function componentFolderStart(segments) {
1639
1663
  if (segments[0] === "features") return 2;
@@ -1646,12 +1670,12 @@ function componentFolderViolation(segments, sourceRoot) {
1646
1670
  for (let depth = segments.length - 2; depth >= start; depth -= 1) {
1647
1671
  const folder = segments[depth];
1648
1672
  if (!folder || SUPPORT_FOLDERS2.has(folder)) continue;
1649
- const folderPath = path12.join(sourceRoot, ...segments.slice(0, depth + 1));
1673
+ const folderPath = path13.join(sourceRoot, ...segments.slice(0, depth + 1));
1650
1674
  const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
1651
- if (!fs2.existsSync(path12.join(folderPath, `${folder}.tsx`))) {
1675
+ if (!fs2.existsSync(path13.join(folderPath, `${folder}.tsx`))) {
1652
1676
  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.`;
1653
1677
  }
1654
- if (!fs2.existsSync(path12.join(folderPath, "index.ts"))) {
1678
+ if (!fs2.existsSync(path13.join(folderPath, "index.ts"))) {
1655
1679
  return `A component folder must have an index.ts that named-re-exports its component; add index.ts to ${label}.`;
1656
1680
  }
1657
1681
  }
@@ -1666,7 +1690,7 @@ var applicationStructureRule = {
1666
1690
  }
1667
1691
  },
1668
1692
  create(context) {
1669
- const filename = path12.resolve(context.filename);
1693
+ const filename = path13.resolve(context.filename);
1670
1694
  const sourceRoot = sourceRootOf(context);
1671
1695
  const segments = segmentsOf(filename, sourceRoot);
1672
1696
  if (segments.length === 0) return {};
@@ -1697,42 +1721,43 @@ var applicationStructureRule = {
1697
1721
  );
1698
1722
  }
1699
1723
  const moduleRoot = configModuleRoot(filename, sourceRoot);
1700
- if (moduleRoot && !fs2.existsSync(path12.join(moduleRoot, "index.ts"))) {
1724
+ if (moduleRoot && !fs2.existsSync(path13.join(moduleRoot, "index.ts"))) {
1701
1725
  return report2(
1702
1726
  context,
1703
- `Add src/config/${path12.basename(moduleRoot)}/index.ts as the configuration module entry point.`
1727
+ `Add src/config/${path13.basename(moduleRoot)}/index.ts as the configuration module entry point.`
1704
1728
  );
1705
1729
  }
1706
- if (moduleRoot && segments.length === 3 && path12.basename(filename) !== "index.ts") {
1730
+ if (moduleRoot && segments.length === 3 && path13.basename(filename) !== "index.ts") {
1707
1731
  const kinds2 = exportedKinds(filename);
1708
1732
  const expected2 = expectedSupportFolder(kinds2);
1709
1733
  if (expected2 !== void 0) {
1710
1734
  return report2(
1711
1735
  context,
1712
- `Move this configuration support file into src/config/${path12.basename(moduleRoot)}/${expected2}/.`
1736
+ `Move this configuration support file into src/config/${path13.basename(moduleRoot)}/${expected2}/.`
1713
1737
  );
1714
1738
  }
1715
1739
  }
1716
1740
  }
1717
1741
  if (topLevel === "app" && isCodeFile(filename)) {
1718
- const basename = path12.basename(filename, path12.extname(filename));
1719
- const currentFolder2 = path12.basename(path12.dirname(filename));
1742
+ const basename = path13.basename(filename, path13.extname(filename));
1743
+ const currentFolder2 = path13.basename(path13.dirname(filename));
1720
1744
  if (SUPPORT_FOLDERS2.has(currentFolder2)) {
1721
1745
  return report2(
1722
1746
  context,
1723
1747
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
1724
1748
  );
1725
1749
  }
1726
- if (!ROUTING_FILES.has(basename) && path12.extname(filename) !== ".css") {
1750
+ if (!ROUTING_FILES.has(basename) && path13.extname(filename) !== ".css") {
1727
1751
  return report2(
1728
1752
  context,
1729
1753
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
1730
1754
  );
1731
1755
  }
1756
+ if (ROUTING_FILES.has(basename) || path13.extname(filename) === ".css") return {};
1732
1757
  }
1733
- const currentFolder = path12.basename(path12.dirname(filename));
1758
+ const currentFolder = path13.basename(path13.dirname(filename));
1734
1759
  const kinds = exportedKinds(filename);
1735
- const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path12.basename(filename) === "index.ts";
1760
+ const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path13.basename(filename) === "index.ts";
1736
1761
  if (isConfigModuleRoot) return {};
1737
1762
  if (!SUPPORT_FOLDERS2.has(currentFolder)) {
1738
1763
  const expected2 = expectedSupportFolder(kinds);
@@ -1749,7 +1774,7 @@ var applicationStructureRule = {
1749
1774
  if (kinds.has("component")) {
1750
1775
  return report2(
1751
1776
  context,
1752
- `A support folder must not contain a component; move ${path12.basename(filename)} beside ${currentFolder}/.`
1777
+ `A support folder must not contain a component; move ${path13.basename(filename)} beside ${currentFolder}/.`
1753
1778
  );
1754
1779
  }
1755
1780
  const expected = expectedSupportFolder(kinds);
@@ -1766,7 +1791,7 @@ var applicationStructureRule = {
1766
1791
  };
1767
1792
 
1768
1793
  // eslint/rules/named-exports.ts
1769
- import path13 from "path";
1794
+ import path14 from "path";
1770
1795
  var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
1771
1796
  // App Router routing files
1772
1797
  "default",
@@ -1788,9 +1813,9 @@ var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
1788
1813
  "twitter-image"
1789
1814
  ]);
1790
1815
  function isFrameworkDefaultExportFile(filename) {
1791
- const normalized = filename.replaceAll(path13.sep, "/");
1816
+ const normalized = filename.replaceAll(path14.sep, "/");
1792
1817
  if (!normalized.includes("/src/app/")) return false;
1793
- const basename = path13.basename(filename, path13.extname(filename));
1818
+ const basename = path14.basename(filename, path14.extname(filename));
1794
1819
  return FRAMEWORK_DEFAULT_EXPORT_FILES.has(basename);
1795
1820
  }
1796
1821
  var namedExportsRule = {
@@ -1815,7 +1840,7 @@ var namedExportsRule = {
1815
1840
  };
1816
1841
 
1817
1842
  // eslint/rules/data-testid-case.ts
1818
- import path14 from "path";
1843
+ import path15 from "path";
1819
1844
  var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
1820
1845
  "page",
1821
1846
  "layout",
@@ -1839,9 +1864,9 @@ var dataTestIdCaseRule = {
1839
1864
  }
1840
1865
  },
1841
1866
  create(context) {
1842
- const filename = path14.resolve(context.filename);
1867
+ const filename = path15.resolve(context.filename);
1843
1868
  if (!filename.endsWith(".tsx")) return {};
1844
- const base = path14.basename(filename, path14.extname(filename));
1869
+ const base = path15.basename(filename, path15.extname(filename));
1845
1870
  if (NEXT_ROUTING_FILES2.has(base)) return {};
1846
1871
  const text = context.sourceCode.text;
1847
1872
  const components = parseComponentInfo(text, filename);
@@ -1883,7 +1908,7 @@ function toKebabCase(value) {
1883
1908
 
1884
1909
  // eslint/rules/support-folder-shape.ts
1885
1910
  import fs3 from "fs";
1886
- import path15 from "path";
1911
+ import path16 from "path";
1887
1912
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
1888
1913
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
1889
1914
  var supportFolderShapeRule = {
@@ -1895,12 +1920,12 @@ var supportFolderShapeRule = {
1895
1920
  }
1896
1921
  },
1897
1922
  create(context) {
1898
- const filename = path15.resolve(context.filename);
1899
- const baseName = path15.basename(filename);
1923
+ const filename = path16.resolve(context.filename);
1924
+ const baseName = path16.basename(filename);
1900
1925
  if (!INDEX_NAMES.has(baseName)) return {};
1901
- const folder = path15.basename(path15.dirname(filename));
1926
+ const folder = path16.basename(path16.dirname(filename));
1902
1927
  if (!SUPPORT_FOLDERS3.has(folder)) return {};
1903
- const directory = path15.dirname(filename);
1928
+ const directory = path16.dirname(filename);
1904
1929
  let entries;
1905
1930
  try {
1906
1931
  entries = fs3.readdirSync(directory);
@@ -1918,7 +1943,7 @@ var supportFolderShapeRule = {
1918
1943
  const exportPattern = /export\s+(?:\{[^}]*\}|\*[^;]*)\s+from\s+["'](?<specifier>\.[^"']+)["']/g;
1919
1944
  for (const match of source.matchAll(exportPattern)) {
1920
1945
  const specifier = match.groups?.specifier;
1921
- if (specifier) exportedFiles.add(path15.basename(specifier));
1946
+ if (specifier) exportedFiles.add(path16.basename(specifier));
1922
1947
  }
1923
1948
  const missing = siblingModules.filter((entry) => {
1924
1949
  const stem = entry.replace(/\.(?:[cm]?tsx?|jsx?)$/, "");
@@ -1935,7 +1960,7 @@ var supportFolderShapeRule = {
1935
1960
  };
1936
1961
 
1937
1962
  // eslint/rules/import-through-index.ts
1938
- import path16 from "path";
1963
+ import path17 from "path";
1939
1964
  var importThroughIndexRule = {
1940
1965
  meta: {
1941
1966
  schema: [],
@@ -1945,7 +1970,7 @@ var importThroughIndexRule = {
1945
1970
  }
1946
1971
  },
1947
1972
  create(context) {
1948
- const filename = path16.resolve(context.filename);
1973
+ const filename = path17.resolve(context.filename);
1949
1974
  const sourceRoot = sourceRootOf2(context, filename);
1950
1975
  return {
1951
1976
  Program(node) {
@@ -1957,7 +1982,7 @@ var importThroughIndexRule = {
1957
1982
  (segment) => ["constants", "types", "schemas"].includes(segment)
1958
1983
  );
1959
1984
  const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
1960
- if (!supportFolder || path16.basename(target).startsWith("index.")) continue;
1985
+ if (!supportFolder || path17.basename(target).startsWith("index.")) continue;
1961
1986
  const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
1962
1987
  const expected = `@/${folderIndex.join("/")}`;
1963
1988
  context.report({
@@ -1979,14 +2004,14 @@ function importSpecifiers(source) {
1979
2004
  return specifiers;
1980
2005
  }
1981
2006
  function sourceRootOf2(context, filename) {
1982
- const marker = `${path16.sep}src${path16.sep}`;
2007
+ const marker = `${path17.sep}src${path17.sep}`;
1983
2008
  const srcIndex = filename.lastIndexOf(marker);
1984
2009
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
1985
- return path16.resolve(context.cwd ?? process.cwd(), "src");
2010
+ return path17.resolve(context.cwd ?? process.cwd(), "src");
1986
2011
  }
1987
2012
 
1988
2013
  // eslint/rules/util-file-name.ts
1989
- import path17 from "path";
2014
+ import path18 from "path";
1990
2015
  function toKebabCase2(value) {
1991
2016
  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();
1992
2017
  }
@@ -1999,7 +2024,7 @@ var utilFileNameRule = {
1999
2024
  }
2000
2025
  },
2001
2026
  create(context) {
2002
- const filename = path17.resolve(context.filename);
2027
+ const filename = path18.resolve(context.filename);
2003
2028
  const segments = filename.replace(/\\/g, "/").split("/");
2004
2029
  if (!segments.includes("utils")) return {};
2005
2030
  let module;
@@ -2013,13 +2038,13 @@ var utilFileNameRule = {
2013
2038
  const functionName = functions[0]?.name;
2014
2039
  if (!functionName) return {};
2015
2040
  const expected = toKebabCase2(functionName);
2016
- const actual = path17.basename(filename, path17.extname(filename));
2041
+ const actual = path18.basename(filename, path18.extname(filename));
2017
2042
  if (!expected || actual === expected) return {};
2018
2043
  return {
2019
2044
  Program(node) {
2020
2045
  context.report({
2021
2046
  node,
2022
- message: `A utility file exporting ${functionName} must be named ${expected}.${path17.extname(filename).slice(1)}.`
2047
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path18.extname(filename).slice(1)}.`
2023
2048
  });
2024
2049
  }
2025
2050
  };
@@ -2027,7 +2052,7 @@ var utilFileNameRule = {
2027
2052
  };
2028
2053
 
2029
2054
  // eslint/rules/no-util-barrel.ts
2030
- import path18 from "path";
2055
+ import path19 from "path";
2031
2056
  var noUtilBarrelRule = {
2032
2057
  meta: {
2033
2058
  schema: [],
@@ -2037,7 +2062,7 @@ var noUtilBarrelRule = {
2037
2062
  }
2038
2063
  },
2039
2064
  create(context) {
2040
- const filename = path18.resolve(context.filename);
2065
+ const filename = path19.resolve(context.filename);
2041
2066
  const sourceRoot = sourceRootOf3(context, filename);
2042
2067
  return {
2043
2068
  Program(node) {
@@ -2046,7 +2071,7 @@ var noUtilBarrelRule = {
2046
2071
  if (!target) continue;
2047
2072
  const segments = target.replace(/\\/g, "/").split("/");
2048
2073
  const utilsIndex = segments.lastIndexOf("utils");
2049
- if (utilsIndex < 0 || !path18.basename(target).startsWith("index.")) continue;
2074
+ if (utilsIndex < 0 || !path19.basename(target).startsWith("index.")) continue;
2050
2075
  context.report({
2051
2076
  node,
2052
2077
  message: `Import utilities directly instead of through "${specifier}". See docs/code-organization-guide/rules/utilities-rule.md`
@@ -2066,10 +2091,10 @@ function importSpecifiers2(source) {
2066
2091
  return specifiers;
2067
2092
  }
2068
2093
  function sourceRootOf3(context, filename) {
2069
- const marker = `${path18.sep}src${path18.sep}`;
2094
+ const marker = `${path19.sep}src${path19.sep}`;
2070
2095
  const srcIndex = filename.lastIndexOf(marker);
2071
2096
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
2072
- return path18.resolve(context.cwd ?? process.cwd(), "src");
2097
+ return path19.resolve(context.cwd ?? process.cwd(), "src");
2073
2098
  }
2074
2099
 
2075
2100
  // eslint/rules/jsx-hygiene.ts
@@ -2445,12 +2470,12 @@ var cvaBooleanVariantsRule = {
2445
2470
  };
2446
2471
 
2447
2472
  // eslint/rules/cross-feature-import.ts
2448
- import path19 from "path";
2473
+ import path20 from "path";
2449
2474
  var FEATURES_SEGMENT = "features";
2450
2475
  function featureNameOf(resolvedPath, sourceRoot) {
2451
- const relative = path19.relative(sourceRoot, resolvedPath);
2476
+ const relative = path20.relative(sourceRoot, resolvedPath);
2452
2477
  if (relative.startsWith("..")) return void 0;
2453
- const segments = relative.split(path19.sep);
2478
+ const segments = relative.split(path20.sep);
2454
2479
  if (segments[0] !== FEATURES_SEGMENT || segments.length < 2) return void 0;
2455
2480
  return segments[1];
2456
2481
  }
@@ -2466,9 +2491,9 @@ var crossFeatureImportRule = {
2466
2491
  const filename = context.filename;
2467
2492
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2468
2493
  const sourceRoot = sourceRootOf(context);
2469
- const fileRelative = path19.relative(sourceRoot, filename);
2494
+ const fileRelative = path20.relative(sourceRoot, filename);
2470
2495
  if (fileRelative.startsWith("..")) return {};
2471
- const fileSegments = fileRelative.split(path19.sep);
2496
+ const fileSegments = fileRelative.split(path20.sep);
2472
2497
  const isInCompositions = fileSegments[0] === "compositions";
2473
2498
  const isInApp = fileSegments[0] === "app";
2474
2499
  const isConfig = fileSegments[0] === "config";
@@ -2482,9 +2507,9 @@ var crossFeatureImportRule = {
2482
2507
  if (typeof source.value !== "string") return;
2483
2508
  let resolved;
2484
2509
  if (source.value.startsWith("@/")) {
2485
- resolved = path19.resolve(sourceRoot, source.value.slice(2));
2510
+ resolved = path20.resolve(sourceRoot, source.value.slice(2));
2486
2511
  } else if (source.value.startsWith(".")) {
2487
- resolved = path19.resolve(path19.dirname(filename), source.value);
2512
+ resolved = path20.resolve(path20.dirname(filename), source.value);
2488
2513
  }
2489
2514
  if (!resolved) return;
2490
2515
  const feature = featureNameOf(resolved, sourceRoot);
@@ -2503,7 +2528,7 @@ var crossFeatureImportRule = {
2503
2528
  };
2504
2529
 
2505
2530
  // eslint/rules/pure-function-extract.ts
2506
- import path20 from "path";
2531
+ import path21 from "path";
2507
2532
  function isComponentLikeName(name) {
2508
2533
  return /^[A-Z]/.test(name);
2509
2534
  }
@@ -2532,9 +2557,9 @@ var pureFunctionExtractRule = {
2532
2557
  const filename = context.filename;
2533
2558
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2534
2559
  const sourceRoot = sourceRootOf(context);
2535
- const relative = path20.relative(sourceRoot, filename);
2560
+ const relative = path21.relative(sourceRoot, filename);
2536
2561
  if (relative.startsWith("..")) return {};
2537
- const segments = relative.split(path20.sep);
2562
+ const segments = relative.split(path21.sep);
2538
2563
  if (segments[0] === "utils") return {};
2539
2564
  if (segments[0] === "app") return {};
2540
2565
  const supportFolders = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
@@ -2574,7 +2599,7 @@ var pureFunctionExtractRule = {
2574
2599
  };
2575
2600
 
2576
2601
  // eslint/rules/hook-complexity.ts
2577
- import path21 from "path";
2602
+ import path22 from "path";
2578
2603
  import ts4 from "typescript";
2579
2604
  var REACT_HOOKS = /* @__PURE__ */ new Set([
2580
2605
  "useState",
@@ -2627,9 +2652,9 @@ var hookComplexityRule = {
2627
2652
  create(context) {
2628
2653
  const filename = context.filename;
2629
2654
  const sourceRoot = sourceRootOf(context);
2630
- const relative = path21.relative(sourceRoot, filename);
2655
+ const relative = path22.relative(sourceRoot, filename);
2631
2656
  if (relative.startsWith("..")) return {};
2632
- const segments = relative.split(path21.sep);
2657
+ const segments = relative.split(path22.sep);
2633
2658
  const sourceText = context.sourceCode.text;
2634
2659
  function checkHook(node, name, body, exported) {
2635
2660
  if (!exported) return;
@@ -2671,9 +2696,9 @@ var hookComplexityRule = {
2671
2696
  };
2672
2697
 
2673
2698
  // eslint/rules/locale-dotted-path.ts
2674
- import path22 from "path";
2699
+ import path23 from "path";
2675
2700
  function isInLocalesDir(filename) {
2676
- const segments = path22.resolve(filename).split(path22.sep);
2701
+ const segments = path23.resolve(filename).split(path23.sep);
2677
2702
  const srcIdx = segments.lastIndexOf("src");
2678
2703
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
2679
2704
  }
@@ -2722,9 +2747,9 @@ var localeDottedPathRule = {
2722
2747
  };
2723
2748
 
2724
2749
  // eslint/rules/locales-location.ts
2725
- import path23 from "path";
2750
+ import path24 from "path";
2726
2751
  function isLocalesFile(filename) {
2727
- const segments = path23.resolve(filename).split(path23.sep);
2752
+ const segments = path24.resolve(filename).split(path24.sep);
2728
2753
  const srcIdx = segments.lastIndexOf("src");
2729
2754
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
2730
2755
  }
@@ -2743,7 +2768,7 @@ var localesLocationRule = {
2743
2768
  create(context) {
2744
2769
  if (isLocalesFile(context.filename)) return {};
2745
2770
  const filename = context.filename;
2746
- const segments = path23.resolve(filename).split(path23.sep);
2771
+ const segments = path24.resolve(filename).split(path24.sep);
2747
2772
  const srcIdx = segments.lastIndexOf("src");
2748
2773
  if (srcIdx === -1) return {};
2749
2774
  const folder = segments[srcIdx + 1];
@@ -2765,7 +2790,7 @@ var localesLocationRule = {
2765
2790
  };
2766
2791
 
2767
2792
  // eslint/rules/hook-extraction.ts
2768
- import path24 from "path";
2793
+ import path25 from "path";
2769
2794
  var hookExtractionRule = {
2770
2795
  meta: {
2771
2796
  schema: [],
@@ -2776,7 +2801,7 @@ var hookExtractionRule = {
2776
2801
  },
2777
2802
  create(context) {
2778
2803
  const sourceRoot = sourceRootOf(context);
2779
- const file = path24.resolve(context.filename);
2804
+ const file = path25.resolve(context.filename);
2780
2805
  const segments = segmentsOf(file, sourceRoot);
2781
2806
  if (segments.length === 0) return {};
2782
2807
  const index = getProjectIndex(sourceRoot);
@@ -2802,7 +2827,7 @@ var hookExtractionRule = {
2802
2827
  };
2803
2828
 
2804
2829
  // eslint/rules/value-extraction.ts
2805
- import path25 from "path";
2830
+ import path26 from "path";
2806
2831
  var valueExtractionRule = {
2807
2832
  meta: {
2808
2833
  schema: [],
@@ -2813,7 +2838,7 @@ var valueExtractionRule = {
2813
2838
  },
2814
2839
  create(context) {
2815
2840
  const sourceRoot = sourceRootOf(context);
2816
- const file = path25.resolve(context.filename);
2841
+ const file = path26.resolve(context.filename);
2817
2842
  const segments = segmentsOf(file, sourceRoot);
2818
2843
  if (segments.length === 0 || segments[0] !== "app") return {};
2819
2844
  const index = getProjectIndex(sourceRoot);
@@ -2834,7 +2859,7 @@ var valueExtractionRule = {
2834
2859
  };
2835
2860
 
2836
2861
  // eslint/rules/config-extraction.ts
2837
- import path26 from "path";
2862
+ import path27 from "path";
2838
2863
  var configExtractionRule = {
2839
2864
  meta: {
2840
2865
  schema: [],
@@ -2845,7 +2870,7 @@ var configExtractionRule = {
2845
2870
  },
2846
2871
  create(context) {
2847
2872
  const sourceRoot = sourceRootOf(context);
2848
- const file = path26.resolve(context.filename);
2873
+ const file = path27.resolve(context.filename);
2849
2874
  const segments = segmentsOf(file, sourceRoot);
2850
2875
  if (segments.length < 3 || segments[0] !== "config") return {};
2851
2876
  if (SUPPORT_FOLDERS2.has(segments[2] ?? "")) return {};
@@ -2883,7 +2908,7 @@ var configExtractionRule = {
2883
2908
  };
2884
2909
 
2885
2910
  // eslint/rules/component-nesting.ts
2886
- import path27 from "path";
2911
+ import path28 from "path";
2887
2912
  var componentNestingRule = {
2888
2913
  meta: {
2889
2914
  schema: [],
@@ -2894,7 +2919,7 @@ var componentNestingRule = {
2894
2919
  },
2895
2920
  create(context) {
2896
2921
  const sourceRoot = sourceRootOf(context);
2897
- const file = path27.resolve(context.filename);
2922
+ const file = path28.resolve(context.filename);
2898
2923
  const segments = segmentsOf(file, sourceRoot);
2899
2924
  if (segments.length !== 4 || segments[0] !== "features") return {};
2900
2925
  const index = getProjectIndex(sourceRoot);
@@ -2927,7 +2952,7 @@ var componentNestingRule = {
2927
2952
  };
2928
2953
 
2929
2954
  // eslint/rules/stay-flat.ts
2930
- import path28 from "path";
2955
+ import path29 from "path";
2931
2956
  var stayFlatRule = {
2932
2957
  meta: {
2933
2958
  schema: [],
@@ -2938,7 +2963,7 @@ var stayFlatRule = {
2938
2963
  },
2939
2964
  create(context) {
2940
2965
  const sourceRoot = sourceRootOf(context);
2941
- const file = path28.resolve(context.filename);
2966
+ const file = path29.resolve(context.filename);
2942
2967
  const segments = segmentsOf(file, sourceRoot);
2943
2968
  if (segments.length !== 3 || segments[0] !== "features") return {};
2944
2969
  const index = getProjectIndex(sourceRoot);
@@ -2978,7 +3003,7 @@ var stayFlatRule = {
2978
3003
  };
2979
3004
 
2980
3005
  // eslint/rules/type-extraction.ts
2981
- import path29 from "path";
3006
+ import path30 from "path";
2982
3007
  var typeExtractionRule = {
2983
3008
  meta: {
2984
3009
  schema: [],
@@ -2989,7 +3014,7 @@ var typeExtractionRule = {
2989
3014
  },
2990
3015
  create(context) {
2991
3016
  const sourceRoot = sourceRootOf(context);
2992
- const file = path29.resolve(context.filename);
3017
+ const file = path30.resolve(context.filename);
2993
3018
  const segments = segmentsOf(file, sourceRoot);
2994
3019
  if (segments.length === 0) return {};
2995
3020
  const index = getProjectIndex(sourceRoot);
@@ -3035,7 +3060,7 @@ var typeExtractionRule = {
3035
3060
  };
3036
3061
 
3037
3062
  // eslint/rules/locale-placement.ts
3038
- import path30 from "path";
3063
+ import path31 from "path";
3039
3064
  import { readFileSync as readFileSync3 } from "fs";
3040
3065
  import ts5 from "typescript";
3041
3066
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
@@ -3083,7 +3108,7 @@ var localePlacementRule = {
3083
3108
  },
3084
3109
  create(context) {
3085
3110
  const sourceRoot = sourceRootOf(context);
3086
- const file = path30.resolve(context.filename);
3111
+ const file = path31.resolve(context.filename);
3087
3112
  const segments = segmentsOf(file, sourceRoot);
3088
3113
  if (segments.length === 0) return {};
3089
3114
  const index = getProjectIndex(sourceRoot);
@@ -3161,7 +3186,7 @@ var localePlacementRule = {
3161
3186
  };
3162
3187
 
3163
3188
  // eslint/rules/sole-state-owner.ts
3164
- import path31 from "path";
3189
+ import path32 from "path";
3165
3190
  import ts6 from "typescript";
3166
3191
  function findStateHooks(node) {
3167
3192
  const hooks = [];
@@ -3241,7 +3266,7 @@ var soleStateOwnerRule = {
3241
3266
  }
3242
3267
  },
3243
3268
  create(context) {
3244
- const filename = path31.resolve(context.filename);
3269
+ const filename = path32.resolve(context.filename);
3245
3270
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
3246
3271
  const text = context.sourceCode.text;
3247
3272
  const components = parseComponentInfo(text, filename);
@@ -3320,7 +3345,7 @@ function usesOutsideJsx(declaration, hook, children) {
3320
3345
  }
3321
3346
 
3322
3347
  // eslint/rules/locale-key-shape.ts
3323
- import path32 from "path";
3348
+ import path33 from "path";
3324
3349
  var MAX_KEY_LENGTH = 30;
3325
3350
  var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
3326
3351
  "Button",
@@ -3370,7 +3395,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
3370
3395
  var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
3371
3396
  var ENGLISH = /^[A-Za-z0-9_]*$/;
3372
3397
  function isLocalesFile2(filename) {
3373
- const segments = path32.resolve(filename).split(path32.sep);
3398
+ const segments = path33.resolve(filename).split(path33.sep);
3374
3399
  const srcIdx = segments.lastIndexOf("src");
3375
3400
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
3376
3401
  }
@@ -3441,7 +3466,7 @@ var localeKeyShapeRule = {
3441
3466
  };
3442
3467
 
3443
3468
  // eslint/rules/shared-style-dedup.ts
3444
- import path33 from "path";
3469
+ import path34 from "path";
3445
3470
  import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
3446
3471
  var CLASS_NAME = /className="(?<classes>[^"]+)"/g;
3447
3472
  var comboCache;
@@ -3483,7 +3508,7 @@ var sharedStyleDedupRule = {
3483
3508
  },
3484
3509
  create(context) {
3485
3510
  const sourceRoot = sourceRootOf(context);
3486
- const file = path33.resolve(context.filename);
3511
+ const file = path34.resolve(context.filename);
3487
3512
  const segments = segmentsOf(file, sourceRoot);
3488
3513
  if (segments.length === 0) return {};
3489
3514
  const index = getProjectIndex(sourceRoot);
@@ -3687,7 +3712,7 @@ var zodSchemaValidationRule = {
3687
3712
  };
3688
3713
 
3689
3714
  // eslint/rules/source-under-src.ts
3690
- import path34 from "path";
3715
+ import path35 from "path";
3691
3716
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
3692
3717
  ".agents",
3693
3718
  ".cache",
@@ -3728,14 +3753,14 @@ var sourceUnderSrcRule = {
3728
3753
  }
3729
3754
  },
3730
3755
  create(context) {
3731
- const filename = path34.resolve(context.filename);
3756
+ const filename = path35.resolve(context.filename);
3732
3757
  if (!MODULE_EXTENSION.test(filename)) return {};
3733
- const relative = path34.relative(context.cwd, filename).replace(/\\/g, "/");
3758
+ const relative = path35.relative(context.cwd, filename).replace(/\\/g, "/");
3734
3759
  if (relative === "src" || relative.startsWith("src/")) return {};
3735
3760
  const topLevel = relative.split("/")[0] ?? "";
3736
3761
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
3737
3762
  if (!relative.includes("/")) {
3738
- const basename = path34.basename(filename);
3763
+ const basename = path35.basename(filename);
3739
3764
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
3740
3765
  }
3741
3766
  return {
@@ -3752,7 +3777,7 @@ var sourceUnderSrcRule = {
3752
3777
 
3753
3778
  // eslint/rules/zirka-baseline.ts
3754
3779
  import fs4 from "fs";
3755
- import path35 from "path";
3780
+ import path36 from "path";
3756
3781
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
3757
3782
  var PRETTIER_CONFIGS = [
3758
3783
  "prettier.config.mjs",
@@ -3771,10 +3796,10 @@ var zirkaBaselineRule = {
3771
3796
  }
3772
3797
  },
3773
3798
  create(context) {
3774
- const filename = path35.resolve(context.filename);
3775
- const basename = path35.basename(filename);
3799
+ const filename = path36.resolve(context.filename);
3800
+ const basename = path36.basename(filename);
3776
3801
  if (!ESLINT_CONFIG.test(basename)) return {};
3777
- const projectRoot = path35.dirname(filename);
3802
+ const projectRoot = path36.dirname(filename);
3778
3803
  const report3 = (message) => {
3779
3804
  context.report({
3780
3805
  node: context.sourceCode.ast,
@@ -3789,7 +3814,7 @@ var zirkaBaselineRule = {
3789
3814
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
3790
3815
  );
3791
3816
  }
3792
- const tsconfigPath = path35.join(projectRoot, "tsconfig.json");
3817
+ const tsconfigPath = path36.join(projectRoot, "tsconfig.json");
3793
3818
  if (!fs4.existsSync(tsconfigPath)) {
3794
3819
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
3795
3820
  } else {
@@ -3807,13 +3832,13 @@ var zirkaBaselineRule = {
3807
3832
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
3808
3833
  }
3809
3834
  }
3810
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs4.existsSync(path35.join(projectRoot, name)));
3835
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs4.existsSync(path36.join(projectRoot, name)));
3811
3836
  if (!prettierConfigFile) {
3812
3837
  report3(
3813
3838
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
3814
3839
  );
3815
3840
  } else {
3816
- const content = fs4.readFileSync(path35.join(projectRoot, prettierConfigFile), "utf8");
3841
+ const content = fs4.readFileSync(path36.join(projectRoot, prettierConfigFile), "utf8");
3817
3842
  if (!content.includes("zirka")) {
3818
3843
  report3(
3819
3844
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -3883,7 +3908,7 @@ var docKindSuffixRule = {
3883
3908
  };
3884
3909
 
3885
3910
  // eslint/rules/documentation/title-matches-file-name.ts
3886
- import path36 from "path";
3911
+ import path37 from "path";
3887
3912
  function toExpectedFileName(title) {
3888
3913
  return `${title.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.md`;
3889
3914
  }
@@ -3903,7 +3928,7 @@ var titleMatchesFileNameRule = {
3903
3928
  if (!filename.endsWith(".md")) return;
3904
3929
  const title = getTextContent(node).trim();
3905
3930
  const expectedFileName = toExpectedFileName(title);
3906
- const actualFileName = path36.basename(filename);
3931
+ const actualFileName = path37.basename(filename);
3907
3932
  if (!title) {
3908
3933
  context.report({
3909
3934
  node,
@@ -4310,7 +4335,7 @@ var referenceBlockHeadingsRule = {
4310
4335
  };
4311
4336
 
4312
4337
  // eslint/rules/documentation/support-document-placement.ts
4313
- import path37 from "path";
4338
+ import path38 from "path";
4314
4339
  var supportDocumentPlacementRule = {
4315
4340
  meta: {
4316
4341
  type: "problem",
@@ -4324,7 +4349,7 @@ var supportDocumentPlacementRule = {
4324
4349
  root(node) {
4325
4350
  const filename = getFilename(context);
4326
4351
  if (!filename.endsWith(".md")) return;
4327
- const parentFolder = path37.basename(path37.dirname(filename));
4352
+ const parentFolder = path38.basename(path38.dirname(filename));
4328
4353
  if (filename.endsWith("-rule.md") && parentFolder !== "rules") {
4329
4354
  context.report({
4330
4355
  node,
@@ -4367,11 +4392,11 @@ var noTemplatePromptRule = {
4367
4392
  };
4368
4393
 
4369
4394
  // eslint/rules/documentation/guide-folder-entry-point.ts
4370
- import path39 from "path";
4395
+ import path40 from "path";
4371
4396
 
4372
4397
  // eslint/rules/documentation/project-index.ts
4373
4398
  import { readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
4374
- import path38 from "path";
4399
+ import path39 from "path";
4375
4400
  var KIND_BY_SUFFIX = [
4376
4401
  ["-rule.md", "rule"],
4377
4402
  ["-guide.md", "guide"],
@@ -4380,7 +4405,7 @@ var KIND_BY_SUFFIX = [
4380
4405
  ];
4381
4406
  function listMarkdownFiles(dir) {
4382
4407
  return readdirSync3(dir).flatMap((entry) => {
4383
- const entryPath = path38.join(dir, entry);
4408
+ const entryPath = path39.join(dir, entry);
4384
4409
  if (statSync4(entryPath).isDirectory()) {
4385
4410
  return entry.startsWith("_") ? [] : listMarkdownFiles(entryPath);
4386
4411
  }
@@ -4398,11 +4423,11 @@ function getProjectDocs(docsRoot) {
4398
4423
  if (cached) return cached;
4399
4424
  const files = listMarkdownFiles(docsRoot);
4400
4425
  const docs = files.sort((a, b) => a.localeCompare(b)).map((filePath) => {
4401
- const fileName = path38.basename(filePath);
4426
+ const fileName = path39.basename(filePath);
4402
4427
  const kind = KIND_BY_SUFFIX.find(([suffix]) => fileName.endsWith(suffix))?.[1];
4403
4428
  return {
4404
4429
  filePath,
4405
- doc: path38.relative(docsRoot, filePath).split(path38.sep).join("/"),
4430
+ doc: path39.relative(docsRoot, filePath).split(path39.sep).join("/"),
4406
4431
  fileName,
4407
4432
  kind,
4408
4433
  title: extractTitle(filePath)
@@ -4412,12 +4437,12 @@ function getProjectDocs(docsRoot) {
4412
4437
  return docs;
4413
4438
  }
4414
4439
  function findDocsRoot(filePath) {
4415
- let dir = path38.dirname(filePath);
4440
+ let dir = path39.dirname(filePath);
4416
4441
  for (; ; ) {
4417
- if (path38.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
4442
+ if (path39.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
4418
4443
  return dir;
4419
4444
  }
4420
- const parent = path38.dirname(dir);
4445
+ const parent = path39.dirname(dir);
4421
4446
  if (parent === dir) return void 0;
4422
4447
  dir = parent;
4423
4448
  }
@@ -4441,13 +4466,13 @@ var guideFolderEntryPointRule = {
4441
4466
  if (!docsRoot) return;
4442
4467
  const docs = getProjectDocs(docsRoot);
4443
4468
  const guideFolders = new Set(
4444
- docs.filter((doc) => ["rules", "references"].includes(path39.basename(path39.dirname(doc.filePath)))).map((doc) => path39.dirname(path39.dirname(doc.filePath))).filter((folder) => path39.resolve(folder) !== path39.resolve(docsRoot))
4469
+ docs.filter((doc) => ["rules", "references"].includes(path40.basename(path40.dirname(doc.filePath)))).map((doc) => path40.dirname(path40.dirname(doc.filePath))).filter((folder) => path40.resolve(folder) !== path40.resolve(docsRoot))
4445
4470
  );
4446
- const currentDir = path39.dirname(filename);
4471
+ const currentDir = path40.dirname(filename);
4447
4472
  if (guideFolders.has(currentDir)) {
4448
- const expectedEntryPoint = `${path39.basename(currentDir)}.md`;
4473
+ const expectedEntryPoint = `${path40.basename(currentDir)}.md`;
4449
4474
  const hasEntryPoint = docs.some(
4450
- (doc) => doc.kind === "guide" && path39.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
4475
+ (doc) => doc.kind === "guide" && path40.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
4451
4476
  );
4452
4477
  if (!hasEntryPoint) {
4453
4478
  context.report({
@@ -4672,7 +4697,7 @@ var noNestedHowToRule = {
4672
4697
 
4673
4698
  // eslint/rules/documentation/glossary-term-linking.ts
4674
4699
  import { readFileSync as readFileSync6 } from "fs";
4675
- import path40 from "path";
4700
+ import path41 from "path";
4676
4701
  function extractGlossaryTerms(filePath) {
4677
4702
  const content = readFileSync6(filePath, "utf8");
4678
4703
  const terms = [];
@@ -4726,9 +4751,9 @@ var glossaryTermLinkingRule = {
4726
4751
  const docsRoot = findDocsRoot(filename);
4727
4752
  if (!docsRoot) return;
4728
4753
  const docs = getProjectDocs(docsRoot);
4729
- const guideDir = path40.dirname(filename);
4754
+ const guideDir = path41.dirname(filename);
4730
4755
  const guideReferences = docs.filter(
4731
- (doc) => doc.kind === "reference" && path40.dirname(doc.filePath) === guideDir
4756
+ (doc) => doc.kind === "reference" && path41.dirname(doc.filePath) === guideDir
4732
4757
  );
4733
4758
  if (guideReferences.length === 0) return;
4734
4759
  const glossaryTerms = [];
@@ -4753,7 +4778,7 @@ var glossaryTermLinkingRule = {
4753
4778
 
4754
4779
  // eslint/rules/documentation/guide-mentions-documents.ts
4755
4780
  import { existsSync } from "fs";
4756
- import path41 from "path";
4781
+ import path42 from "path";
4757
4782
  function visitSteps3(node, check) {
4758
4783
  if (node.type === "list" && node.ordered) {
4759
4784
  for (const child of node.children) check(child);
@@ -4786,12 +4811,12 @@ var guideMentionsDocumentsRule = {
4786
4811
  if (!filename.endsWith("-guide.md")) return;
4787
4812
  const docsRoot = findDocsRoot(filename);
4788
4813
  if (!docsRoot) return;
4789
- const guideDir = path41.dirname(filename);
4790
- if (path41.basename(filename, ".md") !== path41.basename(guideDir)) return;
4814
+ const guideDir = path42.dirname(filename);
4815
+ if (path42.basename(filename, ".md") !== path42.basename(guideDir)) return;
4791
4816
  const docs = getProjectDocs(docsRoot);
4792
4817
  const owned = docs.filter((doc) => {
4793
- const parent = path41.dirname(doc.filePath);
4794
- return parent === path41.join(guideDir, "rules") || parent === path41.join(guideDir, "references");
4818
+ const parent = path42.dirname(doc.filePath);
4819
+ return parent === path42.join(guideDir, "rules") || parent === path42.join(guideDir, "references");
4795
4820
  });
4796
4821
  const allLinks = [];
4797
4822
  collectMarkdownLinks(node, allLinks);
@@ -4818,7 +4843,7 @@ var guideMentionsDocumentsRule = {
4818
4843
  for (const link of allLinks) {
4819
4844
  const target = linkTarget(link.url);
4820
4845
  if (!target.endsWith(".md")) continue;
4821
- const resolved = path41.normalize(path41.join(guideDir, target));
4846
+ const resolved = path42.normalize(path42.join(guideDir, target));
4822
4847
  if (!existsSync(resolved)) {
4823
4848
  context.report({
4824
4849
  node: link,
@@ -5270,11 +5295,11 @@ var themeVariableNamespaceRule = {
5270
5295
 
5271
5296
  // eslint/rules/tailwind/css-entry-point.ts
5272
5297
  import { statSync as statSync6 } from "fs";
5273
- import path44 from "path";
5298
+ import path45 from "path";
5274
5299
 
5275
5300
  // eslint/rules/tailwind/source-files.ts
5276
5301
  import { readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
5277
- import path42 from "path";
5302
+ import path43 from "path";
5278
5303
  var CSS_EXTENSIONS = [".css"];
5279
5304
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
5280
5305
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS3, ...CSS_EXTENSIONS];
@@ -5287,7 +5312,7 @@ function findFiles(dir, extensions) {
5287
5312
  }
5288
5313
  return entries.flatMap((entry) => {
5289
5314
  if (entry.startsWith(".") || entry === "node_modules") return [];
5290
- const entryPath = path42.join(dir, entry);
5315
+ const entryPath = path43.join(dir, entry);
5291
5316
  let stats;
5292
5317
  try {
5293
5318
  stats = statSync5(entryPath);
@@ -5295,7 +5320,7 @@ function findFiles(dir, extensions) {
5295
5320
  return [];
5296
5321
  }
5297
5322
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
5298
- return extensions.includes(path42.extname(entry)) ? [entryPath] : [];
5323
+ return extensions.includes(path43.extname(entry)) ? [entryPath] : [];
5299
5324
  });
5300
5325
  }
5301
5326
  function cachedTextReader() {
@@ -5318,7 +5343,7 @@ function escapeRegExp(text) {
5318
5343
  }
5319
5344
 
5320
5345
  // eslint/rules/tailwind/stylesheet-graph.ts
5321
- import path43 from "path";
5346
+ import path44 from "path";
5322
5347
  function registersTailwind(text) {
5323
5348
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
5324
5349
  }
@@ -5332,25 +5357,25 @@ function moduleImports(text, fileName) {
5332
5357
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
5333
5358
  }
5334
5359
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
5335
- if (spec.startsWith("/")) return path43.resolve(spec);
5336
- if (spec.startsWith("./") || spec.startsWith("../")) return path43.resolve(path43.dirname(fromFile), spec);
5337
- if (spec.startsWith("@/")) return path43.resolve(sourceRoot, spec.slice(2));
5360
+ if (spec.startsWith("/")) return path44.resolve(spec);
5361
+ if (spec.startsWith("./") || spec.startsWith("../")) return path44.resolve(path44.dirname(fromFile), spec);
5362
+ if (spec.startsWith("@/")) return path44.resolve(sourceRoot, spec.slice(2));
5338
5363
  return void 0;
5339
5364
  }
5340
5365
  function buildStylesheetGraph(options) {
5341
5366
  const { cssFiles, sourceRoot, textOf } = options;
5342
- const cssSet = new Set(cssFiles.map((file) => path43.normalize(file)));
5367
+ const cssSet = new Set(cssFiles.map((file) => path44.normalize(file)));
5343
5368
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
5344
5369
  const reachable = /* @__PURE__ */ new Set();
5345
5370
  const queue = [...globals];
5346
- for (const global of globals) reachable.add(path43.normalize(global));
5371
+ for (const global of globals) reachable.add(path44.normalize(global));
5347
5372
  while (queue.length > 0) {
5348
5373
  const from = queue.shift();
5349
5374
  if (!from) continue;
5350
5375
  for (const spec of importedSpecifiers(textOf(from))) {
5351
5376
  const target = resolveSpecifier2(from, spec, sourceRoot);
5352
5377
  if (!target) continue;
5353
- const normalized = path43.normalize(target);
5378
+ const normalized = path44.normalize(target);
5354
5379
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
5355
5380
  reachable.add(normalized);
5356
5381
  queue.push(normalized);
@@ -5362,7 +5387,7 @@ function buildStylesheetGraph(options) {
5362
5387
  for (const spec of importedSpecifiers(textOf(global))) {
5363
5388
  const target = resolveSpecifier2(global, spec, sourceRoot);
5364
5389
  if (!target) continue;
5365
- const normalized = path43.normalize(target);
5390
+ const normalized = path44.normalize(target);
5366
5391
  if (cssSet.has(normalized)) directChildren.add(normalized);
5367
5392
  }
5368
5393
  }
@@ -5395,7 +5420,7 @@ var cssEntryPointRule = {
5395
5420
  return {
5396
5421
  "StyleSheet:exit"(node) {
5397
5422
  if (globals.length === 0) return;
5398
- const current = path44.normalize(path44.resolve(context.filename));
5423
+ const current = path45.normalize(path45.resolve(context.filename));
5399
5424
  if (globals.includes(current)) {
5400
5425
  if (globals.length > 1) {
5401
5426
  context.report({
@@ -5404,7 +5429,7 @@ var cssEntryPointRule = {
5404
5429
  });
5405
5430
  return;
5406
5431
  }
5407
- const basename = path44.basename(current);
5432
+ const basename = path45.basename(current);
5408
5433
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
5409
5434
  if (importCount !== 1) {
5410
5435
  context.report({
@@ -5673,7 +5698,7 @@ var nextjsPackageJsonRules = {
5673
5698
 
5674
5699
  // eslint/rules/husky/husky-hook.ts
5675
5700
  import { existsSync as existsSync2, readFileSync as readFileSync8 } from "fs";
5676
- import path45 from "path";
5701
+ import path46 from "path";
5677
5702
  function memberName4(member) {
5678
5703
  return member.name.type === "String" ? member.name.value : member.name.name;
5679
5704
  }
@@ -5692,7 +5717,7 @@ var huskyHookRule = {
5692
5717
  if (root.type !== "Object") return;
5693
5718
  const scriptName = context.filename;
5694
5719
  if (!scriptName.endsWith("package.json")) return;
5695
- const hookPath = path45.join(context.cwd, ".husky", "pre-commit");
5720
+ const hookPath = path46.join(context.cwd, ".husky", "pre-commit");
5696
5721
  if (!existsSync2(hookPath)) {
5697
5722
  context.report({
5698
5723
  node,
@@ -5732,7 +5757,7 @@ var huskyRules = {
5732
5757
 
5733
5758
  // eslint/rules/vulyk/vulyk-docs.ts
5734
5759
  import { existsSync as existsSync3, readFileSync as readFileSync9 } from "fs";
5735
- import path46 from "path";
5760
+ import path47 from "path";
5736
5761
  var PASIKA_REPO = "Bredansky/pasika";
5737
5762
  var BASE_REQUIRED_DOCS = [
5738
5763
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -5765,8 +5790,8 @@ var vulykDocsRule = {
5765
5790
  if (!context.filename.endsWith("package.json")) return;
5766
5791
  const root = node.body;
5767
5792
  if (root.type !== "Object") return;
5768
- const projectRoot = path46.dirname(path46.resolve(context.filename));
5769
- const configPath = path46.join(projectRoot, "vulyk.config.ts");
5793
+ const projectRoot = path47.dirname(path47.resolve(context.filename));
5794
+ const configPath = path47.join(projectRoot, "vulyk.config.ts");
5770
5795
  if (!existsSync3(configPath)) {
5771
5796
  context.report({
5772
5797
  node,
@@ -5791,7 +5816,7 @@ var vulykDocsRule = {
5791
5816
  });
5792
5817
  }
5793
5818
  }
5794
- const agentsPath = path46.join(projectRoot, "AGENTS.md");
5819
+ const agentsPath = path47.join(projectRoot, "AGENTS.md");
5795
5820
  if (!existsSync3(agentsPath)) {
5796
5821
  context.report({
5797
5822
  node,