pasika 0.10.56 → 0.10.58

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.
@@ -4,17 +4,170 @@ import jsonPlugin from "@eslint/json";
4
4
  import markdown from "@eslint/markdown";
5
5
  import tsParser from "@typescript-eslint/parser";
6
6
 
7
+ // eslint/rules/api-contract.ts
8
+ import path from "path";
9
+ var HELPER = "defineApiContract";
10
+ var ENTRY = "pasika/api-contract";
11
+ var DOC = "docs/pasika-adoption-guide/rules/api-contract-rule.md";
12
+ var TEST_FILE = /(?:^|[\\/])(?:__tests__|tests)[\\/]|[.](?:test|spec)[.][cm]?[jt]sx?$/;
13
+ var DECLARED = `A repository must not declare its own ${HELPER}; import it from ${ENTRY}. See ${DOC}`;
14
+ var IMPORTED = `${HELPER} must be imported from ${ENTRY}. See ${DOC}`;
15
+ var EXPORTED = `A call to ${HELPER} must initialize an exported named contract. See ${DOC}`;
16
+ var DEFINED = `An exported *ApiContract value must be created with ${HELPER}. See ${DOC}`;
17
+ var ROUTE_IMPORTED = `withResponse must receive an imported API contract for a JSON route. See ${DOC}`;
18
+ var CLIENT_CONTRACT = `A schema-validated request must use an imported API contract through zodFetch({ contract }). See ${DOC}`;
19
+ var MOCK_PATH = `A mock apiRoutePath must come from an imported API contract through contract.path. See ${DOC}`;
20
+ var MOCK_RESPONSE = `A mock must validate successful JSON with the same API contract responseSchema. See ${DOC}`;
21
+ function isNamed(node, name) {
22
+ return node?.type === "Identifier" && node.name === name;
23
+ }
24
+ function importedBindings(program) {
25
+ const names = /* @__PURE__ */ new Set();
26
+ for (const statement of program.body) {
27
+ if (statement.type !== "ImportDeclaration") continue;
28
+ for (const specifier of statement.specifiers) {
29
+ names.add(specifier.local.name);
30
+ }
31
+ }
32
+ return names;
33
+ }
34
+ function memberPropertyName(node) {
35
+ if (!node.computed && node.property.type === "Identifier") return node.property.name;
36
+ if (node.computed && node.property.type === "Literal" && typeof node.property.value === "string") {
37
+ return node.property.value;
38
+ }
39
+ return void 0;
40
+ }
41
+ function importedContractMember(expression, propertyName3, imports) {
42
+ if (expression?.type !== "MemberExpression" || memberPropertyName(expression) !== propertyName3 || expression.object.type !== "Identifier" || !imports.has(expression.object.name)) {
43
+ return void 0;
44
+ }
45
+ return expression.object.name;
46
+ }
47
+ function responseSchemaParserContract(callee, imports) {
48
+ if (callee.type === "Super" || callee.type !== "MemberExpression" || memberPropertyName(callee) !== "parse") {
49
+ return void 0;
50
+ }
51
+ if (callee.object.type !== "MemberExpression" || memberPropertyName(callee.object) !== "responseSchema") {
52
+ return void 0;
53
+ }
54
+ if (callee.object.object.type !== "Identifier" || !imports.has(callee.object.object.name)) return void 0;
55
+ return callee.object.object.name;
56
+ }
57
+ function objectProperty(object, name) {
58
+ return object.properties.find(
59
+ (property) => property.type === "Property" && !property.computed && (property.key.type === "Identifier" && property.key.name === name || property.key.type === "Literal" && property.key.value === name)
60
+ );
61
+ }
62
+ function isExportedVariable(context, node) {
63
+ const ancestors = context.sourceCode.getAncestors(node);
64
+ return ancestors.at(-2)?.type === "ExportNamedDeclaration";
65
+ }
66
+ function isExportedDefinition(context, node) {
67
+ const ancestors = context.sourceCode.getAncestors(node);
68
+ const declarator = ancestors.at(-1);
69
+ const declaration = ancestors.at(-2);
70
+ const exported = ancestors.at(-3);
71
+ return declarator?.type === "VariableDeclarator" && declarator.init === node && declarator.id.type === "Identifier" && declaration?.type === "VariableDeclaration" && exported?.type === "ExportNamedDeclaration";
72
+ }
73
+ var apiContractRule = {
74
+ meta: {
75
+ schema: [],
76
+ type: "problem",
77
+ docs: {
78
+ description: "Require schema-validated JSON routes and clients to reuse one exported API contract instead of restating schemas."
79
+ }
80
+ },
81
+ create(context) {
82
+ if (TEST_FILE.test(context.filename)) return {};
83
+ const imports = importedBindings(context.sourceCode.ast);
84
+ let mockContract;
85
+ const mockResponseContracts = /* @__PURE__ */ new Set();
86
+ return {
87
+ ImportDeclaration(node) {
88
+ if (node.source.value === ENTRY) return;
89
+ for (const specifier of node.specifiers) {
90
+ if (isNamed(specifier.local, HELPER)) {
91
+ context.report({ node: specifier, message: IMPORTED });
92
+ }
93
+ }
94
+ },
95
+ FunctionDeclaration(node) {
96
+ if (isNamed(node.id, HELPER)) context.report({ node, message: DECLARED });
97
+ },
98
+ VariableDeclarator(node) {
99
+ if (node.id.type !== "Identifier") return;
100
+ if (node.id.name === HELPER) {
101
+ context.report({ node, message: DECLARED });
102
+ return;
103
+ }
104
+ if (node.id.name.endsWith("ApiContract") && isExportedVariable(context, node)) {
105
+ const isFactoryCall = node.init?.type === "CallExpression" && isNamed(node.init.callee, HELPER);
106
+ if (!isFactoryCall) {
107
+ context.report({ node, message: DEFINED });
108
+ return;
109
+ }
110
+ }
111
+ if (node.id.name !== "apiRoutePath") return;
112
+ const contractName = importedContractMember(node.init, "path", imports);
113
+ if (!contractName) {
114
+ context.report({ node, message: MOCK_PATH });
115
+ return;
116
+ }
117
+ mockContract = { name: contractName, node };
118
+ },
119
+ CallExpression(node) {
120
+ const responseContract = responseSchemaParserContract(node.callee, imports);
121
+ if (responseContract) mockResponseContracts.add(responseContract);
122
+ if (isNamed(node.callee, HELPER) && !isExportedDefinition(context, node)) {
123
+ context.report({ node, message: EXPORTED });
124
+ return;
125
+ }
126
+ if (isNamed(node.callee, "withResponse") && path.basename(context.filename) === "route.ts") {
127
+ const contract = node.arguments[0];
128
+ if (contract && contract.type !== "SpreadElement" && contract.type !== "ArrowFunctionExpression" && contract.type !== "FunctionExpression" && (contract.type !== "Identifier" || !imports.has(contract.name))) {
129
+ context.report({ node: contract, message: ROUTE_IMPORTED });
130
+ }
131
+ return;
132
+ }
133
+ if (!isNamed(node.callee, "zodFetch")) return;
134
+ const options = node.arguments[0];
135
+ if (options?.type !== "ObjectExpression") return;
136
+ const contractProperty = objectProperty(options, "contract");
137
+ if (contractProperty) {
138
+ const value = contractProperty.value;
139
+ if (!(value.type === "Identifier" && imports.has(value.name))) {
140
+ context.report({ node: value, message: CLIENT_CONTRACT });
141
+ }
142
+ return;
143
+ }
144
+ const responseSchemaProperty = objectProperty(options, "responseSchema");
145
+ const requestSchemaProperty = objectProperty(options, "requestSchema");
146
+ const schemaProperty = responseSchemaProperty ?? requestSchemaProperty;
147
+ if (schemaProperty) {
148
+ context.report({ node: schemaProperty, message: CLIENT_CONTRACT });
149
+ }
150
+ },
151
+ "Program:exit"() {
152
+ if (mockContract && !mockResponseContracts.has(mockContract.name)) {
153
+ context.report({ node: mockContract.node, message: MOCK_RESPONSE });
154
+ }
155
+ }
156
+ };
157
+ }
158
+ };
159
+
7
160
  // eslint/rules/application-structure.ts
8
161
  import fs2 from "fs";
9
- import path4 from "path";
162
+ import path5 from "path";
10
163
 
11
164
  // eslint/project/ccf.ts
12
165
  import fs from "fs";
13
- import path from "path";
166
+ import path2 from "path";
14
167
  var SUPPORT_FOLDERS = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
15
168
  function segmentsOf(file, sourceRoot) {
16
- const relative = path.relative(sourceRoot, file);
17
- return relative.startsWith("..") ? [] : relative.split(path.sep);
169
+ const relative = path2.relative(sourceRoot, file);
170
+ return relative.startsWith("..") ? [] : relative.split(path2.sep);
18
171
  }
19
172
  function folderSegmentsOf(file, sourceRoot) {
20
173
  return segmentsOf(file, sourceRoot).slice(0, -1);
@@ -77,7 +230,7 @@ function hasComponentOwner(folderPath, folderName) {
77
230
  function isValidComponentFolder(folder, sourceRoot) {
78
231
  const name = folder[folder.length - 1];
79
232
  if (!name || SUPPORT_FOLDERS.has(name)) return false;
80
- const folderPath = path.join(sourceRoot, ...folder);
233
+ const folderPath = path2.join(sourceRoot, ...folder);
81
234
  return hasComponentOwner(folderPath, name) && hasExactEntry(folderPath, "index.ts");
82
235
  }
83
236
  function owningFolderOf(consumer, sourceRoot) {
@@ -114,18 +267,18 @@ function resolveSupportPlacement(supportFile, supportFolder, index, importedBy =
114
267
  }
115
268
  function describeConsumers(consumers, sourceRoot) {
116
269
  const shown = 3;
117
- const names = consumers.map((consumer) => path.relative(path.dirname(sourceRoot), consumer).split(path.sep).join("/")).sort((left, right) => left.localeCompare(right));
270
+ const names = consumers.map((consumer) => path2.relative(path2.dirname(sourceRoot), consumer).split(path2.sep).join("/")).sort((left, right) => left.localeCompare(right));
118
271
  if (names.length <= shown) return names.join(", ");
119
272
  return `${names.slice(0, shown).join(", ")} and ${String(names.length - shown)} more`;
120
273
  }
121
274
 
122
275
  // eslint/project/parse-module.ts
123
276
  import { readFileSync } from "fs";
124
- import path2 from "path";
277
+ import path3 from "path";
125
278
  import ts from "typescript";
126
279
  var isPascalCase = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
127
280
  var isHookName = (name) => /^use[A-Z]/.test(name);
128
- var isSchemaName = (name) => /[Ss]chema$/.test(name);
281
+ var isSchemaName = (name) => /(?:[Ss]chema|ApiContract)$/.test(name);
129
282
  function lineOf(sourceFile, node) {
130
283
  return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
131
284
  }
@@ -245,13 +398,13 @@ function parseModule(file) {
245
398
  });
246
399
  }
247
400
  }
248
- return { file: path2.resolve(file), imports, reexports, exports };
401
+ return { file: path3.resolve(file), imports, reexports, exports };
249
402
  }
250
403
 
251
404
  // eslint/rules/project-root.ts
252
- import path3 from "path";
405
+ import path4 from "path";
253
406
  function sourceRootOf(context) {
254
- return path3.resolve(context.cwd ?? process.cwd(), "src");
407
+ return path4.resolve(context.cwd ?? process.cwd(), "src");
255
408
  }
256
409
 
257
410
  // eslint/rules/application-structure.ts
@@ -292,7 +445,7 @@ function report(context, message) {
292
445
  };
293
446
  }
294
447
  function isCodeFile(filename) {
295
- return MODULE_EXTENSIONS.has(path4.extname(filename));
448
+ return MODULE_EXTENSIONS.has(path5.extname(filename));
296
449
  }
297
450
  function isRootSupportFolder(folder) {
298
451
  return SUPPORT_FOLDERS.has(folder);
@@ -319,7 +472,7 @@ function mixedSupportKinds(folder, kinds) {
319
472
  function configModuleRoot(filename, sourceRoot) {
320
473
  const segments = segmentsOf(filename, sourceRoot);
321
474
  if (segments[0] !== "config" || segments.length < 3) return void 0;
322
- return path4.join(sourceRoot, "config", segments[1] ?? "");
475
+ return path5.join(sourceRoot, "config", segments[1] ?? "");
323
476
  }
324
477
  function componentFolderStart(segments) {
325
478
  if (segments[0] === "features") return 2;
@@ -335,7 +488,7 @@ function componentFolderViolation(segments, sourceRoot) {
335
488
  for (let depth = segments.length - 2; depth >= start; depth -= 1) {
336
489
  const folder = segments[depth];
337
490
  if (!folder || SUPPORT_FOLDERS.has(folder)) continue;
338
- const folderPath = path4.join(sourceRoot, ...segments.slice(0, depth + 1));
491
+ const folderPath = path5.join(sourceRoot, ...segments.slice(0, depth + 1));
339
492
  const label = `src/${segments.slice(0, depth + 1).join("/")}/`;
340
493
  if (!hasComponentOwner(folderPath, folder)) {
341
494
  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.`;
@@ -355,7 +508,7 @@ var applicationStructureRule = {
355
508
  }
356
509
  },
357
510
  create(context) {
358
- const filename = path4.resolve(context.filename);
511
+ const filename = path5.resolve(context.filename);
359
512
  const sourceRoot = sourceRootOf(context);
360
513
  const segments = segmentsOf(filename, sourceRoot);
361
514
  if (segments.length === 0) return {};
@@ -386,43 +539,43 @@ var applicationStructureRule = {
386
539
  );
387
540
  }
388
541
  const moduleRoot = configModuleRoot(filename, sourceRoot);
389
- if (moduleRoot && !fs2.existsSync(path4.join(moduleRoot, "index.ts"))) {
542
+ if (moduleRoot && !fs2.existsSync(path5.join(moduleRoot, "index.ts"))) {
390
543
  return report(
391
544
  context,
392
- `Add src/config/${path4.basename(moduleRoot)}/index.ts as the configuration module entry point.`
545
+ `Add src/config/${path5.basename(moduleRoot)}/index.ts as the configuration module entry point.`
393
546
  );
394
547
  }
395
- if (moduleRoot && segments.length === 3 && path4.basename(filename) !== "index.ts") {
548
+ if (moduleRoot && segments.length === 3 && path5.basename(filename) !== "index.ts") {
396
549
  const kinds2 = exportedKinds(filename);
397
550
  const expected2 = expectedSupportFolder(kinds2);
398
551
  if (expected2 !== void 0) {
399
552
  return report(
400
553
  context,
401
- `Move this configuration support file into src/config/${path4.basename(moduleRoot)}/${expected2}/.`
554
+ `Move this configuration support file into src/config/${path5.basename(moduleRoot)}/${expected2}/.`
402
555
  );
403
556
  }
404
557
  }
405
558
  }
406
559
  if (topLevel === "app" && isCodeFile(filename)) {
407
- const basename = path4.basename(filename, path4.extname(filename));
408
- const currentFolder2 = path4.basename(path4.dirname(filename));
560
+ const basename = path5.basename(filename, path5.extname(filename));
561
+ const currentFolder2 = path5.basename(path5.dirname(filename));
409
562
  if (SUPPORT_FOLDERS.has(currentFolder2)) {
410
563
  return report(
411
564
  context,
412
565
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
413
566
  );
414
567
  }
415
- if (!ROUTING_FILES.has(basename) && path4.extname(filename) !== ".css") {
568
+ if (!ROUTING_FILES.has(basename) && path5.extname(filename) !== ".css") {
416
569
  return report(
417
570
  context,
418
571
  "src/app/ may contain routing files and framework assets, but ordinary components and support files must live outside src/app/."
419
572
  );
420
573
  }
421
- if (ROUTING_FILES.has(basename) || path4.extname(filename) === ".css") return {};
574
+ if (ROUTING_FILES.has(basename) || path5.extname(filename) === ".css") return {};
422
575
  }
423
- const currentFolder = path4.basename(path4.dirname(filename));
576
+ const currentFolder = path5.basename(path5.dirname(filename));
424
577
  const kinds = exportedKinds(filename);
425
- const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path4.basename(filename) === "index.ts";
578
+ const isConfigModuleRoot = topLevel === "config" && segments.length === 3 && path5.basename(filename) === "index.ts";
426
579
  if (isConfigModuleRoot) return {};
427
580
  if (!SUPPORT_FOLDERS.has(currentFolder)) {
428
581
  const expected2 = expectedSupportFolder(kinds);
@@ -439,7 +592,7 @@ var applicationStructureRule = {
439
592
  if (kinds.has("component")) {
440
593
  return report(
441
594
  context,
442
- `A support folder must not contain a component; move ${path4.basename(filename)} beside ${currentFolder}/.`
595
+ `A support folder must not contain a component; move ${path5.basename(filename)} beside ${currentFolder}/.`
443
596
  );
444
597
  }
445
598
  if (mixedSupportKinds(currentFolder, kinds)) {
@@ -462,12 +615,12 @@ var applicationStructureRule = {
462
615
  };
463
616
 
464
617
  // eslint/rules/cn-helper.ts
465
- var HELPER = "cn";
466
- var ENTRY = "pasika/cn";
467
- var DOC = "docs/pasika-adoption-guide/rules/cn-helper-rule.md";
468
- var DECLARED = `A file must not declare its own ${HELPER}; import it from ${ENTRY}. See ${DOC}`;
469
- var IMPORTED = `${HELPER} must be imported from ${ENTRY}. See ${DOC}`;
470
- function isNamed(node, name) {
618
+ var HELPER2 = "cn";
619
+ var ENTRY2 = "pasika/cn";
620
+ var DOC2 = "docs/pasika-adoption-guide/rules/cn-helper-rule.md";
621
+ var DECLARED2 = `A file must not declare its own ${HELPER2}; import it from ${ENTRY2}. See ${DOC2}`;
622
+ var IMPORTED2 = `${HELPER2} must be imported from ${ENTRY2}. See ${DOC2}`;
623
+ function isNamed2(node, name) {
471
624
  return node?.type === "Identifier" && node.name === name;
472
625
  }
473
626
  var cnHelperRule = {
@@ -475,24 +628,24 @@ var cnHelperRule = {
475
628
  schema: [],
476
629
  type: "problem",
477
630
  docs: {
478
- description: `Require ${HELPER} to be imported from ${ENTRY} rather than declared in the repository.`
631
+ description: `Require ${HELPER2} to be imported from ${ENTRY2} rather than declared in the repository.`
479
632
  }
480
633
  },
481
634
  create(context) {
482
635
  const checkSource = (node) => {
483
- if (!node.source || node.source.value === ENTRY) return;
636
+ if (!node.source || node.source.value === ENTRY2) return;
484
637
  for (const specifier of node.specifiers) {
485
- if (!isNamed(specifier.local, HELPER)) continue;
486
- context.report({ node: specifier, message: IMPORTED });
638
+ if (!isNamed2(specifier.local, HELPER2)) continue;
639
+ context.report({ node: specifier, message: IMPORTED2 });
487
640
  }
488
641
  };
489
642
  return {
490
643
  FunctionDeclaration(node) {
491
- if (isNamed(node.id, HELPER)) context.report({ node, message: DECLARED });
644
+ if (isNamed2(node.id, HELPER2)) context.report({ node, message: DECLARED2 });
492
645
  },
493
646
  VariableDeclarator(node) {
494
- if (isNamed(node.id.type === "Identifier" ? node.id : null, HELPER)) {
495
- context.report({ node, message: DECLARED });
647
+ if (isNamed2(node.id.type === "Identifier" ? node.id : null, HELPER2)) {
648
+ context.report({ node, message: DECLARED2 });
496
649
  }
497
650
  },
498
651
  ImportDeclaration: checkSource,
@@ -502,10 +655,10 @@ var cnHelperRule = {
502
655
  };
503
656
 
504
657
  // eslint/rules/component-casing.ts
505
- import path6 from "path";
658
+ import path7 from "path";
506
659
 
507
660
  // eslint/rules/component-conventions.ts
508
- import path5 from "path";
661
+ import path6 from "path";
509
662
  import ts2 from "typescript";
510
663
  var isPascalCase2 = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
511
664
  var isHookCallName = (name) => /^use[A-Z]/.test(name);
@@ -622,7 +775,7 @@ function componentFromVariable(node) {
622
775
  };
623
776
  }
624
777
  function parseComponentInfo(text, filename, options) {
625
- const sourceFile = ts2.createSourceFile(path5.resolve(filename), text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
778
+ const sourceFile = ts2.createSourceFile(path6.resolve(filename), text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
626
779
  const components = [];
627
780
  const namedExports = namedExportedLocalNames(sourceFile);
628
781
  for (const statement of sourceFile.statements) {
@@ -646,7 +799,7 @@ function parseComponentInfo(text, filename, options) {
646
799
  return components;
647
800
  }
648
801
  function findJsxReturningDeclarations(text, filename) {
649
- const sourceFile = ts2.createSourceFile(path5.resolve(filename), text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
802
+ const sourceFile = ts2.createSourceFile(path6.resolve(filename), text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
650
803
  const results = [];
651
804
  const record = (identifier, body) => {
652
805
  if (isHookCallName(identifier.text) || !containsJsx(body)) return;
@@ -763,10 +916,10 @@ var componentCasingRule = {
763
916
  }
764
917
  },
765
918
  create(context) {
766
- const filename = path6.resolve(context.filename);
919
+ const filename = path7.resolve(context.filename);
767
920
  const sourceRoot = sourceRootOf(context);
768
- if (!filename.startsWith(sourceRoot + path6.sep)) return {};
769
- if (path6.extname(filename) !== ".tsx") return {};
921
+ if (!filename.startsWith(sourceRoot + path7.sep)) return {};
922
+ if (path7.extname(filename) !== ".tsx") return {};
770
923
  return {
771
924
  Program(node) {
772
925
  for (const declaration of findJsxReturningDeclarations(context.sourceCode.text, filename)) {
@@ -783,11 +936,11 @@ var componentCasingRule = {
783
936
  };
784
937
 
785
938
  // eslint/rules/component-nesting.ts
786
- import path8 from "path";
939
+ import path9 from "path";
787
940
 
788
941
  // eslint/project/index.ts
789
942
  import { readdirSync, statSync } from "fs";
790
- import path7 from "path";
943
+ import path8 from "path";
791
944
  var MODULE_EXTENSIONS2 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
792
945
  var INDEX_BASENAMES = ["index.ts", "index.tsx", "index.mts", "index.cts", "index.js", "index.jsx"];
793
946
  var REVALIDATE_AFTER_MS = 2e3;
@@ -801,7 +954,7 @@ function listSourceFiles(dir) {
801
954
  }
802
955
  return entries.flatMap((entry) => {
803
956
  if (entry.startsWith(".") || entry === "node_modules") return [];
804
- const entryPath = path7.join(dir, entry);
957
+ const entryPath = path8.join(dir, entry);
805
958
  let stats;
806
959
  try {
807
960
  stats = statSync(entryPath);
@@ -809,7 +962,7 @@ function listSourceFiles(dir) {
809
962
  return [];
810
963
  }
811
964
  if (stats.isDirectory()) return listSourceFiles(entryPath);
812
- return MODULE_EXTENSIONS2.includes(path7.extname(entry)) ? [entryPath] : [];
965
+ return MODULE_EXTENSIONS2.includes(path8.extname(entry)) ? [entryPath] : [];
813
966
  });
814
967
  }
815
968
  function fingerprint(files) {
@@ -825,16 +978,16 @@ function fingerprint(files) {
825
978
  function resolveSpecifier(fromFile, specifier, sourceRoot) {
826
979
  let base;
827
980
  if (specifier.startsWith("@/")) {
828
- base = path7.resolve(sourceRoot, specifier.slice(2));
981
+ base = path8.resolve(sourceRoot, specifier.slice(2));
829
982
  } else if (specifier.startsWith(".")) {
830
- base = path7.resolve(path7.dirname(fromFile), specifier);
983
+ base = path8.resolve(path8.dirname(fromFile), specifier);
831
984
  } else {
832
985
  return void 0;
833
986
  }
834
987
  const candidates = [
835
988
  base,
836
989
  ...MODULE_EXTENSIONS2.map((extension) => `${base}${extension}`),
837
- ...INDEX_BASENAMES.map((name) => path7.join(base, name))
990
+ ...INDEX_BASENAMES.map((name) => path8.join(base, name))
838
991
  ];
839
992
  for (const candidate of candidates) {
840
993
  try {
@@ -926,7 +1079,7 @@ var componentNestingRule = {
926
1079
  },
927
1080
  create(context) {
928
1081
  const sourceRoot = sourceRootOf(context);
929
- const file = path8.resolve(context.filename);
1082
+ const file = path9.resolve(context.filename);
930
1083
  const segments = segmentsOf(file, sourceRoot);
931
1084
  if (segments.length !== 4 || segments[0] !== "features") return {};
932
1085
  const index = getProjectIndex(sourceRoot);
@@ -960,7 +1113,7 @@ var componentNestingRule = {
960
1113
 
961
1114
  // eslint/rules/component-placement.ts
962
1115
  import fs3 from "fs";
963
- import path9 from "path";
1116
+ import path10 from "path";
964
1117
  var REASON_TEXT = {
965
1118
  ccf: "that is the closest folder its consumers share",
966
1119
  "across-features": "its consumers span more than one feature, and no feature may import from another",
@@ -972,7 +1125,7 @@ function isNestedInside(expectedFolder, currentFolder, componentFile) {
972
1125
  if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
973
1126
  const folderName = currentFolder[currentFolder.length - 1];
974
1127
  if (!folderName) return false;
975
- return fs3.existsSync(path9.join(path9.dirname(componentFile), `${folderName}.tsx`));
1128
+ return fs3.existsSync(path10.join(path10.dirname(componentFile), `${folderName}.tsx`));
976
1129
  }
977
1130
  var componentPlacementRule = {
978
1131
  meta: {
@@ -988,7 +1141,7 @@ var componentPlacementRule = {
988
1141
  const sourceRoot = sourceRootOf(context);
989
1142
  const index = getProjectIndex(sourceRoot);
990
1143
  if (!index) return {};
991
- const componentFile = path9.resolve(filename);
1144
+ const componentFile = path10.resolve(filename);
992
1145
  const segments = segmentsOf(componentFile, sourceRoot);
993
1146
  if (segments.length === 0) return {};
994
1147
  if (isUnderApp(segments) || isConfigModule(segments)) return {};
@@ -1037,7 +1190,7 @@ var componentPlacementRule = {
1037
1190
  };
1038
1191
 
1039
1192
  // eslint/rules/config-extraction.ts
1040
- import path10 from "path";
1193
+ import path11 from "path";
1041
1194
  var configExtractionRule = {
1042
1195
  meta: {
1043
1196
  schema: [],
@@ -1048,7 +1201,7 @@ var configExtractionRule = {
1048
1201
  },
1049
1202
  create(context) {
1050
1203
  const sourceRoot = sourceRootOf(context);
1051
- const file = path10.resolve(context.filename);
1204
+ const file = path11.resolve(context.filename);
1052
1205
  const segments = segmentsOf(file, sourceRoot);
1053
1206
  if (segments.length < 3 || segments[0] !== "config") return {};
1054
1207
  if (SUPPORT_FOLDERS.has(segments[2] ?? "")) return {};
@@ -1086,7 +1239,7 @@ var configExtractionRule = {
1086
1239
  };
1087
1240
 
1088
1241
  // eslint/rules/constant-casing.ts
1089
- import path11 from "path";
1242
+ import path12 from "path";
1090
1243
  var NEXTJS_ROUTE_HANDLER_NAMES = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
1091
1244
  function isScreamingSnakeCase(name) {
1092
1245
  return /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/.test(name);
@@ -1100,9 +1253,9 @@ var constantCasingRule = {
1100
1253
  }
1101
1254
  },
1102
1255
  create(context) {
1103
- const filename = path11.resolve(context.filename);
1256
+ const filename = path12.resolve(context.filename);
1104
1257
  const sourceRoot = sourceRootOf(context);
1105
- if (!filename.startsWith(sourceRoot + path11.sep)) return {};
1258
+ if (!filename.startsWith(sourceRoot + path12.sep)) return {};
1106
1259
  return {
1107
1260
  VariableDeclarator(node) {
1108
1261
  if (node.id.type !== "Identifier") return;
@@ -1124,12 +1277,12 @@ var constantCasingRule = {
1124
1277
  };
1125
1278
 
1126
1279
  // eslint/rules/cross-feature-import.ts
1127
- import path12 from "path";
1280
+ import path13 from "path";
1128
1281
  var FEATURES_SEGMENT = "features";
1129
1282
  function featureNameOf(resolvedPath, sourceRoot) {
1130
- const relative = path12.relative(sourceRoot, resolvedPath);
1283
+ const relative = path13.relative(sourceRoot, resolvedPath);
1131
1284
  if (relative.startsWith("..")) return void 0;
1132
- const segments = relative.split(path12.sep);
1285
+ const segments = relative.split(path13.sep);
1133
1286
  if (segments[0] !== FEATURES_SEGMENT || segments.length < 2) return void 0;
1134
1287
  return segments[1];
1135
1288
  }
@@ -1145,9 +1298,9 @@ var crossFeatureImportRule = {
1145
1298
  const filename = context.filename;
1146
1299
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
1147
1300
  const sourceRoot = sourceRootOf(context);
1148
- const fileRelative = path12.relative(sourceRoot, filename);
1301
+ const fileRelative = path13.relative(sourceRoot, filename);
1149
1302
  if (fileRelative.startsWith("..")) return {};
1150
- const fileSegments = fileRelative.split(path12.sep);
1303
+ const fileSegments = fileRelative.split(path13.sep);
1151
1304
  const isInCompositions = fileSegments[0] === "compositions";
1152
1305
  const isInApp = fileSegments[0] === "app";
1153
1306
  const isConfig = fileSegments[0] === "config";
@@ -1162,9 +1315,9 @@ var crossFeatureImportRule = {
1162
1315
  if (typeof source.value !== "string") return;
1163
1316
  let resolved;
1164
1317
  if (source.value.startsWith("@/")) {
1165
- resolved = path12.resolve(sourceRoot, source.value.slice(2));
1318
+ resolved = path13.resolve(sourceRoot, source.value.slice(2));
1166
1319
  } else if (source.value.startsWith(".")) {
1167
- resolved = path12.resolve(path12.dirname(filename), source.value);
1320
+ resolved = path13.resolve(path13.dirname(filename), source.value);
1168
1321
  }
1169
1322
  if (!resolved) return;
1170
1323
  const feature = featureNameOf(resolved, sourceRoot);
@@ -1315,7 +1468,7 @@ var cvaBooleanVariantsRule = {
1315
1468
  };
1316
1469
 
1317
1470
  // eslint/rules/data-component-case.ts
1318
- import path13 from "path";
1471
+ import path14 from "path";
1319
1472
  var NEXT_ROUTING_FILES = /* @__PURE__ */ new Set([
1320
1473
  "default",
1321
1474
  "error",
@@ -1346,9 +1499,9 @@ var dataComponentCaseRule = {
1346
1499
  }
1347
1500
  },
1348
1501
  create(context) {
1349
- const filename = path13.resolve(context.filename);
1502
+ const filename = path14.resolve(context.filename);
1350
1503
  if (!filename.endsWith(".tsx")) return {};
1351
- const base = path13.basename(filename, path13.extname(filename));
1504
+ const base = path14.basename(filename, path14.extname(filename));
1352
1505
  if (NEXT_ROUTING_FILES.has(base)) return {};
1353
1506
  const components = parseComponentInfo(context.sourceCode.text, filename);
1354
1507
  return {
@@ -1383,7 +1536,7 @@ function toKebabCase(value) {
1383
1536
  }
1384
1537
 
1385
1538
  // eslint/rules/documentation/helpers.ts
1386
- import path14 from "path";
1539
+ import path15 from "path";
1387
1540
 
1388
1541
  // constants/rfc2119.ts
1389
1542
  var RFC_2119_KEYWORDS = ["MUST NOT", "MUST", "SHOULD NOT", "SHOULD", "MAY"];
@@ -1398,11 +1551,11 @@ function getFilename(context) {
1398
1551
  return context.filename;
1399
1552
  }
1400
1553
  function isAgentDocument(filename) {
1401
- const base = path14.basename(filename);
1554
+ const base = path15.basename(filename);
1402
1555
  return base === "AGENTS.md" || base === "CLAUDE.md";
1403
1556
  }
1404
1557
  function isDocumentationTemplate(filename) {
1405
- return path14.basename(path14.dirname(filename)) === "_templates";
1558
+ return path15.basename(path15.dirname(filename)) === "_templates";
1406
1559
  }
1407
1560
  function getTextContent(node) {
1408
1561
  if ("value" in node && typeof node.value === "string") return node.value;
@@ -1480,11 +1633,11 @@ var exampleHeadingDescriptionRule = {
1480
1633
 
1481
1634
  // eslint/rules/documentation/glossary-term-linking.ts
1482
1635
  import { readFileSync as readFileSync3 } from "fs";
1483
- import path16 from "path";
1636
+ import path17 from "path";
1484
1637
 
1485
1638
  // eslint/rules/documentation/project-index.ts
1486
1639
  import { readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
1487
- import path15 from "path";
1640
+ import path16 from "path";
1488
1641
  var KIND_BY_SUFFIX = [
1489
1642
  ["-rule.md", "rule"],
1490
1643
  ["-guide.md", "guide"],
@@ -1493,7 +1646,7 @@ var KIND_BY_SUFFIX = [
1493
1646
  ];
1494
1647
  function listMarkdownFiles(dir) {
1495
1648
  return readdirSync2(dir).flatMap((entry) => {
1496
- const entryPath = path15.join(dir, entry);
1649
+ const entryPath = path16.join(dir, entry);
1497
1650
  if (statSync2(entryPath).isDirectory()) {
1498
1651
  return entry.startsWith("_") ? [] : listMarkdownFiles(entryPath);
1499
1652
  }
@@ -1511,11 +1664,11 @@ function getProjectDocs(docsRoot) {
1511
1664
  if (cached) return cached;
1512
1665
  const files = listMarkdownFiles(docsRoot);
1513
1666
  const docs = files.sort((a, b) => a.localeCompare(b)).map((filePath) => {
1514
- const fileName = path15.basename(filePath);
1667
+ const fileName = path16.basename(filePath);
1515
1668
  const kind = KIND_BY_SUFFIX.find(([suffix]) => fileName.endsWith(suffix))?.[1];
1516
1669
  return {
1517
1670
  filePath,
1518
- doc: path15.relative(docsRoot, filePath).split(path15.sep).join("/"),
1671
+ doc: path16.relative(docsRoot, filePath).split(path16.sep).join("/"),
1519
1672
  fileName,
1520
1673
  kind,
1521
1674
  title: extractTitle(filePath)
@@ -1525,12 +1678,12 @@ function getProjectDocs(docsRoot) {
1525
1678
  return docs;
1526
1679
  }
1527
1680
  function findDocsRoot(filePath) {
1528
- let dir = path15.dirname(filePath);
1681
+ let dir = path16.dirname(filePath);
1529
1682
  for (; ; ) {
1530
- if (path15.basename(dir) === "docs" && statSync2(dir).isDirectory()) {
1683
+ if (path16.basename(dir) === "docs" && statSync2(dir).isDirectory()) {
1531
1684
  return dir;
1532
1685
  }
1533
- const parent = path15.dirname(dir);
1686
+ const parent = path16.dirname(dir);
1534
1687
  if (parent === dir) return void 0;
1535
1688
  dir = parent;
1536
1689
  }
@@ -1538,7 +1691,7 @@ function findDocsRoot(filePath) {
1538
1691
 
1539
1692
  // eslint/rules/documentation/glossary-term-linking.ts
1540
1693
  function isGlossary(filePath) {
1541
- return path16.basename(filePath).includes("glossary");
1694
+ return path17.basename(filePath).includes("glossary");
1542
1695
  }
1543
1696
  function termNames(cell) {
1544
1697
  const abbreviation = /\((?<abbreviation>[^()]+)\)/.exec(cell)?.groups?.abbreviation?.trim();
@@ -1631,10 +1784,10 @@ var glossaryTermLinkingRule = {
1631
1784
  const docsRoot = findDocsRoot(filename);
1632
1785
  if (!docsRoot) return;
1633
1786
  const docs = getProjectDocs(docsRoot);
1634
- const guideDir = path16.dirname(filename);
1635
- const referencesDir = path16.join(guideDir, "references");
1787
+ const guideDir = path17.dirname(filename);
1788
+ const referencesDir = path17.join(guideDir, "references");
1636
1789
  const guideReferences = docs.filter(
1637
- (doc) => doc.kind === "reference" && path16.dirname(doc.filePath) === referencesDir
1790
+ (doc) => doc.kind === "reference" && path17.dirname(doc.filePath) === referencesDir
1638
1791
  );
1639
1792
  const glossaryReferences = guideReferences.filter((doc) => isGlossary(doc.filePath));
1640
1793
  if (glossaryReferences.length === 0) return;
@@ -1651,7 +1804,7 @@ var glossaryTermLinkingRule = {
1651
1804
  (section) => section.firstStepLinks.some((link) => {
1652
1805
  const fragment = link.split("#")[1] ?? "";
1653
1806
  if (fragment.toLowerCase() !== anchor) return false;
1654
- return path16.resolve(guideDir, linkTarget(link)) === path16.resolve(ref.filePath);
1807
+ return path17.resolve(guideDir, linkTarget(link)) === path17.resolve(ref.filePath);
1655
1808
  })
1656
1809
  );
1657
1810
  if (!anchored) {
@@ -1687,7 +1840,7 @@ var glossaryTermLinkingRule = {
1687
1840
  };
1688
1841
 
1689
1842
  // eslint/rules/documentation/guide-folder-entry-point.ts
1690
- import path17 from "path";
1843
+ import path18 from "path";
1691
1844
  var guideFolderEntryPointRule = {
1692
1845
  meta: {
1693
1846
  type: "problem",
@@ -1705,13 +1858,13 @@ var guideFolderEntryPointRule = {
1705
1858
  if (!docsRoot) return;
1706
1859
  const docs = getProjectDocs(docsRoot);
1707
1860
  const guideFolders = new Set(
1708
- docs.filter((doc) => ["rules", "references"].includes(path17.basename(path17.dirname(doc.filePath)))).map((doc) => path17.dirname(path17.dirname(doc.filePath))).filter((folder) => path17.resolve(folder) !== path17.resolve(docsRoot))
1861
+ docs.filter((doc) => ["rules", "references"].includes(path18.basename(path18.dirname(doc.filePath)))).map((doc) => path18.dirname(path18.dirname(doc.filePath))).filter((folder) => path18.resolve(folder) !== path18.resolve(docsRoot))
1709
1862
  );
1710
- const currentDir = path17.dirname(filename);
1863
+ const currentDir = path18.dirname(filename);
1711
1864
  if (guideFolders.has(currentDir)) {
1712
- const expectedEntryPoint = `${path17.basename(currentDir)}.md`;
1865
+ const expectedEntryPoint = `${path18.basename(currentDir)}.md`;
1713
1866
  const hasEntryPoint = docs.some(
1714
- (doc) => doc.kind === "guide" && path17.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
1867
+ (doc) => doc.kind === "guide" && path18.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
1715
1868
  );
1716
1869
  if (!hasEntryPoint) {
1717
1870
  context.report({
@@ -1727,7 +1880,7 @@ var guideFolderEntryPointRule = {
1727
1880
 
1728
1881
  // eslint/rules/documentation/guide-link-anchors.ts
1729
1882
  import { existsSync, readFileSync as readFileSync4 } from "fs";
1730
- import path18 from "path";
1883
+ import path19 from "path";
1731
1884
  function visitSteps(node, check) {
1732
1885
  if (node.type === "list" && node.ordered) {
1733
1886
  for (const child of node.children) check(child);
@@ -1806,7 +1959,7 @@ var guideLinkAnchorsRule = {
1806
1959
  for (const link of links) {
1807
1960
  const [target = "", fragment = ""] = link.url.split("#");
1808
1961
  if (!fragment || !isDocLink(link.url)) continue;
1809
- const targetPath = path18.resolve(path18.dirname(filename), target);
1962
+ const targetPath = path19.resolve(path19.dirname(filename), target);
1810
1963
  if (!existsSync(targetPath)) continue;
1811
1964
  if (documentAnchors(targetPath).has(fragment.toLowerCase())) continue;
1812
1965
  context.report({
@@ -1821,7 +1974,7 @@ var guideLinkAnchorsRule = {
1821
1974
 
1822
1975
  // eslint/rules/documentation/guide-mentions-documents.ts
1823
1976
  import { existsSync as existsSync2 } from "fs";
1824
- import path19 from "path";
1977
+ import path20 from "path";
1825
1978
  function visitSteps2(node, check) {
1826
1979
  if (node.type === "list" && node.ordered) {
1827
1980
  for (const child of node.children) check(child);
@@ -1851,12 +2004,12 @@ var guideMentionsDocumentsRule = {
1851
2004
  if (!filename.endsWith("-guide.md")) return;
1852
2005
  const docsRoot = findDocsRoot(filename);
1853
2006
  if (!docsRoot) return;
1854
- const guideDir = path19.dirname(filename);
1855
- if (path19.basename(filename, ".md") !== path19.basename(guideDir)) return;
2007
+ const guideDir = path20.dirname(filename);
2008
+ if (path20.basename(filename, ".md") !== path20.basename(guideDir)) return;
1856
2009
  const docs = getProjectDocs(docsRoot);
1857
2010
  const owned = docs.filter((doc) => {
1858
- const parent = path19.dirname(doc.filePath);
1859
- return parent === path19.join(guideDir, "rules") || parent === path19.join(guideDir, "references");
2011
+ const parent = path20.dirname(doc.filePath);
2012
+ return parent === path20.join(guideDir, "rules") || parent === path20.join(guideDir, "references");
1860
2013
  });
1861
2014
  const allLinks = [];
1862
2015
  collectMarkdownLinks(node, allLinks);
@@ -1883,7 +2036,7 @@ var guideMentionsDocumentsRule = {
1883
2036
  for (const link of allLinks) {
1884
2037
  const target = linkTarget(link.url);
1885
2038
  if (!target.endsWith(".md")) continue;
1886
- const resolved = path19.normalize(path19.join(guideDir, target));
2039
+ const resolved = path20.normalize(path20.join(guideDir, target));
1887
2040
  if (!existsSync2(resolved)) {
1888
2041
  context.report({
1889
2042
  node: link,
@@ -2562,20 +2715,20 @@ var rulePairedExamplesRule = {
2562
2715
 
2563
2716
  // eslint/rules/documentation/support-document-placement.ts
2564
2717
  import { existsSync as existsSync3 } from "fs";
2565
- import path20 from "path";
2718
+ import path21 from "path";
2566
2719
  function checkPlacement(filename, kind) {
2567
- const parentFolder = path20.basename(path20.dirname(filename));
2720
+ const parentFolder = path21.basename(path21.dirname(filename));
2568
2721
  const expectedParent = `${kind}s`;
2569
2722
  if (parentFolder !== expectedParent) {
2570
2723
  return `${kind} lives in "${parentFolder}/" instead of "${expectedParent}/"`;
2571
2724
  }
2572
- const guideFolderPath = path20.dirname(path20.dirname(filename));
2573
- const guideFolder = path20.basename(guideFolderPath);
2725
+ const guideFolderPath = path21.dirname(path21.dirname(filename));
2726
+ const guideFolder = path21.basename(guideFolderPath);
2574
2727
  if (!guideFolder.endsWith("-guide")) {
2575
2728
  return `${kind} owner folder "${guideFolder}/" does not use the "*-guide/" suffix`;
2576
2729
  }
2577
2730
  const entryPoint = `${guideFolder}.md`;
2578
- if (!existsSync3(path20.join(guideFolderPath, entryPoint))) {
2731
+ if (!existsSync3(path21.join(guideFolderPath, entryPoint))) {
2579
2732
  return `${kind} owner folder "${guideFolder}/" has no "${entryPoint}" entry point`;
2580
2733
  }
2581
2734
  return void 0;
@@ -2610,7 +2763,7 @@ var supportDocumentPlacementRule = {
2610
2763
  };
2611
2764
 
2612
2765
  // eslint/rules/documentation/title-matches-file-name.ts
2613
- import path21 from "path";
2766
+ import path22 from "path";
2614
2767
  function toExpectedFileName(title) {
2615
2768
  return `${title.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.md`;
2616
2769
  }
@@ -2630,7 +2783,7 @@ var titleMatchesFileNameRule = {
2630
2783
  if (!filename.endsWith(".md") || isAgentDocument(filename) || isDocumentationTemplate(filename)) return;
2631
2784
  const title = getTextContent(node).trim();
2632
2785
  const expectedFileName = toExpectedFileName(title);
2633
- const actualFileName = path21.basename(filename);
2786
+ const actualFileName = path22.basename(filename);
2634
2787
  if (!title) {
2635
2788
  context.report({
2636
2789
  node,
@@ -2678,7 +2831,7 @@ var documentationRules = {
2678
2831
 
2679
2832
  // eslint/rules/enforce-barrel-exports.ts
2680
2833
  import fs4 from "fs";
2681
- import path22 from "path";
2834
+ import path23 from "path";
2682
2835
  function isPascalCase4(str) {
2683
2836
  return /^[A-Z][A-Za-z0-9]*$/.test(str);
2684
2837
  }
@@ -2687,7 +2840,7 @@ function isKebabCase(str) {
2687
2840
  }
2688
2841
  var SUPPORT_FOLDERS2 = /* @__PURE__ */ new Set(["types", "schemas", "hooks", "constants", "utils", "config", "locales"]);
2689
2842
  function parentComponentName(dirPath, folderName) {
2690
- const componentFile = path22.join(dirPath, `${folderName}.tsx`);
2843
+ const componentFile = path23.join(dirPath, `${folderName}.tsx`);
2691
2844
  if (!fs4.existsSync(componentFile)) return void 0;
2692
2845
  try {
2693
2846
  const exports = parseModule(componentFile).exports;
@@ -2707,12 +2860,12 @@ var enforceBarrelExportsRule = {
2707
2860
  create(context) {
2708
2861
  const filename = context.filename;
2709
2862
  if (!filename) return {};
2710
- const baseName = path22.basename(filename);
2863
+ const baseName = path23.basename(filename);
2711
2864
  const isIndexFile = baseName === "index.ts";
2712
2865
  if (!isIndexFile) return {};
2713
- const dirPath = path22.dirname(filename);
2714
- const folderName = path22.basename(dirPath);
2715
- const parentFolderName = path22.basename(path22.dirname(dirPath));
2866
+ const dirPath = path23.dirname(filename);
2867
+ const folderName = path23.basename(dirPath);
2868
+ const parentFolderName = path23.basename(path23.dirname(dirPath));
2716
2869
  if (SUPPORT_FOLDERS2.has(folderName)) return {};
2717
2870
  if (!isPascalCase4(folderName) && !isKebabCase(folderName)) return {};
2718
2871
  const parentName = parentComponentName(dirPath, folderName);
@@ -2750,7 +2903,7 @@ var enforceBarrelExportsRule = {
2750
2903
  };
2751
2904
 
2752
2905
  // eslint/rules/enforce-cn-merge.ts
2753
- import path23 from "path";
2906
+ import path24 from "path";
2754
2907
  function classCount(str) {
2755
2908
  return str.split(/\s+/).filter(Boolean).length;
2756
2909
  }
@@ -2780,7 +2933,7 @@ var enforceCnMergeRule = {
2780
2933
  create(context) {
2781
2934
  const packageComponents = /* @__PURE__ */ new Set();
2782
2935
  const index = getProjectIndex(sourceRootOf(context));
2783
- const module = index?.modules.get(path23.resolve(context.filename));
2936
+ const module = index?.modules.get(path24.resolve(context.filename));
2784
2937
  for (const moduleImport of module?.imports ?? []) {
2785
2938
  if (moduleImport.specifier.startsWith(".") || moduleImport.specifier.startsWith("@/")) continue;
2786
2939
  for (const name of moduleImport.names) {
@@ -2934,7 +3087,7 @@ var enforceCvaVariantPropsRule = {
2934
3087
  };
2935
3088
 
2936
3089
  // eslint/rules/enum-placement.ts
2937
- import path24 from "path";
3090
+ import path25 from "path";
2938
3091
  var enumPlacementRule = {
2939
3092
  meta: {
2940
3093
  schema: [],
@@ -2944,10 +3097,10 @@ var enumPlacementRule = {
2944
3097
  }
2945
3098
  },
2946
3099
  create(context) {
2947
- const filename = path24.resolve(context.filename);
3100
+ const filename = path25.resolve(context.filename);
2948
3101
  const sourceRoot = sourceRootOf(context);
2949
- if (!filename.startsWith(sourceRoot + path24.sep)) return {};
2950
- if (path24.basename(path24.dirname(filename)) === "constants") return {};
3102
+ if (!filename.startsWith(sourceRoot + path25.sep)) return {};
3103
+ if (path25.basename(path25.dirname(filename)) === "constants") return {};
2951
3104
  return {
2952
3105
  TSEnumDeclaration(node) {
2953
3106
  context.report({
@@ -2985,7 +3138,7 @@ var fileLengthRule = {
2985
3138
  };
2986
3139
 
2987
3140
  // eslint/rules/filename-case.ts
2988
- import path25 from "path";
3141
+ import path26 from "path";
2989
3142
  var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
2990
3143
  "page",
2991
3144
  "layout",
@@ -3031,11 +3184,11 @@ var filenameCaseRule = {
3031
3184
  if (!normalized.includes("/src/")) {
3032
3185
  return {};
3033
3186
  }
3034
- const ext = path25.extname(filename);
3035
- let base = path25.basename(filename, ext);
3036
- const baseExt = path25.extname(base);
3187
+ const ext = path26.extname(filename);
3188
+ let base = path26.basename(filename, ext);
3189
+ const baseExt = path26.extname(base);
3037
3190
  if (baseExt && COMPOUND_SUFFIXES.has(baseExt.slice(1))) {
3038
- base = path25.basename(base, baseExt);
3191
+ base = path26.basename(base, baseExt);
3039
3192
  }
3040
3193
  if (NEXT_ROUTING_FILES2.has(base)) {
3041
3194
  return {};
@@ -3048,21 +3201,21 @@ var filenameCaseRule = {
3048
3201
  if (component?.smart && !isPascalCase5(base)) {
3049
3202
  context.report({
3050
3203
  node,
3051
- message: `Smart component files must use PascalCase.tsx. Filename "${path25.basename(filename)}" is not PascalCase.`
3204
+ message: `Smart component files must use PascalCase.tsx. Filename "${path26.basename(filename)}" is not PascalCase.`
3052
3205
  });
3053
3206
  return;
3054
3207
  }
3055
3208
  if (component && !component.smart && !isKebabCase2(base)) {
3056
3209
  context.report({
3057
3210
  node,
3058
- message: `Dumb component files must use kebab-case.tsx. Filename "${path25.basename(filename)}" is not kebab-case.`
3211
+ message: `Dumb component files must use kebab-case.tsx. Filename "${path26.basename(filename)}" is not kebab-case.`
3059
3212
  });
3060
3213
  return;
3061
3214
  }
3062
3215
  if (!component && !(isPascalCase5(base) || isKebabCase2(base))) {
3063
3216
  context.report({
3064
3217
  node,
3065
- message: `Filename "${path25.basename(filename)}" does not match pasika conventions. Component files must be PascalCase.tsx (smart) or kebab-case.tsx (dumb).`
3218
+ message: `Filename "${path26.basename(filename)}" does not match pasika conventions. Component files must be PascalCase.tsx (smart) or kebab-case.tsx (dumb).`
3066
3219
  });
3067
3220
  }
3068
3221
  }
@@ -3081,14 +3234,14 @@ function report2(context, filename, ext) {
3081
3234
  context.report({
3082
3235
  node,
3083
3236
  loc: { line: 1, column: 0 },
3084
- message: `Filename "${path25.basename(filename)}" does not match pasika conventions. ${convention}`
3237
+ message: `Filename "${path26.basename(filename)}" does not match pasika conventions. ${convention}`
3085
3238
  });
3086
3239
  }
3087
3240
  };
3088
3241
  }
3089
3242
 
3090
3243
  // eslint/rules/hook-complexity.ts
3091
- import path26 from "path";
3244
+ import path27 from "path";
3092
3245
  import ts3 from "typescript";
3093
3246
  var REACT_HOOKS = /* @__PURE__ */ new Set([
3094
3247
  "useState",
@@ -3213,9 +3366,9 @@ var hookComplexityRule = {
3213
3366
  create(context) {
3214
3367
  const filename = context.filename;
3215
3368
  const sourceRoot = sourceRootOf(context);
3216
- const relative = path26.relative(sourceRoot, filename);
3369
+ const relative = path27.relative(sourceRoot, filename);
3217
3370
  if (relative.startsWith("..")) return {};
3218
- const segments = relative.split(path26.sep);
3371
+ const segments = relative.split(path27.sep);
3219
3372
  const sourceText = context.sourceCode.text;
3220
3373
  const index = getProjectIndex(sourceRoot);
3221
3374
  const localHookCalls = /* @__PURE__ */ new Set();
@@ -3302,7 +3455,7 @@ var hookComplexityRule = {
3302
3455
  };
3303
3456
 
3304
3457
  // eslint/rules/hook-extraction.ts
3305
- import path27 from "path";
3458
+ import path28 from "path";
3306
3459
  var hookExtractionRule = {
3307
3460
  meta: {
3308
3461
  schema: [],
@@ -3313,7 +3466,7 @@ var hookExtractionRule = {
3313
3466
  },
3314
3467
  create(context) {
3315
3468
  const sourceRoot = sourceRootOf(context);
3316
- const file = path27.resolve(context.filename);
3469
+ const file = path28.resolve(context.filename);
3317
3470
  const segments = segmentsOf(file, sourceRoot);
3318
3471
  if (segments.length === 0) return {};
3319
3472
  const index = getProjectIndex(sourceRoot);
@@ -3340,14 +3493,14 @@ var hookExtractionRule = {
3340
3493
 
3341
3494
  // eslint/rules/http-error-usage.ts
3342
3495
  import { readFileSync as readFileSync5 } from "fs";
3343
- import path28 from "path";
3496
+ import path29 from "path";
3344
3497
  import ts4 from "typescript";
3345
3498
  var HTTP_ERROR = "HttpError";
3346
3499
  var ROUTE_FILE = "route.ts";
3347
- var DOC2 = "docs/next-codebase-guide/rules/route-handler-rule.md";
3500
+ var DOC3 = "docs/next-codebase-guide/rules/route-handler-rule.md";
3348
3501
  var HERITAGE_DEPTH = 5;
3349
- var HANDS_ERROR_BACK = `A delegated module must throw the HttpError it reports a failure with, not return it. See ${DOC2}`;
3350
- var delegatedModuleMessage = (name) => `A delegated module must report a failure by throwing an HttpError, not "${name}". See ${DOC2}`;
3502
+ var HANDS_ERROR_BACK = `A delegated module must throw the HttpError it reports a failure with, not return it. See ${DOC3}`;
3503
+ var delegatedModuleMessage = (name) => `A delegated module must report a failure by throwing an HttpError, not "${name}". See ${DOC3}`;
3351
3504
  function constructedErrorName(node) {
3352
3505
  if (node === void 0) return void 0;
3353
3506
  if (node.type === "NewExpression") {
@@ -3384,13 +3537,13 @@ function parentClassOf(file, name) {
3384
3537
  return void 0;
3385
3538
  }
3386
3539
  function importedFrom(file, name, sourceRoot, index) {
3387
- const module = index.modules.get(path28.resolve(file));
3540
+ const module = index.modules.get(path29.resolve(file));
3388
3541
  const moduleImport = module?.imports.find((entry) => entry.names.includes(name));
3389
3542
  if (!moduleImport) return void 0;
3390
3543
  return resolveSpecifier(file, moduleImport.specifier, sourceRoot);
3391
3544
  }
3392
3545
  function isHttpErrorClass(file, name, sourceRoot, index) {
3393
- let currentFile = path28.resolve(file);
3546
+ let currentFile = path29.resolve(file);
3394
3547
  let currentName = name;
3395
3548
  for (let depth = 0; depth <= HERITAGE_DEPTH; depth += 1) {
3396
3549
  if (currentName === HTTP_ERROR) return true;
@@ -3411,7 +3564,7 @@ function pipelineFiles(sourceRoot) {
3411
3564
  if (!index) return void 0;
3412
3565
  if (pipelineCache?.index === index) return pipelineCache.files;
3413
3566
  const files = /* @__PURE__ */ new Set();
3414
- const queue = [...index.modules.keys()].filter((file) => path28.basename(file) === ROUTE_FILE);
3567
+ const queue = [...index.modules.keys()].filter((file) => path29.basename(file) === ROUTE_FILE);
3415
3568
  while (queue.length > 0) {
3416
3569
  const file = queue.pop();
3417
3570
  if (file === void 0 || files.has(file)) continue;
@@ -3434,7 +3587,7 @@ var httpErrorUsageRule = {
3434
3587
  },
3435
3588
  create(context) {
3436
3589
  const sourceRoot = sourceRootOf(context);
3437
- const file = path28.resolve(context.filename);
3590
+ const file = path29.resolve(context.filename);
3438
3591
  let delegated;
3439
3592
  function inPipeline() {
3440
3593
  delegated ??= pipelineFiles(sourceRoot)?.has(file) ?? false;
@@ -3469,7 +3622,7 @@ var httpErrorUsageRule = {
3469
3622
 
3470
3623
  // eslint/rules/husky/husky-hook.ts
3471
3624
  import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
3472
- import path29 from "path";
3625
+ import path30 from "path";
3473
3626
  function memberName(member) {
3474
3627
  return member.name.type === "String" ? member.name.value : member.name.name;
3475
3628
  }
@@ -3487,7 +3640,7 @@ var huskyHookRule = {
3487
3640
  const root = node.body;
3488
3641
  if (root.type !== "Object") return;
3489
3642
  if (!context.filename.endsWith("package.json")) return;
3490
- const hookPath = path29.join(context.cwd, ".husky", "pre-commit");
3643
+ const hookPath = path30.join(context.cwd, ".husky", "pre-commit");
3491
3644
  if (!existsSync4(hookPath)) {
3492
3645
  context.report({
3493
3646
  node,
@@ -3514,7 +3667,7 @@ var huskyHookRule = {
3514
3667
  if (!content.includes("libyear --limit-major-individual=1")) {
3515
3668
  context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
3516
3669
  }
3517
- const suppressionsPath = path29.join(context.cwd, "eslint-suppressions.json");
3670
+ const suppressionsPath = path30.join(context.cwd, "eslint-suppressions.json");
3518
3671
  if (existsSync4(suppressionsPath)) {
3519
3672
  requireNamedScript("lint:prune");
3520
3673
  const pruneIndex = content.indexOf("npm run lint:prune");
@@ -3546,28 +3699,28 @@ var huskyRules = {
3546
3699
  };
3547
3700
 
3548
3701
  // eslint/rules/import-boundaries.ts
3549
- import path30 from "path";
3702
+ import path31 from "path";
3550
3703
  var rootSupportFolders = /* @__PURE__ */ new Set(["config", "constants", "hooks", "locales", "schemas", "types", "utils"]);
3551
3704
  var moduleExtensions = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"]);
3552
3705
  var styleExtensions = /* @__PURE__ */ new Set([".css", ".less", ".sass", ".scss"]);
3553
3706
  function resolveSourceImport(sourceRoot, filename, importPath) {
3554
3707
  if (importPath.startsWith("@/")) {
3555
- return path30.resolve(sourceRoot, importPath.slice(2));
3708
+ return path31.resolve(sourceRoot, importPath.slice(2));
3556
3709
  }
3557
3710
  if (importPath.startsWith(".")) {
3558
- return path30.resolve(path30.dirname(filename), importPath);
3711
+ return path31.resolve(path31.dirname(filename), importPath);
3559
3712
  }
3560
3713
  return void 0;
3561
3714
  }
3562
3715
  function sourceSegments(sourceRoot, absolutePath) {
3563
- const relativePath = path30.relative(sourceRoot, absolutePath);
3564
- if (relativePath.startsWith("..") || path30.isAbsolute(relativePath)) {
3716
+ const relativePath = path31.relative(sourceRoot, absolutePath);
3717
+ if (relativePath.startsWith("..") || path31.isAbsolute(relativePath)) {
3565
3718
  return void 0;
3566
3719
  }
3567
- return relativePath.split(path30.sep);
3720
+ return relativePath.split(path31.sep);
3568
3721
  }
3569
3722
  function relativeSpecifier(filename, resolvedPath) {
3570
- const relativePath = path30.relative(path30.dirname(filename), resolvedPath).split(path30.sep).join("/");
3723
+ const relativePath = path31.relative(path31.dirname(filename), resolvedPath).split(path31.sep).join("/");
3571
3724
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
3572
3725
  }
3573
3726
  function aliasSpecifier(sourceRoot, resolvedPath) {
@@ -3606,7 +3759,7 @@ var importBoundariesRule = {
3606
3759
  }
3607
3760
  const [importerLayer = "", importerFeature] = importer;
3608
3761
  const [importedLayer = "", importedFeature] = imported;
3609
- const extension = path30.extname(importPath);
3762
+ const extension = path31.extname(importPath);
3610
3763
  const isCodeModule = !extension || moduleExtensions.has(extension);
3611
3764
  const isAppLocalStyleImport = importerLayer === "app" && importedLayer === "app" && styleExtensions.has(extension);
3612
3765
  const importedIsRootSupport = rootSupportFolders.has(importedLayer);
@@ -3704,7 +3857,7 @@ var importSpacingRule = {
3704
3857
  };
3705
3858
 
3706
3859
  // eslint/rules/import-through-index.ts
3707
- import path31 from "path";
3860
+ import path32 from "path";
3708
3861
  var importThroughIndexRule = {
3709
3862
  meta: {
3710
3863
  schema: [],
@@ -3714,7 +3867,7 @@ var importThroughIndexRule = {
3714
3867
  }
3715
3868
  },
3716
3869
  create(context) {
3717
- const filename = path31.resolve(context.filename);
3870
+ const filename = path32.resolve(context.filename);
3718
3871
  const sourceRoot = sourceRootOf2(context, filename);
3719
3872
  return {
3720
3873
  Program(node) {
@@ -3726,7 +3879,7 @@ var importThroughIndexRule = {
3726
3879
  (segment) => ["constants", "types", "schemas"].includes(segment)
3727
3880
  );
3728
3881
  const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
3729
- if (!supportFolder || path31.basename(target).startsWith("index.")) continue;
3882
+ if (!supportFolder || path32.basename(target).startsWith("index.")) continue;
3730
3883
  const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
3731
3884
  const expected = `@/${folderIndex.join("/")}`;
3732
3885
  context.report({
@@ -3748,14 +3901,14 @@ function importSpecifiers(source) {
3748
3901
  return specifiers;
3749
3902
  }
3750
3903
  function sourceRootOf2(context, filename) {
3751
- const marker = `${path31.sep}src${path31.sep}`;
3904
+ const marker = `${path32.sep}src${path32.sep}`;
3752
3905
  const srcIndex = filename.lastIndexOf(marker);
3753
3906
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
3754
- return path31.resolve(context.cwd ?? process.cwd(), "src");
3907
+ return path32.resolve(context.cwd ?? process.cwd(), "src");
3755
3908
  }
3756
3909
 
3757
3910
  // eslint/rules/interactive-component.ts
3758
- import path32 from "path";
3911
+ import path33 from "path";
3759
3912
  var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
3760
3913
  "a",
3761
3914
  "button",
@@ -3911,8 +4064,8 @@ var interactiveComponentRule = {
3911
4064
  },
3912
4065
  create(context) {
3913
4066
  if (!context.filename.endsWith(".tsx") && !context.filename.endsWith(".jsx")) return {};
3914
- const filename = path32.resolve(context.filename);
3915
- const base = path32.basename(filename, path32.extname(filename));
4067
+ const filename = path33.resolve(context.filename);
4068
+ const base = path33.basename(filename, path33.extname(filename));
3916
4069
  if (NEXT_ROUTING_FILES3.has(base)) return {};
3917
4070
  return {
3918
4071
  JSXElement(node) {
@@ -4036,9 +4189,9 @@ var jsxHygieneRule = {
4036
4189
  };
4037
4190
 
4038
4191
  // eslint/rules/locale-dotted-path.ts
4039
- import path33 from "path";
4192
+ import path34 from "path";
4040
4193
  function isInLocalesDir(filename) {
4041
- const segments = path33.resolve(filename).split(path33.sep);
4194
+ const segments = path34.resolve(filename).split(path34.sep);
4042
4195
  const srcIdx = segments.lastIndexOf("src");
4043
4196
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4044
4197
  }
@@ -4087,7 +4240,7 @@ var localeDottedPathRule = {
4087
4240
  };
4088
4241
 
4089
4242
  // eslint/rules/locale-key-shape.ts
4090
- import path34 from "path";
4243
+ import path35 from "path";
4091
4244
  var MAX_KEY_LENGTH = 30;
4092
4245
  var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
4093
4246
  "Button",
@@ -4137,7 +4290,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
4137
4290
  var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
4138
4291
  var ENGLISH = /^[A-Za-z0-9_]*$/;
4139
4292
  function isLocalesFile(filename) {
4140
- const segments = path34.resolve(filename).split(path34.sep);
4293
+ const segments = path35.resolve(filename).split(path35.sep);
4141
4294
  const srcIdx = segments.lastIndexOf("src");
4142
4295
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4143
4296
  }
@@ -4209,7 +4362,7 @@ var localeKeyShapeRule = {
4209
4362
 
4210
4363
  // eslint/rules/locale-placement.ts
4211
4364
  import { readFileSync as readFileSync7 } from "fs";
4212
- import path35 from "path";
4365
+ import path36 from "path";
4213
4366
  import ts6 from "typescript";
4214
4367
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
4215
4368
  var camelCase = (name) => name.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase());
@@ -4256,7 +4409,7 @@ var localePlacementRule = {
4256
4409
  },
4257
4410
  create(context) {
4258
4411
  const sourceRoot = sourceRootOf(context);
4259
- const file = path35.resolve(context.filename);
4412
+ const file = path36.resolve(context.filename);
4260
4413
  const segments = segmentsOf(file, sourceRoot);
4261
4414
  if (segments.length === 0) return {};
4262
4415
  const index = getProjectIndex(sourceRoot);
@@ -4334,9 +4487,9 @@ var localePlacementRule = {
4334
4487
  };
4335
4488
 
4336
4489
  // eslint/rules/locales-location.ts
4337
- import path36 from "path";
4490
+ import path37 from "path";
4338
4491
  function isLocalesFile2(filename) {
4339
- const segments = path36.resolve(filename).split(path36.sep);
4492
+ const segments = path37.resolve(filename).split(path37.sep);
4340
4493
  const srcIdx = segments.lastIndexOf("src");
4341
4494
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4342
4495
  }
@@ -4416,7 +4569,7 @@ var localesLocationRule = {
4416
4569
  create(context) {
4417
4570
  if (isLocalesFile2(context.filename) || isTestFile(context.filename)) return {};
4418
4571
  const filename = context.filename;
4419
- const segments = path36.resolve(filename).split(path36.sep);
4572
+ const segments = path37.resolve(filename).split(path37.sep);
4420
4573
  const srcIdx = segments.lastIndexOf("src");
4421
4574
  if (srcIdx === -1) return {};
4422
4575
  const folder = segments[srcIdx + 1];
@@ -4501,7 +4654,7 @@ var localesLocationRule = {
4501
4654
  };
4502
4655
 
4503
4656
  // eslint/rules/named-exports.ts
4504
- import path37 from "path";
4657
+ import path38 from "path";
4505
4658
  var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
4506
4659
  // App Router routing files
4507
4660
  "default",
@@ -4523,9 +4676,9 @@ var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
4523
4676
  "twitter-image"
4524
4677
  ]);
4525
4678
  function isFrameworkDefaultExportFile(filename) {
4526
- const normalized = filename.replaceAll(path37.sep, "/");
4679
+ const normalized = filename.replaceAll(path38.sep, "/");
4527
4680
  if (!normalized.includes("/src/app/")) return false;
4528
- const basename = path37.basename(filename, path37.extname(filename));
4681
+ const basename = path38.basename(filename, path38.extname(filename));
4529
4682
  return FRAMEWORK_DEFAULT_EXPORT_FILES.has(basename);
4530
4683
  }
4531
4684
  var namedExportsRule = {
@@ -4788,8 +4941,8 @@ var noMixedConcernsRule = {
4788
4941
  };
4789
4942
 
4790
4943
  // eslint/rules/no-redundant-alias.ts
4791
- import path38 from "path";
4792
- var DOC3 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
4944
+ import path39 from "path";
4945
+ var DOC4 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
4793
4946
  var VALUE_SENTINELS = /* @__PURE__ */ new Set(["undefined", "NaN", "Infinity"]);
4794
4947
  var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
4795
4948
  var PRIMITIVE_TYPE_NAMES = {
@@ -4821,7 +4974,7 @@ function aliasedTypeName(annotation) {
4821
4974
  function aliasMessage(alias, source) {
4822
4975
  const aliasName = alias ?? "This declaration";
4823
4976
  const sourceName = source ?? "the original symbol";
4824
- return `"${aliasName}" only renames "${sourceName}". Use "${sourceName}" directly or rename the original symbol and its consumers. ${DOC3}`;
4977
+ return `"${aliasName}" only renames "${sourceName}". Use "${sourceName}" directly or rename the original symbol and its consumers. ${DOC4}`;
4825
4978
  }
4826
4979
  var noRedundantAliasRule = {
4827
4980
  meta: {
@@ -4838,7 +4991,7 @@ var noRedundantAliasRule = {
4838
4991
  const declaration = node.parent;
4839
4992
  if (declaration.type !== "VariableDeclaration" || declaration.kind !== "const") return;
4840
4993
  const exported = declaration.parent.type === "ExportNamedDeclaration";
4841
- const frameworkRouteAlias = path38.basename(context.filename) === "route.ts" && exported && HTTP_METHODS.has(node.id.name);
4994
+ const frameworkRouteAlias = path39.basename(context.filename) === "route.ts" && exported && HTTP_METHODS.has(node.id.name);
4842
4995
  if (frameworkRouteAlias || VALUE_SENTINELS.has(node.init.name)) return;
4843
4996
  context.report({
4844
4997
  node,
@@ -4862,7 +5015,7 @@ var noRedundantAliasRule = {
4862
5015
  const source = specifier.local.name;
4863
5016
  const alias = specifier.exported.name;
4864
5017
  if (source === alias) continue;
4865
- const frameworkRouteAlias = path38.basename(context.filename) === "route.ts" && HTTP_METHODS.has(alias);
5018
+ const frameworkRouteAlias = path39.basename(context.filename) === "route.ts" && HTTP_METHODS.has(alias);
4866
5019
  if (frameworkRouteAlias) continue;
4867
5020
  context.report({
4868
5021
  node: specifier,
@@ -4887,7 +5040,7 @@ var noRedundantAliasRule = {
4887
5040
  };
4888
5041
 
4889
5042
  // eslint/rules/no-util-barrel.ts
4890
- import path39 from "path";
5043
+ import path40 from "path";
4891
5044
  var noUtilBarrelRule = {
4892
5045
  meta: {
4893
5046
  schema: [],
@@ -4897,7 +5050,7 @@ var noUtilBarrelRule = {
4897
5050
  }
4898
5051
  },
4899
5052
  create(context) {
4900
- const filename = path39.resolve(context.filename);
5053
+ const filename = path40.resolve(context.filename);
4901
5054
  const sourceRoot = sourceRootOf3(context, filename);
4902
5055
  return {
4903
5056
  Program(node) {
@@ -4906,7 +5059,7 @@ var noUtilBarrelRule = {
4906
5059
  if (!target) continue;
4907
5060
  const segments = target.replace(/\\/g, "/").split("/");
4908
5061
  const utilsIndex = segments.lastIndexOf("utils");
4909
- if (utilsIndex < 0 || !path39.basename(target).startsWith("index.")) continue;
5062
+ if (utilsIndex < 0 || !path40.basename(target).startsWith("index.")) continue;
4910
5063
  context.report({
4911
5064
  node,
4912
5065
  message: `Import utilities directly instead of through "${specifier}". See docs/next-codebase-guide/rules/utilities-rule.md`
@@ -4926,10 +5079,10 @@ function importSpecifiers2(source) {
4926
5079
  return specifiers;
4927
5080
  }
4928
5081
  function sourceRootOf3(context, filename) {
4929
- const marker = `${path39.sep}src${path39.sep}`;
5082
+ const marker = `${path40.sep}src${path40.sep}`;
4930
5083
  const srcIndex = filename.lastIndexOf(marker);
4931
5084
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
4932
- return path39.resolve(context.cwd ?? process.cwd(), "src");
5085
+ return path40.resolve(context.cwd ?? process.cwd(), "src");
4933
5086
  }
4934
5087
 
4935
5088
  // eslint/rules/package-json/exact-version.ts
@@ -5148,7 +5301,7 @@ var nextjsStackRule = {
5148
5301
 
5149
5302
  // eslint/rules/package-json/vitest-coverage.ts
5150
5303
  import { existsSync as existsSync5, readFileSync as readFileSync8 } from "fs";
5151
- import path40 from "path";
5304
+ import path41 from "path";
5152
5305
  function memberName5(member) {
5153
5306
  return member.name.type === "String" ? member.name.value : member.name.name;
5154
5307
  }
@@ -5218,7 +5371,7 @@ var vitestCoverageRule = {
5218
5371
  message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
5219
5372
  });
5220
5373
  }
5221
- const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path40.join(context.cwd, name)));
5374
+ const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path41.join(context.cwd, name)));
5222
5375
  if (!configName) {
5223
5376
  context.report({
5224
5377
  node,
@@ -5226,7 +5379,7 @@ var vitestCoverageRule = {
5226
5379
  });
5227
5380
  return;
5228
5381
  }
5229
- const content = readFileSync8(path40.join(context.cwd, configName), "utf8");
5382
+ const content = readFileSync8(path41.join(context.cwd, configName), "utf8");
5230
5383
  for (const metric of THRESHOLD_METRICS) {
5231
5384
  if (!new RegExp(`\\b${metric}\\s*:\\s*[1-9]\\d*`).test(content)) {
5232
5385
  context.report({ node, message: `${configName} must set a coverage threshold above zero for ${metric}.` });
@@ -5272,7 +5425,7 @@ var nextjsPackageJsonRules = {
5272
5425
  };
5273
5426
 
5274
5427
  // eslint/rules/prefer-enum.ts
5275
- import path41 from "path";
5428
+ import path42 from "path";
5276
5429
  function isConstAssertion(node) {
5277
5430
  const typeAnnotation = node.typeAnnotation;
5278
5431
  return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
@@ -5324,9 +5477,9 @@ var preferEnumRule = {
5324
5477
  }
5325
5478
  },
5326
5479
  create(context) {
5327
- const filename = path41.resolve(context.filename);
5480
+ const filename = path42.resolve(context.filename);
5328
5481
  const sourceRoot = sourceRootOf(context);
5329
- if (!filename.startsWith(sourceRoot + path41.sep)) return {};
5482
+ if (!filename.startsWith(sourceRoot + path42.sep)) return {};
5330
5483
  const objectSchemas = /* @__PURE__ */ new Map();
5331
5484
  const discriminatedUnions = [];
5332
5485
  const reportedDiscriminants = /* @__PURE__ */ new Set();
@@ -5397,7 +5550,7 @@ var preferEnumRule = {
5397
5550
  };
5398
5551
 
5399
5552
  // eslint/rules/pure-function-extract.ts
5400
- import path42 from "path";
5553
+ import path43 from "path";
5401
5554
  var ROUTE_HANDLER_EXPORT_NAMES = /* @__PURE__ */ new Set([
5402
5555
  "GET",
5403
5556
  "POST",
@@ -5462,12 +5615,12 @@ var pureFunctionExtractRule = {
5462
5615
  },
5463
5616
  create(context) {
5464
5617
  const filename = context.filename;
5465
- const isRouteFile = path42.basename(filename) === "route.ts";
5618
+ const isRouteFile = path43.basename(filename) === "route.ts";
5466
5619
  const isComponentFile = filename.endsWith(".tsx") || filename.endsWith(".jsx");
5467
5620
  const sourceRoot = sourceRootOf(context);
5468
- const relative = path42.relative(sourceRoot, filename);
5621
+ const relative = path43.relative(sourceRoot, filename);
5469
5622
  if (relative.startsWith("..")) return {};
5470
- const segments = relative.split(path42.sep);
5623
+ const segments = relative.split(path43.sep);
5471
5624
  const folders = segments.slice(0, -1);
5472
5625
  const isHookSupportFile = folders.includes("hooks") && /\.(?:[cm]?[jt]s)$/.test(filename);
5473
5626
  if (!isComponentFile && !isRouteFile && !isHookSupportFile) return {};
@@ -5708,7 +5861,7 @@ var repeatedStructureRule = {
5708
5861
 
5709
5862
  // eslint/rules/require-barrel-star-exports.ts
5710
5863
  import fs5 from "fs";
5711
- import path43 from "path";
5864
+ import path44 from "path";
5712
5865
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
5713
5866
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
5714
5867
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
@@ -5716,9 +5869,9 @@ function resolveSiblingModule(indexFile, specifier) {
5716
5869
  if (!specifier.startsWith("./")) return void 0;
5717
5870
  const relative = specifier.slice(2);
5718
5871
  if (!relative || relative.includes("/")) return void 0;
5719
- const directory = path43.dirname(indexFile);
5720
- const direct = path43.resolve(directory, relative);
5721
- const candidates = path43.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
5872
+ const directory = path44.dirname(indexFile);
5873
+ const direct = path44.resolve(directory, relative);
5874
+ const candidates = path44.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
5722
5875
  return candidates.find((candidate) => fs5.existsSync(candidate) && fs5.statSync(candidate).isFile());
5723
5876
  }
5724
5877
  var requireBarrelStarExportsRule = {
@@ -5731,9 +5884,9 @@ var requireBarrelStarExportsRule = {
5731
5884
  fixable: "code"
5732
5885
  },
5733
5886
  create(context) {
5734
- const filename = path43.resolve(context.filename);
5735
- if (!INDEX_NAMES.has(path43.basename(filename))) return {};
5736
- if (!SUPPORT_FOLDERS3.has(path43.basename(path43.dirname(filename)))) return {};
5887
+ const filename = path44.resolve(context.filename);
5888
+ if (!INDEX_NAMES.has(path44.basename(filename))) return {};
5889
+ if (!SUPPORT_FOLDERS3.has(path44.basename(path44.dirname(filename)))) return {};
5737
5890
  return {
5738
5891
  ExportNamedDeclaration(node) {
5739
5892
  const sourceNode = node.source;
@@ -5786,7 +5939,7 @@ var requireBarrelStarExportsRule = {
5786
5939
  };
5787
5940
 
5788
5941
  // eslint/rules/root-support-placement.ts
5789
- import path44 from "path";
5942
+ import path45 from "path";
5790
5943
  function isSupportFolder(value) {
5791
5944
  return value === "utils" || value === "types" || value === "schemas" || value === "constants";
5792
5945
  }
@@ -5819,7 +5972,7 @@ var rootSupportPlacementRule = {
5819
5972
  },
5820
5973
  create(context) {
5821
5974
  const sourceRoot = sourceRootOf(context);
5822
- const file = path44.resolve(context.filename);
5975
+ const file = path45.resolve(context.filename);
5823
5976
  const segments = segmentsOf(file, sourceRoot);
5824
5977
  const folderSegments = folderSegmentsOf(file, sourceRoot);
5825
5978
  const supportFolder = folderSegments[folderSegments.length - 1];
@@ -5859,7 +6012,7 @@ var rootSupportPlacementRule = {
5859
6012
  };
5860
6013
 
5861
6014
  // eslint/rules/route-handler-shape.ts
5862
- import path45 from "path";
6015
+ import path46 from "path";
5863
6016
  import ts7 from "typescript";
5864
6017
  var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
5865
6018
  var REQUIRED_BOUNDARY = "withResponse";
@@ -5944,7 +6097,7 @@ var routeHandlerShapeRule = {
5944
6097
  }
5945
6098
  },
5946
6099
  create(context) {
5947
- if (path45.basename(context.filename) !== "route.ts") return {};
6100
+ if (path46.basename(context.filename) !== "route.ts") return {};
5948
6101
  const sourceText = context.sourceCode.text;
5949
6102
  function reportUnwrapped(node, name) {
5950
6103
  context.report({
@@ -6003,7 +6156,7 @@ var routeHandlerShapeRule = {
6003
6156
  };
6004
6157
 
6005
6158
  // eslint/rules/schema-casing.ts
6006
- import path46 from "path";
6159
+ import path47 from "path";
6007
6160
  function isCamelCase(name) {
6008
6161
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
6009
6162
  }
@@ -6031,9 +6184,9 @@ var schemaCasingRule = {
6031
6184
  }
6032
6185
  },
6033
6186
  create(context) {
6034
- const filename = path46.resolve(context.filename);
6187
+ const filename = path47.resolve(context.filename);
6035
6188
  const sourceRoot = sourceRootOf(context);
6036
- if (!filename.startsWith(sourceRoot + path46.sep)) return {};
6189
+ if (!filename.startsWith(sourceRoot + path47.sep)) return {};
6037
6190
  let zodLocalName;
6038
6191
  return {
6039
6192
  ImportDeclaration(node) {
@@ -6065,7 +6218,7 @@ var schemaCasingRule = {
6065
6218
  };
6066
6219
 
6067
6220
  // eslint/rules/sole-state-owner.ts
6068
- import path47 from "path";
6221
+ import path48 from "path";
6069
6222
  import ts8 from "typescript";
6070
6223
  function findStateHooks(node) {
6071
6224
  const hooks = [];
@@ -6145,7 +6298,7 @@ var soleStateOwnerRule = {
6145
6298
  }
6146
6299
  },
6147
6300
  create(context) {
6148
- const filename = path47.resolve(context.filename);
6301
+ const filename = path48.resolve(context.filename);
6149
6302
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
6150
6303
  const text = context.sourceCode.text;
6151
6304
  const components = parseComponentInfo(text, filename);
@@ -6224,7 +6377,7 @@ function usesOutsideJsx(declaration, hook, children) {
6224
6377
  }
6225
6378
 
6226
6379
  // eslint/rules/source-under-src.ts
6227
- import path48 from "path";
6380
+ import path49 from "path";
6228
6381
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
6229
6382
  ".agents",
6230
6383
  ".cache",
@@ -6265,14 +6418,14 @@ var sourceUnderSrcRule = {
6265
6418
  }
6266
6419
  },
6267
6420
  create(context) {
6268
- const filename = path48.resolve(context.filename);
6421
+ const filename = path49.resolve(context.filename);
6269
6422
  if (!MODULE_EXTENSION.test(filename)) return {};
6270
- const relative = path48.relative(context.cwd, filename).replace(/\\/g, "/");
6423
+ const relative = path49.relative(context.cwd, filename).replace(/\\/g, "/");
6271
6424
  if (relative === "src" || relative.startsWith("src/")) return {};
6272
6425
  const topLevel = relative.split("/")[0] ?? "";
6273
6426
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
6274
6427
  if (!relative.includes("/")) {
6275
- const basename = path48.basename(filename);
6428
+ const basename = path49.basename(filename);
6276
6429
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
6277
6430
  }
6278
6431
  return {
@@ -6288,7 +6441,7 @@ var sourceUnderSrcRule = {
6288
6441
  };
6289
6442
 
6290
6443
  // eslint/rules/stay-flat.ts
6291
- import path49 from "path";
6444
+ import path50 from "path";
6292
6445
  var stayFlatRule = {
6293
6446
  meta: {
6294
6447
  schema: [],
@@ -6299,7 +6452,7 @@ var stayFlatRule = {
6299
6452
  },
6300
6453
  create(context) {
6301
6454
  const sourceRoot = sourceRootOf(context);
6302
- const file = path49.resolve(context.filename);
6455
+ const file = path50.resolve(context.filename);
6303
6456
  const segments = segmentsOf(file, sourceRoot);
6304
6457
  if (segments.length !== 3 || segments[0] !== "features") return {};
6305
6458
  const index = getProjectIndex(sourceRoot);
@@ -6339,7 +6492,7 @@ var stayFlatRule = {
6339
6492
  };
6340
6493
 
6341
6494
  // eslint/rules/support-file-placement.ts
6342
- import path50 from "path";
6495
+ import path51 from "path";
6343
6496
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
6344
6497
  var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
6345
6498
  ["constants", "constant"],
@@ -6364,7 +6517,7 @@ var supportFilePlacementRule = {
6364
6517
  },
6365
6518
  create(context) {
6366
6519
  const sourceRoot = sourceRootOf(context);
6367
- const supportFile = path50.resolve(context.filename);
6520
+ const supportFile = path51.resolve(context.filename);
6368
6521
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
6369
6522
  const supportFolder = currentFolder[currentFolder.length - 1];
6370
6523
  if (supportFolder === void 0 || !SUPPORT_FOLDERS.has(supportFolder)) return {};
@@ -6418,7 +6571,7 @@ var supportFilePlacementRule = {
6418
6571
 
6419
6572
  // eslint/rules/support-folder-shape.ts
6420
6573
  import fs6 from "fs";
6421
- import path51 from "path";
6574
+ import path52 from "path";
6422
6575
  var SUPPORT_FOLDERS4 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
6423
6576
  var INDEX_NAMES2 = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
6424
6577
  var supportFolderShapeRule = {
@@ -6430,12 +6583,12 @@ var supportFolderShapeRule = {
6430
6583
  }
6431
6584
  },
6432
6585
  create(context) {
6433
- const filename = path51.resolve(context.filename);
6434
- const baseName = path51.basename(filename);
6586
+ const filename = path52.resolve(context.filename);
6587
+ const baseName = path52.basename(filename);
6435
6588
  if (!INDEX_NAMES2.has(baseName)) return {};
6436
- const folder = path51.basename(path51.dirname(filename));
6589
+ const folder = path52.basename(path52.dirname(filename));
6437
6590
  if (!SUPPORT_FOLDERS4.has(folder)) return {};
6438
- const directory = path51.dirname(filename);
6591
+ const directory = path52.dirname(filename);
6439
6592
  let entries;
6440
6593
  try {
6441
6594
  entries = fs6.readdirSync(directory);
@@ -6453,7 +6606,7 @@ var supportFolderShapeRule = {
6453
6606
  for (const match of source.matchAll(exportPattern)) {
6454
6607
  hasAnyReExport = true;
6455
6608
  const specifier = match.groups?.specifier;
6456
- if (specifier?.startsWith(".")) exportedFiles.add(path51.basename(specifier));
6609
+ if (specifier?.startsWith(".")) exportedFiles.add(path52.basename(specifier));
6457
6610
  }
6458
6611
  const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
6459
6612
  if (siblingModules.length === 0) {
@@ -6632,11 +6785,11 @@ var baseLayerPairRule = {
6632
6785
 
6633
6786
  // eslint/rules/tailwind/css-entry-point.ts
6634
6787
  import { statSync as statSync4 } from "fs";
6635
- import path54 from "path";
6788
+ import path55 from "path";
6636
6789
 
6637
6790
  // eslint/rules/tailwind/source-files.ts
6638
6791
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
6639
- import path52 from "path";
6792
+ import path53 from "path";
6640
6793
  var CSS_EXTENSIONS = [".css"];
6641
6794
  var MODULE_EXTENSIONS4 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
6642
6795
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS4, ...CSS_EXTENSIONS];
@@ -6649,7 +6802,7 @@ function findFiles(dir, extensions) {
6649
6802
  }
6650
6803
  return entries.flatMap((entry) => {
6651
6804
  if (entry.startsWith(".") || entry === "node_modules") return [];
6652
- const entryPath = path52.join(dir, entry);
6805
+ const entryPath = path53.join(dir, entry);
6653
6806
  let stats;
6654
6807
  try {
6655
6808
  stats = statSync3(entryPath);
@@ -6657,7 +6810,7 @@ function findFiles(dir, extensions) {
6657
6810
  return [];
6658
6811
  }
6659
6812
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
6660
- return extensions.includes(path52.extname(entry)) ? [entryPath] : [];
6813
+ return extensions.includes(path53.extname(entry)) ? [entryPath] : [];
6661
6814
  });
6662
6815
  }
6663
6816
  function cachedTextReader() {
@@ -6680,7 +6833,7 @@ function escapeRegExp(text) {
6680
6833
  }
6681
6834
 
6682
6835
  // eslint/rules/tailwind/stylesheet-graph.ts
6683
- import path53 from "path";
6836
+ import path54 from "path";
6684
6837
  function registersTailwind(text) {
6685
6838
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
6686
6839
  }
@@ -6694,25 +6847,25 @@ function moduleImports(text, fileName) {
6694
6847
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
6695
6848
  }
6696
6849
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
6697
- if (spec.startsWith("/")) return path53.resolve(spec);
6698
- if (spec.startsWith("./") || spec.startsWith("../")) return path53.resolve(path53.dirname(fromFile), spec);
6699
- if (spec.startsWith("@/")) return path53.resolve(sourceRoot, spec.slice(2));
6850
+ if (spec.startsWith("/")) return path54.resolve(spec);
6851
+ if (spec.startsWith("./") || spec.startsWith("../")) return path54.resolve(path54.dirname(fromFile), spec);
6852
+ if (spec.startsWith("@/")) return path54.resolve(sourceRoot, spec.slice(2));
6700
6853
  return void 0;
6701
6854
  }
6702
6855
  function buildStylesheetGraph(options) {
6703
6856
  const { cssFiles, sourceRoot, textOf } = options;
6704
- const cssSet = new Set(cssFiles.map((file) => path53.normalize(file)));
6857
+ const cssSet = new Set(cssFiles.map((file) => path54.normalize(file)));
6705
6858
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
6706
6859
  const reachable = /* @__PURE__ */ new Set();
6707
6860
  const queue = [...globals];
6708
- for (const global of globals) reachable.add(path53.normalize(global));
6861
+ for (const global of globals) reachable.add(path54.normalize(global));
6709
6862
  while (queue.length > 0) {
6710
6863
  const from = queue.shift();
6711
6864
  if (!from) continue;
6712
6865
  for (const spec of importedSpecifiers(textOf(from))) {
6713
6866
  const target = resolveSpecifier2(from, spec, sourceRoot);
6714
6867
  if (!target) continue;
6715
- const normalized = path53.normalize(target);
6868
+ const normalized = path54.normalize(target);
6716
6869
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
6717
6870
  reachable.add(normalized);
6718
6871
  queue.push(normalized);
@@ -6724,7 +6877,7 @@ function buildStylesheetGraph(options) {
6724
6877
  for (const spec of importedSpecifiers(textOf(global))) {
6725
6878
  const target = resolveSpecifier2(global, spec, sourceRoot);
6726
6879
  if (!target) continue;
6727
- const normalized = path53.normalize(target);
6880
+ const normalized = path54.normalize(target);
6728
6881
  if (cssSet.has(normalized)) directChildren.add(normalized);
6729
6882
  }
6730
6883
  }
@@ -6732,8 +6885,8 @@ function buildStylesheetGraph(options) {
6732
6885
  }
6733
6886
 
6734
6887
  // eslint/rules/tailwind/css-entry-point.ts
6735
- var APP_STYLES_DIR = path54.join("app", "styles");
6736
- var GLOBAL_STYLESHEET_PATH = path54.join(APP_STYLES_DIR, "globals.css");
6888
+ var APP_STYLES_DIR = path55.join("app", "styles");
6889
+ var GLOBAL_STYLESHEET_PATH = path55.join(APP_STYLES_DIR, "globals.css");
6737
6890
  var cssEntryPointRule = {
6738
6891
  meta: {
6739
6892
  schema: [],
@@ -6759,8 +6912,8 @@ var cssEntryPointRule = {
6759
6912
  return {
6760
6913
  "StyleSheet:exit"(node) {
6761
6914
  if (globals.length === 0) return;
6762
- const current = path54.normalize(path54.resolve(context.filename));
6763
- const relative = path54.relative(sourceRoot, current);
6915
+ const current = path55.normalize(path55.resolve(context.filename));
6916
+ const relative = path55.relative(sourceRoot, current);
6764
6917
  if (globals.includes(current)) {
6765
6918
  if (globals.length > 1) {
6766
6919
  context.report({
@@ -6776,7 +6929,7 @@ var cssEntryPointRule = {
6776
6929
  });
6777
6930
  return;
6778
6931
  }
6779
- const basename = path54.basename(current);
6932
+ const basename = path55.basename(current);
6780
6933
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
6781
6934
  if (importCount !== 1) {
6782
6935
  context.report({
@@ -6786,7 +6939,7 @@ var cssEntryPointRule = {
6786
6939
  }
6787
6940
  return;
6788
6941
  }
6789
- const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path54.sep}`);
6942
+ const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path55.sep}`);
6790
6943
  if (!isInAppStyles) {
6791
6944
  context.report({
6792
6945
  node,
@@ -7275,7 +7428,7 @@ var tailwindRules = {
7275
7428
  };
7276
7429
 
7277
7430
  // eslint/rules/type-extraction.ts
7278
- import path55 from "path";
7431
+ import path56 from "path";
7279
7432
  var typeExtractionRule = {
7280
7433
  meta: {
7281
7434
  schema: [],
@@ -7286,7 +7439,7 @@ var typeExtractionRule = {
7286
7439
  },
7287
7440
  create(context) {
7288
7441
  const sourceRoot = sourceRootOf(context);
7289
- const file = path55.resolve(context.filename);
7442
+ const file = path56.resolve(context.filename);
7290
7443
  const segments = segmentsOf(file, sourceRoot);
7291
7444
  if (segments.length === 0) return {};
7292
7445
  const index = getProjectIndex(sourceRoot);
@@ -7421,7 +7574,7 @@ var uiStateRule = {
7421
7574
  // eslint/rules/unknown-utility.ts
7422
7575
  import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
7423
7576
  import { createRequire } from "module";
7424
- import path56 from "path";
7577
+ import path57 from "path";
7425
7578
  var PREFIX_NAMESPACES = {
7426
7579
  bg: ["color"],
7427
7580
  text: ["color", "text"],
@@ -7661,7 +7814,7 @@ function stylesheetFiles(dir) {
7661
7814
  }
7662
7815
  return entries.flatMap((entry) => {
7663
7816
  if (entry.startsWith(".") || entry === "node_modules") return [];
7664
- const entryPath = path56.join(dir, entry);
7817
+ const entryPath = path57.join(dir, entry);
7665
7818
  let stats;
7666
7819
  try {
7667
7820
  stats = statSync6(entryPath);
@@ -7669,7 +7822,7 @@ function stylesheetFiles(dir) {
7669
7822
  return [];
7670
7823
  }
7671
7824
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
7672
- return path56.extname(entry) === ".css" ? [entryPath] : [];
7825
+ return path57.extname(entry) === ".css" ? [entryPath] : [];
7673
7826
  });
7674
7827
  }
7675
7828
  function packageNameOf(specifier) {
@@ -7680,10 +7833,10 @@ function packageNameOf(specifier) {
7680
7833
  function resolvePackageStylesheet(fromFile, specifier) {
7681
7834
  const packageName = packageNameOf(specifier);
7682
7835
  if (!packageName || packageName === "tailwindcss") return void 0;
7683
- let directory = path56.dirname(fromFile);
7684
- while (directory !== path56.dirname(directory)) {
7685
- const packageRoot = path56.join(directory, "node_modules", packageName);
7686
- const manifestPath = path56.join(packageRoot, "package.json");
7836
+ let directory = path57.dirname(fromFile);
7837
+ while (directory !== path57.dirname(directory)) {
7838
+ const packageRoot = path57.join(directory, "node_modules", packageName);
7839
+ const manifestPath = path57.join(packageRoot, "package.json");
7687
7840
  if (existsSync6(manifestPath)) {
7688
7841
  try {
7689
7842
  const manifest = readFileSync10(manifestPath, "utf8");
@@ -7691,13 +7844,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
7691
7844
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
7692
7845
  const target = stylesheet ?? main;
7693
7846
  if (!target) return void 0;
7694
- const resolved = path56.resolve(packageRoot, target);
7847
+ const resolved = path57.resolve(packageRoot, target);
7695
7848
  return existsSync6(resolved) ? resolved : void 0;
7696
7849
  } catch {
7697
7850
  return void 0;
7698
7851
  }
7699
7852
  }
7700
- directory = path56.dirname(directory);
7853
+ directory = path57.dirname(directory);
7701
7854
  }
7702
7855
  return void 0;
7703
7856
  }
@@ -7948,7 +8101,7 @@ var unknownUtilityRule = {
7948
8101
  };
7949
8102
 
7950
8103
  // eslint/rules/util-file-name.ts
7951
- import path57 from "path";
8104
+ import path58 from "path";
7952
8105
  function toKebabCase2(value) {
7953
8106
  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();
7954
8107
  }
@@ -7961,7 +8114,7 @@ var utilFileNameRule = {
7961
8114
  }
7962
8115
  },
7963
8116
  create(context) {
7964
- const filename = path57.resolve(context.filename);
8117
+ const filename = path58.resolve(context.filename);
7965
8118
  const segments = filename.replace(/\\/g, "/").split("/");
7966
8119
  if (!segments.includes("utils")) return {};
7967
8120
  let module;
@@ -7975,13 +8128,13 @@ var utilFileNameRule = {
7975
8128
  const functionName = functions[0]?.name;
7976
8129
  if (!functionName) return {};
7977
8130
  const expected = toKebabCase2(functionName);
7978
- const actual = path57.basename(filename, path57.extname(filename));
8131
+ const actual = path58.basename(filename, path58.extname(filename));
7979
8132
  if (!expected || actual === expected) return {};
7980
8133
  return {
7981
8134
  Program(node) {
7982
8135
  context.report({
7983
8136
  node,
7984
- message: `A utility file exporting ${functionName} must be named ${expected}.${path57.extname(filename).slice(1)}.`
8137
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path58.extname(filename).slice(1)}.`
7985
8138
  });
7986
8139
  }
7987
8140
  };
@@ -7989,7 +8142,7 @@ var utilFileNameRule = {
7989
8142
  };
7990
8143
 
7991
8144
  // eslint/rules/value-extraction.ts
7992
- import path58 from "path";
8145
+ import path59 from "path";
7993
8146
  var valueExtractionRule = {
7994
8147
  meta: {
7995
8148
  schema: [],
@@ -8000,7 +8153,7 @@ var valueExtractionRule = {
8000
8153
  },
8001
8154
  create(context) {
8002
8155
  const sourceRoot = sourceRootOf(context);
8003
- const file = path58.resolve(context.filename);
8156
+ const file = path59.resolve(context.filename);
8004
8157
  const segments = segmentsOf(file, sourceRoot);
8005
8158
  if (segments.length === 0 || segments[0] !== "app") return {};
8006
8159
  const index = getProjectIndex(sourceRoot);
@@ -8022,7 +8175,7 @@ var valueExtractionRule = {
8022
8175
 
8023
8176
  // eslint/rules/vulyk/tracked-docs.ts
8024
8177
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "fs";
8025
- import path59 from "path";
8178
+ import path60 from "path";
8026
8179
  var PASIKA_REPO = "Bredansky/pasika";
8027
8180
  var BASE_REQUIRED_TRACKED_DOCS = [
8028
8181
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -8055,8 +8208,8 @@ var trackedDocsRule = {
8055
8208
  if (!context.filename.endsWith("package.json")) return;
8056
8209
  const root = node.body;
8057
8210
  if (root.type !== "Object") return;
8058
- const projectRoot = path59.dirname(path59.resolve(context.filename));
8059
- const configPath = path59.join(projectRoot, "vulyk.config.ts");
8211
+ const projectRoot = path60.dirname(path60.resolve(context.filename));
8212
+ const configPath = path60.join(projectRoot, "vulyk.config.ts");
8060
8213
  if (!existsSync7(configPath)) {
8061
8214
  context.report({
8062
8215
  node,
@@ -8081,7 +8234,7 @@ var trackedDocsRule = {
8081
8234
  });
8082
8235
  }
8083
8236
  }
8084
- const agentsPath = path59.join(projectRoot, "AGENTS.md");
8237
+ const agentsPath = path60.join(projectRoot, "AGENTS.md");
8085
8238
  if (!existsSync7(agentsPath)) {
8086
8239
  context.report({
8087
8240
  node,
@@ -8140,12 +8293,12 @@ var vulykRules = {
8140
8293
  };
8141
8294
 
8142
8295
  // eslint/rules/with-response-helper.ts
8143
- var HELPER2 = "withResponse";
8144
- var ENTRY2 = "pasika/with-response";
8145
- var DOC4 = "docs/pasika-adoption-guide/rules/with-response-helper-rule.md";
8146
- var DECLARED2 = `A repository must not declare its own ${HELPER2}; import it from ${ENTRY2}. See ${DOC4}`;
8147
- var IMPORTED2 = `${HELPER2} must be imported from ${ENTRY2}. See ${DOC4}`;
8148
- function isNamed2(node, name) {
8296
+ var HELPER3 = "withResponse";
8297
+ var ENTRY3 = "pasika/with-response";
8298
+ var DOC5 = "docs/pasika-adoption-guide/rules/with-response-helper-rule.md";
8299
+ var DECLARED3 = `A repository must not declare its own ${HELPER3}; import it from ${ENTRY3}. See ${DOC5}`;
8300
+ var IMPORTED3 = `${HELPER3} must be imported from ${ENTRY3}. See ${DOC5}`;
8301
+ function isNamed3(node, name) {
8149
8302
  return node?.type === "Identifier" && node.name === name;
8150
8303
  }
8151
8304
  var withResponseHelperRule = {
@@ -8153,24 +8306,24 @@ var withResponseHelperRule = {
8153
8306
  schema: [],
8154
8307
  type: "problem",
8155
8308
  docs: {
8156
- description: `Require ${HELPER2} to be imported from ${ENTRY2} rather than declared in the repository.`
8309
+ description: `Require ${HELPER3} to be imported from ${ENTRY3} rather than declared in the repository.`
8157
8310
  }
8158
8311
  },
8159
8312
  create(context) {
8160
8313
  const checkSource = (node) => {
8161
- if (!node.source || node.source.value === ENTRY2) return;
8314
+ if (!node.source || node.source.value === ENTRY3) return;
8162
8315
  for (const specifier of node.specifiers) {
8163
- if (!isNamed2(specifier.local, HELPER2)) continue;
8164
- context.report({ node: specifier, message: IMPORTED2 });
8316
+ if (!isNamed3(specifier.local, HELPER3)) continue;
8317
+ context.report({ node: specifier, message: IMPORTED3 });
8165
8318
  }
8166
8319
  };
8167
8320
  return {
8168
8321
  FunctionDeclaration(node) {
8169
- if (isNamed2(node.id, HELPER2)) context.report({ node, message: DECLARED2 });
8322
+ if (isNamed3(node.id, HELPER3)) context.report({ node, message: DECLARED3 });
8170
8323
  },
8171
8324
  VariableDeclarator(node) {
8172
- if (isNamed2(node.id.type === "Identifier" ? node.id : null, HELPER2)) {
8173
- context.report({ node, message: DECLARED2 });
8325
+ if (isNamed3(node.id.type === "Identifier" ? node.id : null, HELPER3)) {
8326
+ context.report({ node, message: DECLARED3 });
8174
8327
  }
8175
8328
  },
8176
8329
  ImportDeclaration: checkSource,
@@ -8181,7 +8334,7 @@ var withResponseHelperRule = {
8181
8334
 
8182
8335
  // eslint/rules/zirka-baseline.ts
8183
8336
  import fs7 from "fs";
8184
- import path60 from "path";
8337
+ import path61 from "path";
8185
8338
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
8186
8339
  var PRETTIER_CONFIGS = [
8187
8340
  "prettier.config.mjs",
@@ -8200,10 +8353,10 @@ var zirkaBaselineRule = {
8200
8353
  }
8201
8354
  },
8202
8355
  create(context) {
8203
- const filename = path60.resolve(context.filename);
8204
- const basename = path60.basename(filename);
8356
+ const filename = path61.resolve(context.filename);
8357
+ const basename = path61.basename(filename);
8205
8358
  if (!ESLINT_CONFIG.test(basename)) return {};
8206
- const projectRoot = path60.dirname(filename);
8359
+ const projectRoot = path61.dirname(filename);
8207
8360
  const report3 = (message) => {
8208
8361
  context.report({
8209
8362
  node: context.sourceCode.ast,
@@ -8218,7 +8371,7 @@ var zirkaBaselineRule = {
8218
8371
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
8219
8372
  );
8220
8373
  }
8221
- const tsconfigPath = path60.join(projectRoot, "tsconfig.json");
8374
+ const tsconfigPath = path61.join(projectRoot, "tsconfig.json");
8222
8375
  if (!fs7.existsSync(tsconfigPath)) {
8223
8376
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
8224
8377
  } else {
@@ -8236,13 +8389,13 @@ var zirkaBaselineRule = {
8236
8389
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
8237
8390
  }
8238
8391
  }
8239
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path60.join(projectRoot, name)));
8392
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path61.join(projectRoot, name)));
8240
8393
  if (!prettierConfigFile) {
8241
8394
  report3(
8242
8395
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
8243
8396
  );
8244
8397
  } else {
8245
- const content = fs7.readFileSync(path60.join(projectRoot, prettierConfigFile), "utf8");
8398
+ const content = fs7.readFileSync(path61.join(projectRoot, prettierConfigFile), "utf8");
8246
8399
  if (!content.includes("zirka")) {
8247
8400
  report3(
8248
8401
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -8263,36 +8416,36 @@ function referencesZirka(sourceCode) {
8263
8416
  }
8264
8417
 
8265
8418
  // eslint/rules/zod-fetch-helper.ts
8266
- var HELPER3 = "zodFetch";
8267
- var ENTRY3 = "pasika/zod-fetch";
8268
- var DOC5 = "docs/pasika-adoption-guide/rules/zod-fetch-helper-rule.md";
8269
- var FETCHED = `fetch must not be called; make the request through ${HELPER3} from ${ENTRY3}. See ${DOC5}`;
8270
- var DECLARED3 = `A file must not declare its own ${HELPER3}; import it from ${ENTRY3}. See ${DOC5}`;
8271
- var IMPORTED3 = `${HELPER3} must be imported from ${ENTRY3}. See ${DOC5}`;
8419
+ var HELPER4 = "zodFetch";
8420
+ var ENTRY4 = "pasika/zod-fetch";
8421
+ var DOC6 = "docs/pasika-adoption-guide/rules/zod-fetch-helper-rule.md";
8422
+ var FETCHED = `fetch must not be called; make the request through ${HELPER4} from ${ENTRY4}. See ${DOC6}`;
8423
+ var DECLARED4 = `A file must not declare its own ${HELPER4}; import it from ${ENTRY4}. See ${DOC6}`;
8424
+ var IMPORTED4 = `${HELPER4} must be imported from ${ENTRY4}. See ${DOC6}`;
8272
8425
  var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
8273
- var TEST_FILE = /(?:^|[\\/])(?:__tests__|tests)[\\/]|[.](?:test|spec)[.][cm]?[jt]sx?$/;
8274
- function isNamed3(node, name) {
8426
+ var TEST_FILE2 = /(?:^|[\\/])(?:__tests__|tests)[\\/]|[.](?:test|spec)[.][cm]?[jt]sx?$/;
8427
+ function isNamed4(node, name) {
8275
8428
  return node?.type === "Identifier" && node.name === name;
8276
8429
  }
8277
8430
  function callsFetch(callee) {
8278
- if (isNamed3(callee, "fetch")) return true;
8279
- return callee.type === "MemberExpression" && !callee.computed && isNamed3(callee.property, "fetch") && callee.object.type === "Identifier" && GLOBAL_OBJECTS.has(callee.object.name);
8431
+ if (isNamed4(callee, "fetch")) return true;
8432
+ return callee.type === "MemberExpression" && !callee.computed && isNamed4(callee.property, "fetch") && callee.object.type === "Identifier" && GLOBAL_OBJECTS.has(callee.object.name);
8280
8433
  }
8281
8434
  var zodFetchHelperRule = {
8282
8435
  meta: {
8283
8436
  schema: [],
8284
8437
  type: "problem",
8285
8438
  docs: {
8286
- description: `Require every request to go through the ${HELPER3} imported from ${ENTRY3}, the only caller of fetch.`
8439
+ description: `Require every request to go through the ${HELPER4} imported from ${ENTRY4}, the only caller of fetch.`
8287
8440
  }
8288
8441
  },
8289
8442
  create(context) {
8290
- if (TEST_FILE.test(context.filename)) return {};
8443
+ if (TEST_FILE2.test(context.filename)) return {};
8291
8444
  const checkSource = (node) => {
8292
- if (!node.source || node.source.value === ENTRY3) return;
8445
+ if (!node.source || node.source.value === ENTRY4) return;
8293
8446
  for (const specifier of node.specifiers) {
8294
- if (!isNamed3(specifier.local, HELPER3)) continue;
8295
- context.report({ node: specifier, message: IMPORTED3 });
8447
+ if (!isNamed4(specifier.local, HELPER4)) continue;
8448
+ context.report({ node: specifier, message: IMPORTED4 });
8296
8449
  }
8297
8450
  };
8298
8451
  return {
@@ -8301,11 +8454,11 @@ var zodFetchHelperRule = {
8301
8454
  context.report({ node, message: FETCHED });
8302
8455
  },
8303
8456
  FunctionDeclaration(node) {
8304
- if (isNamed3(node.id, HELPER3)) context.report({ node, message: DECLARED3 });
8457
+ if (isNamed4(node.id, HELPER4)) context.report({ node, message: DECLARED4 });
8305
8458
  },
8306
8459
  VariableDeclarator(node) {
8307
- if (isNamed3(node.id.type === "Identifier" ? node.id : null, HELPER3)) {
8308
- context.report({ node, message: DECLARED3 });
8460
+ if (isNamed4(node.id.type === "Identifier" ? node.id : null, HELPER4)) {
8461
+ context.report({ node, message: DECLARED4 });
8309
8462
  }
8310
8463
  },
8311
8464
  ImportDeclaration: checkSource,
@@ -8437,6 +8590,7 @@ function assertTypescriptAlignment() {
8437
8590
  // eslint/index.ts
8438
8591
  var pasikaNextjsAppRules = {
8439
8592
  // Framework-agnostic TypeScript rules.
8593
+ "api-contract": apiContractRule,
8440
8594
  "file-length": fileLengthRule,
8441
8595
  "filename-case": filenameCaseRule,
8442
8596
  "import-boundaries": importBoundariesRule,