pasika 0.10.52 → 0.10.54

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.
@@ -204,10 +204,12 @@ declare const pasikaPlugin: {
204
204
  "no-util-barrel": eslint.Rule.RuleModule;
205
205
  "no-redundant-alias": eslint.Rule.RuleModule;
206
206
  "enforce-barrel-exports": eslint.Rule.RuleModule;
207
+ "require-barrel-star-exports": eslint.Rule.RuleModule;
207
208
  "config-extraction": eslint.Rule.RuleModule;
208
209
  "value-extraction": eslint.Rule.RuleModule;
209
210
  "constant-casing": eslint.Rule.RuleModule;
210
211
  "prefer-enum": eslint.Rule.RuleModule;
212
+ "enum-placement": eslint.Rule.RuleModule;
211
213
  "type-extraction": eslint.Rule.RuleModule;
212
214
  "zod-schema-validation": eslint.Rule.RuleModule;
213
215
  "schema-casing": eslint.Rule.RuleModule;
@@ -229,6 +229,14 @@ function parseModule(file) {
229
229
  }
230
230
  continue;
231
231
  }
232
+ if (ts.isEnumDeclaration(statement)) {
233
+ exports.push({
234
+ name: statement.name.text,
235
+ kind: "constant",
236
+ line: lineOf(sourceFile, statement)
237
+ });
238
+ continue;
239
+ }
232
240
  if (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) {
233
241
  exports.push({
234
242
  name: statement.name.text,
@@ -2925,6 +2933,32 @@ var enforceCvaVariantPropsRule = {
2925
2933
  }
2926
2934
  };
2927
2935
 
2936
+ // eslint/rules/enum-placement.ts
2937
+ import path24 from "path";
2938
+ var enumPlacementRule = {
2939
+ meta: {
2940
+ schema: [],
2941
+ type: "problem",
2942
+ docs: {
2943
+ description: "Require TypeScript enum declarations to live in constants/ folders."
2944
+ }
2945
+ },
2946
+ create(context) {
2947
+ const filename = path24.resolve(context.filename);
2948
+ const sourceRoot = sourceRootOf(context);
2949
+ if (!filename.startsWith(sourceRoot + path24.sep)) return {};
2950
+ if (path24.basename(path24.dirname(filename)) === "constants") return {};
2951
+ return {
2952
+ TSEnumDeclaration(node) {
2953
+ context.report({
2954
+ node,
2955
+ message: "A TypeScript enum must live in a constants/ folder because it creates runtime values as well as a type. See docs/next-codebase-guide/rules/constants-rule.md"
2956
+ });
2957
+ }
2958
+ };
2959
+ }
2960
+ };
2961
+
2928
2962
  // eslint/rules/file-length.ts
2929
2963
  var MAX_SOURCE_FILE_LINES = 300;
2930
2964
  var fileLengthRule = {
@@ -2951,7 +2985,7 @@ var fileLengthRule = {
2951
2985
  };
2952
2986
 
2953
2987
  // eslint/rules/filename-case.ts
2954
- import path24 from "path";
2988
+ import path25 from "path";
2955
2989
  var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
2956
2990
  "page",
2957
2991
  "layout",
@@ -2997,11 +3031,11 @@ var filenameCaseRule = {
2997
3031
  if (!normalized.includes("/src/")) {
2998
3032
  return {};
2999
3033
  }
3000
- const ext = path24.extname(filename);
3001
- let base = path24.basename(filename, ext);
3002
- const baseExt = path24.extname(base);
3034
+ const ext = path25.extname(filename);
3035
+ let base = path25.basename(filename, ext);
3036
+ const baseExt = path25.extname(base);
3003
3037
  if (baseExt && COMPOUND_SUFFIXES.has(baseExt.slice(1))) {
3004
- base = path24.basename(base, baseExt);
3038
+ base = path25.basename(base, baseExt);
3005
3039
  }
3006
3040
  if (NEXT_ROUTING_FILES2.has(base)) {
3007
3041
  return {};
@@ -3014,21 +3048,21 @@ var filenameCaseRule = {
3014
3048
  if (component?.smart && !isPascalCase5(base)) {
3015
3049
  context.report({
3016
3050
  node,
3017
- message: `Smart component files must use PascalCase.tsx. Filename "${path24.basename(filename)}" is not PascalCase.`
3051
+ message: `Smart component files must use PascalCase.tsx. Filename "${path25.basename(filename)}" is not PascalCase.`
3018
3052
  });
3019
3053
  return;
3020
3054
  }
3021
3055
  if (component && !component.smart && !isKebabCase2(base)) {
3022
3056
  context.report({
3023
3057
  node,
3024
- message: `Dumb component files must use kebab-case.tsx. Filename "${path24.basename(filename)}" is not kebab-case.`
3058
+ message: `Dumb component files must use kebab-case.tsx. Filename "${path25.basename(filename)}" is not kebab-case.`
3025
3059
  });
3026
3060
  return;
3027
3061
  }
3028
3062
  if (!component && !(isPascalCase5(base) || isKebabCase2(base))) {
3029
3063
  context.report({
3030
3064
  node,
3031
- message: `Filename "${path24.basename(filename)}" does not match pasika conventions. Component files must be PascalCase.tsx (smart) or kebab-case.tsx (dumb).`
3065
+ message: `Filename "${path25.basename(filename)}" does not match pasika conventions. Component files must be PascalCase.tsx (smart) or kebab-case.tsx (dumb).`
3032
3066
  });
3033
3067
  }
3034
3068
  }
@@ -3047,14 +3081,14 @@ function report2(context, filename, ext) {
3047
3081
  context.report({
3048
3082
  node,
3049
3083
  loc: { line: 1, column: 0 },
3050
- message: `Filename "${path24.basename(filename)}" does not match pasika conventions. ${convention}`
3084
+ message: `Filename "${path25.basename(filename)}" does not match pasika conventions. ${convention}`
3051
3085
  });
3052
3086
  }
3053
3087
  };
3054
3088
  }
3055
3089
 
3056
3090
  // eslint/rules/hook-complexity.ts
3057
- import path25 from "path";
3091
+ import path26 from "path";
3058
3092
  import ts3 from "typescript";
3059
3093
  var REACT_HOOKS = /* @__PURE__ */ new Set([
3060
3094
  "useState",
@@ -3179,9 +3213,9 @@ var hookComplexityRule = {
3179
3213
  create(context) {
3180
3214
  const filename = context.filename;
3181
3215
  const sourceRoot = sourceRootOf(context);
3182
- const relative = path25.relative(sourceRoot, filename);
3216
+ const relative = path26.relative(sourceRoot, filename);
3183
3217
  if (relative.startsWith("..")) return {};
3184
- const segments = relative.split(path25.sep);
3218
+ const segments = relative.split(path26.sep);
3185
3219
  const sourceText = context.sourceCode.text;
3186
3220
  const index = getProjectIndex(sourceRoot);
3187
3221
  const localHookCalls = /* @__PURE__ */ new Set();
@@ -3268,7 +3302,7 @@ var hookComplexityRule = {
3268
3302
  };
3269
3303
 
3270
3304
  // eslint/rules/hook-extraction.ts
3271
- import path26 from "path";
3305
+ import path27 from "path";
3272
3306
  var hookExtractionRule = {
3273
3307
  meta: {
3274
3308
  schema: [],
@@ -3279,7 +3313,7 @@ var hookExtractionRule = {
3279
3313
  },
3280
3314
  create(context) {
3281
3315
  const sourceRoot = sourceRootOf(context);
3282
- const file = path26.resolve(context.filename);
3316
+ const file = path27.resolve(context.filename);
3283
3317
  const segments = segmentsOf(file, sourceRoot);
3284
3318
  if (segments.length === 0) return {};
3285
3319
  const index = getProjectIndex(sourceRoot);
@@ -3306,7 +3340,7 @@ var hookExtractionRule = {
3306
3340
 
3307
3341
  // eslint/rules/http-error-usage.ts
3308
3342
  import { readFileSync as readFileSync5 } from "fs";
3309
- import path27 from "path";
3343
+ import path28 from "path";
3310
3344
  import ts4 from "typescript";
3311
3345
  var HTTP_ERROR = "HttpError";
3312
3346
  var ROUTE_FILE = "route.ts";
@@ -3350,13 +3384,13 @@ function parentClassOf(file, name) {
3350
3384
  return void 0;
3351
3385
  }
3352
3386
  function importedFrom(file, name, sourceRoot, index) {
3353
- const module = index.modules.get(path27.resolve(file));
3387
+ const module = index.modules.get(path28.resolve(file));
3354
3388
  const moduleImport = module?.imports.find((entry) => entry.names.includes(name));
3355
3389
  if (!moduleImport) return void 0;
3356
3390
  return resolveSpecifier(file, moduleImport.specifier, sourceRoot);
3357
3391
  }
3358
3392
  function isHttpErrorClass(file, name, sourceRoot, index) {
3359
- let currentFile = path27.resolve(file);
3393
+ let currentFile = path28.resolve(file);
3360
3394
  let currentName = name;
3361
3395
  for (let depth = 0; depth <= HERITAGE_DEPTH; depth += 1) {
3362
3396
  if (currentName === HTTP_ERROR) return true;
@@ -3377,7 +3411,7 @@ function pipelineFiles(sourceRoot) {
3377
3411
  if (!index) return void 0;
3378
3412
  if (pipelineCache?.index === index) return pipelineCache.files;
3379
3413
  const files = /* @__PURE__ */ new Set();
3380
- const queue = [...index.modules.keys()].filter((file) => path27.basename(file) === ROUTE_FILE);
3414
+ const queue = [...index.modules.keys()].filter((file) => path28.basename(file) === ROUTE_FILE);
3381
3415
  while (queue.length > 0) {
3382
3416
  const file = queue.pop();
3383
3417
  if (file === void 0 || files.has(file)) continue;
@@ -3400,7 +3434,7 @@ var httpErrorUsageRule = {
3400
3434
  },
3401
3435
  create(context) {
3402
3436
  const sourceRoot = sourceRootOf(context);
3403
- const file = path27.resolve(context.filename);
3437
+ const file = path28.resolve(context.filename);
3404
3438
  let delegated;
3405
3439
  function inPipeline() {
3406
3440
  delegated ??= pipelineFiles(sourceRoot)?.has(file) ?? false;
@@ -3435,7 +3469,7 @@ var httpErrorUsageRule = {
3435
3469
 
3436
3470
  // eslint/rules/husky/husky-hook.ts
3437
3471
  import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
3438
- import path28 from "path";
3472
+ import path29 from "path";
3439
3473
  function memberName(member) {
3440
3474
  return member.name.type === "String" ? member.name.value : member.name.name;
3441
3475
  }
@@ -3453,7 +3487,7 @@ var huskyHookRule = {
3453
3487
  const root = node.body;
3454
3488
  if (root.type !== "Object") return;
3455
3489
  if (!context.filename.endsWith("package.json")) return;
3456
- const hookPath = path28.join(context.cwd, ".husky", "pre-commit");
3490
+ const hookPath = path29.join(context.cwd, ".husky", "pre-commit");
3457
3491
  if (!existsSync4(hookPath)) {
3458
3492
  context.report({
3459
3493
  node,
@@ -3480,7 +3514,7 @@ var huskyHookRule = {
3480
3514
  if (!content.includes("libyear --limit-major-individual=1")) {
3481
3515
  context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
3482
3516
  }
3483
- const suppressionsPath = path28.join(context.cwd, "eslint-suppressions.json");
3517
+ const suppressionsPath = path29.join(context.cwd, "eslint-suppressions.json");
3484
3518
  if (existsSync4(suppressionsPath)) {
3485
3519
  requireNamedScript("lint:prune");
3486
3520
  const pruneIndex = content.indexOf("npm run lint:prune");
@@ -3512,28 +3546,28 @@ var huskyRules = {
3512
3546
  };
3513
3547
 
3514
3548
  // eslint/rules/import-boundaries.ts
3515
- import path29 from "path";
3549
+ import path30 from "path";
3516
3550
  var rootSupportFolders = /* @__PURE__ */ new Set(["config", "constants", "hooks", "locales", "schemas", "types", "utils"]);
3517
3551
  var moduleExtensions = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"]);
3518
3552
  var styleExtensions = /* @__PURE__ */ new Set([".css", ".less", ".sass", ".scss"]);
3519
3553
  function resolveSourceImport(sourceRoot, filename, importPath) {
3520
3554
  if (importPath.startsWith("@/")) {
3521
- return path29.resolve(sourceRoot, importPath.slice(2));
3555
+ return path30.resolve(sourceRoot, importPath.slice(2));
3522
3556
  }
3523
3557
  if (importPath.startsWith(".")) {
3524
- return path29.resolve(path29.dirname(filename), importPath);
3558
+ return path30.resolve(path30.dirname(filename), importPath);
3525
3559
  }
3526
3560
  return void 0;
3527
3561
  }
3528
3562
  function sourceSegments(sourceRoot, absolutePath) {
3529
- const relativePath = path29.relative(sourceRoot, absolutePath);
3530
- if (relativePath.startsWith("..") || path29.isAbsolute(relativePath)) {
3563
+ const relativePath = path30.relative(sourceRoot, absolutePath);
3564
+ if (relativePath.startsWith("..") || path30.isAbsolute(relativePath)) {
3531
3565
  return void 0;
3532
3566
  }
3533
- return relativePath.split(path29.sep);
3567
+ return relativePath.split(path30.sep);
3534
3568
  }
3535
3569
  function relativeSpecifier(filename, resolvedPath) {
3536
- const relativePath = path29.relative(path29.dirname(filename), resolvedPath).split(path29.sep).join("/");
3570
+ const relativePath = path30.relative(path30.dirname(filename), resolvedPath).split(path30.sep).join("/");
3537
3571
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
3538
3572
  }
3539
3573
  function aliasSpecifier(sourceRoot, resolvedPath) {
@@ -3572,7 +3606,7 @@ var importBoundariesRule = {
3572
3606
  }
3573
3607
  const [importerLayer = "", importerFeature] = importer;
3574
3608
  const [importedLayer = "", importedFeature] = imported;
3575
- const extension = path29.extname(importPath);
3609
+ const extension = path30.extname(importPath);
3576
3610
  const isCodeModule = !extension || moduleExtensions.has(extension);
3577
3611
  const isAppLocalStyleImport = importerLayer === "app" && importedLayer === "app" && styleExtensions.has(extension);
3578
3612
  const importedIsRootSupport = rootSupportFolders.has(importedLayer);
@@ -3670,7 +3704,7 @@ var importSpacingRule = {
3670
3704
  };
3671
3705
 
3672
3706
  // eslint/rules/import-through-index.ts
3673
- import path30 from "path";
3707
+ import path31 from "path";
3674
3708
  var importThroughIndexRule = {
3675
3709
  meta: {
3676
3710
  schema: [],
@@ -3680,7 +3714,7 @@ var importThroughIndexRule = {
3680
3714
  }
3681
3715
  },
3682
3716
  create(context) {
3683
- const filename = path30.resolve(context.filename);
3717
+ const filename = path31.resolve(context.filename);
3684
3718
  const sourceRoot = sourceRootOf2(context, filename);
3685
3719
  return {
3686
3720
  Program(node) {
@@ -3692,7 +3726,7 @@ var importThroughIndexRule = {
3692
3726
  (segment) => ["constants", "types", "schemas"].includes(segment)
3693
3727
  );
3694
3728
  const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
3695
- if (!supportFolder || path30.basename(target).startsWith("index.")) continue;
3729
+ if (!supportFolder || path31.basename(target).startsWith("index.")) continue;
3696
3730
  const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
3697
3731
  const expected = `@/${folderIndex.join("/")}`;
3698
3732
  context.report({
@@ -3714,14 +3748,14 @@ function importSpecifiers(source) {
3714
3748
  return specifiers;
3715
3749
  }
3716
3750
  function sourceRootOf2(context, filename) {
3717
- const marker = `${path30.sep}src${path30.sep}`;
3751
+ const marker = `${path31.sep}src${path31.sep}`;
3718
3752
  const srcIndex = filename.lastIndexOf(marker);
3719
3753
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
3720
- return path30.resolve(context.cwd ?? process.cwd(), "src");
3754
+ return path31.resolve(context.cwd ?? process.cwd(), "src");
3721
3755
  }
3722
3756
 
3723
3757
  // eslint/rules/interactive-component.ts
3724
- import path31 from "path";
3758
+ import path32 from "path";
3725
3759
  var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
3726
3760
  "a",
3727
3761
  "button",
@@ -3877,8 +3911,8 @@ var interactiveComponentRule = {
3877
3911
  },
3878
3912
  create(context) {
3879
3913
  if (!context.filename.endsWith(".tsx") && !context.filename.endsWith(".jsx")) return {};
3880
- const filename = path31.resolve(context.filename);
3881
- const base = path31.basename(filename, path31.extname(filename));
3914
+ const filename = path32.resolve(context.filename);
3915
+ const base = path32.basename(filename, path32.extname(filename));
3882
3916
  if (NEXT_ROUTING_FILES3.has(base)) return {};
3883
3917
  return {
3884
3918
  JSXElement(node) {
@@ -4002,9 +4036,9 @@ var jsxHygieneRule = {
4002
4036
  };
4003
4037
 
4004
4038
  // eslint/rules/locale-dotted-path.ts
4005
- import path32 from "path";
4039
+ import path33 from "path";
4006
4040
  function isInLocalesDir(filename) {
4007
- const segments = path32.resolve(filename).split(path32.sep);
4041
+ const segments = path33.resolve(filename).split(path33.sep);
4008
4042
  const srcIdx = segments.lastIndexOf("src");
4009
4043
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4010
4044
  }
@@ -4053,7 +4087,7 @@ var localeDottedPathRule = {
4053
4087
  };
4054
4088
 
4055
4089
  // eslint/rules/locale-key-shape.ts
4056
- import path33 from "path";
4090
+ import path34 from "path";
4057
4091
  var MAX_KEY_LENGTH = 30;
4058
4092
  var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
4059
4093
  "Button",
@@ -4103,7 +4137,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
4103
4137
  var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
4104
4138
  var ENGLISH = /^[A-Za-z0-9_]*$/;
4105
4139
  function isLocalesFile(filename) {
4106
- const segments = path33.resolve(filename).split(path33.sep);
4140
+ const segments = path34.resolve(filename).split(path34.sep);
4107
4141
  const srcIdx = segments.lastIndexOf("src");
4108
4142
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4109
4143
  }
@@ -4175,7 +4209,7 @@ var localeKeyShapeRule = {
4175
4209
 
4176
4210
  // eslint/rules/locale-placement.ts
4177
4211
  import { readFileSync as readFileSync7 } from "fs";
4178
- import path34 from "path";
4212
+ import path35 from "path";
4179
4213
  import ts6 from "typescript";
4180
4214
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
4181
4215
  var camelCase = (name) => name.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase());
@@ -4222,7 +4256,7 @@ var localePlacementRule = {
4222
4256
  },
4223
4257
  create(context) {
4224
4258
  const sourceRoot = sourceRootOf(context);
4225
- const file = path34.resolve(context.filename);
4259
+ const file = path35.resolve(context.filename);
4226
4260
  const segments = segmentsOf(file, sourceRoot);
4227
4261
  if (segments.length === 0) return {};
4228
4262
  const index = getProjectIndex(sourceRoot);
@@ -4300,9 +4334,9 @@ var localePlacementRule = {
4300
4334
  };
4301
4335
 
4302
4336
  // eslint/rules/locales-location.ts
4303
- import path35 from "path";
4337
+ import path36 from "path";
4304
4338
  function isLocalesFile2(filename) {
4305
- const segments = path35.resolve(filename).split(path35.sep);
4339
+ const segments = path36.resolve(filename).split(path36.sep);
4306
4340
  const srcIdx = segments.lastIndexOf("src");
4307
4341
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
4308
4342
  }
@@ -4382,7 +4416,7 @@ var localesLocationRule = {
4382
4416
  create(context) {
4383
4417
  if (isLocalesFile2(context.filename) || isTestFile(context.filename)) return {};
4384
4418
  const filename = context.filename;
4385
- const segments = path35.resolve(filename).split(path35.sep);
4419
+ const segments = path36.resolve(filename).split(path36.sep);
4386
4420
  const srcIdx = segments.lastIndexOf("src");
4387
4421
  if (srcIdx === -1) return {};
4388
4422
  const folder = segments[srcIdx + 1];
@@ -4467,7 +4501,7 @@ var localesLocationRule = {
4467
4501
  };
4468
4502
 
4469
4503
  // eslint/rules/named-exports.ts
4470
- import path36 from "path";
4504
+ import path37 from "path";
4471
4505
  var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
4472
4506
  // App Router routing files
4473
4507
  "default",
@@ -4489,9 +4523,9 @@ var FRAMEWORK_DEFAULT_EXPORT_FILES = /* @__PURE__ */ new Set([
4489
4523
  "twitter-image"
4490
4524
  ]);
4491
4525
  function isFrameworkDefaultExportFile(filename) {
4492
- const normalized = filename.replaceAll(path36.sep, "/");
4526
+ const normalized = filename.replaceAll(path37.sep, "/");
4493
4527
  if (!normalized.includes("/src/app/")) return false;
4494
- const basename = path36.basename(filename, path36.extname(filename));
4528
+ const basename = path37.basename(filename, path37.extname(filename));
4495
4529
  return FRAMEWORK_DEFAULT_EXPORT_FILES.has(basename);
4496
4530
  }
4497
4531
  var namedExportsRule = {
@@ -4754,7 +4788,7 @@ var noMixedConcernsRule = {
4754
4788
  };
4755
4789
 
4756
4790
  // eslint/rules/no-redundant-alias.ts
4757
- import path37 from "path";
4791
+ import path38 from "path";
4758
4792
  var DOC3 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
4759
4793
  var VALUE_SENTINELS = /* @__PURE__ */ new Set(["undefined", "NaN", "Infinity"]);
4760
4794
  var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
@@ -4804,7 +4838,7 @@ var noRedundantAliasRule = {
4804
4838
  const declaration = node.parent;
4805
4839
  if (declaration.type !== "VariableDeclaration" || declaration.kind !== "const") return;
4806
4840
  const exported = declaration.parent.type === "ExportNamedDeclaration";
4807
- const frameworkRouteAlias = path37.basename(context.filename) === "route.ts" && exported && HTTP_METHODS.has(node.id.name);
4841
+ const frameworkRouteAlias = path38.basename(context.filename) === "route.ts" && exported && HTTP_METHODS.has(node.id.name);
4808
4842
  if (frameworkRouteAlias || VALUE_SENTINELS.has(node.init.name)) return;
4809
4843
  context.report({
4810
4844
  node,
@@ -4828,7 +4862,7 @@ var noRedundantAliasRule = {
4828
4862
  const source = specifier.local.name;
4829
4863
  const alias = specifier.exported.name;
4830
4864
  if (source === alias) continue;
4831
- const frameworkRouteAlias = path37.basename(context.filename) === "route.ts" && HTTP_METHODS.has(alias);
4865
+ const frameworkRouteAlias = path38.basename(context.filename) === "route.ts" && HTTP_METHODS.has(alias);
4832
4866
  if (frameworkRouteAlias) continue;
4833
4867
  context.report({
4834
4868
  node: specifier,
@@ -4853,7 +4887,7 @@ var noRedundantAliasRule = {
4853
4887
  };
4854
4888
 
4855
4889
  // eslint/rules/no-util-barrel.ts
4856
- import path38 from "path";
4890
+ import path39 from "path";
4857
4891
  var noUtilBarrelRule = {
4858
4892
  meta: {
4859
4893
  schema: [],
@@ -4863,7 +4897,7 @@ var noUtilBarrelRule = {
4863
4897
  }
4864
4898
  },
4865
4899
  create(context) {
4866
- const filename = path38.resolve(context.filename);
4900
+ const filename = path39.resolve(context.filename);
4867
4901
  const sourceRoot = sourceRootOf3(context, filename);
4868
4902
  return {
4869
4903
  Program(node) {
@@ -4872,7 +4906,7 @@ var noUtilBarrelRule = {
4872
4906
  if (!target) continue;
4873
4907
  const segments = target.replace(/\\/g, "/").split("/");
4874
4908
  const utilsIndex = segments.lastIndexOf("utils");
4875
- if (utilsIndex < 0 || !path38.basename(target).startsWith("index.")) continue;
4909
+ if (utilsIndex < 0 || !path39.basename(target).startsWith("index.")) continue;
4876
4910
  context.report({
4877
4911
  node,
4878
4912
  message: `Import utilities directly instead of through "${specifier}". See docs/next-codebase-guide/rules/utilities-rule.md`
@@ -4892,10 +4926,10 @@ function importSpecifiers2(source) {
4892
4926
  return specifiers;
4893
4927
  }
4894
4928
  function sourceRootOf3(context, filename) {
4895
- const marker = `${path38.sep}src${path38.sep}`;
4929
+ const marker = `${path39.sep}src${path39.sep}`;
4896
4930
  const srcIndex = filename.lastIndexOf(marker);
4897
4931
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
4898
- return path38.resolve(context.cwd ?? process.cwd(), "src");
4932
+ return path39.resolve(context.cwd ?? process.cwd(), "src");
4899
4933
  }
4900
4934
 
4901
4935
  // eslint/rules/package-json/exact-version.ts
@@ -5114,7 +5148,7 @@ var nextjsStackRule = {
5114
5148
 
5115
5149
  // eslint/rules/package-json/vitest-coverage.ts
5116
5150
  import { existsSync as existsSync5, readFileSync as readFileSync8 } from "fs";
5117
- import path39 from "path";
5151
+ import path40 from "path";
5118
5152
  function memberName5(member) {
5119
5153
  return member.name.type === "String" ? member.name.value : member.name.name;
5120
5154
  }
@@ -5138,13 +5172,13 @@ var THRESHOLD_METRICS = ["lines", "functions", "branches", "statements"];
5138
5172
  var SOURCE_GLOB_PATTERN2 = /(?:^|[^a-z])(?:[cm]?[jt]sx?)(?:[^a-z]|$)/i;
5139
5173
  var COVERAGE_FLAG_PATTERN = /(?:^|\s)--coverage(?:[=\s]|$)/;
5140
5174
  var RELATED_PATTERN = /\brelated\b/;
5141
- var AUTO_UPDATE_PATTERN = /autoUpdate\s*:\s*true/;
5175
+ var AUTO_UPDATE_PATTERN = /autoUpdate\s*:\s*\(\s*newThreshold\s*,\s*previousThreshold\s*\)\s*=>\s*Math\.max\(\s*previousThreshold\s*,\s*Math\.floor\(\s*\(\s*newThreshold\s*-\s*0\.1\s*\)\s*\*\s*10\s*\)\s*\/\s*10\s*\)/;
5142
5176
  var vitestCoverageRule = {
5143
5177
  meta: {
5144
5178
  schema: [],
5145
5179
  type: "problem",
5146
5180
  docs: {
5147
- description: "Require Vitest unit-test scripts, the V8 provider, a rising aggregate coverage threshold, and related tests via lint-staged."
5181
+ description: "Require Vitest unit-test scripts, the V8 provider, a platform-stable rising aggregate coverage threshold, and related tests via lint-staged."
5148
5182
  }
5149
5183
  },
5150
5184
  create(context) {
@@ -5183,7 +5217,7 @@ var vitestCoverageRule = {
5183
5217
  message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
5184
5218
  });
5185
5219
  }
5186
- const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path39.join(context.cwd, name)));
5220
+ const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path40.join(context.cwd, name)));
5187
5221
  if (!configName) {
5188
5222
  context.report({
5189
5223
  node,
@@ -5191,7 +5225,7 @@ var vitestCoverageRule = {
5191
5225
  });
5192
5226
  return;
5193
5227
  }
5194
- const content = readFileSync8(path39.join(context.cwd, configName), "utf8");
5228
+ const content = readFileSync8(path40.join(context.cwd, configName), "utf8");
5195
5229
  for (const metric of THRESHOLD_METRICS) {
5196
5230
  if (!new RegExp(`\\b${metric}\\s*:\\s*[1-9]\\d*`).test(content)) {
5197
5231
  context.report({ node, message: `${configName} must set a coverage threshold above zero for ${metric}.` });
@@ -5200,7 +5234,7 @@ var vitestCoverageRule = {
5200
5234
  if (!AUTO_UPDATE_PATTERN.test(content)) {
5201
5235
  context.report({
5202
5236
  node,
5203
- message: `${configName} must set coverage.thresholds.autoUpdate to true.`
5237
+ message: `${configName} must set coverage.thresholds.autoUpdate to the monotonic 0.1-point buffered formatter.`
5204
5238
  });
5205
5239
  }
5206
5240
  const stagedTests = scriptMembers.find((member) => memberName5(member) === "test:unit:staged");
@@ -5237,7 +5271,7 @@ var nextjsPackageJsonRules = {
5237
5271
  };
5238
5272
 
5239
5273
  // eslint/rules/prefer-enum.ts
5240
- import path40 from "path";
5274
+ import path41 from "path";
5241
5275
  function isConstAssertion(node) {
5242
5276
  const typeAnnotation = node.typeAnnotation;
5243
5277
  return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
@@ -5289,9 +5323,9 @@ var preferEnumRule = {
5289
5323
  }
5290
5324
  },
5291
5325
  create(context) {
5292
- const filename = path40.resolve(context.filename);
5326
+ const filename = path41.resolve(context.filename);
5293
5327
  const sourceRoot = sourceRootOf(context);
5294
- if (!filename.startsWith(sourceRoot + path40.sep)) return {};
5328
+ if (!filename.startsWith(sourceRoot + path41.sep)) return {};
5295
5329
  const objectSchemas = /* @__PURE__ */ new Map();
5296
5330
  const discriminatedUnions = [];
5297
5331
  const reportedDiscriminants = /* @__PURE__ */ new Set();
@@ -5362,7 +5396,7 @@ var preferEnumRule = {
5362
5396
  };
5363
5397
 
5364
5398
  // eslint/rules/pure-function-extract.ts
5365
- import path41 from "path";
5399
+ import path42 from "path";
5366
5400
  var ROUTE_HANDLER_EXPORT_NAMES = /* @__PURE__ */ new Set([
5367
5401
  "GET",
5368
5402
  "POST",
@@ -5427,12 +5461,12 @@ var pureFunctionExtractRule = {
5427
5461
  },
5428
5462
  create(context) {
5429
5463
  const filename = context.filename;
5430
- const isRouteFile = path41.basename(filename) === "route.ts";
5464
+ const isRouteFile = path42.basename(filename) === "route.ts";
5431
5465
  const isComponentFile = filename.endsWith(".tsx") || filename.endsWith(".jsx");
5432
5466
  const sourceRoot = sourceRootOf(context);
5433
- const relative = path41.relative(sourceRoot, filename);
5467
+ const relative = path42.relative(sourceRoot, filename);
5434
5468
  if (relative.startsWith("..")) return {};
5435
- const segments = relative.split(path41.sep);
5469
+ const segments = relative.split(path42.sep);
5436
5470
  const folders = segments.slice(0, -1);
5437
5471
  const isHookSupportFile = folders.includes("hooks") && /\.(?:[cm]?[jt]s)$/.test(filename);
5438
5472
  if (!isComponentFile && !isRouteFile && !isHookSupportFile) return {};
@@ -5671,8 +5705,87 @@ var repeatedStructureRule = {
5671
5705
  }
5672
5706
  };
5673
5707
 
5708
+ // eslint/rules/require-barrel-star-exports.ts
5709
+ import fs5 from "fs";
5710
+ import path43 from "path";
5711
+ var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
5712
+ var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
5713
+ var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
5714
+ function resolveSiblingModule(indexFile, specifier) {
5715
+ if (!specifier.startsWith("./")) return void 0;
5716
+ const relative = specifier.slice(2);
5717
+ if (!relative || relative.includes("/")) return void 0;
5718
+ const directory = path43.dirname(indexFile);
5719
+ const direct = path43.resolve(directory, relative);
5720
+ const candidates = path43.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
5721
+ return candidates.find((candidate) => fs5.existsSync(candidate) && fs5.statSync(candidate).isFile());
5722
+ }
5723
+ var requireBarrelStarExportsRule = {
5724
+ meta: {
5725
+ schema: [],
5726
+ type: "suggestion",
5727
+ docs: {
5728
+ description: "Require support-folder barrels to mirror local sibling modules through wildcard re-exports."
5729
+ },
5730
+ fixable: "code"
5731
+ },
5732
+ create(context) {
5733
+ const filename = path43.resolve(context.filename);
5734
+ if (!INDEX_NAMES.has(path43.basename(filename))) return {};
5735
+ if (!SUPPORT_FOLDERS3.has(path43.basename(path43.dirname(filename)))) return {};
5736
+ return {
5737
+ ExportNamedDeclaration(node) {
5738
+ const sourceNode = node.source;
5739
+ const sourceValue = sourceNode?.value;
5740
+ if (!sourceNode || typeof sourceValue !== "string" || node.specifiers.length === 0) return;
5741
+ const siblingFile = resolveSiblingModule(filename, sourceValue);
5742
+ if (!siblingFile) return;
5743
+ let replacement;
5744
+ try {
5745
+ const siblingExports = parseModule(siblingFile).exports;
5746
+ if (siblingExports.length > 0) {
5747
+ const reExportedNames = /* @__PURE__ */ new Set();
5748
+ let hasRename = false;
5749
+ for (const specifier of node.specifiers) {
5750
+ if (specifier.local.type !== "Identifier" || specifier.exported.type !== "Identifier") {
5751
+ hasRename = true;
5752
+ break;
5753
+ }
5754
+ if (specifier.local.name !== specifier.exported.name) {
5755
+ hasRename = true;
5756
+ break;
5757
+ }
5758
+ reExportedNames.add(specifier.local.name);
5759
+ }
5760
+ const siblingExportNames = new Set(siblingExports.map((moduleExport) => moduleExport.name));
5761
+ const exportsCompleteSurface = !hasRename && reExportedNames.size === siblingExportNames.size && [...siblingExportNames].every((name) => reExportedNames.has(name));
5762
+ if (exportsCompleteSurface) {
5763
+ const siblingExportsOnlyTypes = siblingExports.every((moduleExport) => moduleExport.kind === "type");
5764
+ const statementIsTypeOnly = context.sourceCode.getText(node).trimStart().startsWith("export type ");
5765
+ if (!statementIsTypeOnly || siblingExportsOnlyTypes) {
5766
+ const keyword = siblingExportsOnlyTypes ? "export type *" : "export *";
5767
+ replacement = `${keyword} from ${context.sourceCode.getText(sourceNode)};`;
5768
+ }
5769
+ }
5770
+ }
5771
+ } catch {
5772
+ }
5773
+ context.report({
5774
+ node,
5775
+ message: "A support-folder barrel MUST re-export a local sibling module with export * or export type *; remove unwanted exports or rename declarations in the sibling module instead of filtering or renaming them in the barrel.",
5776
+ ...replacement ? {
5777
+ fix(fixer) {
5778
+ return fixer.replaceText(node, replacement);
5779
+ }
5780
+ } : {}
5781
+ });
5782
+ }
5783
+ };
5784
+ }
5785
+ };
5786
+
5674
5787
  // eslint/rules/root-support-placement.ts
5675
- import path42 from "path";
5788
+ import path44 from "path";
5676
5789
  function isSupportFolder(value) {
5677
5790
  return value === "utils" || value === "types" || value === "schemas" || value === "constants";
5678
5791
  }
@@ -5705,7 +5818,7 @@ var rootSupportPlacementRule = {
5705
5818
  },
5706
5819
  create(context) {
5707
5820
  const sourceRoot = sourceRootOf(context);
5708
- const file = path42.resolve(context.filename);
5821
+ const file = path44.resolve(context.filename);
5709
5822
  const segments = segmentsOf(file, sourceRoot);
5710
5823
  const folderSegments = folderSegmentsOf(file, sourceRoot);
5711
5824
  const supportFolder = folderSegments[folderSegments.length - 1];
@@ -5745,7 +5858,7 @@ var rootSupportPlacementRule = {
5745
5858
  };
5746
5859
 
5747
5860
  // eslint/rules/route-handler-shape.ts
5748
- import path43 from "path";
5861
+ import path45 from "path";
5749
5862
  import ts7 from "typescript";
5750
5863
  var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
5751
5864
  var REQUIRED_BOUNDARY = "withResponse";
@@ -5830,7 +5943,7 @@ var routeHandlerShapeRule = {
5830
5943
  }
5831
5944
  },
5832
5945
  create(context) {
5833
- if (path43.basename(context.filename) !== "route.ts") return {};
5946
+ if (path45.basename(context.filename) !== "route.ts") return {};
5834
5947
  const sourceText = context.sourceCode.text;
5835
5948
  function reportUnwrapped(node, name) {
5836
5949
  context.report({
@@ -5889,7 +6002,7 @@ var routeHandlerShapeRule = {
5889
6002
  };
5890
6003
 
5891
6004
  // eslint/rules/schema-casing.ts
5892
- import path44 from "path";
6005
+ import path46 from "path";
5893
6006
  function isCamelCase(name) {
5894
6007
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
5895
6008
  }
@@ -5917,9 +6030,9 @@ var schemaCasingRule = {
5917
6030
  }
5918
6031
  },
5919
6032
  create(context) {
5920
- const filename = path44.resolve(context.filename);
6033
+ const filename = path46.resolve(context.filename);
5921
6034
  const sourceRoot = sourceRootOf(context);
5922
- if (!filename.startsWith(sourceRoot + path44.sep)) return {};
6035
+ if (!filename.startsWith(sourceRoot + path46.sep)) return {};
5923
6036
  let zodLocalName;
5924
6037
  return {
5925
6038
  ImportDeclaration(node) {
@@ -5951,7 +6064,7 @@ var schemaCasingRule = {
5951
6064
  };
5952
6065
 
5953
6066
  // eslint/rules/sole-state-owner.ts
5954
- import path45 from "path";
6067
+ import path47 from "path";
5955
6068
  import ts8 from "typescript";
5956
6069
  function findStateHooks(node) {
5957
6070
  const hooks = [];
@@ -6031,7 +6144,7 @@ var soleStateOwnerRule = {
6031
6144
  }
6032
6145
  },
6033
6146
  create(context) {
6034
- const filename = path45.resolve(context.filename);
6147
+ const filename = path47.resolve(context.filename);
6035
6148
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
6036
6149
  const text = context.sourceCode.text;
6037
6150
  const components = parseComponentInfo(text, filename);
@@ -6110,7 +6223,7 @@ function usesOutsideJsx(declaration, hook, children) {
6110
6223
  }
6111
6224
 
6112
6225
  // eslint/rules/source-under-src.ts
6113
- import path46 from "path";
6226
+ import path48 from "path";
6114
6227
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
6115
6228
  ".agents",
6116
6229
  ".cache",
@@ -6151,14 +6264,14 @@ var sourceUnderSrcRule = {
6151
6264
  }
6152
6265
  },
6153
6266
  create(context) {
6154
- const filename = path46.resolve(context.filename);
6267
+ const filename = path48.resolve(context.filename);
6155
6268
  if (!MODULE_EXTENSION.test(filename)) return {};
6156
- const relative = path46.relative(context.cwd, filename).replace(/\\/g, "/");
6269
+ const relative = path48.relative(context.cwd, filename).replace(/\\/g, "/");
6157
6270
  if (relative === "src" || relative.startsWith("src/")) return {};
6158
6271
  const topLevel = relative.split("/")[0] ?? "";
6159
6272
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
6160
6273
  if (!relative.includes("/")) {
6161
- const basename = path46.basename(filename);
6274
+ const basename = path48.basename(filename);
6162
6275
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
6163
6276
  }
6164
6277
  return {
@@ -6174,7 +6287,7 @@ var sourceUnderSrcRule = {
6174
6287
  };
6175
6288
 
6176
6289
  // eslint/rules/stay-flat.ts
6177
- import path47 from "path";
6290
+ import path49 from "path";
6178
6291
  var stayFlatRule = {
6179
6292
  meta: {
6180
6293
  schema: [],
@@ -6185,7 +6298,7 @@ var stayFlatRule = {
6185
6298
  },
6186
6299
  create(context) {
6187
6300
  const sourceRoot = sourceRootOf(context);
6188
- const file = path47.resolve(context.filename);
6301
+ const file = path49.resolve(context.filename);
6189
6302
  const segments = segmentsOf(file, sourceRoot);
6190
6303
  if (segments.length !== 3 || segments[0] !== "features") return {};
6191
6304
  const index = getProjectIndex(sourceRoot);
@@ -6225,7 +6338,7 @@ var stayFlatRule = {
6225
6338
  };
6226
6339
 
6227
6340
  // eslint/rules/support-file-placement.ts
6228
- import path48 from "path";
6341
+ import path50 from "path";
6229
6342
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
6230
6343
  var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
6231
6344
  ["constants", "constant"],
@@ -6250,7 +6363,7 @@ var supportFilePlacementRule = {
6250
6363
  },
6251
6364
  create(context) {
6252
6365
  const sourceRoot = sourceRootOf(context);
6253
- const supportFile = path48.resolve(context.filename);
6366
+ const supportFile = path50.resolve(context.filename);
6254
6367
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
6255
6368
  const supportFolder = currentFolder[currentFolder.length - 1];
6256
6369
  if (supportFolder === void 0 || !SUPPORT_FOLDERS.has(supportFolder)) return {};
@@ -6303,10 +6416,10 @@ var supportFilePlacementRule = {
6303
6416
  };
6304
6417
 
6305
6418
  // eslint/rules/support-folder-shape.ts
6306
- import fs5 from "fs";
6307
- import path49 from "path";
6308
- var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
6309
- var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
6419
+ import fs6 from "fs";
6420
+ import path51 from "path";
6421
+ var SUPPORT_FOLDERS4 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
6422
+ var INDEX_NAMES2 = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
6310
6423
  var supportFolderShapeRule = {
6311
6424
  meta: {
6312
6425
  schema: [],
@@ -6316,15 +6429,15 @@ var supportFolderShapeRule = {
6316
6429
  }
6317
6430
  },
6318
6431
  create(context) {
6319
- const filename = path49.resolve(context.filename);
6320
- const baseName = path49.basename(filename);
6321
- if (!INDEX_NAMES.has(baseName)) return {};
6322
- const folder = path49.basename(path49.dirname(filename));
6323
- if (!SUPPORT_FOLDERS3.has(folder)) return {};
6324
- const directory = path49.dirname(filename);
6432
+ const filename = path51.resolve(context.filename);
6433
+ const baseName = path51.basename(filename);
6434
+ if (!INDEX_NAMES2.has(baseName)) return {};
6435
+ const folder = path51.basename(path51.dirname(filename));
6436
+ if (!SUPPORT_FOLDERS4.has(folder)) return {};
6437
+ const directory = path51.dirname(filename);
6325
6438
  let entries;
6326
6439
  try {
6327
- entries = fs5.readdirSync(directory);
6440
+ entries = fs6.readdirSync(directory);
6328
6441
  } catch {
6329
6442
  return {};
6330
6443
  }
@@ -6339,7 +6452,7 @@ var supportFolderShapeRule = {
6339
6452
  for (const match of source.matchAll(exportPattern)) {
6340
6453
  hasAnyReExport = true;
6341
6454
  const specifier = match.groups?.specifier;
6342
- if (specifier?.startsWith(".")) exportedFiles.add(path49.basename(specifier));
6455
+ if (specifier?.startsWith(".")) exportedFiles.add(path51.basename(specifier));
6343
6456
  }
6344
6457
  const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
6345
6458
  if (siblingModules.length === 0) {
@@ -6518,14 +6631,14 @@ var baseLayerPairRule = {
6518
6631
 
6519
6632
  // eslint/rules/tailwind/css-entry-point.ts
6520
6633
  import { statSync as statSync4 } from "fs";
6521
- import path52 from "path";
6634
+ import path54 from "path";
6522
6635
 
6523
6636
  // eslint/rules/tailwind/source-files.ts
6524
6637
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
6525
- import path50 from "path";
6638
+ import path52 from "path";
6526
6639
  var CSS_EXTENSIONS = [".css"];
6527
- var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
6528
- var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS3, ...CSS_EXTENSIONS];
6640
+ var MODULE_EXTENSIONS4 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
6641
+ var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS4, ...CSS_EXTENSIONS];
6529
6642
  function findFiles(dir, extensions) {
6530
6643
  let entries;
6531
6644
  try {
@@ -6535,7 +6648,7 @@ function findFiles(dir, extensions) {
6535
6648
  }
6536
6649
  return entries.flatMap((entry) => {
6537
6650
  if (entry.startsWith(".") || entry === "node_modules") return [];
6538
- const entryPath = path50.join(dir, entry);
6651
+ const entryPath = path52.join(dir, entry);
6539
6652
  let stats;
6540
6653
  try {
6541
6654
  stats = statSync3(entryPath);
@@ -6543,7 +6656,7 @@ function findFiles(dir, extensions) {
6543
6656
  return [];
6544
6657
  }
6545
6658
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
6546
- return extensions.includes(path50.extname(entry)) ? [entryPath] : [];
6659
+ return extensions.includes(path52.extname(entry)) ? [entryPath] : [];
6547
6660
  });
6548
6661
  }
6549
6662
  function cachedTextReader() {
@@ -6566,7 +6679,7 @@ function escapeRegExp(text) {
6566
6679
  }
6567
6680
 
6568
6681
  // eslint/rules/tailwind/stylesheet-graph.ts
6569
- import path51 from "path";
6682
+ import path53 from "path";
6570
6683
  function registersTailwind(text) {
6571
6684
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
6572
6685
  }
@@ -6580,25 +6693,25 @@ function moduleImports(text, fileName) {
6580
6693
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
6581
6694
  }
6582
6695
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
6583
- if (spec.startsWith("/")) return path51.resolve(spec);
6584
- if (spec.startsWith("./") || spec.startsWith("../")) return path51.resolve(path51.dirname(fromFile), spec);
6585
- if (spec.startsWith("@/")) return path51.resolve(sourceRoot, spec.slice(2));
6696
+ if (spec.startsWith("/")) return path53.resolve(spec);
6697
+ if (spec.startsWith("./") || spec.startsWith("../")) return path53.resolve(path53.dirname(fromFile), spec);
6698
+ if (spec.startsWith("@/")) return path53.resolve(sourceRoot, spec.slice(2));
6586
6699
  return void 0;
6587
6700
  }
6588
6701
  function buildStylesheetGraph(options) {
6589
6702
  const { cssFiles, sourceRoot, textOf } = options;
6590
- const cssSet = new Set(cssFiles.map((file) => path51.normalize(file)));
6703
+ const cssSet = new Set(cssFiles.map((file) => path53.normalize(file)));
6591
6704
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
6592
6705
  const reachable = /* @__PURE__ */ new Set();
6593
6706
  const queue = [...globals];
6594
- for (const global of globals) reachable.add(path51.normalize(global));
6707
+ for (const global of globals) reachable.add(path53.normalize(global));
6595
6708
  while (queue.length > 0) {
6596
6709
  const from = queue.shift();
6597
6710
  if (!from) continue;
6598
6711
  for (const spec of importedSpecifiers(textOf(from))) {
6599
6712
  const target = resolveSpecifier2(from, spec, sourceRoot);
6600
6713
  if (!target) continue;
6601
- const normalized = path51.normalize(target);
6714
+ const normalized = path53.normalize(target);
6602
6715
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
6603
6716
  reachable.add(normalized);
6604
6717
  queue.push(normalized);
@@ -6610,7 +6723,7 @@ function buildStylesheetGraph(options) {
6610
6723
  for (const spec of importedSpecifiers(textOf(global))) {
6611
6724
  const target = resolveSpecifier2(global, spec, sourceRoot);
6612
6725
  if (!target) continue;
6613
- const normalized = path51.normalize(target);
6726
+ const normalized = path53.normalize(target);
6614
6727
  if (cssSet.has(normalized)) directChildren.add(normalized);
6615
6728
  }
6616
6729
  }
@@ -6618,8 +6731,8 @@ function buildStylesheetGraph(options) {
6618
6731
  }
6619
6732
 
6620
6733
  // eslint/rules/tailwind/css-entry-point.ts
6621
- var APP_STYLES_DIR = path52.join("app", "styles");
6622
- var GLOBAL_STYLESHEET_PATH = path52.join(APP_STYLES_DIR, "globals.css");
6734
+ var APP_STYLES_DIR = path54.join("app", "styles");
6735
+ var GLOBAL_STYLESHEET_PATH = path54.join(APP_STYLES_DIR, "globals.css");
6623
6736
  var cssEntryPointRule = {
6624
6737
  meta: {
6625
6738
  schema: [],
@@ -6635,7 +6748,7 @@ var cssEntryPointRule = {
6635
6748
  try {
6636
6749
  if (!statSync4(sourceRoot).isDirectory()) return {};
6637
6750
  cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
6638
- moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS3);
6751
+ moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
6639
6752
  } catch {
6640
6753
  return {};
6641
6754
  }
@@ -6645,8 +6758,8 @@ var cssEntryPointRule = {
6645
6758
  return {
6646
6759
  "StyleSheet:exit"(node) {
6647
6760
  if (globals.length === 0) return;
6648
- const current = path52.normalize(path52.resolve(context.filename));
6649
- const relative = path52.relative(sourceRoot, current);
6761
+ const current = path54.normalize(path54.resolve(context.filename));
6762
+ const relative = path54.relative(sourceRoot, current);
6650
6763
  if (globals.includes(current)) {
6651
6764
  if (globals.length > 1) {
6652
6765
  context.report({
@@ -6662,7 +6775,7 @@ var cssEntryPointRule = {
6662
6775
  });
6663
6776
  return;
6664
6777
  }
6665
- const basename = path52.basename(current);
6778
+ const basename = path54.basename(current);
6666
6779
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
6667
6780
  if (importCount !== 1) {
6668
6781
  context.report({
@@ -6672,7 +6785,7 @@ var cssEntryPointRule = {
6672
6785
  }
6673
6786
  return;
6674
6787
  }
6675
- const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path52.sep}`);
6788
+ const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path54.sep}`);
6676
6789
  if (!isInAppStyles) {
6677
6790
  context.report({
6678
6791
  node,
@@ -7161,7 +7274,7 @@ var tailwindRules = {
7161
7274
  };
7162
7275
 
7163
7276
  // eslint/rules/type-extraction.ts
7164
- import path53 from "path";
7277
+ import path55 from "path";
7165
7278
  var typeExtractionRule = {
7166
7279
  meta: {
7167
7280
  schema: [],
@@ -7172,7 +7285,7 @@ var typeExtractionRule = {
7172
7285
  },
7173
7286
  create(context) {
7174
7287
  const sourceRoot = sourceRootOf(context);
7175
- const file = path53.resolve(context.filename);
7288
+ const file = path55.resolve(context.filename);
7176
7289
  const segments = segmentsOf(file, sourceRoot);
7177
7290
  if (segments.length === 0) return {};
7178
7291
  const index = getProjectIndex(sourceRoot);
@@ -7307,7 +7420,7 @@ var uiStateRule = {
7307
7420
  // eslint/rules/unknown-utility.ts
7308
7421
  import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
7309
7422
  import { createRequire } from "module";
7310
- import path54 from "path";
7423
+ import path56 from "path";
7311
7424
  var PREFIX_NAMESPACES = {
7312
7425
  bg: ["color"],
7313
7426
  text: ["color", "text"],
@@ -7547,7 +7660,7 @@ function stylesheetFiles(dir) {
7547
7660
  }
7548
7661
  return entries.flatMap((entry) => {
7549
7662
  if (entry.startsWith(".") || entry === "node_modules") return [];
7550
- const entryPath = path54.join(dir, entry);
7663
+ const entryPath = path56.join(dir, entry);
7551
7664
  let stats;
7552
7665
  try {
7553
7666
  stats = statSync6(entryPath);
@@ -7555,7 +7668,7 @@ function stylesheetFiles(dir) {
7555
7668
  return [];
7556
7669
  }
7557
7670
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
7558
- return path54.extname(entry) === ".css" ? [entryPath] : [];
7671
+ return path56.extname(entry) === ".css" ? [entryPath] : [];
7559
7672
  });
7560
7673
  }
7561
7674
  function packageNameOf(specifier) {
@@ -7566,10 +7679,10 @@ function packageNameOf(specifier) {
7566
7679
  function resolvePackageStylesheet(fromFile, specifier) {
7567
7680
  const packageName = packageNameOf(specifier);
7568
7681
  if (!packageName || packageName === "tailwindcss") return void 0;
7569
- let directory = path54.dirname(fromFile);
7570
- while (directory !== path54.dirname(directory)) {
7571
- const packageRoot = path54.join(directory, "node_modules", packageName);
7572
- const manifestPath = path54.join(packageRoot, "package.json");
7682
+ let directory = path56.dirname(fromFile);
7683
+ while (directory !== path56.dirname(directory)) {
7684
+ const packageRoot = path56.join(directory, "node_modules", packageName);
7685
+ const manifestPath = path56.join(packageRoot, "package.json");
7573
7686
  if (existsSync6(manifestPath)) {
7574
7687
  try {
7575
7688
  const manifest = readFileSync10(manifestPath, "utf8");
@@ -7577,13 +7690,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
7577
7690
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
7578
7691
  const target = stylesheet ?? main;
7579
7692
  if (!target) return void 0;
7580
- const resolved = path54.resolve(packageRoot, target);
7693
+ const resolved = path56.resolve(packageRoot, target);
7581
7694
  return existsSync6(resolved) ? resolved : void 0;
7582
7695
  } catch {
7583
7696
  return void 0;
7584
7697
  }
7585
7698
  }
7586
- directory = path54.dirname(directory);
7699
+ directory = path56.dirname(directory);
7587
7700
  }
7588
7701
  return void 0;
7589
7702
  }
@@ -7834,7 +7947,7 @@ var unknownUtilityRule = {
7834
7947
  };
7835
7948
 
7836
7949
  // eslint/rules/util-file-name.ts
7837
- import path55 from "path";
7950
+ import path57 from "path";
7838
7951
  function toKebabCase2(value) {
7839
7952
  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();
7840
7953
  }
@@ -7847,7 +7960,7 @@ var utilFileNameRule = {
7847
7960
  }
7848
7961
  },
7849
7962
  create(context) {
7850
- const filename = path55.resolve(context.filename);
7963
+ const filename = path57.resolve(context.filename);
7851
7964
  const segments = filename.replace(/\\/g, "/").split("/");
7852
7965
  if (!segments.includes("utils")) return {};
7853
7966
  let module;
@@ -7861,13 +7974,13 @@ var utilFileNameRule = {
7861
7974
  const functionName = functions[0]?.name;
7862
7975
  if (!functionName) return {};
7863
7976
  const expected = toKebabCase2(functionName);
7864
- const actual = path55.basename(filename, path55.extname(filename));
7977
+ const actual = path57.basename(filename, path57.extname(filename));
7865
7978
  if (!expected || actual === expected) return {};
7866
7979
  return {
7867
7980
  Program(node) {
7868
7981
  context.report({
7869
7982
  node,
7870
- message: `A utility file exporting ${functionName} must be named ${expected}.${path55.extname(filename).slice(1)}.`
7983
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path57.extname(filename).slice(1)}.`
7871
7984
  });
7872
7985
  }
7873
7986
  };
@@ -7875,7 +7988,7 @@ var utilFileNameRule = {
7875
7988
  };
7876
7989
 
7877
7990
  // eslint/rules/value-extraction.ts
7878
- import path56 from "path";
7991
+ import path58 from "path";
7879
7992
  var valueExtractionRule = {
7880
7993
  meta: {
7881
7994
  schema: [],
@@ -7886,7 +7999,7 @@ var valueExtractionRule = {
7886
7999
  },
7887
8000
  create(context) {
7888
8001
  const sourceRoot = sourceRootOf(context);
7889
- const file = path56.resolve(context.filename);
8002
+ const file = path58.resolve(context.filename);
7890
8003
  const segments = segmentsOf(file, sourceRoot);
7891
8004
  if (segments.length === 0 || segments[0] !== "app") return {};
7892
8005
  const index = getProjectIndex(sourceRoot);
@@ -7908,7 +8021,7 @@ var valueExtractionRule = {
7908
8021
 
7909
8022
  // eslint/rules/vulyk/tracked-docs.ts
7910
8023
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "fs";
7911
- import path57 from "path";
8024
+ import path59 from "path";
7912
8025
  var PASIKA_REPO = "Bredansky/pasika";
7913
8026
  var BASE_REQUIRED_TRACKED_DOCS = [
7914
8027
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -7941,8 +8054,8 @@ var trackedDocsRule = {
7941
8054
  if (!context.filename.endsWith("package.json")) return;
7942
8055
  const root = node.body;
7943
8056
  if (root.type !== "Object") return;
7944
- const projectRoot = path57.dirname(path57.resolve(context.filename));
7945
- const configPath = path57.join(projectRoot, "vulyk.config.ts");
8057
+ const projectRoot = path59.dirname(path59.resolve(context.filename));
8058
+ const configPath = path59.join(projectRoot, "vulyk.config.ts");
7946
8059
  if (!existsSync7(configPath)) {
7947
8060
  context.report({
7948
8061
  node,
@@ -7967,7 +8080,7 @@ var trackedDocsRule = {
7967
8080
  });
7968
8081
  }
7969
8082
  }
7970
- const agentsPath = path57.join(projectRoot, "AGENTS.md");
8083
+ const agentsPath = path59.join(projectRoot, "AGENTS.md");
7971
8084
  if (!existsSync7(agentsPath)) {
7972
8085
  context.report({
7973
8086
  node,
@@ -8066,8 +8179,8 @@ var withResponseHelperRule = {
8066
8179
  };
8067
8180
 
8068
8181
  // eslint/rules/zirka-baseline.ts
8069
- import fs6 from "fs";
8070
- import path58 from "path";
8182
+ import fs7 from "fs";
8183
+ import path60 from "path";
8071
8184
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
8072
8185
  var PRETTIER_CONFIGS = [
8073
8186
  "prettier.config.mjs",
@@ -8086,10 +8199,10 @@ var zirkaBaselineRule = {
8086
8199
  }
8087
8200
  },
8088
8201
  create(context) {
8089
- const filename = path58.resolve(context.filename);
8090
- const basename = path58.basename(filename);
8202
+ const filename = path60.resolve(context.filename);
8203
+ const basename = path60.basename(filename);
8091
8204
  if (!ESLINT_CONFIG.test(basename)) return {};
8092
- const projectRoot = path58.dirname(filename);
8205
+ const projectRoot = path60.dirname(filename);
8093
8206
  const report3 = (message) => {
8094
8207
  context.report({
8095
8208
  node: context.sourceCode.ast,
@@ -8104,13 +8217,13 @@ var zirkaBaselineRule = {
8104
8217
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
8105
8218
  );
8106
8219
  }
8107
- const tsconfigPath = path58.join(projectRoot, "tsconfig.json");
8108
- if (!fs6.existsSync(tsconfigPath)) {
8220
+ const tsconfigPath = path60.join(projectRoot, "tsconfig.json");
8221
+ if (!fs7.existsSync(tsconfigPath)) {
8109
8222
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
8110
8223
  } else {
8111
8224
  let extendsValue;
8112
8225
  try {
8113
- const parsed = JSON.parse(fs6.readFileSync(tsconfigPath, "utf8"));
8226
+ const parsed = JSON.parse(fs7.readFileSync(tsconfigPath, "utf8"));
8114
8227
  extendsValue = typeof parsed === "object" && parsed !== null && "extends" in parsed ? parsed.extends : void 0;
8115
8228
  } catch {
8116
8229
  report3(
@@ -8122,13 +8235,13 @@ var zirkaBaselineRule = {
8122
8235
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
8123
8236
  }
8124
8237
  }
8125
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs6.existsSync(path58.join(projectRoot, name)));
8238
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path60.join(projectRoot, name)));
8126
8239
  if (!prettierConfigFile) {
8127
8240
  report3(
8128
8241
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
8129
8242
  );
8130
8243
  } else {
8131
- const content = fs6.readFileSync(path58.join(projectRoot, prettierConfigFile), "utf8");
8244
+ const content = fs7.readFileSync(path60.join(projectRoot, prettierConfigFile), "utf8");
8132
8245
  if (!content.includes("zirka")) {
8133
8246
  report3(
8134
8247
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -8335,10 +8448,12 @@ var pasikaNextjsAppRules = {
8335
8448
  "no-util-barrel": noUtilBarrelRule,
8336
8449
  "no-redundant-alias": noRedundantAliasRule,
8337
8450
  "enforce-barrel-exports": enforceBarrelExportsRule,
8451
+ "require-barrel-star-exports": requireBarrelStarExportsRule,
8338
8452
  "config-extraction": configExtractionRule,
8339
8453
  "value-extraction": valueExtractionRule,
8340
8454
  "constant-casing": constantCasingRule,
8341
8455
  "prefer-enum": preferEnumRule,
8456
+ "enum-placement": enumPlacementRule,
8342
8457
  "type-extraction": typeExtractionRule,
8343
8458
  "zod-schema-validation": zodSchemaValidationRule,
8344
8459
  "schema-casing": schemaCasingRule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.52",
3
+ "version": "0.10.54",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",