@sarj/eslint-plugin 2.12.0 → 2.12.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/index.cjs +123 -26
- 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 +123 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -70,6 +70,10 @@ interface RuleOptions$2 {
|
|
|
70
70
|
* `api.ts` / `*-api.ts` module — plus test files and codemod fixtures.
|
|
71
71
|
* - A method named `fetch` on some other receiver (`cache.fetch(k)`,
|
|
72
72
|
* `queryClient.fetch()`): only the global is HTTP.
|
|
73
|
+
* - A pre-signed upload/download URL transfer (`fetch(uploadUrl, ...)`,
|
|
74
|
+
* `fetch(file.downloadUrl)`). Those URLs are one-off storage handoffs,
|
|
75
|
+
* not calls to a first-party service API that belongs behind a client
|
|
76
|
+
* wrapper.
|
|
73
77
|
* - `new Request(...)` / `axios(...)` and friends. This rule is about the
|
|
74
78
|
* global `fetch`, not about every HTTP library.
|
|
75
79
|
*
|
|
@@ -237,7 +241,9 @@ declare const rules: {
|
|
|
237
241
|
"prefer-schema-for-api-payload": _typescript_eslint_utils_ts_eslint.RuleModule<"unparsedJsonAccess", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
238
242
|
name: string;
|
|
239
243
|
};
|
|
240
|
-
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [
|
|
244
|
+
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [{
|
|
245
|
+
requireSemanticTokens?: boolean;
|
|
246
|
+
}?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
241
247
|
name: string;
|
|
242
248
|
};
|
|
243
249
|
"prefer-server-actions": _typescript_eslint_utils_ts_eslint.RuleModule<"preferServerAction", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
@@ -379,7 +385,9 @@ declare const plugin: {
|
|
|
379
385
|
"prefer-schema-for-api-payload": _typescript_eslint_utils_ts_eslint.RuleModule<"unparsedJsonAccess", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
380
386
|
name: string;
|
|
381
387
|
};
|
|
382
|
-
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [
|
|
388
|
+
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [{
|
|
389
|
+
requireSemanticTokens?: boolean;
|
|
390
|
+
}?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
383
391
|
name: string;
|
|
384
392
|
};
|
|
385
393
|
"prefer-server-actions": _typescript_eslint_utils_ts_eslint.RuleModule<"preferServerAction", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
@@ -491,7 +499,9 @@ declare const plugin: {
|
|
|
491
499
|
"@sarj/no-string-concat-in-loop": string;
|
|
492
500
|
"@sarj/prefer-discriminated-union": string;
|
|
493
501
|
"@sarj/no-comment-cruft": string;
|
|
494
|
-
"@sarj/prefer-semantic-colors": string
|
|
502
|
+
"@sarj/prefer-semantic-colors": (string | {
|
|
503
|
+
requireSemanticTokens: boolean;
|
|
504
|
+
})[];
|
|
495
505
|
"@sarj/no-fat-try-blocks": string;
|
|
496
506
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
497
507
|
"@sarj/no-secret-in-log": string;
|
|
@@ -535,7 +545,9 @@ declare const plugin: {
|
|
|
535
545
|
"@sarj/no-string-concat-in-loop": string;
|
|
536
546
|
"@sarj/prefer-discriminated-union": string;
|
|
537
547
|
"@sarj/no-comment-cruft": string;
|
|
538
|
-
"@sarj/prefer-semantic-colors": string
|
|
548
|
+
"@sarj/prefer-semantic-colors": (string | {
|
|
549
|
+
requireSemanticTokens: boolean;
|
|
550
|
+
})[];
|
|
539
551
|
"@sarj/no-fat-try-blocks": string;
|
|
540
552
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
541
553
|
"@sarj/no-secret-in-log": string;
|
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,10 @@ interface RuleOptions$2 {
|
|
|
70
70
|
* `api.ts` / `*-api.ts` module — plus test files and codemod fixtures.
|
|
71
71
|
* - A method named `fetch` on some other receiver (`cache.fetch(k)`,
|
|
72
72
|
* `queryClient.fetch()`): only the global is HTTP.
|
|
73
|
+
* - A pre-signed upload/download URL transfer (`fetch(uploadUrl, ...)`,
|
|
74
|
+
* `fetch(file.downloadUrl)`). Those URLs are one-off storage handoffs,
|
|
75
|
+
* not calls to a first-party service API that belongs behind a client
|
|
76
|
+
* wrapper.
|
|
73
77
|
* - `new Request(...)` / `axios(...)` and friends. This rule is about the
|
|
74
78
|
* global `fetch`, not about every HTTP library.
|
|
75
79
|
*
|
|
@@ -237,7 +241,9 @@ declare const rules: {
|
|
|
237
241
|
"prefer-schema-for-api-payload": _typescript_eslint_utils_ts_eslint.RuleModule<"unparsedJsonAccess", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
238
242
|
name: string;
|
|
239
243
|
};
|
|
240
|
-
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [
|
|
244
|
+
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [{
|
|
245
|
+
requireSemanticTokens?: boolean;
|
|
246
|
+
}?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
241
247
|
name: string;
|
|
242
248
|
};
|
|
243
249
|
"prefer-server-actions": _typescript_eslint_utils_ts_eslint.RuleModule<"preferServerAction", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
@@ -379,7 +385,9 @@ declare const plugin: {
|
|
|
379
385
|
"prefer-schema-for-api-payload": _typescript_eslint_utils_ts_eslint.RuleModule<"unparsedJsonAccess", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
380
386
|
name: string;
|
|
381
387
|
};
|
|
382
|
-
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [
|
|
388
|
+
"prefer-semantic-colors": _typescript_eslint_utils_ts_eslint.RuleModule<"rawPalette" | "arbitraryColor" | "inlineColor", readonly [{
|
|
389
|
+
requireSemanticTokens?: boolean;
|
|
390
|
+
}?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
383
391
|
name: string;
|
|
384
392
|
};
|
|
385
393
|
"prefer-server-actions": _typescript_eslint_utils_ts_eslint.RuleModule<"preferServerAction", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
@@ -491,7 +499,9 @@ declare const plugin: {
|
|
|
491
499
|
"@sarj/no-string-concat-in-loop": string;
|
|
492
500
|
"@sarj/prefer-discriminated-union": string;
|
|
493
501
|
"@sarj/no-comment-cruft": string;
|
|
494
|
-
"@sarj/prefer-semantic-colors": string
|
|
502
|
+
"@sarj/prefer-semantic-colors": (string | {
|
|
503
|
+
requireSemanticTokens: boolean;
|
|
504
|
+
})[];
|
|
495
505
|
"@sarj/no-fat-try-blocks": string;
|
|
496
506
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
497
507
|
"@sarj/no-secret-in-log": string;
|
|
@@ -535,7 +545,9 @@ declare const plugin: {
|
|
|
535
545
|
"@sarj/no-string-concat-in-loop": string;
|
|
536
546
|
"@sarj/prefer-discriminated-union": string;
|
|
537
547
|
"@sarj/no-comment-cruft": string;
|
|
538
|
-
"@sarj/prefer-semantic-colors": string
|
|
548
|
+
"@sarj/prefer-semantic-colors": (string | {
|
|
549
|
+
requireSemanticTokens: boolean;
|
|
550
|
+
})[];
|
|
539
551
|
"@sarj/no-fat-try-blocks": string;
|
|
540
552
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
541
553
|
"@sarj/no-secret-in-log": string;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
// src/rules/enforce-file-structure.ts
|
|
2
2
|
import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
3
|
+
|
|
4
|
+
// src/rules/_paths.ts
|
|
5
|
+
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
6
|
+
var STORY_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
7
|
+
var GENERATED_FILE_RE = /([\\/]generated[\\/])|(\.gen\.[cm]?[jt]sx?$)|(\.generated\.[cm]?[jt]sx?$)|(\.d\.[cm]?ts$)/;
|
|
8
|
+
function isTestFile(filename) {
|
|
9
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
10
|
+
const base = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
11
|
+
if (/\.(test|spec|e2e|integration)\.[cm]?[jt]sx?$/.test(base)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return /(^|\/)(tests?|__tests__|__mocks__|fixtures|e2e|integration)\//.test(normalized);
|
|
15
|
+
}
|
|
16
|
+
function isStoryFile(filename) {
|
|
17
|
+
return STORY_FILE_RE.test(filename);
|
|
18
|
+
}
|
|
19
|
+
function isGeneratedFile(filename, sourceText = "") {
|
|
20
|
+
return GENERATED_FILE_RE.test(filename.replaceAll("\\", "/")) || /@generated\b/.test(sourceText.slice(0, 1024));
|
|
21
|
+
}
|
|
22
|
+
function isScriptFile(filename) {
|
|
23
|
+
return SCRIPT_FILE_RE.test(filename);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/rules/enforce-file-structure.ts
|
|
3
27
|
var classifyStatement = (statement) => {
|
|
4
28
|
switch (statement.type) {
|
|
5
29
|
case AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -36,6 +60,9 @@ var enforce_file_structure_default = ESLintUtils.RuleCreator(
|
|
|
36
60
|
},
|
|
37
61
|
defaultOptions: [],
|
|
38
62
|
create(context) {
|
|
63
|
+
if (isTestFile(context.filename)) {
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
39
66
|
return {
|
|
40
67
|
Program(node) {
|
|
41
68
|
const body = node.body;
|
|
@@ -565,22 +592,6 @@ var no_enum_default = ESLintUtils4.RuleCreator(
|
|
|
565
592
|
|
|
566
593
|
// src/rules/no-insecure-random-id.ts
|
|
567
594
|
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
568
|
-
|
|
569
|
-
// src/rules/_paths.ts
|
|
570
|
-
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
571
|
-
function isTestFile(filename) {
|
|
572
|
-
const normalized = filename.replaceAll("\\", "/");
|
|
573
|
-
const base = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
574
|
-
if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(base)) {
|
|
575
|
-
return true;
|
|
576
|
-
}
|
|
577
|
-
return /(^|\/)(tests?|__tests__|__mocks__|fixtures)\//.test(normalized);
|
|
578
|
-
}
|
|
579
|
-
function isScriptFile(filename) {
|
|
580
|
-
return SCRIPT_FILE_RE.test(filename);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// src/rules/no-insecure-random-id.ts
|
|
584
595
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
585
596
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
586
597
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -1124,6 +1135,10 @@ var no_log_only_catch_default = ESLintUtils7.RuleCreator(
|
|
|
1124
1135
|
// src/rules/no-raw-env.ts
|
|
1125
1136
|
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
1126
1137
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1138
|
+
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1139
|
+
function isValidatedEnvBoundary(filename, sourceText) {
|
|
1140
|
+
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) && /\bz\.object\s*\(/.test(sourceText) && /\.parse\s*\(/.test(sourceText);
|
|
1141
|
+
}
|
|
1127
1142
|
function isProcessEnv(node) {
|
|
1128
1143
|
return !node.computed && node.object.type === "Identifier" && node.object.name === "process" && node.property.type === "Identifier" && node.property.name === "env";
|
|
1129
1144
|
}
|
|
@@ -1173,7 +1188,7 @@ var no_raw_env_default = ESLintUtils8.RuleCreator(
|
|
|
1173
1188
|
defaultOptions: [],
|
|
1174
1189
|
create(context) {
|
|
1175
1190
|
const filename = context.filename;
|
|
1176
|
-
if (isTestFile(filename) || isScriptFile(filename) || CONFIG_FILE_RE.test(filename.replaceAll("\\", "/"))) {
|
|
1191
|
+
if (isTestFile(filename) || isScriptFile(filename) || CONFIG_FILE_RE.test(filename.replaceAll("\\", "/")) || isValidatedEnvBoundary(filename, context.sourceCode.text)) {
|
|
1177
1192
|
return {};
|
|
1178
1193
|
}
|
|
1179
1194
|
return {
|
|
@@ -2493,6 +2508,8 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2493
2508
|
|
|
2494
2509
|
// src/rules/prefer-semantic-colors.ts
|
|
2495
2510
|
import { AST_NODE_TYPES as AST_NODE_TYPES8, ESLintUtils as ESLintUtils15 } from "@typescript-eslint/utils";
|
|
2511
|
+
import { existsSync, readFileSync } from "fs";
|
|
2512
|
+
import { dirname, join, parse } from "path";
|
|
2496
2513
|
|
|
2497
2514
|
// src/rules/_tailwind.ts
|
|
2498
2515
|
var tailwindBase = (token) => token.replace(/^(?:[a-z0-9-]+:)+/i, "").replace(/^!/, "");
|
|
@@ -2530,6 +2547,20 @@ var STYLE_COLOR_PROPS = /* @__PURE__ */ new Set([
|
|
|
2530
2547
|
]);
|
|
2531
2548
|
var RAW_COLOR_VALUE_RE = new RegExp(`#[0-9a-fA-F]{3,8}\\b|\\b(?:${COLOR_FN})\\s*\\(`, "i");
|
|
2532
2549
|
var STORIES_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
2550
|
+
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/;
|
|
2551
|
+
var DETECTION_FILES = [
|
|
2552
|
+
"components.json",
|
|
2553
|
+
"tailwind.config.js",
|
|
2554
|
+
"tailwind.config.cjs",
|
|
2555
|
+
"tailwind.config.mjs",
|
|
2556
|
+
"tailwind.config.ts",
|
|
2557
|
+
"app/globals.css",
|
|
2558
|
+
"src/app/globals.css",
|
|
2559
|
+
"src/index.css",
|
|
2560
|
+
"src/styles/globals.css",
|
|
2561
|
+
"styles/globals.css"
|
|
2562
|
+
];
|
|
2563
|
+
var semanticTokenCache = /* @__PURE__ */ new Map();
|
|
2533
2564
|
var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
|
|
2534
2565
|
"mask",
|
|
2535
2566
|
"clipPath",
|
|
@@ -2558,6 +2589,34 @@ var isInsideSvg = (node) => {
|
|
|
2558
2589
|
}
|
|
2559
2590
|
return false;
|
|
2560
2591
|
};
|
|
2592
|
+
var hasSemanticTokenSystem = (filename) => {
|
|
2593
|
+
let dir = dirname(filename);
|
|
2594
|
+
const root = parse(dir).root;
|
|
2595
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
2596
|
+
const cached = semanticTokenCache.get(dir);
|
|
2597
|
+
if (cached !== void 0) return cached;
|
|
2598
|
+
let found = false;
|
|
2599
|
+
for (const rel of DETECTION_FILES) {
|
|
2600
|
+
const candidate = join(dir, rel);
|
|
2601
|
+
if (!existsSync(candidate)) continue;
|
|
2602
|
+
if (rel === "components.json") {
|
|
2603
|
+
found = true;
|
|
2604
|
+
break;
|
|
2605
|
+
}
|
|
2606
|
+
try {
|
|
2607
|
+
if (SEMANTIC_TOKEN_RE.test(readFileSync(candidate, "utf8"))) {
|
|
2608
|
+
found = true;
|
|
2609
|
+
break;
|
|
2610
|
+
}
|
|
2611
|
+
} catch {
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
semanticTokenCache.set(dir, found);
|
|
2615
|
+
if (found || dir === root) return found;
|
|
2616
|
+
dir = dirname(dir);
|
|
2617
|
+
}
|
|
2618
|
+
return false;
|
|
2619
|
+
};
|
|
2561
2620
|
var propName = (key) => {
|
|
2562
2621
|
if (key.type === AST_NODE_TYPES8.Identifier) return key.name;
|
|
2563
2622
|
if (key.type === AST_NODE_TYPES8.Literal && typeof key.value === "string") return key.value;
|
|
@@ -2572,16 +2631,27 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2572
2631
|
docs: {
|
|
2573
2632
|
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."
|
|
2574
2633
|
},
|
|
2575
|
-
schema: [
|
|
2634
|
+
schema: [
|
|
2635
|
+
{
|
|
2636
|
+
type: "object",
|
|
2637
|
+
additionalProperties: false,
|
|
2638
|
+
properties: {
|
|
2639
|
+
requireSemanticTokens: { type: "boolean" }
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
],
|
|
2576
2643
|
messages: {
|
|
2577
2644
|
rawPalette: "Raw palette class '{{class}}' \u2014 use a semantic token (e.g. text-foreground, bg-primary, text-destructive, bg-muted).",
|
|
2578
2645
|
arbitraryColor: "Hardcoded color '{{class}}' \u2014 use a semantic token, or var(--\u2026). For charts/brand add an eslint-disable with a reason.",
|
|
2579
2646
|
inlineColor: "Hardcoded color '{{value}}' \u2014 use a semantic token / CSS variable. For charts/standalone pages add an eslint-disable with a reason."
|
|
2580
2647
|
}
|
|
2581
2648
|
},
|
|
2582
|
-
defaultOptions: [],
|
|
2583
|
-
create(context) {
|
|
2649
|
+
defaultOptions: [{}],
|
|
2650
|
+
create(context, [options]) {
|
|
2584
2651
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
2652
|
+
if (options?.requireSemanticTokens === true && !hasSemanticTokenSystem(context.filename)) {
|
|
2653
|
+
return {};
|
|
2654
|
+
}
|
|
2585
2655
|
const reportClasses = (value, node) => {
|
|
2586
2656
|
for (const token of classTokens(value)) {
|
|
2587
2657
|
const base = tailwindBase(token);
|
|
@@ -2843,7 +2913,7 @@ var INPUT_TYPE_REPLACEMENTS = {
|
|
|
2843
2913
|
radio: "RadioGroup",
|
|
2844
2914
|
range: "Slider"
|
|
2845
2915
|
};
|
|
2846
|
-
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["hidden"]);
|
|
2916
|
+
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
|
|
2847
2917
|
var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2848
2918
|
var literalTypeAttr = (node) => {
|
|
2849
2919
|
for (const attribute of node.attributes) {
|
|
@@ -2857,8 +2927,12 @@ var literalTypeAttr = (node) => {
|
|
|
2857
2927
|
}
|
|
2858
2928
|
return null;
|
|
2859
2929
|
};
|
|
2930
|
+
var hasFileAcceptAttr = (node) => node.attributes.some(
|
|
2931
|
+
(attribute) => attribute.type === AST_NODE_TYPES9.JSXAttribute && attribute.name.type === AST_NODE_TYPES9.JSXIdentifier && attribute.name.name === "accept"
|
|
2932
|
+
);
|
|
2860
2933
|
var resolveInputReplacement = (node) => {
|
|
2861
2934
|
const typeAttr = literalTypeAttr(node);
|
|
2935
|
+
if (hasFileAcceptAttr(node)) return null;
|
|
2862
2936
|
if (typeAttr === null || typeAttr.kind === "dynamic") return "Input";
|
|
2863
2937
|
if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
|
|
2864
2938
|
return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
|
|
@@ -2879,7 +2953,7 @@ var prefer_shadcn_default = ESLintUtils17.RuleCreator(
|
|
|
2879
2953
|
},
|
|
2880
2954
|
defaultOptions: [],
|
|
2881
2955
|
create(context) {
|
|
2882
|
-
if (isTestFile(context.filename)) {
|
|
2956
|
+
if (isTestFile(context.filename) || isStoryFile(context.filename)) {
|
|
2883
2957
|
return {};
|
|
2884
2958
|
}
|
|
2885
2959
|
return {
|
|
@@ -3200,7 +3274,7 @@ var zod_naming_convention_default = ESLintUtils20.RuleCreator(
|
|
|
3200
3274
|
const convention = optionsArg?.convention ?? "either";
|
|
3201
3275
|
const { test, messageId } = CONVENTIONS[convention];
|
|
3202
3276
|
const acceptsSchemaWord = convention !== "prefix";
|
|
3203
|
-
if (isTestFile(context.filename)) {
|
|
3277
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3204
3278
|
return {};
|
|
3205
3279
|
}
|
|
3206
3280
|
return {
|
|
@@ -5509,7 +5583,9 @@ var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
|
5509
5583
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5510
5584
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
5511
5585
|
var SENTINEL_PREFIX_RE = /^(skip|sentinel|empty|none|missing|unset|placeholder|dummy|fake|example|noop)[A-Z]/;
|
|
5586
|
+
var AST_NODE_TYPE_RE = /^(?:TS|JSX)?[A-Z][A-Za-z]*(?:Signature|Keyword|Expression|Declaration|Element|Literal|Identifier)$/;
|
|
5512
5587
|
function isConstantReference(identifier) {
|
|
5588
|
+
if (AST_NODE_TYPE_RE.test(identifier)) return true;
|
|
5513
5589
|
if (isAuthSecretName(identifier) && !SENTINEL_WORDS.test(identifier)) return false;
|
|
5514
5590
|
return identifier === identifier.toUpperCase() && /[A-Za-z]/.test(identifier);
|
|
5515
5591
|
}
|
|
@@ -5776,6 +5852,7 @@ var GLOBAL_RECEIVERS = /* @__PURE__ */ new Set([
|
|
|
5776
5852
|
"window",
|
|
5777
5853
|
"self"
|
|
5778
5854
|
]);
|
|
5855
|
+
var PRESIGNED_URL_NAME_RE = /(?:pre-?signed|signed|upload|download)Url$/i;
|
|
5779
5856
|
function isGlobalFetchCall(node) {
|
|
5780
5857
|
const callee = node.callee;
|
|
5781
5858
|
if (callee.type === "Identifier") {
|
|
@@ -5786,6 +5863,23 @@ function isGlobalFetchCall(node) {
|
|
|
5786
5863
|
}
|
|
5787
5864
|
return false;
|
|
5788
5865
|
}
|
|
5866
|
+
function identifierLikeName(node) {
|
|
5867
|
+
if (node.type === "Identifier") {
|
|
5868
|
+
return node.name;
|
|
5869
|
+
}
|
|
5870
|
+
if (node.type === "MemberExpression" && !node.computed && node.property.type === "Identifier") {
|
|
5871
|
+
return node.property.name;
|
|
5872
|
+
}
|
|
5873
|
+
return null;
|
|
5874
|
+
}
|
|
5875
|
+
function isPresignedUrlTransfer(node) {
|
|
5876
|
+
const first = node.arguments[0];
|
|
5877
|
+
if (first === void 0) {
|
|
5878
|
+
return false;
|
|
5879
|
+
}
|
|
5880
|
+
const name = identifierLikeName(first);
|
|
5881
|
+
return name !== null && PRESIGNED_URL_NAME_RE.test(name);
|
|
5882
|
+
}
|
|
5789
5883
|
function compile(patterns) {
|
|
5790
5884
|
const compiled = [];
|
|
5791
5885
|
for (const pattern of patterns) {
|
|
@@ -5832,6 +5926,9 @@ var no_raw_fetch_outside_clients_default = ESLintUtils38.RuleCreator(
|
|
|
5832
5926
|
}
|
|
5833
5927
|
return {
|
|
5834
5928
|
CallExpression(node) {
|
|
5929
|
+
if (isPresignedUrlTransfer(node)) {
|
|
5930
|
+
return;
|
|
5931
|
+
}
|
|
5835
5932
|
if (isGlobalFetchCall(node)) {
|
|
5836
5933
|
context.report({ node, messageId: "rawFetch" });
|
|
5837
5934
|
}
|
|
@@ -6463,7 +6560,7 @@ var rules = {
|
|
|
6463
6560
|
var plugin = {
|
|
6464
6561
|
meta: {
|
|
6465
6562
|
name: "@sarj/eslint-plugin",
|
|
6466
|
-
version: "2.12.
|
|
6563
|
+
version: "2.12.1"
|
|
6467
6564
|
},
|
|
6468
6565
|
rules,
|
|
6469
6566
|
configs: {
|
|
@@ -6488,7 +6585,7 @@ var plugin = {
|
|
|
6488
6585
|
"@sarj/prefer-discriminated-union": "warn",
|
|
6489
6586
|
"@sarj/no-comment-cruft": "warn",
|
|
6490
6587
|
// Frontend / styling — distilled from frontend PR-review mining.
|
|
6491
|
-
"@sarj/prefer-semantic-colors": "warn",
|
|
6588
|
+
"@sarj/prefer-semantic-colors": ["warn", { requireSemanticTokens: true }],
|
|
6492
6589
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
6493
6590
|
"@sarj/no-fat-try-blocks": "warn",
|
|
6494
6591
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
@@ -6547,7 +6644,7 @@ var plugin = {
|
|
|
6547
6644
|
"@sarj/no-comment-cruft": "error",
|
|
6548
6645
|
// Frontend / styling — distilled from frontend PR-review mining. Stylistic,
|
|
6549
6646
|
// no autofix → warn (rollout should prove the FP rate before raising it).
|
|
6550
|
-
"@sarj/prefer-semantic-colors": "error",
|
|
6647
|
+
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
6551
6648
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
6552
6649
|
"@sarj/no-fat-try-blocks": "error",
|
|
6553
6650
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|