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.
- package/dist/eslint/pasika/index.d.ts +1 -0
- package/dist/eslint/pasika/index.js +196 -131
- package/package.json +1 -1
|
@@ -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/
|
|
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 =
|
|
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 ||
|
|
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 = `${
|
|
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
|
|
2260
|
+
return path19.resolve(context.cwd ?? process.cwd(), "src");
|
|
2222
2261
|
}
|
|
2223
2262
|
|
|
2224
2263
|
// eslint/rules/util-file-name.ts
|
|
2225
|
-
import
|
|
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 =
|
|
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 =
|
|
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}.${
|
|
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
|
|
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 =
|
|
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 || !
|
|
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 = `${
|
|
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
|
|
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
|
|
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 =
|
|
2557
|
-
const base =
|
|
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
|
|
2847
|
+
import path23 from "path";
|
|
2809
2848
|
var FEATURES_SEGMENT = "features";
|
|
2810
2849
|
function featureNameOf(resolvedPath, sourceRoot) {
|
|
2811
|
-
const relative =
|
|
2850
|
+
const relative = path23.relative(sourceRoot, resolvedPath);
|
|
2812
2851
|
if (relative.startsWith("..")) return void 0;
|
|
2813
|
-
const segments = relative.split(
|
|
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 =
|
|
2868
|
+
const fileRelative = path23.relative(sourceRoot, filename);
|
|
2830
2869
|
if (fileRelative.startsWith("..")) return {};
|
|
2831
|
-
const fileSegments = fileRelative.split(
|
|
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 =
|
|
2884
|
+
resolved = path23.resolve(sourceRoot, source.value.slice(2));
|
|
2846
2885
|
} else if (source.value.startsWith(".")) {
|
|
2847
|
-
resolved =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
2952
|
+
const relative = path24.relative(sourceRoot, filename);
|
|
2896
2953
|
if (relative.startsWith("..")) return {};
|
|
2897
|
-
const segments = relative.split(
|
|
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
|
-
|
|
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
|
|
2923
|
-
|
|
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
|
|
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 =
|
|
3054
|
+
const relative = path25.relative(sourceRoot, filename);
|
|
2991
3055
|
if (relative.startsWith("..")) return {};
|
|
2992
|
-
const segments = relative.split(
|
|
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
|
|
3098
|
+
import path26 from "path";
|
|
3035
3099
|
function isInLocalesDir(filename) {
|
|
3036
|
-
const segments =
|
|
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
|
|
3149
|
+
import path27 from "path";
|
|
3086
3150
|
function isLocalesFile(filename) {
|
|
3087
|
-
const segments =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
4146
|
+
const filename = path38.resolve(context.filename);
|
|
4083
4147
|
const sourceRoot = sourceRootOf(context);
|
|
4084
|
-
if (!filename.startsWith(sourceRoot +
|
|
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
|
|
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 =
|
|
4193
|
+
const filename = path39.resolve(context.filename);
|
|
4130
4194
|
const sourceRoot = sourceRootOf(context);
|
|
4131
|
-
if (!filename.startsWith(sourceRoot +
|
|
4132
|
-
if (
|
|
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
|
|
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 =
|
|
4254
|
+
const filename = path40.resolve(context.filename);
|
|
4191
4255
|
if (!MODULE_EXTENSION.test(filename)) return {};
|
|
4192
|
-
const relative =
|
|
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 =
|
|
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
|
|
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 =
|
|
4234
|
-
const basename =
|
|
4297
|
+
const filename = path41.resolve(context.filename);
|
|
4298
|
+
const basename = path41.basename(filename);
|
|
4235
4299
|
if (!ESLINT_CONFIG.test(basename)) return {};
|
|
4236
|
-
const projectRoot =
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
4872
|
+
import path43 from "path";
|
|
4809
4873
|
function checkPlacement(filename, kind) {
|
|
4810
|
-
const parentFolder =
|
|
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 =
|
|
4816
|
-
const guideFolder =
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 =
|
|
4989
|
+
let dir = path44.dirname(filePath);
|
|
4926
4990
|
for (; ; ) {
|
|
4927
|
-
if (
|
|
4991
|
+
if (path44.basename(dir) === "docs" && statSync4(dir).isDirectory()) {
|
|
4928
4992
|
return dir;
|
|
4929
4993
|
}
|
|
4930
|
-
const parent =
|
|
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(
|
|
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 =
|
|
5020
|
+
const currentDir = path45.dirname(filename);
|
|
4957
5021
|
if (guideFolders.has(currentDir)) {
|
|
4958
|
-
const expectedEntryPoint = `${
|
|
5022
|
+
const expectedEntryPoint = `${path45.basename(currentDir)}.md`;
|
|
4959
5023
|
const hasEntryPoint = docs.some(
|
|
4960
|
-
(doc) => doc.kind === "guide" &&
|
|
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
|
|
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 =
|
|
5303
|
+
const guideDir = path46.dirname(filename);
|
|
5240
5304
|
const guideReferences = docs.filter(
|
|
5241
|
-
(doc) => doc.kind === "reference" &&
|
|
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
|
|
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 =
|
|
5300
|
-
if (
|
|
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 =
|
|
5304
|
-
return parent ===
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
5944
|
-
if (spec.startsWith("./") || spec.startsWith("../")) return
|
|
5945
|
-
if (spec.startsWith("@/")) return
|
|
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) =>
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
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 =
|
|
6639
|
-
const configPath =
|
|
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 =
|
|
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,
|