@sarj/eslint-plugin 2.12.0 → 2.12.2
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/index.cjs +164 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -4
- package/dist/index.d.ts +16 -4
- package/dist/index.js +164 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,31 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
37
|
|
|
38
38
|
// src/rules/enforce-file-structure.ts
|
|
39
39
|
var import_utils = require("@typescript-eslint/utils");
|
|
40
|
+
|
|
41
|
+
// src/rules/_paths.ts
|
|
42
|
+
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
43
|
+
var STORY_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
44
|
+
var GENERATED_FILE_RE = /([\\/](?:generated|openapi-gen|graphql[\\/]types)[\\/])|(\.gen\.[cm]?[jt]sx?$)|(\.generated\.[cm]?[jt]sx?$)|(\.d\.[cm]?ts$)|(\.types\.[cm]?ts$)/;
|
|
45
|
+
var GENERATED_MARKER_RE = /(?:@generated\b|generated (?:with|by)|generated (?:graphql )?types|do not edit(?: directly| manually)?)/i;
|
|
46
|
+
function isTestFile(filename) {
|
|
47
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
48
|
+
const base = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
49
|
+
if (/\.(test|spec|e2e|integration)\.[cm]?[jt]sx?$/.test(base)) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return /(^|\/)(tests?|__tests__|__mocks__|fixtures|e2e|integration)\//.test(normalized);
|
|
53
|
+
}
|
|
54
|
+
function isStoryFile(filename) {
|
|
55
|
+
return STORY_FILE_RE.test(filename);
|
|
56
|
+
}
|
|
57
|
+
function isGeneratedFile(filename, sourceText = "") {
|
|
58
|
+
return GENERATED_FILE_RE.test(filename.replaceAll("\\", "/")) || GENERATED_MARKER_RE.test(sourceText.slice(0, 2048));
|
|
59
|
+
}
|
|
60
|
+
function isScriptFile(filename) {
|
|
61
|
+
return SCRIPT_FILE_RE.test(filename);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/rules/enforce-file-structure.ts
|
|
40
65
|
var classifyStatement = (statement) => {
|
|
41
66
|
switch (statement.type) {
|
|
42
67
|
case import_utils.AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -73,6 +98,9 @@ var enforce_file_structure_default = import_utils.ESLintUtils.RuleCreator(
|
|
|
73
98
|
},
|
|
74
99
|
defaultOptions: [],
|
|
75
100
|
create(context) {
|
|
101
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
76
104
|
return {
|
|
77
105
|
Program(node) {
|
|
78
106
|
const body = node.body;
|
|
@@ -459,6 +487,9 @@ var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
|
|
|
459
487
|
},
|
|
460
488
|
defaultOptions: [],
|
|
461
489
|
create(context) {
|
|
490
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
491
|
+
return {};
|
|
492
|
+
}
|
|
462
493
|
const sourceCode = context.sourceCode;
|
|
463
494
|
function isStandalone(comment) {
|
|
464
495
|
const before = sourceCode.getTokenBefore(comment, {
|
|
@@ -531,6 +562,7 @@ var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
|
|
|
531
562
|
var import_utils4 = require("@typescript-eslint/utils");
|
|
532
563
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
533
564
|
/[\\/]generated[\\/]/,
|
|
565
|
+
/[\\/]openapi-gen[\\/]/,
|
|
534
566
|
/\.gen\.tsx?$/,
|
|
535
567
|
/\.generated\.tsx?$/
|
|
536
568
|
];
|
|
@@ -582,7 +614,7 @@ var no_enum_default = import_utils4.ESLintUtils.RuleCreator(
|
|
|
582
614
|
(re) => re.test(filename)
|
|
583
615
|
);
|
|
584
616
|
const isIgnoredByOption = ignoreFiles.length > 0 && matchesAnyPattern(filename, ignoreFiles);
|
|
585
|
-
const isGenerated = hasGeneratedMarker(sourceText);
|
|
617
|
+
const isGenerated = hasGeneratedMarker(sourceText) || isGeneratedFile(filename, sourceText);
|
|
586
618
|
if (isIgnoredByDefault || isIgnoredByOption || isGenerated) {
|
|
587
619
|
return {};
|
|
588
620
|
}
|
|
@@ -599,22 +631,6 @@ var no_enum_default = import_utils4.ESLintUtils.RuleCreator(
|
|
|
599
631
|
|
|
600
632
|
// src/rules/no-insecure-random-id.ts
|
|
601
633
|
var import_utils5 = require("@typescript-eslint/utils");
|
|
602
|
-
|
|
603
|
-
// src/rules/_paths.ts
|
|
604
|
-
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
605
|
-
function isTestFile(filename) {
|
|
606
|
-
const normalized = filename.replaceAll("\\", "/");
|
|
607
|
-
const base = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
608
|
-
if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(base)) {
|
|
609
|
-
return true;
|
|
610
|
-
}
|
|
611
|
-
return /(^|\/)(tests?|__tests__|__mocks__|fixtures)\//.test(normalized);
|
|
612
|
-
}
|
|
613
|
-
function isScriptFile(filename) {
|
|
614
|
-
return SCRIPT_FILE_RE.test(filename);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// src/rules/no-insecure-random-id.ts
|
|
618
634
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
619
635
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
620
636
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -1158,6 +1174,10 @@ var no_log_only_catch_default = import_utils8.ESLintUtils.RuleCreator(
|
|
|
1158
1174
|
// src/rules/no-raw-env.ts
|
|
1159
1175
|
var import_utils9 = require("@typescript-eslint/utils");
|
|
1160
1176
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1177
|
+
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1178
|
+
function isValidatedEnvBoundary(filename, sourceText) {
|
|
1179
|
+
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) && /\bz\.object\s*\(/.test(sourceText) && /\.parse\s*\(/.test(sourceText);
|
|
1180
|
+
}
|
|
1161
1181
|
function isProcessEnv(node) {
|
|
1162
1182
|
return !node.computed && node.object.type === "Identifier" && node.object.name === "process" && node.property.type === "Identifier" && node.property.name === "env";
|
|
1163
1183
|
}
|
|
@@ -1207,7 +1227,7 @@ var no_raw_env_default = import_utils9.ESLintUtils.RuleCreator(
|
|
|
1207
1227
|
defaultOptions: [],
|
|
1208
1228
|
create(context) {
|
|
1209
1229
|
const filename = context.filename;
|
|
1210
|
-
if (isTestFile(filename) || isScriptFile(filename) || CONFIG_FILE_RE.test(filename.replaceAll("\\", "/"))) {
|
|
1230
|
+
if (isTestFile(filename) || isScriptFile(filename) || CONFIG_FILE_RE.test(filename.replaceAll("\\", "/")) || isValidatedEnvBoundary(filename, context.sourceCode.text)) {
|
|
1211
1231
|
return {};
|
|
1212
1232
|
}
|
|
1213
1233
|
return {
|
|
@@ -1549,6 +1569,9 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
|
|
|
1549
1569
|
},
|
|
1550
1570
|
defaultOptions: [{}],
|
|
1551
1571
|
create(context, [loggingOptions]) {
|
|
1572
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
1573
|
+
return {};
|
|
1574
|
+
}
|
|
1552
1575
|
const matcher = createLogMatcher(loggingOptions);
|
|
1553
1576
|
function logsOrReportsError(catchBody, caughtName) {
|
|
1554
1577
|
return walkWithinScope(catchBody, (current) => {
|
|
@@ -1955,6 +1978,9 @@ var no_string_concat_in_loop_default = import_utils12.ESLintUtils.RuleCreator(
|
|
|
1955
1978
|
},
|
|
1956
1979
|
defaultOptions: [],
|
|
1957
1980
|
create(context) {
|
|
1981
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
1982
|
+
return {};
|
|
1983
|
+
}
|
|
1958
1984
|
const reported = /* @__PURE__ */ new WeakMap();
|
|
1959
1985
|
return {
|
|
1960
1986
|
AssignmentExpression(node) {
|
|
@@ -2419,7 +2445,7 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
|
|
|
2419
2445
|
},
|
|
2420
2446
|
defaultOptions: [],
|
|
2421
2447
|
create(context) {
|
|
2422
|
-
if (isTestFile(context.filename)) {
|
|
2448
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
2423
2449
|
return {};
|
|
2424
2450
|
}
|
|
2425
2451
|
const unvalidatedVariables = /* @__PURE__ */ new Set();
|
|
@@ -2518,6 +2544,8 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
|
|
|
2518
2544
|
|
|
2519
2545
|
// src/rules/prefer-semantic-colors.ts
|
|
2520
2546
|
var import_utils17 = require("@typescript-eslint/utils");
|
|
2547
|
+
var import_fs = require("fs");
|
|
2548
|
+
var import_path = require("path");
|
|
2521
2549
|
|
|
2522
2550
|
// src/rules/_tailwind.ts
|
|
2523
2551
|
var tailwindBase = (token) => token.replace(/^(?:[a-z0-9-]+:)+/i, "").replace(/^!/, "");
|
|
@@ -2555,6 +2583,20 @@ var STYLE_COLOR_PROPS = /* @__PURE__ */ new Set([
|
|
|
2555
2583
|
]);
|
|
2556
2584
|
var RAW_COLOR_VALUE_RE = new RegExp(`#[0-9a-fA-F]{3,8}\\b|\\b(?:${COLOR_FN})\\s*\\(`, "i");
|
|
2557
2585
|
var STORIES_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
2586
|
+
var SEMANTIC_TOKEN_RE = /--(?:background|foreground|primary|secondary|muted|accent|destructive|border|card|popover)\b|(?:bg|text|border)-(?:background|foreground|primary|secondary|muted|accent|destructive|border|card|popover)\b/;
|
|
2587
|
+
var DETECTION_FILES = [
|
|
2588
|
+
"components.json",
|
|
2589
|
+
"tailwind.config.js",
|
|
2590
|
+
"tailwind.config.cjs",
|
|
2591
|
+
"tailwind.config.mjs",
|
|
2592
|
+
"tailwind.config.ts",
|
|
2593
|
+
"app/globals.css",
|
|
2594
|
+
"src/app/globals.css",
|
|
2595
|
+
"src/index.css",
|
|
2596
|
+
"src/styles/globals.css",
|
|
2597
|
+
"styles/globals.css"
|
|
2598
|
+
];
|
|
2599
|
+
var semanticTokenCache = /* @__PURE__ */ new Map();
|
|
2558
2600
|
var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
|
|
2559
2601
|
"mask",
|
|
2560
2602
|
"clipPath",
|
|
@@ -2573,16 +2615,66 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
2573
2615
|
"currentcolor",
|
|
2574
2616
|
"inherit"
|
|
2575
2617
|
]);
|
|
2618
|
+
function jsxElementName(node) {
|
|
2619
|
+
const name = node.openingElement.name;
|
|
2620
|
+
if (name.type === import_utils17.AST_NODE_TYPES.JSXIdentifier) return name.name;
|
|
2621
|
+
if (name.type === import_utils17.AST_NODE_TYPES.JSXMemberExpression && name.property.type === import_utils17.AST_NODE_TYPES.JSXIdentifier) {
|
|
2622
|
+
return name.property.name;
|
|
2623
|
+
}
|
|
2624
|
+
return null;
|
|
2625
|
+
}
|
|
2626
|
+
function isSvgLikeElementName(name) {
|
|
2627
|
+
return name === "svg" || SVG_DEFS_CONTAINERS.has(name) || /svg$/i.test(name);
|
|
2628
|
+
}
|
|
2576
2629
|
var isInsideSvg = (node) => {
|
|
2577
2630
|
let current = node.parent;
|
|
2578
2631
|
while (current !== void 0 && current !== null) {
|
|
2579
|
-
if (current.type === import_utils17.AST_NODE_TYPES.JSXElement
|
|
2632
|
+
if (current.type === import_utils17.AST_NODE_TYPES.JSXElement) {
|
|
2633
|
+
const name = jsxElementName(current);
|
|
2634
|
+
if (name !== null && isSvgLikeElementName(name)) return true;
|
|
2635
|
+
}
|
|
2636
|
+
current = current.parent;
|
|
2637
|
+
}
|
|
2638
|
+
return false;
|
|
2639
|
+
};
|
|
2640
|
+
var isInsideIconFactoryPath = (node) => {
|
|
2641
|
+
let current = node.parent;
|
|
2642
|
+
while (current !== void 0 && current !== null) {
|
|
2643
|
+
if (current.type === import_utils17.AST_NODE_TYPES.Property && propName(current.key) === "path" && current.parent.type === import_utils17.AST_NODE_TYPES.ObjectExpression && current.parent.parent.type === import_utils17.AST_NODE_TYPES.CallExpression && current.parent.parent.callee.type === import_utils17.AST_NODE_TYPES.Identifier && current.parent.parent.callee.name === "createIcon") {
|
|
2580
2644
|
return true;
|
|
2581
2645
|
}
|
|
2582
2646
|
current = current.parent;
|
|
2583
2647
|
}
|
|
2584
2648
|
return false;
|
|
2585
2649
|
};
|
|
2650
|
+
var hasSemanticTokenSystem = (filename) => {
|
|
2651
|
+
let dir = (0, import_path.dirname)(filename);
|
|
2652
|
+
const root = (0, import_path.parse)(dir).root;
|
|
2653
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
2654
|
+
const cached = semanticTokenCache.get(dir);
|
|
2655
|
+
if (cached !== void 0) return cached;
|
|
2656
|
+
let found = false;
|
|
2657
|
+
for (const rel of DETECTION_FILES) {
|
|
2658
|
+
const candidate = (0, import_path.join)(dir, rel);
|
|
2659
|
+
if (!(0, import_fs.existsSync)(candidate)) continue;
|
|
2660
|
+
if (rel === "components.json") {
|
|
2661
|
+
found = true;
|
|
2662
|
+
break;
|
|
2663
|
+
}
|
|
2664
|
+
try {
|
|
2665
|
+
if (SEMANTIC_TOKEN_RE.test((0, import_fs.readFileSync)(candidate, "utf8"))) {
|
|
2666
|
+
found = true;
|
|
2667
|
+
break;
|
|
2668
|
+
}
|
|
2669
|
+
} catch {
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
semanticTokenCache.set(dir, found);
|
|
2673
|
+
if (found || dir === root) return found;
|
|
2674
|
+
dir = (0, import_path.dirname)(dir);
|
|
2675
|
+
}
|
|
2676
|
+
return false;
|
|
2677
|
+
};
|
|
2586
2678
|
var propName = (key) => {
|
|
2587
2679
|
if (key.type === import_utils17.AST_NODE_TYPES.Identifier) return key.name;
|
|
2588
2680
|
if (key.type === import_utils17.AST_NODE_TYPES.Literal && typeof key.value === "string") return key.value;
|
|
@@ -2597,16 +2689,27 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
|
|
|
2597
2689
|
docs: {
|
|
2598
2690
|
description: "Enforce design-system semantic color tokens (bg-primary, text-destructive, \u2026) over raw Tailwind palette classes (text-red-500), arbitrary color values (bg-[#fff]), and inline color literals."
|
|
2599
2691
|
},
|
|
2600
|
-
schema: [
|
|
2692
|
+
schema: [
|
|
2693
|
+
{
|
|
2694
|
+
type: "object",
|
|
2695
|
+
additionalProperties: false,
|
|
2696
|
+
properties: {
|
|
2697
|
+
requireSemanticTokens: { type: "boolean" }
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
],
|
|
2601
2701
|
messages: {
|
|
2602
2702
|
rawPalette: "Raw palette class '{{class}}' \u2014 use a semantic token (e.g. text-foreground, bg-primary, text-destructive, bg-muted).",
|
|
2603
2703
|
arbitraryColor: "Hardcoded color '{{class}}' \u2014 use a semantic token, or var(--\u2026). For charts/brand add an eslint-disable with a reason.",
|
|
2604
2704
|
inlineColor: "Hardcoded color '{{value}}' \u2014 use a semantic token / CSS variable. For charts/standalone pages add an eslint-disable with a reason."
|
|
2605
2705
|
}
|
|
2606
2706
|
},
|
|
2607
|
-
defaultOptions: [],
|
|
2608
|
-
create(context) {
|
|
2707
|
+
defaultOptions: [{}],
|
|
2708
|
+
create(context, [options]) {
|
|
2609
2709
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
2710
|
+
if (options?.requireSemanticTokens === true && !hasSemanticTokenSystem(context.filename)) {
|
|
2711
|
+
return {};
|
|
2712
|
+
}
|
|
2610
2713
|
const reportClasses = (value, node) => {
|
|
2611
2714
|
for (const token of classTokens(value)) {
|
|
2612
2715
|
const base = tailwindBase(token);
|
|
@@ -2686,7 +2789,7 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
|
|
|
2686
2789
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
2687
2790
|
return;
|
|
2688
2791
|
}
|
|
2689
|
-
if (isInsideSvg(node)) return;
|
|
2792
|
+
if (isInsideSvg(node) || isInsideIconFactoryPath(node)) return;
|
|
2690
2793
|
checkColorValueNode(node.value);
|
|
2691
2794
|
},
|
|
2692
2795
|
// Inline style objects: style={{ color: "#111827", backgroundColor: "#fff" }}
|
|
@@ -2865,7 +2968,7 @@ var INPUT_TYPE_REPLACEMENTS = {
|
|
|
2865
2968
|
radio: "RadioGroup",
|
|
2866
2969
|
range: "Slider"
|
|
2867
2970
|
};
|
|
2868
|
-
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["hidden"]);
|
|
2971
|
+
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
|
|
2869
2972
|
var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2870
2973
|
var literalTypeAttr = (node) => {
|
|
2871
2974
|
for (const attribute of node.attributes) {
|
|
@@ -2879,8 +2982,12 @@ var literalTypeAttr = (node) => {
|
|
|
2879
2982
|
}
|
|
2880
2983
|
return null;
|
|
2881
2984
|
};
|
|
2985
|
+
var hasFileAcceptAttr = (node) => node.attributes.some(
|
|
2986
|
+
(attribute) => attribute.type === import_utils19.AST_NODE_TYPES.JSXAttribute && attribute.name.type === import_utils19.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "accept"
|
|
2987
|
+
);
|
|
2882
2988
|
var resolveInputReplacement = (node) => {
|
|
2883
2989
|
const typeAttr = literalTypeAttr(node);
|
|
2990
|
+
if (hasFileAcceptAttr(node)) return null;
|
|
2884
2991
|
if (typeAttr === null || typeAttr.kind === "dynamic") return "Input";
|
|
2885
2992
|
if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
|
|
2886
2993
|
return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
|
|
@@ -2901,7 +3008,7 @@ var prefer_shadcn_default = import_utils19.ESLintUtils.RuleCreator(
|
|
|
2901
3008
|
},
|
|
2902
3009
|
defaultOptions: [],
|
|
2903
3010
|
create(context) {
|
|
2904
|
-
if (isTestFile(context.filename)) {
|
|
3011
|
+
if (isTestFile(context.filename) || isStoryFile(context.filename)) {
|
|
2905
3012
|
return {};
|
|
2906
3013
|
}
|
|
2907
3014
|
return {
|
|
@@ -3219,7 +3326,7 @@ var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
|
|
|
3219
3326
|
const convention = optionsArg?.convention ?? "either";
|
|
3220
3327
|
const { test, messageId } = CONVENTIONS[convention];
|
|
3221
3328
|
const acceptsSchemaWord = convention !== "prefix";
|
|
3222
|
-
if (isTestFile(context.filename)) {
|
|
3329
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3223
3330
|
return {};
|
|
3224
3331
|
}
|
|
3225
3332
|
return {
|
|
@@ -3970,6 +4077,9 @@ var no_fat_try_blocks_default = import_utils27.ESLintUtils.RuleCreator(
|
|
|
3970
4077
|
},
|
|
3971
4078
|
defaultOptions: [],
|
|
3972
4079
|
create(context) {
|
|
4080
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
4081
|
+
return {};
|
|
4082
|
+
}
|
|
3973
4083
|
const sourceCode = context.sourceCode;
|
|
3974
4084
|
return {
|
|
3975
4085
|
TryStatement(node) {
|
|
@@ -4359,7 +4469,7 @@ var no_unsafe_cast_default = import_utils29.ESLintUtils.RuleCreator(
|
|
|
4359
4469
|
},
|
|
4360
4470
|
defaultOptions: [],
|
|
4361
4471
|
create(context) {
|
|
4362
|
-
if (isTestFile(context.filename)) {
|
|
4472
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
4363
4473
|
return {};
|
|
4364
4474
|
}
|
|
4365
4475
|
function checkAssertion(node) {
|
|
@@ -5518,7 +5628,9 @@ var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
|
5518
5628
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5519
5629
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
5520
5630
|
var SENTINEL_PREFIX_RE = /^(skip|sentinel|empty|none|missing|unset|placeholder|dummy|fake|example|noop)[A-Z]/;
|
|
5631
|
+
var AST_NODE_TYPE_RE = /^(?:TS|JSX)?[A-Z][A-Za-z]*(?:Signature|Keyword|Expression|Declaration|Element|Literal|Identifier)$/;
|
|
5521
5632
|
function isConstantReference(identifier) {
|
|
5633
|
+
if (AST_NODE_TYPE_RE.test(identifier)) return true;
|
|
5522
5634
|
if (isAuthSecretName(identifier) && !SENTINEL_WORDS.test(identifier)) return false;
|
|
5523
5635
|
return identifier === identifier.toUpperCase() && /[A-Za-z]/.test(identifier);
|
|
5524
5636
|
}
|
|
@@ -5785,6 +5897,7 @@ var GLOBAL_RECEIVERS = /* @__PURE__ */ new Set([
|
|
|
5785
5897
|
"window",
|
|
5786
5898
|
"self"
|
|
5787
5899
|
]);
|
|
5900
|
+
var PRESIGNED_URL_NAME_RE = /(?:pre-?signed|signed|upload|download)Url$/i;
|
|
5788
5901
|
function isGlobalFetchCall(node) {
|
|
5789
5902
|
const callee = node.callee;
|
|
5790
5903
|
if (callee.type === "Identifier") {
|
|
@@ -5795,6 +5908,23 @@ function isGlobalFetchCall(node) {
|
|
|
5795
5908
|
}
|
|
5796
5909
|
return false;
|
|
5797
5910
|
}
|
|
5911
|
+
function identifierLikeName(node) {
|
|
5912
|
+
if (node.type === "Identifier") {
|
|
5913
|
+
return node.name;
|
|
5914
|
+
}
|
|
5915
|
+
if (node.type === "MemberExpression" && !node.computed && node.property.type === "Identifier") {
|
|
5916
|
+
return node.property.name;
|
|
5917
|
+
}
|
|
5918
|
+
return null;
|
|
5919
|
+
}
|
|
5920
|
+
function isPresignedUrlTransfer(node) {
|
|
5921
|
+
const first = node.arguments[0];
|
|
5922
|
+
if (first === void 0) {
|
|
5923
|
+
return false;
|
|
5924
|
+
}
|
|
5925
|
+
const name = identifierLikeName(first);
|
|
5926
|
+
return name !== null && PRESIGNED_URL_NAME_RE.test(name);
|
|
5927
|
+
}
|
|
5798
5928
|
function compile(patterns) {
|
|
5799
5929
|
const compiled = [];
|
|
5800
5930
|
for (const pattern of patterns) {
|
|
@@ -5841,6 +5971,9 @@ var no_raw_fetch_outside_clients_default = import_utils42.ESLintUtils.RuleCreato
|
|
|
5841
5971
|
}
|
|
5842
5972
|
return {
|
|
5843
5973
|
CallExpression(node) {
|
|
5974
|
+
if (isPresignedUrlTransfer(node)) {
|
|
5975
|
+
return;
|
|
5976
|
+
}
|
|
5844
5977
|
if (isGlobalFetchCall(node)) {
|
|
5845
5978
|
context.report({ node, messageId: "rawFetch" });
|
|
5846
5979
|
}
|
|
@@ -6466,7 +6599,7 @@ var rules = {
|
|
|
6466
6599
|
var plugin = {
|
|
6467
6600
|
meta: {
|
|
6468
6601
|
name: "@sarj/eslint-plugin",
|
|
6469
|
-
version: "2.12.
|
|
6602
|
+
version: "2.12.2"
|
|
6470
6603
|
},
|
|
6471
6604
|
rules,
|
|
6472
6605
|
configs: {
|
|
@@ -6491,7 +6624,7 @@ var plugin = {
|
|
|
6491
6624
|
"@sarj/prefer-discriminated-union": "warn",
|
|
6492
6625
|
"@sarj/no-comment-cruft": "warn",
|
|
6493
6626
|
// Frontend / styling — distilled from frontend PR-review mining.
|
|
6494
|
-
"@sarj/prefer-semantic-colors": "warn",
|
|
6627
|
+
"@sarj/prefer-semantic-colors": ["warn", { requireSemanticTokens: true }],
|
|
6495
6628
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
6496
6629
|
"@sarj/no-fat-try-blocks": "warn",
|
|
6497
6630
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
@@ -6550,7 +6683,7 @@ var plugin = {
|
|
|
6550
6683
|
"@sarj/no-comment-cruft": "error",
|
|
6551
6684
|
// Frontend / styling — distilled from frontend PR-review mining. Stylistic,
|
|
6552
6685
|
// no autofix → warn (rollout should prove the FP rate before raising it).
|
|
6553
|
-
"@sarj/prefer-semantic-colors": "error",
|
|
6686
|
+
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
6554
6687
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
6555
6688
|
"@sarj/no-fat-try-blocks": "error",
|
|
6556
6689
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|