pasika 0.8.1 → 0.9.1

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.
@@ -200,6 +200,7 @@ declare const pasikaPlugin: {
200
200
  "config-extraction": eslint.Rule.RuleModule;
201
201
  "value-extraction": eslint.Rule.RuleModule;
202
202
  "constant-casing": eslint.Rule.RuleModule;
203
+ "prefer-enum": eslint.Rule.RuleModule;
203
204
  "type-extraction": eslint.Rule.RuleModule;
204
205
  "zod-schema-validation": eslint.Rule.RuleModule;
205
206
  "schema-casing": eslint.Rule.RuleModule;
@@ -2170,8 +2170,47 @@ var constantCasingRule = {
2170
2170
  }
2171
2171
  };
2172
2172
 
2173
- // eslint/rules/import-through-index.ts
2173
+ // eslint/rules/prefer-enum.ts
2174
2174
  import path18 from "path";
2175
+ function isConstAssertion(node) {
2176
+ const typeAnnotation = node.typeAnnotation;
2177
+ return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
2178
+ }
2179
+ function isEnumConvertibleProperty(property) {
2180
+ if (property.type !== "Property" || property.computed) return false;
2181
+ const { value } = property;
2182
+ return value.type === "Literal" && (typeof value.value === "string" || typeof value.value === "number");
2183
+ }
2184
+ var preferEnumRule = {
2185
+ meta: {
2186
+ schema: [],
2187
+ type: "problem",
2188
+ docs: {
2189
+ description: "Require a fixed set of named string/number values to be a TypeScript enum, not an `as const` object literal."
2190
+ }
2191
+ },
2192
+ create(context) {
2193
+ const filename = path18.resolve(context.filename);
2194
+ const sourceRoot = sourceRootOf(context);
2195
+ if (!filename.startsWith(sourceRoot + path18.sep)) return {};
2196
+ return {
2197
+ TSAsExpression(node) {
2198
+ if (!isConstAssertion(node)) return;
2199
+ const expression = node.expression;
2200
+ if (!expression || expression.type !== "ObjectExpression") return;
2201
+ if (expression.properties.length === 0) return;
2202
+ if (!expression.properties.every(isEnumConvertibleProperty)) return;
2203
+ context.report({
2204
+ node,
2205
+ message: "A fixed set of named values must be a TypeScript enum, not an object literal marked as const. See docs/next-codebase-guide/rules/constants-rule.md"
2206
+ });
2207
+ }
2208
+ };
2209
+ }
2210
+ };
2211
+
2212
+ // eslint/rules/import-through-index.ts
2213
+ import path19 from "path";
2175
2214
  var importThroughIndexRule = {
2176
2215
  meta: {
2177
2216
  schema: [],
@@ -2181,7 +2220,7 @@ var importThroughIndexRule = {
2181
2220
  }
2182
2221
  },
2183
2222
  create(context) {
2184
- const filename = path18.resolve(context.filename);
2223
+ const filename = path19.resolve(context.filename);
2185
2224
  const sourceRoot = sourceRootOf2(context, filename);
2186
2225
  return {
2187
2226
  Program(node) {
@@ -2193,7 +2232,7 @@ var importThroughIndexRule = {
2193
2232
  (segment) => ["constants", "types", "schemas"].includes(segment)
2194
2233
  );
2195
2234
  const supportFolder = supportFolderIndex >= 0 ? targetSegments[supportFolderIndex] : void 0;
2196
- if (!supportFolder || path18.basename(target).startsWith("index.")) continue;
2235
+ if (!supportFolder || path19.basename(target).startsWith("index.")) continue;
2197
2236
  const folderIndex = targetSegments.slice(0, supportFolderIndex + 1);
2198
2237
  const expected = `@/${folderIndex.join("/")}`;
2199
2238
  context.report({
@@ -2215,14 +2254,14 @@ function importSpecifiers(source) {
2215
2254
  return specifiers;
2216
2255
  }
2217
2256
  function sourceRootOf2(context, filename) {
2218
- const marker = `${path18.sep}src${path18.sep}`;
2257
+ const marker = `${path19.sep}src${path19.sep}`;
2219
2258
  const srcIndex = filename.lastIndexOf(marker);
2220
2259
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
2221
- return path18.resolve(context.cwd ?? process.cwd(), "src");
2260
+ return path19.resolve(context.cwd ?? process.cwd(), "src");
2222
2261
  }
2223
2262
 
2224
2263
  // eslint/rules/util-file-name.ts
2225
- import path19 from "path";
2264
+ import path20 from "path";
2226
2265
  function toKebabCase2(value) {
2227
2266
  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();
2228
2267
  }
@@ -2235,7 +2274,7 @@ var utilFileNameRule = {
2235
2274
  }
2236
2275
  },
2237
2276
  create(context) {
2238
- const filename = path19.resolve(context.filename);
2277
+ const filename = path20.resolve(context.filename);
2239
2278
  const segments = filename.replace(/\\/g, "/").split("/");
2240
2279
  if (!segments.includes("utils")) return {};
2241
2280
  let module;
@@ -2249,13 +2288,13 @@ var utilFileNameRule = {
2249
2288
  const functionName = functions[0]?.name;
2250
2289
  if (!functionName) return {};
2251
2290
  const expected = toKebabCase2(functionName);
2252
- const actual = path19.basename(filename, path19.extname(filename));
2291
+ const actual = path20.basename(filename, path20.extname(filename));
2253
2292
  if (!expected || actual === expected) return {};
2254
2293
  return {
2255
2294
  Program(node) {
2256
2295
  context.report({
2257
2296
  node,
2258
- message: `A utility file exporting ${functionName} must be named ${expected}.${path19.extname(filename).slice(1)}.`
2297
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path20.extname(filename).slice(1)}.`
2259
2298
  });
2260
2299
  }
2261
2300
  };
@@ -2263,7 +2302,7 @@ var utilFileNameRule = {
2263
2302
  };
2264
2303
 
2265
2304
  // eslint/rules/no-util-barrel.ts
2266
- import path20 from "path";
2305
+ import path21 from "path";
2267
2306
  var noUtilBarrelRule = {
2268
2307
  meta: {
2269
2308
  schema: [],
@@ -2273,7 +2312,7 @@ var noUtilBarrelRule = {
2273
2312
  }
2274
2313
  },
2275
2314
  create(context) {
2276
- const filename = path20.resolve(context.filename);
2315
+ const filename = path21.resolve(context.filename);
2277
2316
  const sourceRoot = sourceRootOf3(context, filename);
2278
2317
  return {
2279
2318
  Program(node) {
@@ -2282,7 +2321,7 @@ var noUtilBarrelRule = {
2282
2321
  if (!target) continue;
2283
2322
  const segments = target.replace(/\\/g, "/").split("/");
2284
2323
  const utilsIndex = segments.lastIndexOf("utils");
2285
- if (utilsIndex < 0 || !path20.basename(target).startsWith("index.")) continue;
2324
+ if (utilsIndex < 0 || !path21.basename(target).startsWith("index.")) continue;
2286
2325
  context.report({
2287
2326
  node,
2288
2327
  message: `Import utilities directly instead of through "${specifier}". See docs/next-codebase-guide/rules/utilities-rule.md`
@@ -2302,10 +2341,10 @@ function importSpecifiers2(source) {
2302
2341
  return specifiers;
2303
2342
  }
2304
2343
  function sourceRootOf3(context, filename) {
2305
- const marker = `${path20.sep}src${path20.sep}`;
2344
+ const marker = `${path21.sep}src${path21.sep}`;
2306
2345
  const srcIndex = filename.lastIndexOf(marker);
2307
2346
  if (srcIndex >= 0) return filename.slice(0, srcIndex + marker.length - 1);
2308
- return path20.resolve(context.cwd ?? process.cwd(), "src");
2347
+ return path21.resolve(context.cwd ?? process.cwd(), "src");
2309
2348
  }
2310
2349
 
2311
2350
  // eslint/rules/jsx-hygiene.ts
@@ -2398,7 +2437,7 @@ var jsxHygieneRule = {
2398
2437
  };
2399
2438
 
2400
2439
  // eslint/rules/interactive-component.ts
2401
- import path21 from "path";
2440
+ import path22 from "path";
2402
2441
  var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
2403
2442
  "a",
2404
2443
  "button",
@@ -2553,8 +2592,8 @@ var interactiveComponentRule = {
2553
2592
  },
2554
2593
  create(context) {
2555
2594
  if (!context.filename.endsWith(".tsx") && !context.filename.endsWith(".jsx")) return {};
2556
- const filename = path21.resolve(context.filename);
2557
- const base = path21.basename(filename, path21.extname(filename));
2595
+ const filename = path22.resolve(context.filename);
2596
+ const base = path22.basename(filename, path22.extname(filename));
2558
2597
  if (NEXT_ROUTING_FILES3.has(base)) return {};
2559
2598
  return {
2560
2599
  JSXElement(node) {
@@ -2805,12 +2844,12 @@ var cvaBooleanVariantsRule = {
2805
2844
  };
2806
2845
 
2807
2846
  // eslint/rules/cross-feature-import.ts
2808
- import path22 from "path";
2847
+ import path23 from "path";
2809
2848
  var FEATURES_SEGMENT = "features";
2810
2849
  function featureNameOf(resolvedPath, sourceRoot) {
2811
- const relative = path22.relative(sourceRoot, resolvedPath);
2850
+ const relative = path23.relative(sourceRoot, resolvedPath);
2812
2851
  if (relative.startsWith("..")) return void 0;
2813
- const segments = relative.split(path22.sep);
2852
+ const segments = relative.split(path23.sep);
2814
2853
  if (segments[0] !== FEATURES_SEGMENT || segments.length < 2) return void 0;
2815
2854
  return segments[1];
2816
2855
  }
@@ -2826,9 +2865,9 @@ var crossFeatureImportRule = {
2826
2865
  const filename = context.filename;
2827
2866
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2828
2867
  const sourceRoot = sourceRootOf(context);
2829
- const fileRelative = path22.relative(sourceRoot, filename);
2868
+ const fileRelative = path23.relative(sourceRoot, filename);
2830
2869
  if (fileRelative.startsWith("..")) return {};
2831
- const fileSegments = fileRelative.split(path22.sep);
2870
+ const fileSegments = fileRelative.split(path23.sep);
2832
2871
  const isInCompositions = fileSegments[0] === "compositions";
2833
2872
  const isInApp = fileSegments[0] === "app";
2834
2873
  const isConfig = fileSegments[0] === "config";
@@ -2842,9 +2881,9 @@ var crossFeatureImportRule = {
2842
2881
  if (typeof source.value !== "string") return;
2843
2882
  let resolved;
2844
2883
  if (source.value.startsWith("@/")) {
2845
- resolved = path22.resolve(sourceRoot, source.value.slice(2));
2884
+ resolved = path23.resolve(sourceRoot, source.value.slice(2));
2846
2885
  } else if (source.value.startsWith(".")) {
2847
- resolved = path22.resolve(path22.dirname(filename), source.value);
2886
+ resolved = path23.resolve(path23.dirname(filename), source.value);
2848
2887
  }
2849
2888
  if (!resolved) return;
2850
2889
  const feature = featureNameOf(resolved, sourceRoot);
@@ -2863,7 +2902,24 @@ var crossFeatureImportRule = {
2863
2902
  };
2864
2903
 
2865
2904
  // eslint/rules/pure-function-extract.ts
2866
- import path23 from "path";
2905
+ import path24 from "path";
2906
+ var ROUTE_HANDLER_EXPORT_NAMES = /* @__PURE__ */ new Set([
2907
+ "GET",
2908
+ "POST",
2909
+ "PUT",
2910
+ "PATCH",
2911
+ "DELETE",
2912
+ "HEAD",
2913
+ "OPTIONS",
2914
+ "dynamic",
2915
+ "dynamicParams",
2916
+ "revalidate",
2917
+ "fetchCache",
2918
+ "runtime",
2919
+ "preferredRegion",
2920
+ "maxDuration",
2921
+ "generateStaticParams"
2922
+ ]);
2867
2923
  function isComponentLikeName(name) {
2868
2924
  return /^[A-Z]/.test(name);
2869
2925
  }
@@ -2890,13 +2946,14 @@ var pureFunctionExtractRule = {
2890
2946
  },
2891
2947
  create(context) {
2892
2948
  const filename = context.filename;
2893
- if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
2949
+ const isRouteFile = path24.basename(filename) === "route.ts";
2950
+ if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx") && !isRouteFile) return {};
2894
2951
  const sourceRoot = sourceRootOf(context);
2895
- const relative = path23.relative(sourceRoot, filename);
2952
+ const relative = path24.relative(sourceRoot, filename);
2896
2953
  if (relative.startsWith("..")) return {};
2897
- const segments = relative.split(path23.sep);
2954
+ const segments = relative.split(path24.sep);
2898
2955
  if (segments[0] === "utils") return {};
2899
- if (segments[0] === "app") return {};
2956
+ if (segments[0] === "app" && !isRouteFile) return {};
2900
2957
  const supportFolders = /* @__PURE__ */ new Set(["hooks", "types", "schemas", "constants", "utils"]);
2901
2958
  if (segments.length >= 2 && supportFolders.has(segments[segments.length - 1] ?? "")) return {};
2902
2959
  function report3(node, name) {
@@ -2908,9 +2965,12 @@ var pureFunctionExtractRule = {
2908
2965
  return {
2909
2966
  FunctionDeclaration(node) {
2910
2967
  const exported = node.parent?.type === "ExportNamedDeclaration";
2911
- if (!exported) return;
2968
+ const moduleLevel = exported || node.parent?.type === "Program";
2969
+ if (!moduleLevel) return;
2970
+ if (!isRouteFile && !exported) return;
2912
2971
  const name = node.id?.name;
2913
2972
  if (!name) return;
2973
+ if (isRouteFile && ROUTE_HANDLER_EXPORT_NAMES.has(name)) return;
2914
2974
  if (isComponentLikeName(name) || isHookName2(name)) return;
2915
2975
  if (!node.body || hasHookUsage(node.body)) return;
2916
2976
  report3(node, name);
@@ -2919,8 +2979,12 @@ var pureFunctionExtractRule = {
2919
2979
  if (node.id.type !== "Identifier") return;
2920
2980
  const name = node.id.name;
2921
2981
  if (!name) return;
2922
- const exported = node.parent.parent?.type === "ExportNamedDeclaration";
2923
- if (!exported) return;
2982
+ const container = node.parent.parent;
2983
+ const exported = container?.type === "ExportNamedDeclaration";
2984
+ const moduleLevel = exported || container?.type === "Program";
2985
+ if (!moduleLevel) return;
2986
+ if (!isRouteFile && !exported) return;
2987
+ if (isRouteFile && ROUTE_HANDLER_EXPORT_NAMES.has(name)) return;
2924
2988
  if (isComponentLikeName(name) || isHookName2(name)) return;
2925
2989
  const init = node.init;
2926
2990
  if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression") {
@@ -2934,7 +2998,7 @@ var pureFunctionExtractRule = {
2934
2998
  };
2935
2999
 
2936
3000
  // eslint/rules/hook-complexity.ts
2937
- import path24 from "path";
3001
+ import path25 from "path";
2938
3002
  import ts4 from "typescript";
2939
3003
  var REACT_HOOKS = /* @__PURE__ */ new Set([
2940
3004
  "useState",
@@ -2987,9 +3051,9 @@ var hookComplexityRule = {
2987
3051
  create(context) {
2988
3052
  const filename = context.filename;
2989
3053
  const sourceRoot = sourceRootOf(context);
2990
- const relative = path24.relative(sourceRoot, filename);
3054
+ const relative = path25.relative(sourceRoot, filename);
2991
3055
  if (relative.startsWith("..")) return {};
2992
- const segments = relative.split(path24.sep);
3056
+ const segments = relative.split(path25.sep);
2993
3057
  const sourceText = context.sourceCode.text;
2994
3058
  function checkHook(node, name, body, exported) {
2995
3059
  if (!exported) return;
@@ -3031,9 +3095,9 @@ var hookComplexityRule = {
3031
3095
  };
3032
3096
 
3033
3097
  // eslint/rules/locale-dotted-path.ts
3034
- import path25 from "path";
3098
+ import path26 from "path";
3035
3099
  function isInLocalesDir(filename) {
3036
- const segments = path25.resolve(filename).split(path25.sep);
3100
+ const segments = path26.resolve(filename).split(path26.sep);
3037
3101
  const srcIdx = segments.lastIndexOf("src");
3038
3102
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
3039
3103
  }
@@ -3082,9 +3146,9 @@ var localeDottedPathRule = {
3082
3146
  };
3083
3147
 
3084
3148
  // eslint/rules/locales-location.ts
3085
- import path26 from "path";
3149
+ import path27 from "path";
3086
3150
  function isLocalesFile(filename) {
3087
- const segments = path26.resolve(filename).split(path26.sep);
3151
+ const segments = path27.resolve(filename).split(path27.sep);
3088
3152
  const srcIdx = segments.lastIndexOf("src");
3089
3153
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
3090
3154
  }
@@ -3109,7 +3173,7 @@ var localesLocationRule = {
3109
3173
  create(context) {
3110
3174
  if (isLocalesFile(context.filename) || isTestFile(context.filename)) return {};
3111
3175
  const filename = context.filename;
3112
- const segments = path26.resolve(filename).split(path26.sep);
3176
+ const segments = path27.resolve(filename).split(path27.sep);
3113
3177
  const srcIdx = segments.lastIndexOf("src");
3114
3178
  if (srcIdx === -1) return {};
3115
3179
  const folder = segments[srcIdx + 1];
@@ -3133,7 +3197,7 @@ var localesLocationRule = {
3133
3197
  };
3134
3198
 
3135
3199
  // eslint/rules/hook-extraction.ts
3136
- import path27 from "path";
3200
+ import path28 from "path";
3137
3201
  var hookExtractionRule = {
3138
3202
  meta: {
3139
3203
  schema: [],
@@ -3144,7 +3208,7 @@ var hookExtractionRule = {
3144
3208
  },
3145
3209
  create(context) {
3146
3210
  const sourceRoot = sourceRootOf(context);
3147
- const file = path27.resolve(context.filename);
3211
+ const file = path28.resolve(context.filename);
3148
3212
  const segments = segmentsOf(file, sourceRoot);
3149
3213
  if (segments.length === 0) return {};
3150
3214
  const index = getProjectIndex(sourceRoot);
@@ -3170,7 +3234,7 @@ var hookExtractionRule = {
3170
3234
  };
3171
3235
 
3172
3236
  // eslint/rules/value-extraction.ts
3173
- import path28 from "path";
3237
+ import path29 from "path";
3174
3238
  var valueExtractionRule = {
3175
3239
  meta: {
3176
3240
  schema: [],
@@ -3181,7 +3245,7 @@ var valueExtractionRule = {
3181
3245
  },
3182
3246
  create(context) {
3183
3247
  const sourceRoot = sourceRootOf(context);
3184
- const file = path28.resolve(context.filename);
3248
+ const file = path29.resolve(context.filename);
3185
3249
  const segments = segmentsOf(file, sourceRoot);
3186
3250
  if (segments.length === 0 || segments[0] !== "app") return {};
3187
3251
  const index = getProjectIndex(sourceRoot);
@@ -3202,7 +3266,7 @@ var valueExtractionRule = {
3202
3266
  };
3203
3267
 
3204
3268
  // eslint/rules/config-extraction.ts
3205
- import path29 from "path";
3269
+ import path30 from "path";
3206
3270
  var configExtractionRule = {
3207
3271
  meta: {
3208
3272
  schema: [],
@@ -3213,7 +3277,7 @@ var configExtractionRule = {
3213
3277
  },
3214
3278
  create(context) {
3215
3279
  const sourceRoot = sourceRootOf(context);
3216
- const file = path29.resolve(context.filename);
3280
+ const file = path30.resolve(context.filename);
3217
3281
  const segments = segmentsOf(file, sourceRoot);
3218
3282
  if (segments.length < 3 || segments[0] !== "config") return {};
3219
3283
  if (SUPPORT_FOLDERS2.has(segments[2] ?? "")) return {};
@@ -3251,7 +3315,7 @@ var configExtractionRule = {
3251
3315
  };
3252
3316
 
3253
3317
  // eslint/rules/component-nesting.ts
3254
- import path30 from "path";
3318
+ import path31 from "path";
3255
3319
  var componentNestingRule = {
3256
3320
  meta: {
3257
3321
  schema: [],
@@ -3262,7 +3326,7 @@ var componentNestingRule = {
3262
3326
  },
3263
3327
  create(context) {
3264
3328
  const sourceRoot = sourceRootOf(context);
3265
- const file = path30.resolve(context.filename);
3329
+ const file = path31.resolve(context.filename);
3266
3330
  const segments = segmentsOf(file, sourceRoot);
3267
3331
  if (segments.length !== 4 || segments[0] !== "features") return {};
3268
3332
  const index = getProjectIndex(sourceRoot);
@@ -3295,7 +3359,7 @@ var componentNestingRule = {
3295
3359
  };
3296
3360
 
3297
3361
  // eslint/rules/stay-flat.ts
3298
- import path31 from "path";
3362
+ import path32 from "path";
3299
3363
  var stayFlatRule = {
3300
3364
  meta: {
3301
3365
  schema: [],
@@ -3306,7 +3370,7 @@ var stayFlatRule = {
3306
3370
  },
3307
3371
  create(context) {
3308
3372
  const sourceRoot = sourceRootOf(context);
3309
- const file = path31.resolve(context.filename);
3373
+ const file = path32.resolve(context.filename);
3310
3374
  const segments = segmentsOf(file, sourceRoot);
3311
3375
  if (segments.length !== 3 || segments[0] !== "features") return {};
3312
3376
  const index = getProjectIndex(sourceRoot);
@@ -3346,7 +3410,7 @@ var stayFlatRule = {
3346
3410
  };
3347
3411
 
3348
3412
  // eslint/rules/type-extraction.ts
3349
- import path32 from "path";
3413
+ import path33 from "path";
3350
3414
  var typeExtractionRule = {
3351
3415
  meta: {
3352
3416
  schema: [],
@@ -3357,7 +3421,7 @@ var typeExtractionRule = {
3357
3421
  },
3358
3422
  create(context) {
3359
3423
  const sourceRoot = sourceRootOf(context);
3360
- const file = path32.resolve(context.filename);
3424
+ const file = path33.resolve(context.filename);
3361
3425
  const segments = segmentsOf(file, sourceRoot);
3362
3426
  if (segments.length === 0) return {};
3363
3427
  const index = getProjectIndex(sourceRoot);
@@ -3403,7 +3467,7 @@ var typeExtractionRule = {
3403
3467
  };
3404
3468
 
3405
3469
  // eslint/rules/locale-placement.ts
3406
- import path33 from "path";
3470
+ import path34 from "path";
3407
3471
  import { readFileSync as readFileSync4 } from "fs";
3408
3472
  import ts5 from "typescript";
3409
3473
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
@@ -3451,7 +3515,7 @@ var localePlacementRule = {
3451
3515
  },
3452
3516
  create(context) {
3453
3517
  const sourceRoot = sourceRootOf(context);
3454
- const file = path33.resolve(context.filename);
3518
+ const file = path34.resolve(context.filename);
3455
3519
  const segments = segmentsOf(file, sourceRoot);
3456
3520
  if (segments.length === 0) return {};
3457
3521
  const index = getProjectIndex(sourceRoot);
@@ -3529,7 +3593,7 @@ var localePlacementRule = {
3529
3593
  };
3530
3594
 
3531
3595
  // eslint/rules/sole-state-owner.ts
3532
- import path34 from "path";
3596
+ import path35 from "path";
3533
3597
  import ts6 from "typescript";
3534
3598
  function findStateHooks(node) {
3535
3599
  const hooks = [];
@@ -3609,7 +3673,7 @@ var soleStateOwnerRule = {
3609
3673
  }
3610
3674
  },
3611
3675
  create(context) {
3612
- const filename = path34.resolve(context.filename);
3676
+ const filename = path35.resolve(context.filename);
3613
3677
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
3614
3678
  const text = context.sourceCode.text;
3615
3679
  const components = parseComponentInfo(text, filename);
@@ -3688,7 +3752,7 @@ function usesOutsideJsx(declaration, hook, children) {
3688
3752
  }
3689
3753
 
3690
3754
  // eslint/rules/locale-key-shape.ts
3691
- import path35 from "path";
3755
+ import path36 from "path";
3692
3756
  var MAX_KEY_LENGTH = 30;
3693
3757
  var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
3694
3758
  "Button",
@@ -3738,7 +3802,7 @@ var ROLE_POSTFIXES = /* @__PURE__ */ new Set([
3738
3802
  var CAMEL_CASE = /^[a-z][a-zA-Z0-9]*$/;
3739
3803
  var ENGLISH = /^[A-Za-z0-9_]*$/;
3740
3804
  function isLocalesFile2(filename) {
3741
- const segments = path35.resolve(filename).split(path35.sep);
3805
+ const segments = path36.resolve(filename).split(path36.sep);
3742
3806
  const srcIdx = segments.lastIndexOf("src");
3743
3807
  return srcIdx !== -1 && segments[srcIdx + 1] === "locales";
3744
3808
  }
@@ -3809,7 +3873,7 @@ var localeKeyShapeRule = {
3809
3873
  };
3810
3874
 
3811
3875
  // eslint/rules/shared-style-dedup.ts
3812
- import path36 from "path";
3876
+ import path37 from "path";
3813
3877
  import { readFileSync as readFileSync5, statSync as statSync3 } from "fs";
3814
3878
  var CLASS_NAME = /className="(?<classes>[^"]+)"/g;
3815
3879
  var comboCache;
@@ -3847,7 +3911,7 @@ var sharedStyleDedupRule = {
3847
3911
  },
3848
3912
  create(context) {
3849
3913
  const sourceRoot = sourceRootOf(context);
3850
- const file = path36.resolve(context.filename);
3914
+ const file = path37.resolve(context.filename);
3851
3915
  const segments = segmentsOf(file, sourceRoot);
3852
3916
  if (segments.length === 0) return {};
3853
3917
  const index = getProjectIndex(sourceRoot);
@@ -4051,7 +4115,7 @@ var zodSchemaValidationRule = {
4051
4115
  };
4052
4116
 
4053
4117
  // eslint/rules/schema-casing.ts
4054
- import path37 from "path";
4118
+ import path38 from "path";
4055
4119
  function isCamelCase(name) {
4056
4120
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
4057
4121
  }
@@ -4079,9 +4143,9 @@ var schemaCasingRule = {
4079
4143
  }
4080
4144
  },
4081
4145
  create(context) {
4082
- const filename = path37.resolve(context.filename);
4146
+ const filename = path38.resolve(context.filename);
4083
4147
  const sourceRoot = sourceRootOf(context);
4084
- if (!filename.startsWith(sourceRoot + path37.sep)) return {};
4148
+ if (!filename.startsWith(sourceRoot + path38.sep)) return {};
4085
4149
  let zodLocalName;
4086
4150
  return {
4087
4151
  ImportDeclaration(node) {
@@ -4113,7 +4177,7 @@ var schemaCasingRule = {
4113
4177
  };
4114
4178
 
4115
4179
  // eslint/rules/component-casing.ts
4116
- import path38 from "path";
4180
+ import path39 from "path";
4117
4181
  function isPascalCase6(name) {
4118
4182
  return /^[A-Z][A-Za-z0-9]*$/.test(name);
4119
4183
  }
@@ -4126,10 +4190,10 @@ var componentCasingRule = {
4126
4190
  }
4127
4191
  },
4128
4192
  create(context) {
4129
- const filename = path38.resolve(context.filename);
4193
+ const filename = path39.resolve(context.filename);
4130
4194
  const sourceRoot = sourceRootOf(context);
4131
- if (!filename.startsWith(sourceRoot + path38.sep)) return {};
4132
- if (path38.extname(filename) !== ".tsx") return {};
4195
+ if (!filename.startsWith(sourceRoot + path39.sep)) return {};
4196
+ if (path39.extname(filename) !== ".tsx") return {};
4133
4197
  return {
4134
4198
  Program(node) {
4135
4199
  for (const declaration of findJsxReturningDeclarations(context.sourceCode.text, filename)) {
@@ -4146,7 +4210,7 @@ var componentCasingRule = {
4146
4210
  };
4147
4211
 
4148
4212
  // eslint/rules/source-under-src.ts
4149
- import path39 from "path";
4213
+ import path40 from "path";
4150
4214
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
4151
4215
  ".agents",
4152
4216
  ".cache",
@@ -4187,14 +4251,14 @@ var sourceUnderSrcRule = {
4187
4251
  }
4188
4252
  },
4189
4253
  create(context) {
4190
- const filename = path39.resolve(context.filename);
4254
+ const filename = path40.resolve(context.filename);
4191
4255
  if (!MODULE_EXTENSION.test(filename)) return {};
4192
- const relative = path39.relative(context.cwd, filename).replace(/\\/g, "/");
4256
+ const relative = path40.relative(context.cwd, filename).replace(/\\/g, "/");
4193
4257
  if (relative === "src" || relative.startsWith("src/")) return {};
4194
4258
  const topLevel = relative.split("/")[0] ?? "";
4195
4259
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
4196
4260
  if (!relative.includes("/")) {
4197
- const basename = path39.basename(filename);
4261
+ const basename = path40.basename(filename);
4198
4262
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
4199
4263
  }
4200
4264
  return {
@@ -4211,7 +4275,7 @@ var sourceUnderSrcRule = {
4211
4275
 
4212
4276
  // eslint/rules/zirka-baseline.ts
4213
4277
  import fs5 from "fs";
4214
- import path40 from "path";
4278
+ import path41 from "path";
4215
4279
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
4216
4280
  var PRETTIER_CONFIGS = [
4217
4281
  "prettier.config.mjs",
@@ -4230,10 +4294,10 @@ var zirkaBaselineRule = {
4230
4294
  }
4231
4295
  },
4232
4296
  create(context) {
4233
- const filename = path40.resolve(context.filename);
4234
- const basename = path40.basename(filename);
4297
+ const filename = path41.resolve(context.filename);
4298
+ const basename = path41.basename(filename);
4235
4299
  if (!ESLINT_CONFIG.test(basename)) return {};
4236
- const projectRoot = path40.dirname(filename);
4300
+ const projectRoot = path41.dirname(filename);
4237
4301
  const report3 = (message) => {
4238
4302
  context.report({
4239
4303
  node: context.sourceCode.ast,
@@ -4248,7 +4312,7 @@ var zirkaBaselineRule = {
4248
4312
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
4249
4313
  );
4250
4314
  }
4251
- const tsconfigPath = path40.join(projectRoot, "tsconfig.json");
4315
+ const tsconfigPath = path41.join(projectRoot, "tsconfig.json");
4252
4316
  if (!fs5.existsSync(tsconfigPath)) {
4253
4317
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
4254
4318
  } else {
@@ -4266,13 +4330,13 @@ var zirkaBaselineRule = {
4266
4330
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
4267
4331
  }
4268
4332
  }
4269
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(path40.join(projectRoot, name)));
4333
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs5.existsSync(path41.join(projectRoot, name)));
4270
4334
  if (!prettierConfigFile) {
4271
4335
  report3(
4272
4336
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
4273
4337
  );
4274
4338
  } else {
4275
- const content = fs5.readFileSync(path40.join(projectRoot, prettierConfigFile), "utf8");
4339
+ const content = fs5.readFileSync(path41.join(projectRoot, prettierConfigFile), "utf8");
4276
4340
  if (!content.includes("zirka")) {
4277
4341
  report3(
4278
4342
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -4342,7 +4406,7 @@ var docKindSuffixRule = {
4342
4406
  };
4343
4407
 
4344
4408
  // eslint/rules/documentation/title-matches-file-name.ts
4345
- import path41 from "path";
4409
+ import path42 from "path";
4346
4410
  function toExpectedFileName(title) {
4347
4411
  return `${title.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.md`;
4348
4412
  }
@@ -4362,7 +4426,7 @@ var titleMatchesFileNameRule = {
4362
4426
  if (!filename.endsWith(".md")) return;
4363
4427
  const title = getTextContent(node).trim();
4364
4428
  const expectedFileName = toExpectedFileName(title);
4365
- const actualFileName = path41.basename(filename);
4429
+ const actualFileName = path42.basename(filename);
4366
4430
  if (!title) {
4367
4431
  context.report({
4368
4432
  node,
@@ -4805,20 +4869,20 @@ var referenceBlockHeadingsRule = {
4805
4869
 
4806
4870
  // eslint/rules/documentation/support-document-placement.ts
4807
4871
  import { existsSync as existsSync2 } from "fs";
4808
- import path42 from "path";
4872
+ import path43 from "path";
4809
4873
  function checkPlacement(filename, kind) {
4810
- const parentFolder = path42.basename(path42.dirname(filename));
4874
+ const parentFolder = path43.basename(path43.dirname(filename));
4811
4875
  const expectedParent = `${kind}s`;
4812
4876
  if (parentFolder !== expectedParent) {
4813
4877
  return `${kind} lives in "${parentFolder}/" instead of "${expectedParent}/"`;
4814
4878
  }
4815
- const guideFolderPath = path42.dirname(path42.dirname(filename));
4816
- const guideFolder = path42.basename(guideFolderPath);
4879
+ const guideFolderPath = path43.dirname(path43.dirname(filename));
4880
+ const guideFolder = path43.basename(guideFolderPath);
4817
4881
  if (!guideFolder.endsWith("-guide")) {
4818
4882
  return `${kind} owner folder "${guideFolder}/" does not use the "*-guide/" suffix`;
4819
4883
  }
4820
4884
  const entryPoint = `${guideFolder}.md`;
4821
- if (!existsSync2(path42.join(guideFolderPath, entryPoint))) {
4885
+ if (!existsSync2(path43.join(guideFolderPath, entryPoint))) {
4822
4886
  return `${kind} owner folder "${guideFolder}/" has no "${entryPoint}" entry point`;
4823
4887
  }
4824
4888
  return void 0;
@@ -4877,11 +4941,11 @@ var noTemplatePromptRule = {
4877
4941
  };
4878
4942
 
4879
4943
  // eslint/rules/documentation/guide-folder-entry-point.ts
4880
- import path44 from "path";
4944
+ import path45 from "path";
4881
4945
 
4882
4946
  // eslint/rules/documentation/project-index.ts
4883
4947
  import { readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
4884
- import path43 from "path";
4948
+ import path44 from "path";
4885
4949
  var KIND_BY_SUFFIX = [
4886
4950
  ["-rule.md", "rule"],
4887
4951
  ["-guide.md", "guide"],
@@ -4890,7 +4954,7 @@ var KIND_BY_SUFFIX = [
4890
4954
  ];
4891
4955
  function listMarkdownFiles(dir) {
4892
4956
  return readdirSync3(dir).flatMap((entry) => {
4893
- const entryPath = path43.join(dir, entry);
4957
+ const entryPath = path44.join(dir, entry);
4894
4958
  if (statSync4(entryPath).isDirectory()) {
4895
4959
  return entry.startsWith("_") ? [] : listMarkdownFiles(entryPath);
4896
4960
  }
@@ -4908,11 +4972,11 @@ function getProjectDocs(docsRoot) {
4908
4972
  if (cached) return cached;
4909
4973
  const files = listMarkdownFiles(docsRoot);
4910
4974
  const docs = files.sort((a, b) => a.localeCompare(b)).map((filePath) => {
4911
- const fileName = path43.basename(filePath);
4975
+ const fileName = path44.basename(filePath);
4912
4976
  const kind = KIND_BY_SUFFIX.find(([suffix]) => fileName.endsWith(suffix))?.[1];
4913
4977
  return {
4914
4978
  filePath,
4915
- doc: path43.relative(docsRoot, filePath).split(path43.sep).join("/"),
4979
+ doc: path44.relative(docsRoot, filePath).split(path44.sep).join("/"),
4916
4980
  fileName,
4917
4981
  kind,
4918
4982
  title: extractTitle(filePath)
@@ -4922,12 +4986,12 @@ function getProjectDocs(docsRoot) {
4922
4986
  return docs;
4923
4987
  }
4924
4988
  function findDocsRoot(filePath) {
4925
- let dir = path43.dirname(filePath);
4989
+ let dir = path44.dirname(filePath);
4926
4990
  for (; ; ) {
4927
- if (path43.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
4991
+ if (path44.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
4928
4992
  return dir;
4929
4993
  }
4930
- const parent = path43.dirname(dir);
4994
+ const parent = path44.dirname(dir);
4931
4995
  if (parent === dir) return void 0;
4932
4996
  dir = parent;
4933
4997
  }
@@ -4951,13 +5015,13 @@ var guideFolderEntryPointRule = {
4951
5015
  if (!docsRoot) return;
4952
5016
  const docs = getProjectDocs(docsRoot);
4953
5017
  const guideFolders = new Set(
4954
- docs.filter((doc) => ["rules", "references"].includes(path44.basename(path44.dirname(doc.filePath)))).map((doc) => path44.dirname(path44.dirname(doc.filePath))).filter((folder) => path44.resolve(folder) !== path44.resolve(docsRoot))
5018
+ docs.filter((doc) => ["rules", "references"].includes(path45.basename(path45.dirname(doc.filePath)))).map((doc) => path45.dirname(path45.dirname(doc.filePath))).filter((folder) => path45.resolve(folder) !== path45.resolve(docsRoot))
4955
5019
  );
4956
- const currentDir = path44.dirname(filename);
5020
+ const currentDir = path45.dirname(filename);
4957
5021
  if (guideFolders.has(currentDir)) {
4958
- const expectedEntryPoint = `${path44.basename(currentDir)}.md`;
5022
+ const expectedEntryPoint = `${path45.basename(currentDir)}.md`;
4959
5023
  const hasEntryPoint = docs.some(
4960
- (doc) => doc.kind === "guide" && path44.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
5024
+ (doc) => doc.kind === "guide" && path45.dirname(doc.filePath) === currentDir && doc.fileName === expectedEntryPoint
4961
5025
  );
4962
5026
  if (!hasEntryPoint) {
4963
5027
  context.report({
@@ -5182,7 +5246,7 @@ var noNestedHowToRule = {
5182
5246
 
5183
5247
  // eslint/rules/documentation/glossary-term-linking.ts
5184
5248
  import { readFileSync as readFileSync7 } from "fs";
5185
- import path45 from "path";
5249
+ import path46 from "path";
5186
5250
  function extractGlossaryTerms(filePath) {
5187
5251
  const content = readFileSync7(filePath, "utf8");
5188
5252
  const terms = [];
@@ -5236,9 +5300,9 @@ var glossaryTermLinkingRule = {
5236
5300
  const docsRoot = findDocsRoot(filename);
5237
5301
  if (!docsRoot) return;
5238
5302
  const docs = getProjectDocs(docsRoot);
5239
- const guideDir = path45.dirname(filename);
5303
+ const guideDir = path46.dirname(filename);
5240
5304
  const guideReferences = docs.filter(
5241
- (doc) => doc.kind === "reference" && path45.dirname(doc.filePath) === guideDir
5305
+ (doc) => doc.kind === "reference" && path46.dirname(doc.filePath) === guideDir
5242
5306
  );
5243
5307
  if (guideReferences.length === 0) return;
5244
5308
  const glossaryTerms = [];
@@ -5263,7 +5327,7 @@ var glossaryTermLinkingRule = {
5263
5327
 
5264
5328
  // eslint/rules/documentation/guide-mentions-documents.ts
5265
5329
  import { existsSync as existsSync3 } from "fs";
5266
- import path46 from "path";
5330
+ import path47 from "path";
5267
5331
  function visitSteps3(node, check) {
5268
5332
  if (node.type === "list" && node.ordered) {
5269
5333
  for (const child of node.children) check(child);
@@ -5296,12 +5360,12 @@ var guideMentionsDocumentsRule = {
5296
5360
  if (!filename.endsWith("-guide.md")) return;
5297
5361
  const docsRoot = findDocsRoot(filename);
5298
5362
  if (!docsRoot) return;
5299
- const guideDir = path46.dirname(filename);
5300
- if (path46.basename(filename, ".md") !== path46.basename(guideDir)) return;
5363
+ const guideDir = path47.dirname(filename);
5364
+ if (path47.basename(filename, ".md") !== path47.basename(guideDir)) return;
5301
5365
  const docs = getProjectDocs(docsRoot);
5302
5366
  const owned = docs.filter((doc) => {
5303
- const parent = path46.dirname(doc.filePath);
5304
- return parent === path46.join(guideDir, "rules") || parent === path46.join(guideDir, "references");
5367
+ const parent = path47.dirname(doc.filePath);
5368
+ return parent === path47.join(guideDir, "rules") || parent === path47.join(guideDir, "references");
5305
5369
  });
5306
5370
  const allLinks = [];
5307
5371
  collectMarkdownLinks(node, allLinks);
@@ -5328,7 +5392,7 @@ var guideMentionsDocumentsRule = {
5328
5392
  for (const link of allLinks) {
5329
5393
  const target = linkTarget(link.url);
5330
5394
  if (!target.endsWith(".md")) continue;
5331
- const resolved = path46.normalize(path46.join(guideDir, target));
5395
+ const resolved = path47.normalize(path47.join(guideDir, target));
5332
5396
  if (!existsSync3(resolved)) {
5333
5397
  context.report({
5334
5398
  node: link,
@@ -5878,11 +5942,11 @@ var themeVariableNamespaceRule = {
5878
5942
 
5879
5943
  // eslint/rules/tailwind/css-entry-point.ts
5880
5944
  import { statSync as statSync6 } from "fs";
5881
- import path49 from "path";
5945
+ import path50 from "path";
5882
5946
 
5883
5947
  // eslint/rules/tailwind/source-files.ts
5884
5948
  import { readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
5885
- import path47 from "path";
5949
+ import path48 from "path";
5886
5950
  var CSS_EXTENSIONS = [".css"];
5887
5951
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
5888
5952
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS3, ...CSS_EXTENSIONS];
@@ -5895,7 +5959,7 @@ function findFiles(dir, extensions) {
5895
5959
  }
5896
5960
  return entries.flatMap((entry) => {
5897
5961
  if (entry.startsWith(".") || entry === "node_modules") return [];
5898
- const entryPath = path47.join(dir, entry);
5962
+ const entryPath = path48.join(dir, entry);
5899
5963
  let stats;
5900
5964
  try {
5901
5965
  stats = statSync5(entryPath);
@@ -5903,7 +5967,7 @@ function findFiles(dir, extensions) {
5903
5967
  return [];
5904
5968
  }
5905
5969
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
5906
- return extensions.includes(path47.extname(entry)) ? [entryPath] : [];
5970
+ return extensions.includes(path48.extname(entry)) ? [entryPath] : [];
5907
5971
  });
5908
5972
  }
5909
5973
  function cachedTextReader() {
@@ -5926,7 +5990,7 @@ function escapeRegExp(text) {
5926
5990
  }
5927
5991
 
5928
5992
  // eslint/rules/tailwind/stylesheet-graph.ts
5929
- import path48 from "path";
5993
+ import path49 from "path";
5930
5994
  function registersTailwind(text) {
5931
5995
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
5932
5996
  }
@@ -5940,25 +6004,25 @@ function moduleImports(text, fileName) {
5940
6004
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
5941
6005
  }
5942
6006
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
5943
- if (spec.startsWith("/")) return path48.resolve(spec);
5944
- if (spec.startsWith("./") || spec.startsWith("../")) return path48.resolve(path48.dirname(fromFile), spec);
5945
- if (spec.startsWith("@/")) return path48.resolve(sourceRoot, spec.slice(2));
6007
+ if (spec.startsWith("/")) return path49.resolve(spec);
6008
+ if (spec.startsWith("./") || spec.startsWith("../")) return path49.resolve(path49.dirname(fromFile), spec);
6009
+ if (spec.startsWith("@/")) return path49.resolve(sourceRoot, spec.slice(2));
5946
6010
  return void 0;
5947
6011
  }
5948
6012
  function buildStylesheetGraph(options) {
5949
6013
  const { cssFiles, sourceRoot, textOf } = options;
5950
- const cssSet = new Set(cssFiles.map((file) => path48.normalize(file)));
6014
+ const cssSet = new Set(cssFiles.map((file) => path49.normalize(file)));
5951
6015
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
5952
6016
  const reachable = /* @__PURE__ */ new Set();
5953
6017
  const queue = [...globals];
5954
- for (const global of globals) reachable.add(path48.normalize(global));
6018
+ for (const global of globals) reachable.add(path49.normalize(global));
5955
6019
  while (queue.length > 0) {
5956
6020
  const from = queue.shift();
5957
6021
  if (!from) continue;
5958
6022
  for (const spec of importedSpecifiers(textOf(from))) {
5959
6023
  const target = resolveSpecifier2(from, spec, sourceRoot);
5960
6024
  if (!target) continue;
5961
- const normalized = path48.normalize(target);
6025
+ const normalized = path49.normalize(target);
5962
6026
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
5963
6027
  reachable.add(normalized);
5964
6028
  queue.push(normalized);
@@ -5970,7 +6034,7 @@ function buildStylesheetGraph(options) {
5970
6034
  for (const spec of importedSpecifiers(textOf(global))) {
5971
6035
  const target = resolveSpecifier2(global, spec, sourceRoot);
5972
6036
  if (!target) continue;
5973
- const normalized = path48.normalize(target);
6037
+ const normalized = path49.normalize(target);
5974
6038
  if (cssSet.has(normalized)) directChildren.add(normalized);
5975
6039
  }
5976
6040
  }
@@ -6003,7 +6067,7 @@ var cssEntryPointRule = {
6003
6067
  return {
6004
6068
  "StyleSheet:exit"(node) {
6005
6069
  if (globals.length === 0) return;
6006
- const current = path49.normalize(path49.resolve(context.filename));
6070
+ const current = path50.normalize(path50.resolve(context.filename));
6007
6071
  if (globals.includes(current)) {
6008
6072
  if (globals.length > 1) {
6009
6073
  context.report({
@@ -6012,7 +6076,7 @@ var cssEntryPointRule = {
6012
6076
  });
6013
6077
  return;
6014
6078
  }
6015
- const basename = path49.basename(current);
6079
+ const basename = path50.basename(current);
6016
6080
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
6017
6081
  if (importCount !== 1) {
6018
6082
  context.report({
@@ -6341,7 +6405,7 @@ var nextjsStackRule = {
6341
6405
 
6342
6406
  // eslint/rules/package-json/vitest-coverage.ts
6343
6407
  import { existsSync as existsSync4, readFileSync as readFileSync9 } from "fs";
6344
- import path50 from "path";
6408
+ import path51 from "path";
6345
6409
  function memberName4(member) {
6346
6410
  return member.name.type === "String" ? member.name.value : member.name.name;
6347
6411
  }
@@ -6410,7 +6474,7 @@ var vitestCoverageRule = {
6410
6474
  message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
6411
6475
  });
6412
6476
  }
6413
- const configName = VITEST_CONFIG_NAMES.find((name) => existsSync4(path50.join(context.cwd, name)));
6477
+ const configName = VITEST_CONFIG_NAMES.find((name) => existsSync4(path51.join(context.cwd, name)));
6414
6478
  if (!configName) {
6415
6479
  context.report({
6416
6480
  node,
@@ -6418,7 +6482,7 @@ var vitestCoverageRule = {
6418
6482
  });
6419
6483
  return;
6420
6484
  }
6421
- const content = readFileSync9(path50.join(context.cwd, configName), "utf8");
6485
+ const content = readFileSync9(path51.join(context.cwd, configName), "utf8");
6422
6486
  for (const metric of THRESHOLD_METRICS) {
6423
6487
  if (!new RegExp(`\\b${metric}\\s*:\\s*[1-9]\\d*`).test(content)) {
6424
6488
  context.report({ node, message: `${configName} must set a coverage threshold above zero for ${metric}.` });
@@ -6465,7 +6529,7 @@ var nextjsPackageJsonRules = {
6465
6529
 
6466
6530
  // eslint/rules/husky/husky-hook.ts
6467
6531
  import { existsSync as existsSync5, readFileSync as readFileSync10 } from "fs";
6468
- import path51 from "path";
6532
+ import path52 from "path";
6469
6533
  var VITEST_CONFIG_NAMES2 = [
6470
6534
  "vitest.config.ts",
6471
6535
  "vitest.config.mts",
@@ -6491,7 +6555,7 @@ var huskyHookRule = {
6491
6555
  const root = node.body;
6492
6556
  if (root.type !== "Object") return;
6493
6557
  if (!context.filename.endsWith("package.json")) return;
6494
- const hookPath = path51.join(context.cwd, ".husky", "pre-commit");
6558
+ const hookPath = path52.join(context.cwd, ".husky", "pre-commit");
6495
6559
  if (!existsSync5(hookPath)) {
6496
6560
  context.report({
6497
6561
  node,
@@ -6515,7 +6579,7 @@ var huskyHookRule = {
6515
6579
  }
6516
6580
  requireNamedScript("typecheck");
6517
6581
  requireNamedScript("test:unit:coverage");
6518
- const vitestConfigName = VITEST_CONFIG_NAMES2.find((name) => existsSync5(path51.join(context.cwd, name)));
6582
+ const vitestConfigName = VITEST_CONFIG_NAMES2.find((name) => existsSync5(path52.join(context.cwd, name)));
6519
6583
  if (vitestConfigName !== void 0) {
6520
6584
  const coverageIndex = content.indexOf("npm run test:unit:coverage");
6521
6585
  const localAddIndex = content.indexOf(`git add ${vitestConfigName}`);
@@ -6529,7 +6593,7 @@ var huskyHookRule = {
6529
6593
  if (!content.includes("libyear --limit-major-individual=1")) {
6530
6594
  context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
6531
6595
  }
6532
- const suppressionsPath = path51.join(context.cwd, "eslint-suppressions.json");
6596
+ const suppressionsPath = path52.join(context.cwd, "eslint-suppressions.json");
6533
6597
  if (existsSync5(suppressionsPath)) {
6534
6598
  requireNamedScript("lint:prune");
6535
6599
  const pruneIndex = content.indexOf("npm run lint:prune");
@@ -6602,7 +6666,7 @@ var vulykDependencyRule = {
6602
6666
 
6603
6667
  // eslint/rules/vulyk/vulyk-docs.ts
6604
6668
  import { existsSync as existsSync6, readFileSync as readFileSync11 } from "fs";
6605
- import path52 from "path";
6669
+ import path53 from "path";
6606
6670
  var PASIKA_REPO = "Bredansky/pasika";
6607
6671
  var BASE_REQUIRED_DOCS = [
6608
6672
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -6635,8 +6699,8 @@ var vulykDocsRule = {
6635
6699
  if (!context.filename.endsWith("package.json")) return;
6636
6700
  const root = node.body;
6637
6701
  if (root.type !== "Object") return;
6638
- const projectRoot = path52.dirname(path52.resolve(context.filename));
6639
- const configPath = path52.join(projectRoot, "vulyk.config.ts");
6702
+ const projectRoot = path53.dirname(path53.resolve(context.filename));
6703
+ const configPath = path53.join(projectRoot, "vulyk.config.ts");
6640
6704
  if (!existsSync6(configPath)) {
6641
6705
  context.report({
6642
6706
  node,
@@ -6661,7 +6725,7 @@ var vulykDocsRule = {
6661
6725
  });
6662
6726
  }
6663
6727
  }
6664
- const agentsPath = path52.join(projectRoot, "AGENTS.md");
6728
+ const agentsPath = path53.join(projectRoot, "AGENTS.md");
6665
6729
  if (!existsSync6(agentsPath)) {
6666
6730
  context.report({
6667
6731
  node,
@@ -6694,6 +6758,7 @@ var pasikaNextjsAppRules = {
6694
6758
  "config-extraction": configExtractionRule,
6695
6759
  "value-extraction": valueExtractionRule,
6696
6760
  "constant-casing": constantCasingRule,
6761
+ "prefer-enum": preferEnumRule,
6697
6762
  "type-extraction": typeExtractionRule,
6698
6763
  "zod-schema-validation": zodSchemaValidationRule,
6699
6764
  "schema-casing": schemaCasingRule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",