pasika 0.10.51 → 0.10.53

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.
@@ -208,6 +208,7 @@ declare const pasikaPlugin: {
208
208
  "value-extraction": eslint.Rule.RuleModule;
209
209
  "constant-casing": eslint.Rule.RuleModule;
210
210
  "prefer-enum": eslint.Rule.RuleModule;
211
+ "enum-placement": eslint.Rule.RuleModule;
211
212
  "type-extraction": eslint.Rule.RuleModule;
212
213
  "zod-schema-validation": eslint.Rule.RuleModule;
213
214
  "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
  }
@@ -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}.` });
@@ -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 {};
@@ -5672,7 +5706,7 @@ var repeatedStructureRule = {
5672
5706
  };
5673
5707
 
5674
5708
  // eslint/rules/root-support-placement.ts
5675
- import path42 from "path";
5709
+ import path43 from "path";
5676
5710
  function isSupportFolder(value) {
5677
5711
  return value === "utils" || value === "types" || value === "schemas" || value === "constants";
5678
5712
  }
@@ -5705,7 +5739,7 @@ var rootSupportPlacementRule = {
5705
5739
  },
5706
5740
  create(context) {
5707
5741
  const sourceRoot = sourceRootOf(context);
5708
- const file = path42.resolve(context.filename);
5742
+ const file = path43.resolve(context.filename);
5709
5743
  const segments = segmentsOf(file, sourceRoot);
5710
5744
  const folderSegments = folderSegmentsOf(file, sourceRoot);
5711
5745
  const supportFolder = folderSegments[folderSegments.length - 1];
@@ -5745,7 +5779,7 @@ var rootSupportPlacementRule = {
5745
5779
  };
5746
5780
 
5747
5781
  // eslint/rules/route-handler-shape.ts
5748
- import path43 from "path";
5782
+ import path44 from "path";
5749
5783
  import ts7 from "typescript";
5750
5784
  var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
5751
5785
  var REQUIRED_BOUNDARY = "withResponse";
@@ -5830,7 +5864,7 @@ var routeHandlerShapeRule = {
5830
5864
  }
5831
5865
  },
5832
5866
  create(context) {
5833
- if (path43.basename(context.filename) !== "route.ts") return {};
5867
+ if (path44.basename(context.filename) !== "route.ts") return {};
5834
5868
  const sourceText = context.sourceCode.text;
5835
5869
  function reportUnwrapped(node, name) {
5836
5870
  context.report({
@@ -5889,7 +5923,7 @@ var routeHandlerShapeRule = {
5889
5923
  };
5890
5924
 
5891
5925
  // eslint/rules/schema-casing.ts
5892
- import path44 from "path";
5926
+ import path45 from "path";
5893
5927
  function isCamelCase(name) {
5894
5928
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
5895
5929
  }
@@ -5917,9 +5951,9 @@ var schemaCasingRule = {
5917
5951
  }
5918
5952
  },
5919
5953
  create(context) {
5920
- const filename = path44.resolve(context.filename);
5954
+ const filename = path45.resolve(context.filename);
5921
5955
  const sourceRoot = sourceRootOf(context);
5922
- if (!filename.startsWith(sourceRoot + path44.sep)) return {};
5956
+ if (!filename.startsWith(sourceRoot + path45.sep)) return {};
5923
5957
  let zodLocalName;
5924
5958
  return {
5925
5959
  ImportDeclaration(node) {
@@ -5951,7 +5985,7 @@ var schemaCasingRule = {
5951
5985
  };
5952
5986
 
5953
5987
  // eslint/rules/sole-state-owner.ts
5954
- import path45 from "path";
5988
+ import path46 from "path";
5955
5989
  import ts8 from "typescript";
5956
5990
  function findStateHooks(node) {
5957
5991
  const hooks = [];
@@ -6031,7 +6065,7 @@ var soleStateOwnerRule = {
6031
6065
  }
6032
6066
  },
6033
6067
  create(context) {
6034
- const filename = path45.resolve(context.filename);
6068
+ const filename = path46.resolve(context.filename);
6035
6069
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
6036
6070
  const text = context.sourceCode.text;
6037
6071
  const components = parseComponentInfo(text, filename);
@@ -6110,7 +6144,7 @@ function usesOutsideJsx(declaration, hook, children) {
6110
6144
  }
6111
6145
 
6112
6146
  // eslint/rules/source-under-src.ts
6113
- import path46 from "path";
6147
+ import path47 from "path";
6114
6148
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
6115
6149
  ".agents",
6116
6150
  ".cache",
@@ -6151,14 +6185,14 @@ var sourceUnderSrcRule = {
6151
6185
  }
6152
6186
  },
6153
6187
  create(context) {
6154
- const filename = path46.resolve(context.filename);
6188
+ const filename = path47.resolve(context.filename);
6155
6189
  if (!MODULE_EXTENSION.test(filename)) return {};
6156
- const relative = path46.relative(context.cwd, filename).replace(/\\/g, "/");
6190
+ const relative = path47.relative(context.cwd, filename).replace(/\\/g, "/");
6157
6191
  if (relative === "src" || relative.startsWith("src/")) return {};
6158
6192
  const topLevel = relative.split("/")[0] ?? "";
6159
6193
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
6160
6194
  if (!relative.includes("/")) {
6161
- const basename = path46.basename(filename);
6195
+ const basename = path47.basename(filename);
6162
6196
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
6163
6197
  }
6164
6198
  return {
@@ -6174,7 +6208,7 @@ var sourceUnderSrcRule = {
6174
6208
  };
6175
6209
 
6176
6210
  // eslint/rules/stay-flat.ts
6177
- import path47 from "path";
6211
+ import path48 from "path";
6178
6212
  var stayFlatRule = {
6179
6213
  meta: {
6180
6214
  schema: [],
@@ -6185,7 +6219,7 @@ var stayFlatRule = {
6185
6219
  },
6186
6220
  create(context) {
6187
6221
  const sourceRoot = sourceRootOf(context);
6188
- const file = path47.resolve(context.filename);
6222
+ const file = path48.resolve(context.filename);
6189
6223
  const segments = segmentsOf(file, sourceRoot);
6190
6224
  if (segments.length !== 3 || segments[0] !== "features") return {};
6191
6225
  const index = getProjectIndex(sourceRoot);
@@ -6225,7 +6259,7 @@ var stayFlatRule = {
6225
6259
  };
6226
6260
 
6227
6261
  // eslint/rules/support-file-placement.ts
6228
- import path48 from "path";
6262
+ import path49 from "path";
6229
6263
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
6230
6264
  var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
6231
6265
  ["constants", "constant"],
@@ -6250,7 +6284,7 @@ var supportFilePlacementRule = {
6250
6284
  },
6251
6285
  create(context) {
6252
6286
  const sourceRoot = sourceRootOf(context);
6253
- const supportFile = path48.resolve(context.filename);
6287
+ const supportFile = path49.resolve(context.filename);
6254
6288
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
6255
6289
  const supportFolder = currentFolder[currentFolder.length - 1];
6256
6290
  if (supportFolder === void 0 || !SUPPORT_FOLDERS.has(supportFolder)) return {};
@@ -6304,7 +6338,7 @@ var supportFilePlacementRule = {
6304
6338
 
6305
6339
  // eslint/rules/support-folder-shape.ts
6306
6340
  import fs5 from "fs";
6307
- import path49 from "path";
6341
+ import path50 from "path";
6308
6342
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
6309
6343
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
6310
6344
  var supportFolderShapeRule = {
@@ -6316,12 +6350,12 @@ var supportFolderShapeRule = {
6316
6350
  }
6317
6351
  },
6318
6352
  create(context) {
6319
- const filename = path49.resolve(context.filename);
6320
- const baseName = path49.basename(filename);
6353
+ const filename = path50.resolve(context.filename);
6354
+ const baseName = path50.basename(filename);
6321
6355
  if (!INDEX_NAMES.has(baseName)) return {};
6322
- const folder = path49.basename(path49.dirname(filename));
6356
+ const folder = path50.basename(path50.dirname(filename));
6323
6357
  if (!SUPPORT_FOLDERS3.has(folder)) return {};
6324
- const directory = path49.dirname(filename);
6358
+ const directory = path50.dirname(filename);
6325
6359
  let entries;
6326
6360
  try {
6327
6361
  entries = fs5.readdirSync(directory);
@@ -6332,14 +6366,14 @@ var supportFolderShapeRule = {
6332
6366
  return {
6333
6367
  Program(node) {
6334
6368
  const source = context.sourceCode.text;
6335
- const hasDirectExport = /export\s+(?:const|let|var|function|class|type|interface|enum)\b/.test(source);
6369
+ const hasDirectExport = /export\s+(?:const|let|var|function|class|interface|enum)\b/.test(source) || /export\s+type\s+[A-Za-z_$][\w$]*(?:\s*<[^;=]*>)?\s*=/.test(source);
6336
6370
  const exportedFiles = /* @__PURE__ */ new Set();
6337
6371
  let hasAnyReExport = false;
6338
6372
  const exportPattern = /export\s+(?:type\s+)?(?:\{[^}]*\}|\*)\s+from\s+["'](?<specifier>[^"']+)["']/g;
6339
6373
  for (const match of source.matchAll(exportPattern)) {
6340
6374
  hasAnyReExport = true;
6341
6375
  const specifier = match.groups?.specifier;
6342
- if (specifier?.startsWith(".")) exportedFiles.add(path49.basename(specifier));
6376
+ if (specifier?.startsWith(".")) exportedFiles.add(path50.basename(specifier));
6343
6377
  }
6344
6378
  const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
6345
6379
  if (siblingModules.length === 0) {
@@ -6518,11 +6552,11 @@ var baseLayerPairRule = {
6518
6552
 
6519
6553
  // eslint/rules/tailwind/css-entry-point.ts
6520
6554
  import { statSync as statSync4 } from "fs";
6521
- import path52 from "path";
6555
+ import path53 from "path";
6522
6556
 
6523
6557
  // eslint/rules/tailwind/source-files.ts
6524
6558
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
6525
- import path50 from "path";
6559
+ import path51 from "path";
6526
6560
  var CSS_EXTENSIONS = [".css"];
6527
6561
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
6528
6562
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS3, ...CSS_EXTENSIONS];
@@ -6535,7 +6569,7 @@ function findFiles(dir, extensions) {
6535
6569
  }
6536
6570
  return entries.flatMap((entry) => {
6537
6571
  if (entry.startsWith(".") || entry === "node_modules") return [];
6538
- const entryPath = path50.join(dir, entry);
6572
+ const entryPath = path51.join(dir, entry);
6539
6573
  let stats;
6540
6574
  try {
6541
6575
  stats = statSync3(entryPath);
@@ -6543,7 +6577,7 @@ function findFiles(dir, extensions) {
6543
6577
  return [];
6544
6578
  }
6545
6579
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
6546
- return extensions.includes(path50.extname(entry)) ? [entryPath] : [];
6580
+ return extensions.includes(path51.extname(entry)) ? [entryPath] : [];
6547
6581
  });
6548
6582
  }
6549
6583
  function cachedTextReader() {
@@ -6566,7 +6600,7 @@ function escapeRegExp(text) {
6566
6600
  }
6567
6601
 
6568
6602
  // eslint/rules/tailwind/stylesheet-graph.ts
6569
- import path51 from "path";
6603
+ import path52 from "path";
6570
6604
  function registersTailwind(text) {
6571
6605
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
6572
6606
  }
@@ -6580,25 +6614,25 @@ function moduleImports(text, fileName) {
6580
6614
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
6581
6615
  }
6582
6616
  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));
6617
+ if (spec.startsWith("/")) return path52.resolve(spec);
6618
+ if (spec.startsWith("./") || spec.startsWith("../")) return path52.resolve(path52.dirname(fromFile), spec);
6619
+ if (spec.startsWith("@/")) return path52.resolve(sourceRoot, spec.slice(2));
6586
6620
  return void 0;
6587
6621
  }
6588
6622
  function buildStylesheetGraph(options) {
6589
6623
  const { cssFiles, sourceRoot, textOf } = options;
6590
- const cssSet = new Set(cssFiles.map((file) => path51.normalize(file)));
6624
+ const cssSet = new Set(cssFiles.map((file) => path52.normalize(file)));
6591
6625
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
6592
6626
  const reachable = /* @__PURE__ */ new Set();
6593
6627
  const queue = [...globals];
6594
- for (const global of globals) reachable.add(path51.normalize(global));
6628
+ for (const global of globals) reachable.add(path52.normalize(global));
6595
6629
  while (queue.length > 0) {
6596
6630
  const from = queue.shift();
6597
6631
  if (!from) continue;
6598
6632
  for (const spec of importedSpecifiers(textOf(from))) {
6599
6633
  const target = resolveSpecifier2(from, spec, sourceRoot);
6600
6634
  if (!target) continue;
6601
- const normalized = path51.normalize(target);
6635
+ const normalized = path52.normalize(target);
6602
6636
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
6603
6637
  reachable.add(normalized);
6604
6638
  queue.push(normalized);
@@ -6610,7 +6644,7 @@ function buildStylesheetGraph(options) {
6610
6644
  for (const spec of importedSpecifiers(textOf(global))) {
6611
6645
  const target = resolveSpecifier2(global, spec, sourceRoot);
6612
6646
  if (!target) continue;
6613
- const normalized = path51.normalize(target);
6647
+ const normalized = path52.normalize(target);
6614
6648
  if (cssSet.has(normalized)) directChildren.add(normalized);
6615
6649
  }
6616
6650
  }
@@ -6618,8 +6652,8 @@ function buildStylesheetGraph(options) {
6618
6652
  }
6619
6653
 
6620
6654
  // 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");
6655
+ var APP_STYLES_DIR = path53.join("app", "styles");
6656
+ var GLOBAL_STYLESHEET_PATH = path53.join(APP_STYLES_DIR, "globals.css");
6623
6657
  var cssEntryPointRule = {
6624
6658
  meta: {
6625
6659
  schema: [],
@@ -6645,8 +6679,8 @@ var cssEntryPointRule = {
6645
6679
  return {
6646
6680
  "StyleSheet:exit"(node) {
6647
6681
  if (globals.length === 0) return;
6648
- const current = path52.normalize(path52.resolve(context.filename));
6649
- const relative = path52.relative(sourceRoot, current);
6682
+ const current = path53.normalize(path53.resolve(context.filename));
6683
+ const relative = path53.relative(sourceRoot, current);
6650
6684
  if (globals.includes(current)) {
6651
6685
  if (globals.length > 1) {
6652
6686
  context.report({
@@ -6662,7 +6696,7 @@ var cssEntryPointRule = {
6662
6696
  });
6663
6697
  return;
6664
6698
  }
6665
- const basename = path52.basename(current);
6699
+ const basename = path53.basename(current);
6666
6700
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
6667
6701
  if (importCount !== 1) {
6668
6702
  context.report({
@@ -6672,7 +6706,7 @@ var cssEntryPointRule = {
6672
6706
  }
6673
6707
  return;
6674
6708
  }
6675
- const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path52.sep}`);
6709
+ const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path53.sep}`);
6676
6710
  if (!isInAppStyles) {
6677
6711
  context.report({
6678
6712
  node,
@@ -7161,7 +7195,7 @@ var tailwindRules = {
7161
7195
  };
7162
7196
 
7163
7197
  // eslint/rules/type-extraction.ts
7164
- import path53 from "path";
7198
+ import path54 from "path";
7165
7199
  var typeExtractionRule = {
7166
7200
  meta: {
7167
7201
  schema: [],
@@ -7172,7 +7206,7 @@ var typeExtractionRule = {
7172
7206
  },
7173
7207
  create(context) {
7174
7208
  const sourceRoot = sourceRootOf(context);
7175
- const file = path53.resolve(context.filename);
7209
+ const file = path54.resolve(context.filename);
7176
7210
  const segments = segmentsOf(file, sourceRoot);
7177
7211
  if (segments.length === 0) return {};
7178
7212
  const index = getProjectIndex(sourceRoot);
@@ -7307,7 +7341,7 @@ var uiStateRule = {
7307
7341
  // eslint/rules/unknown-utility.ts
7308
7342
  import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
7309
7343
  import { createRequire } from "module";
7310
- import path54 from "path";
7344
+ import path55 from "path";
7311
7345
  var PREFIX_NAMESPACES = {
7312
7346
  bg: ["color"],
7313
7347
  text: ["color", "text"],
@@ -7547,7 +7581,7 @@ function stylesheetFiles(dir) {
7547
7581
  }
7548
7582
  return entries.flatMap((entry) => {
7549
7583
  if (entry.startsWith(".") || entry === "node_modules") return [];
7550
- const entryPath = path54.join(dir, entry);
7584
+ const entryPath = path55.join(dir, entry);
7551
7585
  let stats;
7552
7586
  try {
7553
7587
  stats = statSync6(entryPath);
@@ -7555,7 +7589,7 @@ function stylesheetFiles(dir) {
7555
7589
  return [];
7556
7590
  }
7557
7591
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
7558
- return path54.extname(entry) === ".css" ? [entryPath] : [];
7592
+ return path55.extname(entry) === ".css" ? [entryPath] : [];
7559
7593
  });
7560
7594
  }
7561
7595
  function packageNameOf(specifier) {
@@ -7566,10 +7600,10 @@ function packageNameOf(specifier) {
7566
7600
  function resolvePackageStylesheet(fromFile, specifier) {
7567
7601
  const packageName = packageNameOf(specifier);
7568
7602
  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");
7603
+ let directory = path55.dirname(fromFile);
7604
+ while (directory !== path55.dirname(directory)) {
7605
+ const packageRoot = path55.join(directory, "node_modules", packageName);
7606
+ const manifestPath = path55.join(packageRoot, "package.json");
7573
7607
  if (existsSync6(manifestPath)) {
7574
7608
  try {
7575
7609
  const manifest = readFileSync10(manifestPath, "utf8");
@@ -7577,13 +7611,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
7577
7611
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
7578
7612
  const target = stylesheet ?? main;
7579
7613
  if (!target) return void 0;
7580
- const resolved = path54.resolve(packageRoot, target);
7614
+ const resolved = path55.resolve(packageRoot, target);
7581
7615
  return existsSync6(resolved) ? resolved : void 0;
7582
7616
  } catch {
7583
7617
  return void 0;
7584
7618
  }
7585
7619
  }
7586
- directory = path54.dirname(directory);
7620
+ directory = path55.dirname(directory);
7587
7621
  }
7588
7622
  return void 0;
7589
7623
  }
@@ -7834,7 +7868,7 @@ var unknownUtilityRule = {
7834
7868
  };
7835
7869
 
7836
7870
  // eslint/rules/util-file-name.ts
7837
- import path55 from "path";
7871
+ import path56 from "path";
7838
7872
  function toKebabCase2(value) {
7839
7873
  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
7874
  }
@@ -7847,7 +7881,7 @@ var utilFileNameRule = {
7847
7881
  }
7848
7882
  },
7849
7883
  create(context) {
7850
- const filename = path55.resolve(context.filename);
7884
+ const filename = path56.resolve(context.filename);
7851
7885
  const segments = filename.replace(/\\/g, "/").split("/");
7852
7886
  if (!segments.includes("utils")) return {};
7853
7887
  let module;
@@ -7861,13 +7895,13 @@ var utilFileNameRule = {
7861
7895
  const functionName = functions[0]?.name;
7862
7896
  if (!functionName) return {};
7863
7897
  const expected = toKebabCase2(functionName);
7864
- const actual = path55.basename(filename, path55.extname(filename));
7898
+ const actual = path56.basename(filename, path56.extname(filename));
7865
7899
  if (!expected || actual === expected) return {};
7866
7900
  return {
7867
7901
  Program(node) {
7868
7902
  context.report({
7869
7903
  node,
7870
- message: `A utility file exporting ${functionName} must be named ${expected}.${path55.extname(filename).slice(1)}.`
7904
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path56.extname(filename).slice(1)}.`
7871
7905
  });
7872
7906
  }
7873
7907
  };
@@ -7875,7 +7909,7 @@ var utilFileNameRule = {
7875
7909
  };
7876
7910
 
7877
7911
  // eslint/rules/value-extraction.ts
7878
- import path56 from "path";
7912
+ import path57 from "path";
7879
7913
  var valueExtractionRule = {
7880
7914
  meta: {
7881
7915
  schema: [],
@@ -7886,7 +7920,7 @@ var valueExtractionRule = {
7886
7920
  },
7887
7921
  create(context) {
7888
7922
  const sourceRoot = sourceRootOf(context);
7889
- const file = path56.resolve(context.filename);
7923
+ const file = path57.resolve(context.filename);
7890
7924
  const segments = segmentsOf(file, sourceRoot);
7891
7925
  if (segments.length === 0 || segments[0] !== "app") return {};
7892
7926
  const index = getProjectIndex(sourceRoot);
@@ -7908,7 +7942,7 @@ var valueExtractionRule = {
7908
7942
 
7909
7943
  // eslint/rules/vulyk/tracked-docs.ts
7910
7944
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "fs";
7911
- import path57 from "path";
7945
+ import path58 from "path";
7912
7946
  var PASIKA_REPO = "Bredansky/pasika";
7913
7947
  var BASE_REQUIRED_TRACKED_DOCS = [
7914
7948
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -7941,8 +7975,8 @@ var trackedDocsRule = {
7941
7975
  if (!context.filename.endsWith("package.json")) return;
7942
7976
  const root = node.body;
7943
7977
  if (root.type !== "Object") return;
7944
- const projectRoot = path57.dirname(path57.resolve(context.filename));
7945
- const configPath = path57.join(projectRoot, "vulyk.config.ts");
7978
+ const projectRoot = path58.dirname(path58.resolve(context.filename));
7979
+ const configPath = path58.join(projectRoot, "vulyk.config.ts");
7946
7980
  if (!existsSync7(configPath)) {
7947
7981
  context.report({
7948
7982
  node,
@@ -7967,7 +8001,7 @@ var trackedDocsRule = {
7967
8001
  });
7968
8002
  }
7969
8003
  }
7970
- const agentsPath = path57.join(projectRoot, "AGENTS.md");
8004
+ const agentsPath = path58.join(projectRoot, "AGENTS.md");
7971
8005
  if (!existsSync7(agentsPath)) {
7972
8006
  context.report({
7973
8007
  node,
@@ -8067,7 +8101,7 @@ var withResponseHelperRule = {
8067
8101
 
8068
8102
  // eslint/rules/zirka-baseline.ts
8069
8103
  import fs6 from "fs";
8070
- import path58 from "path";
8104
+ import path59 from "path";
8071
8105
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
8072
8106
  var PRETTIER_CONFIGS = [
8073
8107
  "prettier.config.mjs",
@@ -8086,10 +8120,10 @@ var zirkaBaselineRule = {
8086
8120
  }
8087
8121
  },
8088
8122
  create(context) {
8089
- const filename = path58.resolve(context.filename);
8090
- const basename = path58.basename(filename);
8123
+ const filename = path59.resolve(context.filename);
8124
+ const basename = path59.basename(filename);
8091
8125
  if (!ESLINT_CONFIG.test(basename)) return {};
8092
- const projectRoot = path58.dirname(filename);
8126
+ const projectRoot = path59.dirname(filename);
8093
8127
  const report3 = (message) => {
8094
8128
  context.report({
8095
8129
  node: context.sourceCode.ast,
@@ -8104,7 +8138,7 @@ var zirkaBaselineRule = {
8104
8138
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
8105
8139
  );
8106
8140
  }
8107
- const tsconfigPath = path58.join(projectRoot, "tsconfig.json");
8141
+ const tsconfigPath = path59.join(projectRoot, "tsconfig.json");
8108
8142
  if (!fs6.existsSync(tsconfigPath)) {
8109
8143
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
8110
8144
  } else {
@@ -8122,13 +8156,13 @@ var zirkaBaselineRule = {
8122
8156
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
8123
8157
  }
8124
8158
  }
8125
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs6.existsSync(path58.join(projectRoot, name)));
8159
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs6.existsSync(path59.join(projectRoot, name)));
8126
8160
  if (!prettierConfigFile) {
8127
8161
  report3(
8128
8162
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
8129
8163
  );
8130
8164
  } else {
8131
- const content = fs6.readFileSync(path58.join(projectRoot, prettierConfigFile), "utf8");
8165
+ const content = fs6.readFileSync(path59.join(projectRoot, prettierConfigFile), "utf8");
8132
8166
  if (!content.includes("zirka")) {
8133
8167
  report3(
8134
8168
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -8339,6 +8373,7 @@ var pasikaNextjsAppRules = {
8339
8373
  "value-extraction": valueExtractionRule,
8340
8374
  "constant-casing": constantCasingRule,
8341
8375
  "prefer-enum": preferEnumRule,
8376
+ "enum-placement": enumPlacementRule,
8342
8377
  "type-extraction": typeExtractionRule,
8343
8378
  "zod-schema-validation": zodSchemaValidationRule,
8344
8379
  "schema-casing": schemaCasingRule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.51",
3
+ "version": "0.10.53",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",