@sarj/eslint-plugin 4.2.0 → 5.1.0
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/README.md +7 -3
- package/dist/index.cjs +1493 -849
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -26
- package/dist/index.d.ts +84 -26
- package/dist/index.js +1507 -863
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// src/rules/
|
|
2
|
-
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
1
|
+
// src/rules/enforce-file-structure.ts
|
|
2
|
+
import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
3
3
|
|
|
4
4
|
// src/rules/_paths.ts
|
|
5
5
|
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
6
6
|
var STORY_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
7
|
-
var
|
|
7
|
+
var STORY_DIR_RE = /(^|\/)stories(?:[_-][^/]*)?\//i;
|
|
8
|
+
var GENERATED_FILE_RE = /([\\/](?:generated|openapi-gen|graphql[\\/]types|vendor|vendored|external|third[-_]?party)[\\/])|(\.gen\.[cm]?[jt]sx?$)|(\.generated\.[cm]?[jt]sx?$)|(\.d\.[cm]?ts$)|(\.types\.[cm]?ts$)/;
|
|
8
9
|
var GENERATED_MARKER_RE = /(?:@generated\b|generated (?:with|by)|generated (?:graphql )?types|do not edit(?: directly| manually)?)/i;
|
|
9
10
|
function isTestFile(filename) {
|
|
10
11
|
const normalized = filename.replaceAll("\\", "/");
|
|
@@ -12,10 +13,13 @@ function isTestFile(filename) {
|
|
|
12
13
|
if (/[.\-_](test|spec|e2e)\.[cm]?[jt]sx?$/.test(base) || /\.integration\.[cm]?[jt]sx?$/.test(base)) {
|
|
13
14
|
return true;
|
|
14
15
|
}
|
|
15
|
-
return /(^|\/)(tests?|__tests__|__mocks__|fixtures
|
|
16
|
+
return /(^|\/)(tests?|__tests__|__mocks__|__fixtures__|__testfixtures__|fixtures?|e2e|integration)\//.test(
|
|
17
|
+
normalized
|
|
18
|
+
);
|
|
16
19
|
}
|
|
17
20
|
function isStoryFile(filename) {
|
|
18
|
-
|
|
21
|
+
const normalized = filename.replaceAll("\\", "/");
|
|
22
|
+
return STORY_FILE_RE.test(normalized) || STORY_DIR_RE.test(normalized);
|
|
19
23
|
}
|
|
20
24
|
function isGeneratedFile(filename, sourceText = "") {
|
|
21
25
|
return GENERATED_FILE_RE.test(filename.replaceAll("\\", "/")) || GENERATED_MARKER_RE.test(sourceText.slice(0, 2048));
|
|
@@ -24,43 +28,7 @@ function isScriptFile(filename) {
|
|
|
24
28
|
return SCRIPT_FILE_RE.test(filename);
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
// src/rules/ban-loose-type-guards-in-tests.ts
|
|
28
|
-
var ban_loose_type_guards_in_tests_default = ESLintUtils.RuleCreator(
|
|
29
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
30
|
-
)({
|
|
31
|
-
name: "ban-loose-type-guards-in-tests",
|
|
32
|
-
meta: {
|
|
33
|
-
type: "problem",
|
|
34
|
-
docs: {
|
|
35
|
-
description: "Disallow loose type guards (`typeof` and `in`) in test files. Enforce Zod schemas or strict matchers for type validation."
|
|
36
|
-
},
|
|
37
|
-
schema: [],
|
|
38
|
-
messages: {
|
|
39
|
-
banLooseTypeGuardsInTests: "Do not use `typeof` or `in` for type validation in tests. Use Zod schemas or strict assertion matchers instead."
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
defaultOptions: [],
|
|
43
|
-
create(context) {
|
|
44
|
-
if (!isTestFile(context.filename)) {
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
UnaryExpression(node) {
|
|
49
|
-
if (node.operator === "typeof") {
|
|
50
|
-
context.report({ node, messageId: "banLooseTypeGuardsInTests" });
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
BinaryExpression(node) {
|
|
54
|
-
if (node.operator === "in") {
|
|
55
|
-
context.report({ node, messageId: "banLooseTypeGuardsInTests" });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
31
|
// src/rules/enforce-file-structure.ts
|
|
63
|
-
import { ESLintUtils as ESLintUtils2, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
64
32
|
var classifyStatement = (statement) => {
|
|
65
33
|
switch (statement.type) {
|
|
66
34
|
case AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -80,7 +48,7 @@ var isUseServerDirective = (statement) => {
|
|
|
80
48
|
if (expr.type !== AST_NODE_TYPES.Literal) return false;
|
|
81
49
|
return expr.value === "use server";
|
|
82
50
|
};
|
|
83
|
-
var enforce_file_structure_default =
|
|
51
|
+
var enforce_file_structure_default = ESLintUtils.RuleCreator(
|
|
84
52
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
85
53
|
)({
|
|
86
54
|
name: "enforce-file-structure",
|
|
@@ -142,7 +110,7 @@ var enforce_file_structure_default = ESLintUtils2.RuleCreator(
|
|
|
142
110
|
// src/rules/no-client-side-data-fetching.ts
|
|
143
111
|
import {
|
|
144
112
|
AST_NODE_TYPES as AST_NODE_TYPES2,
|
|
145
|
-
ESLintUtils as
|
|
113
|
+
ESLintUtils as ESLintUtils2
|
|
146
114
|
} from "@typescript-eslint/utils";
|
|
147
115
|
var FETCH_LIBS = /* @__PURE__ */ new Set(["axios", "ky", "superagent"]);
|
|
148
116
|
var HTTP_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -240,7 +208,7 @@ function isAnalyticsCall(node) {
|
|
|
240
208
|
if (url === "") return false;
|
|
241
209
|
return url.split(/[/.]/).some((segment) => ANALYTICS_SEGMENTS.has(segment));
|
|
242
210
|
}
|
|
243
|
-
var no_client_side_data_fetching_default =
|
|
211
|
+
var no_client_side_data_fetching_default = ESLintUtils2.RuleCreator(
|
|
244
212
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
245
213
|
)({
|
|
246
214
|
name: "no-client-side-data-fetching",
|
|
@@ -278,7 +246,7 @@ var no_client_side_data_fetching_default = ESLintUtils3.RuleCreator(
|
|
|
278
246
|
});
|
|
279
247
|
|
|
280
248
|
// src/rules/no-comment-cruft.ts
|
|
281
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as
|
|
249
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
|
|
282
250
|
|
|
283
251
|
// src/rules/_comments.ts
|
|
284
252
|
import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
|
|
@@ -542,7 +510,8 @@ var DUMMY_TRANSLATION_RE = /^(?:increment|return|returns|get|gets|set\b(?! up\b)
|
|
|
542
510
|
var DIAGRAM_ARROW_RE = /[-=~]{2,}>|<[-=~]{2,}/;
|
|
543
511
|
var CODE_KEYWORD_RE = /^(import |export |const |let |var |function\b|class |interface |type \w|enum |return\b|throw |await |async |if\s*\(|for\s*\(|while\s*\(|switch\s*\(|new |console\.)/;
|
|
544
512
|
var CODE_TAIL_RE = /[;{}()]\s*$|=>\s*$|,\s*$/;
|
|
545
|
-
var
|
|
513
|
+
var ASSIGN_RE = /^[A-Za-z_$][\w.$[\]]*\s*(?:=(?![=>])|\+=|-=|\*=)\s*\S.*[;)}\]]\s*$/;
|
|
514
|
+
var CALL_RE = /^[A-Za-z_$][\w.$]*\([^)]*\)\s*;?\s*$/;
|
|
546
515
|
var PSEUDOCODE_RE = /%\w+%|\[opt\]|(?:^|\s)<[A-Za-z]\w*>|…|\.\.\./;
|
|
547
516
|
function stripCommentMarker(line) {
|
|
548
517
|
return line.replace(/^\s*\/{1,2}/, "").replace(/^\s*\*+/, "").trim();
|
|
@@ -556,11 +525,12 @@ function isBanner(text) {
|
|
|
556
525
|
if (BANNER_FULL_RE.test(t) || isRegionMarker(t)) return true;
|
|
557
526
|
return BANNER_RUN_RE.test(t) && !DIAGRAM_ARROW_RE.test(t);
|
|
558
527
|
}
|
|
559
|
-
function looksLikeCode(text) {
|
|
528
|
+
function looksLikeCode(text, allowCall = true) {
|
|
560
529
|
const t = text.trim();
|
|
561
530
|
if (!t) return false;
|
|
562
531
|
if (CODE_KEYWORD_RE.test(t) && CODE_TAIL_RE.test(t)) return true;
|
|
563
|
-
|
|
532
|
+
if (ASSIGN_RE.test(t)) return true;
|
|
533
|
+
return allowCall && CALL_RE.test(t);
|
|
564
534
|
}
|
|
565
535
|
function hasPseudocode(text) {
|
|
566
536
|
return PSEUDOCODE_RE.test(text);
|
|
@@ -578,20 +548,24 @@ function isProse(text) {
|
|
|
578
548
|
}
|
|
579
549
|
return false;
|
|
580
550
|
}
|
|
581
|
-
var JUSTIFICATION_RE = /\b(?:because|since|until|due to|so that|otherwise|which is why|in order to|to avoid|to work around|to prevent)\b/i;
|
|
551
|
+
var JUSTIFICATION_RE = /\b(?:because|since|until|due to|so that|so we|so it|so the|otherwise|which is why|in order to|to avoid|to work around|to prevent|backwards? compat(?:ibility)?|for compatibility)\b/i;
|
|
552
|
+
function restatesWholeStatement(body, statement) {
|
|
553
|
+
return statement !== null && restatesStatementHead(body, statement.replaceAll("(", " "));
|
|
554
|
+
}
|
|
582
555
|
function isRedundantNarration(body, statementBelow, standalone, isolatedEnumeration, nested) {
|
|
583
556
|
const t = body.trim();
|
|
584
557
|
if (!t || looksLikeCode(t) || hasPseudocode(t)) return false;
|
|
585
558
|
if (standalone) {
|
|
586
|
-
|
|
587
|
-
if (
|
|
559
|
+
const justified = JUSTIFICATION_RE.test(t);
|
|
560
|
+
if (STEP_NARRATION_RE.test(t) && !justified) return true;
|
|
561
|
+
if (META_COMMENTARY_RE.test(t) && !justified) return true;
|
|
588
562
|
if (HELPER_OPENER_RE.test(t) || LETS_RE.test(t)) return true;
|
|
589
563
|
const words = t.split(/\s+/);
|
|
590
|
-
if (words.length <= 4 && DUMMY_TRANSLATION_RE.test(t) && !/[():=]/.test(t)) {
|
|
564
|
+
if (words.length > 1 && words.length <= 4 && DUMMY_TRANSLATION_RE.test(t) && !/[():=]/.test(t)) {
|
|
591
565
|
const lowerT = t.toLowerCase();
|
|
592
566
|
const rationaleWords = ["when", "because", "if", "so that", "due to", "for", "instead of", "to prevent", "to avoid", "only"];
|
|
593
|
-
if (!rationaleWords.some((w) => lowerT.includes(w))) {
|
|
594
|
-
|
|
567
|
+
if (!rationaleWords.some((w) => lowerT.includes(w)) && restatesWholeStatement(t, statementBelow)) {
|
|
568
|
+
return true;
|
|
595
569
|
}
|
|
596
570
|
}
|
|
597
571
|
if (!nested && isSectionLabel(t)) return true;
|
|
@@ -608,6 +582,10 @@ var STATEMENT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
|
608
582
|
AST_NODE_TYPES4.TSModuleBlock,
|
|
609
583
|
AST_NODE_TYPES4.TSInterfaceBody
|
|
610
584
|
]);
|
|
585
|
+
var TYPE_MEMBER_CONTAINERS = /* @__PURE__ */ new Set([
|
|
586
|
+
AST_NODE_TYPES4.TSInterfaceBody,
|
|
587
|
+
AST_NODE_TYPES4.TSTypeLiteral
|
|
588
|
+
]);
|
|
611
589
|
function runCitesAReference(comments, index) {
|
|
612
590
|
for (let i = index; i >= 0; i--) {
|
|
613
591
|
if (i < index && !areAdjacentLineComments(comments[i], comments[i + 1])) break;
|
|
@@ -635,10 +613,10 @@ function hasIllustrationLeadInAbove(comments, index) {
|
|
|
635
613
|
}
|
|
636
614
|
return false;
|
|
637
615
|
}
|
|
638
|
-
function hasCommentedOutCode(texts, precedingProse) {
|
|
616
|
+
function hasCommentedOutCode(texts, precedingProse, allowCall) {
|
|
639
617
|
for (let i = 0; i < texts.length; i++) {
|
|
640
618
|
const line = texts[i];
|
|
641
|
-
if (line === void 0 || !looksLikeCode(line) || hasPseudocode(line)) {
|
|
619
|
+
if (line === void 0 || !looksLikeCode(line, allowCall) || hasPseudocode(line)) {
|
|
642
620
|
continue;
|
|
643
621
|
}
|
|
644
622
|
const prev = i > 0 ? texts[i - 1] : void 0;
|
|
@@ -647,7 +625,7 @@ function hasCommentedOutCode(texts, precedingProse) {
|
|
|
647
625
|
}
|
|
648
626
|
return false;
|
|
649
627
|
}
|
|
650
|
-
var no_comment_cruft_default =
|
|
628
|
+
var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
651
629
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
652
630
|
)({
|
|
653
631
|
name: "no-comment-cruft",
|
|
@@ -732,7 +710,9 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
732
710
|
}
|
|
733
711
|
const prev = comments[i - 1];
|
|
734
712
|
const precedingProse = prev !== void 0 && prev.type === "Line" && prev.loc.end.line === comment.loc.start.line - 1 && isProse(stripCommentMarker(prev.value));
|
|
735
|
-
|
|
713
|
+
const container = sourceCode.getNodeByRangeIndex(comment.range[0]);
|
|
714
|
+
const inTypeMembers = container !== null && TYPE_MEMBER_CONTAINERS.has(container.type);
|
|
715
|
+
if (hasCommentedOutCode(texts, precedingProse, !inTypeMembers) && !hasIllustrationLeadInAbove(comments, i)) {
|
|
736
716
|
context.report({ node: comment, messageId: "commentedOutCode" });
|
|
737
717
|
continue;
|
|
738
718
|
}
|
|
@@ -740,7 +720,6 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
740
720
|
const body = texts[0];
|
|
741
721
|
const statement = restatableStatementBelow(comment, sourceCode);
|
|
742
722
|
const standalone = !isInsideCommentRun(comments, i);
|
|
743
|
-
const container = sourceCode.getNodeByRangeIndex(comment.range[0]);
|
|
744
723
|
const nested = container !== null && !STATEMENT_CONTAINERS.has(container.type);
|
|
745
724
|
if (body !== void 0 && !runCitesAReference(comments, i) && isRedundantNarration(body, statement, standalone, enumerated.length === 1, nested)) {
|
|
746
725
|
context.report({ node: comment, messageId: "redundantNarration" });
|
|
@@ -754,7 +733,7 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
754
733
|
});
|
|
755
734
|
|
|
756
735
|
// src/rules/no-enum.ts
|
|
757
|
-
import { ESLintUtils as
|
|
736
|
+
import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
758
737
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
759
738
|
/[\\/]generated[\\/]/,
|
|
760
739
|
/[\\/]openapi-gen[\\/]/,
|
|
@@ -774,7 +753,7 @@ function hasGeneratedMarker(sourceText) {
|
|
|
774
753
|
const head = sourceText.slice(0, 1024);
|
|
775
754
|
return /@generated\b/.test(head);
|
|
776
755
|
}
|
|
777
|
-
var no_enum_default =
|
|
756
|
+
var no_enum_default = ESLintUtils4.RuleCreator(
|
|
778
757
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
779
758
|
)({
|
|
780
759
|
name: "no-enum",
|
|
@@ -825,7 +804,7 @@ var no_enum_default = ESLintUtils5.RuleCreator(
|
|
|
825
804
|
});
|
|
826
805
|
|
|
827
806
|
// src/rules/no-insecure-random-id.ts
|
|
828
|
-
import { ESLintUtils as
|
|
807
|
+
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
829
808
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
830
809
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
831
810
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -966,7 +945,7 @@ function isConcatenatedIntoPathOrDomId(node) {
|
|
|
966
945
|
collectStaticStringParts(top, parts);
|
|
967
946
|
return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
|
|
968
947
|
}
|
|
969
|
-
var no_insecure_random_id_default =
|
|
948
|
+
var no_insecure_random_id_default = ESLintUtils5.RuleCreator(
|
|
970
949
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
971
950
|
)({
|
|
972
951
|
name: "no-insecure-random-id",
|
|
@@ -1010,7 +989,7 @@ var no_insecure_random_id_default = ESLintUtils6.RuleCreator(
|
|
|
1010
989
|
});
|
|
1011
990
|
|
|
1012
991
|
// src/rules/no-json-stringify-error.ts
|
|
1013
|
-
import { ESLintUtils as
|
|
992
|
+
import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
|
|
1014
993
|
var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
|
|
1015
994
|
var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
|
|
1016
995
|
var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
|
|
@@ -1144,7 +1123,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
1144
1123
|
function isJsonStringify(callee) {
|
|
1145
1124
|
return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
|
|
1146
1125
|
}
|
|
1147
|
-
var no_json_stringify_error_default =
|
|
1126
|
+
var no_json_stringify_error_default = ESLintUtils6.RuleCreator(
|
|
1148
1127
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1149
1128
|
)({
|
|
1150
1129
|
name: "no-json-stringify-error",
|
|
@@ -1194,7 +1173,7 @@ var no_json_stringify_error_default = ESLintUtils7.RuleCreator(
|
|
|
1194
1173
|
});
|
|
1195
1174
|
|
|
1196
1175
|
// src/rules/no-log-only-catch.ts
|
|
1197
|
-
import { ESLintUtils as
|
|
1176
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES5, ASTUtils, ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
|
|
1198
1177
|
|
|
1199
1178
|
// src/rules/_logging.ts
|
|
1200
1179
|
import "@typescript-eslint/utils";
|
|
@@ -1299,12 +1278,92 @@ function createLogMatcher(options = {}) {
|
|
|
1299
1278
|
}
|
|
1300
1279
|
|
|
1301
1280
|
// src/rules/no-log-only-catch.ts
|
|
1302
|
-
var
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1281
|
+
var BENCHMARK_DIR_RE = /(?:^|[\\/])benchmarks?[\\/]/;
|
|
1282
|
+
var SINGLE_STATEMENT_HOSTS = /* @__PURE__ */ new Set([
|
|
1283
|
+
AST_NODE_TYPES5.DoWhileStatement,
|
|
1284
|
+
AST_NODE_TYPES5.ForInStatement,
|
|
1285
|
+
AST_NODE_TYPES5.ForOfStatement,
|
|
1286
|
+
AST_NODE_TYPES5.ForStatement,
|
|
1287
|
+
AST_NODE_TYPES5.IfStatement,
|
|
1288
|
+
AST_NODE_TYPES5.WhileStatement
|
|
1289
|
+
]);
|
|
1290
|
+
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
1291
|
+
AST_NODE_TYPES5.ArrowFunctionExpression,
|
|
1292
|
+
AST_NODE_TYPES5.FunctionDeclaration,
|
|
1293
|
+
AST_NODE_TYPES5.FunctionExpression
|
|
1294
|
+
]);
|
|
1295
|
+
function statementSlot(node) {
|
|
1296
|
+
const parent = node.parent;
|
|
1297
|
+
if (parent === void 0) return null;
|
|
1298
|
+
let list;
|
|
1299
|
+
switch (parent.type) {
|
|
1300
|
+
case AST_NODE_TYPES5.BlockStatement:
|
|
1301
|
+
case AST_NODE_TYPES5.Program:
|
|
1302
|
+
case AST_NODE_TYPES5.StaticBlock:
|
|
1303
|
+
list = parent.body;
|
|
1304
|
+
break;
|
|
1305
|
+
case AST_NODE_TYPES5.SwitchCase:
|
|
1306
|
+
list = parent.consequent;
|
|
1307
|
+
break;
|
|
1308
|
+
default:
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1311
|
+
const index = list.indexOf(node);
|
|
1312
|
+
return index === -1 ? null : { list, index };
|
|
1313
|
+
}
|
|
1314
|
+
function hasFollowingStatement(node) {
|
|
1315
|
+
for (let current = node; current !== void 0 && !FUNCTION_TYPES.has(current.type); current = current.parent) {
|
|
1316
|
+
const slot = statementSlot(current);
|
|
1317
|
+
if (slot !== null && slot.index < slot.list.length - 1) return true;
|
|
1318
|
+
}
|
|
1319
|
+
return false;
|
|
1320
|
+
}
|
|
1321
|
+
function fallbackFollowsTry(tryStatement) {
|
|
1322
|
+
const body = tryStatement.block.body;
|
|
1323
|
+
const last = body.at(-1);
|
|
1324
|
+
return last?.type === AST_NODE_TYPES5.ReturnStatement && hasFollowingStatement(tryStatement);
|
|
1325
|
+
}
|
|
1326
|
+
function isSeedValue(node) {
|
|
1327
|
+
const inner = node.type === AST_NODE_TYPES5.TSAsExpression ? node.expression : node;
|
|
1328
|
+
switch (inner.type) {
|
|
1329
|
+
case AST_NODE_TYPES5.Literal:
|
|
1330
|
+
return true;
|
|
1331
|
+
case AST_NODE_TYPES5.Identifier:
|
|
1332
|
+
return inner.name === "undefined";
|
|
1333
|
+
case AST_NODE_TYPES5.UnaryExpression:
|
|
1334
|
+
return inner.argument.type === AST_NODE_TYPES5.Literal;
|
|
1335
|
+
case AST_NODE_TYPES5.ArrayExpression:
|
|
1336
|
+
return inner.elements.length === 0;
|
|
1337
|
+
case AST_NODE_TYPES5.ObjectExpression:
|
|
1338
|
+
return inner.properties.length === 0;
|
|
1339
|
+
default:
|
|
1340
|
+
return false;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
function seededFallbackHandled(tryStatement, scope) {
|
|
1344
|
+
const slot = statementSlot(tryStatement);
|
|
1345
|
+
if (slot === null || slot.index === 0) return false;
|
|
1346
|
+
const previous = slot.list[slot.index - 1];
|
|
1347
|
+
if (previous?.type !== AST_NODE_TYPES5.VariableDeclaration || previous.kind === "const") {
|
|
1348
|
+
return false;
|
|
1349
|
+
}
|
|
1350
|
+
const declarator = previous.declarations[0];
|
|
1351
|
+
if (previous.declarations.length !== 1 || declarator === void 0) return false;
|
|
1352
|
+
if (declarator.id.type !== AST_NODE_TYPES5.Identifier) return false;
|
|
1353
|
+
if (declarator.init == null || !isSeedValue(declarator.init)) return false;
|
|
1354
|
+
const variable = ASTUtils.findVariable(scope, declarator.id.name);
|
|
1355
|
+
if (variable === null) return false;
|
|
1356
|
+
const [tryStart, tryEnd] = tryStatement.block.range;
|
|
1357
|
+
let writtenInTry = false;
|
|
1358
|
+
let readAfter = false;
|
|
1359
|
+
for (const reference of variable.references) {
|
|
1360
|
+
const [start] = reference.identifier.range;
|
|
1361
|
+
if (reference.isWrite() && start >= tryStart && start < tryEnd) writtenInTry = true;
|
|
1362
|
+
if (reference.isRead() && start >= tryStatement.range[1]) readAfter = true;
|
|
1363
|
+
}
|
|
1364
|
+
return writtenInTry && readAfter;
|
|
1365
|
+
}
|
|
1366
|
+
var no_log_only_catch_default = ESLintUtils7.RuleCreator(
|
|
1308
1367
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1309
1368
|
)({
|
|
1310
1369
|
name: "no-log-only-catch",
|
|
@@ -1329,26 +1388,40 @@ var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
|
1329
1388
|
create(context, [loggingOptions]) {
|
|
1330
1389
|
const matcher = createLogMatcher(loggingOptions);
|
|
1331
1390
|
const filename = context.filename;
|
|
1391
|
+
const sourceCode = context.sourceCode;
|
|
1332
1392
|
function isLoggingCallStatement(statement) {
|
|
1333
1393
|
if (statement.type !== "ExpressionStatement") {
|
|
1334
1394
|
return false;
|
|
1335
1395
|
}
|
|
1336
1396
|
return matcher.isLoggingCall(statement.expression);
|
|
1337
1397
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1398
|
+
function hasCommentDirectlyAbove(node) {
|
|
1399
|
+
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
1400
|
+
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
1401
|
+
}
|
|
1402
|
+
function hasAdjacentRationale(node) {
|
|
1403
|
+
const tryStatement = node.parent;
|
|
1404
|
+
if (hasCommentDirectlyAbove(tryStatement) || hasCommentDirectlyAbove(node)) return true;
|
|
1405
|
+
const block = tryStatement.parent;
|
|
1406
|
+
if (block?.type !== AST_NODE_TYPES5.BlockStatement || block.body.length !== 1 || block.parent === void 0 || !SINGLE_STATEMENT_HOSTS.has(block.parent.type)) {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
return hasCommentDirectlyAbove(block.parent);
|
|
1410
|
+
}
|
|
1411
|
+
if (isTestFile(filename) || BENCHMARK_DIR_RE.test(filename.replaceAll("\\", "/"))) {
|
|
1342
1412
|
return {};
|
|
1343
1413
|
}
|
|
1344
1414
|
return {
|
|
1345
1415
|
CatchClause(node) {
|
|
1346
1416
|
const statements = node.body.body;
|
|
1347
|
-
const isDocumented =
|
|
1417
|
+
const isDocumented = sourceCode.getCommentsInside(node.body).length > 0 || hasAdjacentRationale(node);
|
|
1348
1418
|
if (statements.length === 0) {
|
|
1349
1419
|
if (isDocumented) {
|
|
1350
1420
|
return;
|
|
1351
1421
|
}
|
|
1422
|
+
if (fallbackFollowsTry(node.parent) || seededFallbackHandled(node.parent, sourceCode.getScope(node))) {
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1352
1425
|
context.report({ node, messageId: "emptyCatch" });
|
|
1353
1426
|
return;
|
|
1354
1427
|
}
|
|
@@ -1367,11 +1440,12 @@ var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
|
1367
1440
|
});
|
|
1368
1441
|
|
|
1369
1442
|
// src/rules/no-raw-env.ts
|
|
1370
|
-
import { ESLintUtils as
|
|
1443
|
+
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
1371
1444
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1372
1445
|
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1446
|
+
var ENV_VALIDATION_MARKER_RE = /\bcreateEnv\s*\(|\bz\.object\s*\(|\.(?:safeParse|parse)\s*\(/;
|
|
1373
1447
|
function isValidatedEnvBoundary(filename, sourceText) {
|
|
1374
|
-
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) &&
|
|
1448
|
+
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) && ENV_VALIDATION_MARKER_RE.test(sourceText);
|
|
1375
1449
|
}
|
|
1376
1450
|
function isProcessEnv(node) {
|
|
1377
1451
|
return !node.computed && node.object.type === "Identifier" && node.object.name === "process" && node.property.type === "Identifier" && node.property.name === "env";
|
|
@@ -1386,9 +1460,15 @@ var BUILD_TIME_CONSTANTS = /* @__PURE__ */ new Set([
|
|
|
1386
1460
|
"PROD",
|
|
1387
1461
|
"SSR"
|
|
1388
1462
|
]);
|
|
1389
|
-
|
|
1463
|
+
var PLATFORM_MARKERS = /* @__PURE__ */ new Set([
|
|
1464
|
+
"NEXT_RUNTIME",
|
|
1465
|
+
"VERCEL",
|
|
1466
|
+
"VERCEL_ENV",
|
|
1467
|
+
"CI"
|
|
1468
|
+
]);
|
|
1469
|
+
function isExemptVariableAccess(node) {
|
|
1390
1470
|
const parent = node.parent;
|
|
1391
|
-
return parent.type === "MemberExpression" && parent.object === node && !parent.computed && parent.property.type === "Identifier" && BUILD_TIME_CONSTANTS.has(parent.property.name);
|
|
1471
|
+
return parent.type === "MemberExpression" && parent.object === node && !parent.computed && parent.property.type === "Identifier" && (BUILD_TIME_CONSTANTS.has(parent.property.name) || PLATFORM_MARKERS.has(parent.property.name));
|
|
1392
1472
|
}
|
|
1393
1473
|
function isWriteTarget(node) {
|
|
1394
1474
|
const access = node.parent.type === "MemberExpression" && node.parent.object === node ? node.parent : node;
|
|
@@ -1405,7 +1485,7 @@ function isWholeEnvSpread(node) {
|
|
|
1405
1485
|
const parent = node.parent;
|
|
1406
1486
|
return parent.type === "SpreadElement" && parent.argument === node;
|
|
1407
1487
|
}
|
|
1408
|
-
var no_raw_env_default =
|
|
1488
|
+
var no_raw_env_default = ESLintUtils8.RuleCreator(
|
|
1409
1489
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1410
1490
|
)({
|
|
1411
1491
|
name: "no-raw-env",
|
|
@@ -1427,7 +1507,7 @@ var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
|
1427
1507
|
}
|
|
1428
1508
|
return {
|
|
1429
1509
|
MemberExpression(node) {
|
|
1430
|
-
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !
|
|
1510
|
+
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !isExemptVariableAccess(node) && !isWriteTarget(node) && !isWholeEnvSpread(node)) {
|
|
1431
1511
|
context.report({
|
|
1432
1512
|
node,
|
|
1433
1513
|
messageId: "noRawEnv"
|
|
@@ -1440,14 +1520,14 @@ var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
|
1440
1520
|
|
|
1441
1521
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
1442
1522
|
import {
|
|
1443
|
-
ESLintUtils as
|
|
1444
|
-
AST_NODE_TYPES as
|
|
1523
|
+
ESLintUtils as ESLintUtils9,
|
|
1524
|
+
AST_NODE_TYPES as AST_NODE_TYPES6
|
|
1445
1525
|
} from "@typescript-eslint/utils";
|
|
1446
1526
|
function sentinelKind(arg) {
|
|
1447
1527
|
if (arg === null) {
|
|
1448
1528
|
return null;
|
|
1449
1529
|
}
|
|
1450
|
-
if (arg.type ===
|
|
1530
|
+
if (arg.type === AST_NODE_TYPES6.Literal) {
|
|
1451
1531
|
if (arg.value === null) {
|
|
1452
1532
|
return "nullish";
|
|
1453
1533
|
}
|
|
@@ -1459,13 +1539,13 @@ function sentinelKind(arg) {
|
|
|
1459
1539
|
}
|
|
1460
1540
|
return null;
|
|
1461
1541
|
}
|
|
1462
|
-
if (arg.type ===
|
|
1542
|
+
if (arg.type === AST_NODE_TYPES6.Identifier && arg.name === "undefined") {
|
|
1463
1543
|
return "nullish";
|
|
1464
1544
|
}
|
|
1465
|
-
if (arg.type ===
|
|
1545
|
+
if (arg.type === AST_NODE_TYPES6.ArrayExpression) {
|
|
1466
1546
|
return "array";
|
|
1467
1547
|
}
|
|
1468
|
-
if (arg.type ===
|
|
1548
|
+
if (arg.type === AST_NODE_TYPES6.ObjectExpression) {
|
|
1469
1549
|
return "object";
|
|
1470
1550
|
}
|
|
1471
1551
|
return null;
|
|
@@ -1474,25 +1554,25 @@ function isSentinelArgument(arg) {
|
|
|
1474
1554
|
if (arg === null) {
|
|
1475
1555
|
return false;
|
|
1476
1556
|
}
|
|
1477
|
-
if (arg.type ===
|
|
1557
|
+
if (arg.type === AST_NODE_TYPES6.Literal && arg.value === null) {
|
|
1478
1558
|
return true;
|
|
1479
1559
|
}
|
|
1480
|
-
if (arg.type ===
|
|
1560
|
+
if (arg.type === AST_NODE_TYPES6.Literal && arg.value === false) {
|
|
1481
1561
|
return true;
|
|
1482
1562
|
}
|
|
1483
|
-
if (arg.type ===
|
|
1563
|
+
if (arg.type === AST_NODE_TYPES6.Identifier && arg.name === "undefined") {
|
|
1484
1564
|
return true;
|
|
1485
1565
|
}
|
|
1486
|
-
if (arg.type ===
|
|
1566
|
+
if (arg.type === AST_NODE_TYPES6.ArrayExpression && arg.elements.length === 0) {
|
|
1487
1567
|
return true;
|
|
1488
1568
|
}
|
|
1489
|
-
if (arg.type ===
|
|
1569
|
+
if (arg.type === AST_NODE_TYPES6.ObjectExpression && arg.properties.length === 0) {
|
|
1490
1570
|
return true;
|
|
1491
1571
|
}
|
|
1492
1572
|
return false;
|
|
1493
1573
|
}
|
|
1494
1574
|
function isFunctionNode(node) {
|
|
1495
|
-
return node.type ===
|
|
1575
|
+
return node.type === AST_NODE_TYPES6.FunctionDeclaration || node.type === AST_NODE_TYPES6.FunctionExpression || node.type === AST_NODE_TYPES6.ArrowFunctionExpression;
|
|
1496
1576
|
}
|
|
1497
1577
|
function isNode(value) {
|
|
1498
1578
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
@@ -1532,24 +1612,24 @@ function walkWithinScope(node, visit) {
|
|
|
1532
1612
|
function containsThrow(node) {
|
|
1533
1613
|
return walkWithinScope(
|
|
1534
1614
|
node,
|
|
1535
|
-
(current) => current.type ===
|
|
1615
|
+
(current) => current.type === AST_NODE_TYPES6.ThrowStatement
|
|
1536
1616
|
);
|
|
1537
1617
|
}
|
|
1538
1618
|
function bindsName(param, name) {
|
|
1539
1619
|
switch (param.type) {
|
|
1540
|
-
case
|
|
1620
|
+
case AST_NODE_TYPES6.Identifier:
|
|
1541
1621
|
return param.name === name;
|
|
1542
|
-
case
|
|
1622
|
+
case AST_NODE_TYPES6.AssignmentPattern:
|
|
1543
1623
|
return bindsName(param.left, name);
|
|
1544
|
-
case
|
|
1624
|
+
case AST_NODE_TYPES6.RestElement:
|
|
1545
1625
|
return bindsName(param.argument, name);
|
|
1546
|
-
case
|
|
1626
|
+
case AST_NODE_TYPES6.ArrayPattern:
|
|
1547
1627
|
return param.elements.some(
|
|
1548
1628
|
(element) => element !== null && bindsName(element, name)
|
|
1549
1629
|
);
|
|
1550
|
-
case
|
|
1630
|
+
case AST_NODE_TYPES6.ObjectPattern:
|
|
1551
1631
|
return param.properties.some(
|
|
1552
|
-
(property) => property.type ===
|
|
1632
|
+
(property) => property.type === AST_NODE_TYPES6.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
|
|
1553
1633
|
);
|
|
1554
1634
|
default:
|
|
1555
1635
|
return false;
|
|
@@ -1564,7 +1644,7 @@ function subtreeReadsName(node, name) {
|
|
|
1564
1644
|
if (found) {
|
|
1565
1645
|
return;
|
|
1566
1646
|
}
|
|
1567
|
-
if (current.type ===
|
|
1647
|
+
if (current.type === AST_NODE_TYPES6.Identifier && current.name === name) {
|
|
1568
1648
|
found = true;
|
|
1569
1649
|
return;
|
|
1570
1650
|
}
|
|
@@ -1575,10 +1655,10 @@ function subtreeReadsName(node, name) {
|
|
|
1575
1655
|
if (key === "parent") {
|
|
1576
1656
|
continue;
|
|
1577
1657
|
}
|
|
1578
|
-
if (key === "key" && current.type ===
|
|
1658
|
+
if (key === "key" && current.type === AST_NODE_TYPES6.Property && !current.computed) {
|
|
1579
1659
|
continue;
|
|
1580
1660
|
}
|
|
1581
|
-
if (key === "property" && current.type ===
|
|
1661
|
+
if (key === "property" && current.type === AST_NODE_TYPES6.MemberExpression && !current.computed) {
|
|
1582
1662
|
continue;
|
|
1583
1663
|
}
|
|
1584
1664
|
const value = current[key];
|
|
@@ -1611,10 +1691,10 @@ var SAFE_PARSE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
1611
1691
|
"URLPattern"
|
|
1612
1692
|
]);
|
|
1613
1693
|
function isParseShapedNode(node) {
|
|
1614
|
-
if (node.type ===
|
|
1694
|
+
if (node.type === AST_NODE_TYPES6.CallExpression && node.callee.type === AST_NODE_TYPES6.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES6.Identifier) {
|
|
1615
1695
|
return node.callee.property.name === "parse";
|
|
1616
1696
|
}
|
|
1617
|
-
if (node.type ===
|
|
1697
|
+
if (node.type === AST_NODE_TYPES6.NewExpression && node.callee.type === AST_NODE_TYPES6.Identifier) {
|
|
1618
1698
|
return SAFE_PARSE_CONSTRUCTORS.has(node.callee.name);
|
|
1619
1699
|
}
|
|
1620
1700
|
return false;
|
|
@@ -1625,10 +1705,10 @@ var BODY_DECODE_METHODS = /* @__PURE__ */ new Set([
|
|
|
1625
1705
|
"arrayBuffer"
|
|
1626
1706
|
]);
|
|
1627
1707
|
function isBodyDecodeNode(node) {
|
|
1628
|
-
return node.type ===
|
|
1708
|
+
return node.type === AST_NODE_TYPES6.CallExpression && node.callee.type === AST_NODE_TYPES6.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES6.Identifier && BODY_DECODE_METHODS.has(node.callee.property.name);
|
|
1629
1709
|
}
|
|
1630
1710
|
function returnsMatching(stmt, predicate) {
|
|
1631
|
-
return stmt.type ===
|
|
1711
|
+
return stmt.type === AST_NODE_TYPES6.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
|
|
1632
1712
|
}
|
|
1633
1713
|
function enclosingReturnTypeNode(node) {
|
|
1634
1714
|
let current = node.parent;
|
|
@@ -1646,11 +1726,11 @@ function enclosingFunctionName(node) {
|
|
|
1646
1726
|
let current = node.parent;
|
|
1647
1727
|
while (current !== void 0 && current !== null) {
|
|
1648
1728
|
if (isFunctionNode(current)) {
|
|
1649
|
-
if ("id" in current && isNode(current.id) && current.id.type ===
|
|
1729
|
+
if ("id" in current && isNode(current.id) && current.id.type === AST_NODE_TYPES6.Identifier) {
|
|
1650
1730
|
return current.id.name;
|
|
1651
1731
|
}
|
|
1652
1732
|
const parent = current.parent;
|
|
1653
|
-
if (parent?.type ===
|
|
1733
|
+
if (parent?.type === AST_NODE_TYPES6.VariableDeclarator && parent.id.type === AST_NODE_TYPES6.Identifier) {
|
|
1654
1734
|
return parent.id.name;
|
|
1655
1735
|
}
|
|
1656
1736
|
return null;
|
|
@@ -1671,10 +1751,10 @@ function isDeclaredBooleanPredicate(catchNode, kind) {
|
|
|
1671
1751
|
return false;
|
|
1672
1752
|
}
|
|
1673
1753
|
let declared = enclosingReturnTypeNode(catchNode);
|
|
1674
|
-
if (declared?.type ===
|
|
1754
|
+
if (declared?.type === AST_NODE_TYPES6.TSTypeReference && declared.typeName.type === AST_NODE_TYPES6.Identifier && declared.typeName.name === "Promise") {
|
|
1675
1755
|
declared = declared.typeArguments?.params[0] ?? null;
|
|
1676
1756
|
}
|
|
1677
|
-
return declared?.type ===
|
|
1757
|
+
return declared?.type === AST_NODE_TYPES6.TSBooleanKeyword;
|
|
1678
1758
|
}
|
|
1679
1759
|
function tryReturnsSafeParse(catchNode) {
|
|
1680
1760
|
const tryBlock = tryBlockOf(catchNode);
|
|
@@ -1690,7 +1770,7 @@ function tryReturnsSafeParse(catchNode) {
|
|
|
1690
1770
|
function enclosingFunctionBody(node) {
|
|
1691
1771
|
let current = node.parent;
|
|
1692
1772
|
while (current !== void 0 && current !== null) {
|
|
1693
|
-
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type ===
|
|
1773
|
+
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === AST_NODE_TYPES6.BlockStatement) {
|
|
1694
1774
|
return current.body;
|
|
1695
1775
|
}
|
|
1696
1776
|
current = current.parent;
|
|
@@ -1703,7 +1783,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
|
|
|
1703
1783
|
return false;
|
|
1704
1784
|
}
|
|
1705
1785
|
return walkWithinScope(functionBody, (current) => {
|
|
1706
|
-
if (current.type !==
|
|
1786
|
+
if (current.type !== AST_NODE_TYPES6.ReturnStatement) {
|
|
1707
1787
|
return false;
|
|
1708
1788
|
}
|
|
1709
1789
|
if (isWithin(current, catchNode.body)) {
|
|
@@ -1722,13 +1802,13 @@ function returnedSentinelKinds(arg) {
|
|
|
1722
1802
|
kinds.add(direct);
|
|
1723
1803
|
return kinds;
|
|
1724
1804
|
}
|
|
1725
|
-
if (arg.type ===
|
|
1805
|
+
if (arg.type === AST_NODE_TYPES6.ConditionalExpression) {
|
|
1726
1806
|
for (const branch of [arg.consequent, arg.alternate]) {
|
|
1727
1807
|
for (const nested of returnedSentinelKinds(branch)) {
|
|
1728
1808
|
kinds.add(nested);
|
|
1729
1809
|
}
|
|
1730
1810
|
}
|
|
1731
|
-
} else if (arg.type ===
|
|
1811
|
+
} else if (arg.type === AST_NODE_TYPES6.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
|
|
1732
1812
|
for (const nested of returnedSentinelKinds(arg.right)) {
|
|
1733
1813
|
kinds.add(nested);
|
|
1734
1814
|
}
|
|
@@ -1745,7 +1825,7 @@ function isWithin(node, ancestor) {
|
|
|
1745
1825
|
}
|
|
1746
1826
|
return false;
|
|
1747
1827
|
}
|
|
1748
|
-
var no_sentinel_return_on_catch_default =
|
|
1828
|
+
var no_sentinel_return_on_catch_default = ESLintUtils9.RuleCreator(
|
|
1749
1829
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1750
1830
|
)({
|
|
1751
1831
|
name: "no-sentinel-return-on-catch",
|
|
@@ -1773,7 +1853,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1773
1853
|
const matcher = createLogMatcher(loggingOptions);
|
|
1774
1854
|
function logsOrReportsError(catchBody, caughtName) {
|
|
1775
1855
|
return walkWithinScope(catchBody, (current) => {
|
|
1776
|
-
if (current.type !==
|
|
1856
|
+
if (current.type !== AST_NODE_TYPES6.CallExpression) {
|
|
1777
1857
|
return false;
|
|
1778
1858
|
}
|
|
1779
1859
|
if (matcher.isLoggingCall(current)) {
|
|
@@ -1790,7 +1870,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1790
1870
|
return;
|
|
1791
1871
|
}
|
|
1792
1872
|
const last = body[body.length - 1];
|
|
1793
|
-
if (last === void 0 || last.type !==
|
|
1873
|
+
if (last === void 0 || last.type !== AST_NODE_TYPES6.ReturnStatement) {
|
|
1794
1874
|
return;
|
|
1795
1875
|
}
|
|
1796
1876
|
if (!isSentinelArgument(last.argument)) {
|
|
@@ -1799,7 +1879,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1799
1879
|
if (containsThrow(node.body)) {
|
|
1800
1880
|
return;
|
|
1801
1881
|
}
|
|
1802
|
-
const caughtName = node.param?.type ===
|
|
1882
|
+
const caughtName = node.param?.type === AST_NODE_TYPES6.Identifier ? node.param.name : null;
|
|
1803
1883
|
if (logsOrReportsError(node.body, caughtName)) {
|
|
1804
1884
|
return;
|
|
1805
1885
|
}
|
|
@@ -1826,7 +1906,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1826
1906
|
});
|
|
1827
1907
|
|
|
1828
1908
|
// src/rules/no-string-concat-in-loop.ts
|
|
1829
|
-
import { ESLintUtils as
|
|
1909
|
+
import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
1830
1910
|
var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
1831
1911
|
"ForStatement",
|
|
1832
1912
|
"ForOfStatement",
|
|
@@ -1911,7 +1991,7 @@ function enclosingLoop(node) {
|
|
|
1911
1991
|
}
|
|
1912
1992
|
return null;
|
|
1913
1993
|
}
|
|
1914
|
-
var no_string_concat_in_loop_default =
|
|
1994
|
+
var no_string_concat_in_loop_default = ESLintUtils10.RuleCreator(
|
|
1915
1995
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1916
1996
|
)({
|
|
1917
1997
|
name: "no-string-concat-in-loop",
|
|
@@ -1975,8 +2055,8 @@ var no_string_concat_in_loop_default = ESLintUtils11.RuleCreator(
|
|
|
1975
2055
|
|
|
1976
2056
|
// src/rules/no-unnecessary-use-client.ts
|
|
1977
2057
|
import {
|
|
1978
|
-
AST_NODE_TYPES as
|
|
1979
|
-
ESLintUtils as
|
|
2058
|
+
AST_NODE_TYPES as AST_NODE_TYPES7,
|
|
2059
|
+
ESLintUtils as ESLintUtils11
|
|
1980
2060
|
} from "@typescript-eslint/utils";
|
|
1981
2061
|
var HOOK_REGEX = /^use([A-Z]|$)/;
|
|
1982
2062
|
var EVENT_PROP_REGEX = /^on[A-Z]/;
|
|
@@ -2003,13 +2083,13 @@ var CLIENT_ONLY_PACKAGES_REGEX = /^(?:@radix-ui\/|framer-motion|react-dom|react-
|
|
|
2003
2083
|
var isBareSpecifier = (source) => !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("@/") && !source.startsWith("~");
|
|
2004
2084
|
var jsxRootName = (name) => {
|
|
2005
2085
|
let current = name;
|
|
2006
|
-
while (current.type ===
|
|
2086
|
+
while (current.type === AST_NODE_TYPES7.JSXMemberExpression) {
|
|
2007
2087
|
current = current.object;
|
|
2008
2088
|
}
|
|
2009
|
-
return current.type ===
|
|
2089
|
+
return current.type === AST_NODE_TYPES7.JSXIdentifier ? current.name : "";
|
|
2010
2090
|
};
|
|
2011
2091
|
var subtreeReadsImportedBinding = (node, imported) => {
|
|
2012
|
-
if (node.type ===
|
|
2092
|
+
if (node.type === AST_NODE_TYPES7.Identifier) {
|
|
2013
2093
|
return imported.has(node.name);
|
|
2014
2094
|
}
|
|
2015
2095
|
for (const key of Object.keys(node)) {
|
|
@@ -2024,16 +2104,16 @@ var subtreeReadsImportedBinding = (node, imported) => {
|
|
|
2024
2104
|
return false;
|
|
2025
2105
|
};
|
|
2026
2106
|
var isUseClientDirective = (node) => {
|
|
2027
|
-
return node.type ===
|
|
2107
|
+
return node.type === AST_NODE_TYPES7.ExpressionStatement && node.expression.type === AST_NODE_TYPES7.Literal && node.expression.value === "use client";
|
|
2028
2108
|
};
|
|
2029
2109
|
var isGlobalReference = (node, context) => {
|
|
2030
2110
|
if (!BROWSER_GLOBALS.has(node.name)) return false;
|
|
2031
2111
|
const parent = node.parent;
|
|
2032
2112
|
if (parent !== void 0) {
|
|
2033
|
-
if (parent.type ===
|
|
2113
|
+
if (parent.type === AST_NODE_TYPES7.MemberExpression && parent.property === node && !parent.computed) {
|
|
2034
2114
|
return false;
|
|
2035
2115
|
}
|
|
2036
|
-
if (parent.type ===
|
|
2116
|
+
if (parent.type === AST_NODE_TYPES7.Property && parent.key === node && !parent.computed) {
|
|
2037
2117
|
return false;
|
|
2038
2118
|
}
|
|
2039
2119
|
if (parent.type.startsWith("TS")) {
|
|
@@ -2050,7 +2130,7 @@ var isGlobalReference = (node, context) => {
|
|
|
2050
2130
|
}
|
|
2051
2131
|
return true;
|
|
2052
2132
|
};
|
|
2053
|
-
var no_unnecessary_use_client_default =
|
|
2133
|
+
var no_unnecessary_use_client_default = ESLintUtils11.RuleCreator(
|
|
2054
2134
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2055
2135
|
)({
|
|
2056
2136
|
name: "no-unnecessary-use-client",
|
|
@@ -2075,13 +2155,13 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2075
2155
|
const importedLocals = /* @__PURE__ */ new Set();
|
|
2076
2156
|
const externalLocals = /* @__PURE__ */ new Set();
|
|
2077
2157
|
const markIfHookOrContext = (callee) => {
|
|
2078
|
-
if (callee.type ===
|
|
2158
|
+
if (callee.type === AST_NODE_TYPES7.Identifier) {
|
|
2079
2159
|
if (HOOK_REGEX.test(callee.name) || callee.name === "createContext") {
|
|
2080
2160
|
hasClientIndicator = true;
|
|
2081
2161
|
}
|
|
2082
2162
|
return;
|
|
2083
2163
|
}
|
|
2084
|
-
if (callee.type ===
|
|
2164
|
+
if (callee.type === AST_NODE_TYPES7.MemberExpression && callee.property.type === AST_NODE_TYPES7.Identifier) {
|
|
2085
2165
|
const name = callee.property.name;
|
|
2086
2166
|
if (HOOK_REGEX.test(name) || name === "createContext") {
|
|
2087
2167
|
hasClientIndicator = true;
|
|
@@ -2091,7 +2171,7 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2091
2171
|
return {
|
|
2092
2172
|
Program(node) {
|
|
2093
2173
|
for (const stmt of node.body) {
|
|
2094
|
-
if (stmt.type !==
|
|
2174
|
+
if (stmt.type !== AST_NODE_TYPES7.ExpressionStatement) break;
|
|
2095
2175
|
if (isUseClientDirective(stmt)) {
|
|
2096
2176
|
directiveNode = stmt;
|
|
2097
2177
|
break;
|
|
@@ -2104,7 +2184,7 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2104
2184
|
},
|
|
2105
2185
|
JSXAttribute(node) {
|
|
2106
2186
|
if (directiveNode === null) return;
|
|
2107
|
-
if (node.name.type ===
|
|
2187
|
+
if (node.name.type === AST_NODE_TYPES7.JSXIdentifier && EVENT_PROP_REGEX.test(node.name.name)) {
|
|
2108
2188
|
hasClientIndicator = true;
|
|
2109
2189
|
}
|
|
2110
2190
|
},
|
|
@@ -2171,8 +2251,8 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2171
2251
|
});
|
|
2172
2252
|
|
|
2173
2253
|
// src/rules/prefer-discriminated-union.ts
|
|
2174
|
-
import { ESLintUtils as
|
|
2175
|
-
import { AST_NODE_TYPES as
|
|
2254
|
+
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
2255
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES8 } from "@typescript-eslint/utils";
|
|
2176
2256
|
var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
2177
2257
|
"success",
|
|
2178
2258
|
"ok",
|
|
@@ -2182,27 +2262,27 @@ var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
|
2182
2262
|
]);
|
|
2183
2263
|
var MIN_OPTIONAL_MEMBERS = 2;
|
|
2184
2264
|
function getMemberName(member) {
|
|
2185
|
-
if (member.type !==
|
|
2265
|
+
if (member.type !== AST_NODE_TYPES8.TSPropertySignature) {
|
|
2186
2266
|
return null;
|
|
2187
2267
|
}
|
|
2188
2268
|
const { key } = member;
|
|
2189
|
-
if (key.type ===
|
|
2269
|
+
if (key.type === AST_NODE_TYPES8.Identifier) {
|
|
2190
2270
|
return key.name;
|
|
2191
2271
|
}
|
|
2192
|
-
if (key.type ===
|
|
2272
|
+
if (key.type === AST_NODE_TYPES8.Literal && typeof key.value === "string") {
|
|
2193
2273
|
return key.value;
|
|
2194
2274
|
}
|
|
2195
2275
|
return null;
|
|
2196
2276
|
}
|
|
2197
2277
|
function isBooleanTyped(member) {
|
|
2198
|
-
return member.typeAnnotation?.typeAnnotation.type ===
|
|
2278
|
+
return member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES8.TSBooleanKeyword;
|
|
2199
2279
|
}
|
|
2200
2280
|
function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
2201
2281
|
let hasStatusBoolean = false;
|
|
2202
2282
|
let optionalCount = 0;
|
|
2203
2283
|
let optionalPayloadCount = 0;
|
|
2204
2284
|
for (const member of typeLiteral.members) {
|
|
2205
|
-
if (member.type !==
|
|
2285
|
+
if (member.type !== AST_NODE_TYPES8.TSPropertySignature) {
|
|
2206
2286
|
continue;
|
|
2207
2287
|
}
|
|
2208
2288
|
if (member.optional) {
|
|
@@ -2218,7 +2298,7 @@ function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
|
2218
2298
|
}
|
|
2219
2299
|
return hasStatusBoolean && optionalCount >= MIN_OPTIONAL_MEMBERS && optionalPayloadCount >= 1;
|
|
2220
2300
|
}
|
|
2221
|
-
var prefer_discriminated_union_default =
|
|
2301
|
+
var prefer_discriminated_union_default = ESLintUtils12.RuleCreator(
|
|
2222
2302
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2223
2303
|
)({
|
|
2224
2304
|
name: "prefer-discriminated-union",
|
|
@@ -2246,7 +2326,7 @@ var prefer_discriminated_union_default = ESLintUtils13.RuleCreator(
|
|
|
2246
2326
|
TSInterfaceDeclaration(node) {
|
|
2247
2327
|
const synthetic = {
|
|
2248
2328
|
...node.body,
|
|
2249
|
-
type:
|
|
2329
|
+
type: AST_NODE_TYPES8.TSTypeLiteral,
|
|
2250
2330
|
members: node.body.body
|
|
2251
2331
|
};
|
|
2252
2332
|
checkTypeLiteral(synthetic, node);
|
|
@@ -2260,15 +2340,15 @@ var prefer_discriminated_union_default = ESLintUtils13.RuleCreator(
|
|
|
2260
2340
|
|
|
2261
2341
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
2262
2342
|
import {
|
|
2263
|
-
AST_NODE_TYPES as
|
|
2264
|
-
ESLintUtils as
|
|
2343
|
+
AST_NODE_TYPES as AST_NODE_TYPES9,
|
|
2344
|
+
ESLintUtils as ESLintUtils13
|
|
2265
2345
|
} from "@typescript-eslint/utils";
|
|
2266
2346
|
var unwrap = (node) => {
|
|
2267
2347
|
let current = node;
|
|
2268
2348
|
while (current !== null && current !== void 0) {
|
|
2269
|
-
if (current.type ===
|
|
2349
|
+
if (current.type === AST_NODE_TYPES9.TSAsExpression || current.type === AST_NODE_TYPES9.TSTypeAssertion || current.type === AST_NODE_TYPES9.TSNonNullExpression || current.type === AST_NODE_TYPES9.TSSatisfiesExpression) {
|
|
2270
2350
|
current = current.expression;
|
|
2271
|
-
} else if (current.type ===
|
|
2351
|
+
} else if (current.type === AST_NODE_TYPES9.ChainExpression) {
|
|
2272
2352
|
current = current.expression;
|
|
2273
2353
|
} else {
|
|
2274
2354
|
break;
|
|
@@ -2276,28 +2356,40 @@ var unwrap = (node) => {
|
|
|
2276
2356
|
}
|
|
2277
2357
|
return current ?? null;
|
|
2278
2358
|
};
|
|
2359
|
+
var PROMISE_CHAIN_METHODS = /* @__PURE__ */ new Set([
|
|
2360
|
+
"then",
|
|
2361
|
+
"catch",
|
|
2362
|
+
"finally"
|
|
2363
|
+
]);
|
|
2364
|
+
var isSchemaParseReference = (node) => {
|
|
2365
|
+
const inner = unwrap(node);
|
|
2366
|
+
return inner !== null && inner.type === AST_NODE_TYPES9.MemberExpression && !inner.computed && inner.property.type === AST_NODE_TYPES9.Identifier && (inner.property.name === "parse" || inner.property.name === "safeParse");
|
|
2367
|
+
};
|
|
2279
2368
|
var isRawPayloadSource = (node) => {
|
|
2280
2369
|
let current = unwrap(node);
|
|
2281
2370
|
if (current === null) return false;
|
|
2282
|
-
if (current.type ===
|
|
2371
|
+
if (current.type === AST_NODE_TYPES9.AwaitExpression) {
|
|
2283
2372
|
current = unwrap(current.argument);
|
|
2284
2373
|
}
|
|
2285
|
-
if (current === null || current.type !==
|
|
2374
|
+
if (current === null || current.type !== AST_NODE_TYPES9.CallExpression) {
|
|
2286
2375
|
return false;
|
|
2287
2376
|
}
|
|
2288
2377
|
const callee = unwrap(current.callee);
|
|
2289
|
-
if (callee === null || callee.type !==
|
|
2378
|
+
if (callee === null || callee.type !== AST_NODE_TYPES9.MemberExpression) {
|
|
2290
2379
|
return false;
|
|
2291
2380
|
}
|
|
2292
2381
|
const property = unwrap(callee.property);
|
|
2293
|
-
if (property === null || property.type !==
|
|
2382
|
+
if (property === null || property.type !== AST_NODE_TYPES9.Identifier) {
|
|
2294
2383
|
return false;
|
|
2295
2384
|
}
|
|
2296
2385
|
if (property.name === "json") {
|
|
2297
2386
|
return true;
|
|
2298
2387
|
}
|
|
2388
|
+
if (PROMISE_CHAIN_METHODS.has(property.name)) {
|
|
2389
|
+
return !current.arguments.some(isSchemaParseReference) && isRawPayloadSource(callee.object);
|
|
2390
|
+
}
|
|
2299
2391
|
const object = unwrap(callee.object);
|
|
2300
|
-
return property.name === "parse" && object !== null && object.type ===
|
|
2392
|
+
return property.name === "parse" && object !== null && object.type === AST_NODE_TYPES9.Identifier && object.name === "JSON" && // ...but not `JSON.parse(readFileSync(p, "utf8"))` — see isLocalFileRead.
|
|
2301
2393
|
!isLocalFileRead(current.arguments[0]);
|
|
2302
2394
|
};
|
|
2303
2395
|
var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
|
|
@@ -2305,9 +2397,9 @@ var isLocalFileRead = (node) => {
|
|
|
2305
2397
|
let found = false;
|
|
2306
2398
|
const visit = (current) => {
|
|
2307
2399
|
if (found || current === null || current === void 0) return;
|
|
2308
|
-
if (current.type ===
|
|
2400
|
+
if (current.type === AST_NODE_TYPES9.CallExpression) {
|
|
2309
2401
|
const callee = unwrap(current.callee);
|
|
2310
|
-
const name = callee?.type ===
|
|
2402
|
+
const name = callee?.type === AST_NODE_TYPES9.Identifier ? callee.name : callee?.type === AST_NODE_TYPES9.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES9.Identifier ? callee.property.name : null;
|
|
2311
2403
|
if (name !== null && FILE_READ_RE.test(name)) {
|
|
2312
2404
|
found = true;
|
|
2313
2405
|
return;
|
|
@@ -2329,15 +2421,15 @@ var isLocalFileRead = (node) => {
|
|
|
2329
2421
|
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
2330
2422
|
var isInsideAssertion = (node) => {
|
|
2331
2423
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
2332
|
-
if (current.type !==
|
|
2424
|
+
if (current.type !== AST_NODE_TYPES9.CallExpression) continue;
|
|
2333
2425
|
let callee = current.callee;
|
|
2334
|
-
while (callee.type ===
|
|
2426
|
+
while (callee.type === AST_NODE_TYPES9.MemberExpression) {
|
|
2335
2427
|
callee = callee.object;
|
|
2336
2428
|
}
|
|
2337
|
-
if (callee.type ===
|
|
2429
|
+
if (callee.type === AST_NODE_TYPES9.CallExpression) {
|
|
2338
2430
|
callee = callee.callee;
|
|
2339
2431
|
}
|
|
2340
|
-
if (callee.type ===
|
|
2432
|
+
if (callee.type === AST_NODE_TYPES9.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
2341
2433
|
return true;
|
|
2342
2434
|
}
|
|
2343
2435
|
}
|
|
@@ -2352,23 +2444,43 @@ var findVariable2 = (scope, name) => {
|
|
|
2352
2444
|
}
|
|
2353
2445
|
return null;
|
|
2354
2446
|
};
|
|
2355
|
-
var GUARD_NAME_RE = /^is[A-Z]/;
|
|
2447
|
+
var GUARD_NAME_RE = /^(?:is|validate|parse|assert|decode|coerce)[A-Z]/;
|
|
2448
|
+
var isValidationRead = (node) => {
|
|
2449
|
+
let current = node;
|
|
2450
|
+
let parent = current.parent;
|
|
2451
|
+
while (parent !== null && parent !== void 0 && (parent.type === AST_NODE_TYPES9.TSAsExpression || parent.type === AST_NODE_TYPES9.TSTypeAssertion || parent.type === AST_NODE_TYPES9.TSNonNullExpression || parent.type === AST_NODE_TYPES9.TSSatisfiesExpression || parent.type === AST_NODE_TYPES9.ChainExpression)) {
|
|
2452
|
+
current = parent;
|
|
2453
|
+
parent = parent.parent;
|
|
2454
|
+
}
|
|
2455
|
+
if (parent === null || parent === void 0) return false;
|
|
2456
|
+
if (parent.type === AST_NODE_TYPES9.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
|
|
2457
|
+
return true;
|
|
2458
|
+
}
|
|
2459
|
+
if (parent.type !== AST_NODE_TYPES9.CallExpression || !parent.arguments.some((arg) => arg === current)) {
|
|
2460
|
+
return false;
|
|
2461
|
+
}
|
|
2462
|
+
const callee = parent.callee;
|
|
2463
|
+
if (callee.type === AST_NODE_TYPES9.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES9.Identifier && callee.object.name === "Array" && callee.property.type === AST_NODE_TYPES9.Identifier && callee.property.name === "isArray") {
|
|
2464
|
+
return parent.arguments.length === 1;
|
|
2465
|
+
}
|
|
2466
|
+
return callee.type === AST_NODE_TYPES9.Identifier && GUARD_NAME_RE.test(callee.name);
|
|
2467
|
+
};
|
|
2356
2468
|
var isGuardTestPosition = (node) => {
|
|
2357
2469
|
let current = node;
|
|
2358
2470
|
let parent = current.parent;
|
|
2359
2471
|
while (parent !== void 0 && parent !== null) {
|
|
2360
2472
|
switch (parent.type) {
|
|
2361
|
-
case
|
|
2362
|
-
case
|
|
2363
|
-
case
|
|
2473
|
+
case AST_NODE_TYPES9.UnaryExpression:
|
|
2474
|
+
case AST_NODE_TYPES9.LogicalExpression:
|
|
2475
|
+
case AST_NODE_TYPES9.ChainExpression:
|
|
2364
2476
|
current = parent;
|
|
2365
2477
|
parent = parent.parent;
|
|
2366
2478
|
continue;
|
|
2367
|
-
case
|
|
2368
|
-
case
|
|
2369
|
-
case
|
|
2370
|
-
case
|
|
2371
|
-
case
|
|
2479
|
+
case AST_NODE_TYPES9.IfStatement:
|
|
2480
|
+
case AST_NODE_TYPES9.ConditionalExpression:
|
|
2481
|
+
case AST_NODE_TYPES9.WhileStatement:
|
|
2482
|
+
case AST_NODE_TYPES9.DoWhileStatement:
|
|
2483
|
+
case AST_NODE_TYPES9.ForStatement:
|
|
2372
2484
|
return parent.test === current;
|
|
2373
2485
|
default:
|
|
2374
2486
|
return false;
|
|
@@ -2378,13 +2490,13 @@ var isGuardTestPosition = (node) => {
|
|
|
2378
2490
|
};
|
|
2379
2491
|
var isUnvalidatedVariableRef = (node, scope, tracked) => {
|
|
2380
2492
|
const unwrapped = unwrap(node);
|
|
2381
|
-
if (unwrapped === null || unwrapped.type !==
|
|
2493
|
+
if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES9.Identifier) {
|
|
2382
2494
|
return false;
|
|
2383
2495
|
}
|
|
2384
2496
|
const variable = findVariable2(scope, unwrapped.name);
|
|
2385
2497
|
return variable !== null && tracked.has(variable);
|
|
2386
2498
|
};
|
|
2387
|
-
var prefer_schema_for_api_payload_default =
|
|
2499
|
+
var prefer_schema_for_api_payload_default = ESLintUtils13.RuleCreator(
|
|
2388
2500
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2389
2501
|
)({
|
|
2390
2502
|
name: "prefer-schema-for-api-payload",
|
|
@@ -2404,6 +2516,14 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2404
2516
|
return {};
|
|
2405
2517
|
}
|
|
2406
2518
|
const unvalidatedVariables = /* @__PURE__ */ new Set();
|
|
2519
|
+
const isFullyNarrowedPattern = (declarator) => {
|
|
2520
|
+
const declared = context.sourceCode.getDeclaredVariables(declarator);
|
|
2521
|
+
return declared.length > 0 && declared.every(
|
|
2522
|
+
(variable) => variable.references.some(
|
|
2523
|
+
(reference) => isValidationRead(reference.identifier)
|
|
2524
|
+
)
|
|
2525
|
+
);
|
|
2526
|
+
};
|
|
2407
2527
|
const trackInitializer = (declarator) => {
|
|
2408
2528
|
if (!isRawPayloadSource(declarator.init)) return;
|
|
2409
2529
|
const declaredVars = context.sourceCode.getDeclaredVariables(declarator);
|
|
@@ -2415,13 +2535,15 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2415
2535
|
return {
|
|
2416
2536
|
VariableDeclarator(node) {
|
|
2417
2537
|
const scope = context.sourceCode.getScope(node);
|
|
2418
|
-
if (node.id.type ===
|
|
2538
|
+
if (node.id.type === AST_NODE_TYPES9.Identifier) {
|
|
2419
2539
|
trackInitializer(node);
|
|
2420
2540
|
return;
|
|
2421
2541
|
}
|
|
2422
|
-
if (node.id.type ===
|
|
2542
|
+
if (node.id.type === AST_NODE_TYPES9.ObjectPattern || node.id.type === AST_NODE_TYPES9.ArrayPattern) {
|
|
2423
2543
|
if (isRawPayloadSource(node.init)) {
|
|
2424
|
-
|
|
2544
|
+
if (!isFullyNarrowedPattern(node)) {
|
|
2545
|
+
context.report({ node: node.id, messageId: "unparsedJsonAccess" });
|
|
2546
|
+
}
|
|
2425
2547
|
return;
|
|
2426
2548
|
}
|
|
2427
2549
|
if (isUnvalidatedVariableRef(node.init, scope, unvalidatedVariables)) {
|
|
@@ -2431,7 +2553,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2431
2553
|
},
|
|
2432
2554
|
AssignmentExpression(node) {
|
|
2433
2555
|
const scope = context.sourceCode.getScope(node);
|
|
2434
|
-
if (node.left.type ===
|
|
2556
|
+
if (node.left.type === AST_NODE_TYPES9.Identifier) {
|
|
2435
2557
|
const variable = findVariable2(scope, node.left.name);
|
|
2436
2558
|
if (variable === null) return;
|
|
2437
2559
|
if (isRawPayloadSource(node.right)) {
|
|
@@ -2441,7 +2563,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2441
2563
|
}
|
|
2442
2564
|
return;
|
|
2443
2565
|
}
|
|
2444
|
-
if (node.left.type ===
|
|
2566
|
+
if (node.left.type === AST_NODE_TYPES9.ObjectPattern || node.left.type === AST_NODE_TYPES9.ArrayPattern) {
|
|
2445
2567
|
if (isRawPayloadSource(node.right)) {
|
|
2446
2568
|
context.report({
|
|
2447
2569
|
node: node.left,
|
|
@@ -2458,15 +2580,15 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2458
2580
|
}
|
|
2459
2581
|
},
|
|
2460
2582
|
CallExpression(node) {
|
|
2461
|
-
if (node.callee.type !==
|
|
2583
|
+
if (node.callee.type !== AST_NODE_TYPES9.Identifier) return;
|
|
2462
2584
|
if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
|
|
2463
2585
|
return;
|
|
2464
2586
|
}
|
|
2465
2587
|
const scope = context.sourceCode.getScope(node);
|
|
2466
2588
|
for (const arg of node.arguments) {
|
|
2467
|
-
if (arg.type ===
|
|
2589
|
+
if (arg.type === AST_NODE_TYPES9.SpreadElement) continue;
|
|
2468
2590
|
const unwrapped = unwrap(arg);
|
|
2469
|
-
if (unwrapped === null || unwrapped.type !==
|
|
2591
|
+
if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES9.Identifier) {
|
|
2470
2592
|
continue;
|
|
2471
2593
|
}
|
|
2472
2594
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -2475,17 +2597,18 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2475
2597
|
},
|
|
2476
2598
|
MemberExpression(node) {
|
|
2477
2599
|
if (isInsideAssertion(node)) return;
|
|
2600
|
+
if (isValidationRead(node)) return;
|
|
2478
2601
|
const scope = context.sourceCode.getScope(node);
|
|
2479
2602
|
const obj = unwrap(node.object);
|
|
2480
2603
|
if (isRawPayloadSource(obj)) {
|
|
2481
2604
|
const parent = node.parent;
|
|
2482
|
-
if (parent.type ===
|
|
2605
|
+
if (parent.type === AST_NODE_TYPES9.CallExpression && parent.callee === node && node.property.type === AST_NODE_TYPES9.Identifier && (node.property.name === "parse" || node.property.name === "safeParse" || PROMISE_CHAIN_METHODS.has(node.property.name))) {
|
|
2483
2606
|
return;
|
|
2484
2607
|
}
|
|
2485
2608
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
2486
2609
|
return;
|
|
2487
2610
|
}
|
|
2488
|
-
if (obj !== null && obj.type ===
|
|
2611
|
+
if (obj !== null && obj.type === AST_NODE_TYPES9.Identifier && isUnvalidatedVariableRef(obj, scope, unvalidatedVariables)) {
|
|
2489
2612
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
2490
2613
|
const variable = findVariable2(scope, obj.name);
|
|
2491
2614
|
if (variable !== null) {
|
|
@@ -2498,7 +2621,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2498
2621
|
});
|
|
2499
2622
|
|
|
2500
2623
|
// src/rules/prefer-semantic-colors.ts
|
|
2501
|
-
import { AST_NODE_TYPES as
|
|
2624
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES10, ESLintUtils as ESLintUtils14 } from "@typescript-eslint/utils";
|
|
2502
2625
|
import { existsSync, readFileSync } from "fs";
|
|
2503
2626
|
import { dirname, join, parse } from "path";
|
|
2504
2627
|
|
|
@@ -2510,7 +2633,8 @@ var classTokens = (value) => value.split(/\s+/).filter(Boolean);
|
|
|
2510
2633
|
var COLOR_PREFIXES = "text|bg|border(?:-[trblxyse])?|ring(?:-offset)?|fill|stroke|from|via|to|divide|decoration|placeholder|accent|caret|shadow|outline";
|
|
2511
2634
|
var PALETTE = "red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|slate|gray|zinc|neutral|stone";
|
|
2512
2635
|
var COLOR_FN = "rgba?|hsla?|hwb|oklch|oklab|lab|lch|color";
|
|
2513
|
-
var
|
|
2636
|
+
var PALETTE_STEP = "50|[1-9]00|950";
|
|
2637
|
+
var RAW_PALETTE_RE = new RegExp(`^(?:${COLOR_PREFIXES})-(?:${PALETTE})-(?:${PALETTE_STEP})(?:/\\d{1,3})?$`);
|
|
2514
2638
|
var ARBITRARY_COLOR_RE = new RegExp(
|
|
2515
2639
|
`^(?:${COLOR_PREFIXES})-\\[(?:#[0-9a-fA-F]{3,8}|(?:${COLOR_FN})\\([^\\]]*\\))\\]$`,
|
|
2516
2640
|
"i"
|
|
@@ -2537,6 +2661,7 @@ var STYLE_COLOR_PROPS = /* @__PURE__ */ new Set([
|
|
|
2537
2661
|
"lightingColor"
|
|
2538
2662
|
]);
|
|
2539
2663
|
var RAW_COLOR_VALUE_RE = new RegExp(`#[0-9a-fA-F]{3,8}\\b|\\b(?:${COLOR_FN})\\s*\\(`, "i");
|
|
2664
|
+
var CSS_VAR_REFERENCE_RE = /var\(\s*--/;
|
|
2540
2665
|
var STORIES_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
2541
2666
|
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/;
|
|
2542
2667
|
var DETECTION_FILES = [
|
|
@@ -2573,8 +2698,8 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
2573
2698
|
]);
|
|
2574
2699
|
function jsxElementName(node) {
|
|
2575
2700
|
const name = node.openingElement.name;
|
|
2576
|
-
if (name.type ===
|
|
2577
|
-
if (name.type ===
|
|
2701
|
+
if (name.type === AST_NODE_TYPES10.JSXIdentifier) return name.name;
|
|
2702
|
+
if (name.type === AST_NODE_TYPES10.JSXMemberExpression && name.property.type === AST_NODE_TYPES10.JSXIdentifier) {
|
|
2578
2703
|
return name.property.name;
|
|
2579
2704
|
}
|
|
2580
2705
|
return null;
|
|
@@ -2582,10 +2707,25 @@ function jsxElementName(node) {
|
|
|
2582
2707
|
function isSvgLikeElementName(name) {
|
|
2583
2708
|
return name === "svg" || SVG_DEFS_CONTAINERS.has(name) || /svg$/i.test(name);
|
|
2584
2709
|
}
|
|
2710
|
+
var SVG_SHAPE_PRIMITIVES = /* @__PURE__ */ new Set([
|
|
2711
|
+
"circle",
|
|
2712
|
+
"ellipse",
|
|
2713
|
+
"g",
|
|
2714
|
+
"line",
|
|
2715
|
+
"path",
|
|
2716
|
+
"polygon",
|
|
2717
|
+
"polyline",
|
|
2718
|
+
"rect",
|
|
2719
|
+
"stop",
|
|
2720
|
+
"text",
|
|
2721
|
+
"tspan",
|
|
2722
|
+
"use"
|
|
2723
|
+
]);
|
|
2724
|
+
var EMAIL_OR_PDF_IMPORT_RE = /@react-(?:email|pdf)\//;
|
|
2585
2725
|
var isInsideSvg = (node) => {
|
|
2586
2726
|
let current = node.parent;
|
|
2587
2727
|
while (current !== void 0 && current !== null) {
|
|
2588
|
-
if (current.type ===
|
|
2728
|
+
if (current.type === AST_NODE_TYPES10.JSXElement) {
|
|
2589
2729
|
const name = jsxElementName(current);
|
|
2590
2730
|
if (name !== null && isSvgLikeElementName(name)) return true;
|
|
2591
2731
|
}
|
|
@@ -2596,7 +2736,7 @@ var isInsideSvg = (node) => {
|
|
|
2596
2736
|
var isInsideIconFactoryPath = (node) => {
|
|
2597
2737
|
let current = node.parent;
|
|
2598
2738
|
while (current !== void 0 && current !== null) {
|
|
2599
|
-
if (current.type ===
|
|
2739
|
+
if (current.type === AST_NODE_TYPES10.Property && propName(current.key) === "path" && current.parent.type === AST_NODE_TYPES10.ObjectExpression && current.parent.parent.type === AST_NODE_TYPES10.CallExpression && current.parent.parent.callee.type === AST_NODE_TYPES10.Identifier && current.parent.parent.callee.name === "createIcon") {
|
|
2600
2740
|
return true;
|
|
2601
2741
|
}
|
|
2602
2742
|
current = current.parent;
|
|
@@ -2646,11 +2786,11 @@ var hasSemanticTokenSystem = (filename) => {
|
|
|
2646
2786
|
return answer;
|
|
2647
2787
|
};
|
|
2648
2788
|
var propName = (key) => {
|
|
2649
|
-
if (key.type ===
|
|
2650
|
-
if (key.type ===
|
|
2789
|
+
if (key.type === AST_NODE_TYPES10.Identifier) return key.name;
|
|
2790
|
+
if (key.type === AST_NODE_TYPES10.Literal && typeof key.value === "string") return key.value;
|
|
2651
2791
|
return null;
|
|
2652
2792
|
};
|
|
2653
|
-
var prefer_semantic_colors_default =
|
|
2793
|
+
var prefer_semantic_colors_default = ESLintUtils14.RuleCreator(
|
|
2654
2794
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2655
2795
|
)({
|
|
2656
2796
|
name: "prefer-semantic-colors",
|
|
@@ -2677,6 +2817,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2677
2817
|
defaultOptions: [{}],
|
|
2678
2818
|
create(context, [options]) {
|
|
2679
2819
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
2820
|
+
if (EMAIL_OR_PDF_IMPORT_RE.test(context.sourceCode.getText())) return {};
|
|
2680
2821
|
if (options?.requireSemanticTokens === true && !hasSemanticTokenSystem(context.filename)) {
|
|
2681
2822
|
return {};
|
|
2682
2823
|
}
|
|
@@ -2685,7 +2826,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2685
2826
|
const base = tailwindBase(token);
|
|
2686
2827
|
if (RAW_PALETTE_RE.test(base)) {
|
|
2687
2828
|
context.report({ node, messageId: "rawPalette", data: { class: token } });
|
|
2688
|
-
} else if (ARBITRARY_COLOR_RE.test(base)) {
|
|
2829
|
+
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
2689
2830
|
context.report({ node, messageId: "arbitraryColor", data: { class: token } });
|
|
2690
2831
|
}
|
|
2691
2832
|
}
|
|
@@ -2693,27 +2834,27 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2693
2834
|
const checkClassNode = (node) => {
|
|
2694
2835
|
if (node === null) return;
|
|
2695
2836
|
switch (node.type) {
|
|
2696
|
-
case
|
|
2837
|
+
case AST_NODE_TYPES10.Literal:
|
|
2697
2838
|
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
2698
2839
|
break;
|
|
2699
|
-
case
|
|
2840
|
+
case AST_NODE_TYPES10.TemplateLiteral:
|
|
2700
2841
|
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
2701
2842
|
break;
|
|
2702
|
-
case
|
|
2843
|
+
case AST_NODE_TYPES10.ArrayExpression:
|
|
2703
2844
|
for (const element of node.elements) {
|
|
2704
|
-
if (element !== null && element.type !==
|
|
2845
|
+
if (element !== null && element.type !== AST_NODE_TYPES10.SpreadElement) checkClassNode(element);
|
|
2705
2846
|
}
|
|
2706
2847
|
break;
|
|
2707
|
-
case
|
|
2848
|
+
case AST_NODE_TYPES10.ObjectExpression:
|
|
2708
2849
|
for (const property of node.properties) {
|
|
2709
|
-
if (property.type ===
|
|
2850
|
+
if (property.type === AST_NODE_TYPES10.Property) checkClassNode(property.value);
|
|
2710
2851
|
}
|
|
2711
2852
|
break;
|
|
2712
|
-
case
|
|
2853
|
+
case AST_NODE_TYPES10.ConditionalExpression:
|
|
2713
2854
|
checkClassNode(node.consequent);
|
|
2714
2855
|
checkClassNode(node.alternate);
|
|
2715
2856
|
break;
|
|
2716
|
-
case
|
|
2857
|
+
case AST_NODE_TYPES10.LogicalExpression:
|
|
2717
2858
|
checkClassNode(node.right);
|
|
2718
2859
|
break;
|
|
2719
2860
|
default:
|
|
@@ -2721,29 +2862,29 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2721
2862
|
}
|
|
2722
2863
|
};
|
|
2723
2864
|
const checkColorValueNode = (node) => {
|
|
2724
|
-
if (node.type ===
|
|
2865
|
+
if (node.type === AST_NODE_TYPES10.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value) && !CSS_VAR_REFERENCE_RE.test(node.value)) {
|
|
2725
2866
|
context.report({ node, messageId: "inlineColor", data: { value: node.value } });
|
|
2726
2867
|
}
|
|
2727
2868
|
};
|
|
2728
2869
|
return {
|
|
2729
2870
|
"JSXAttribute[name.name='className']"(node) {
|
|
2730
2871
|
if (node.value === null) return;
|
|
2731
|
-
if (node.value.type ===
|
|
2732
|
-
else if (node.value.type ===
|
|
2733
|
-
if (node.value.expression.type !==
|
|
2872
|
+
if (node.value.type === AST_NODE_TYPES10.Literal) checkClassNode(node.value);
|
|
2873
|
+
else if (node.value.type === AST_NODE_TYPES10.JSXExpressionContainer) {
|
|
2874
|
+
if (node.value.expression.type !== AST_NODE_TYPES10.JSXEmptyExpression) {
|
|
2734
2875
|
checkClassNode(node.value.expression);
|
|
2735
2876
|
}
|
|
2736
2877
|
}
|
|
2737
2878
|
},
|
|
2738
2879
|
CallExpression(node) {
|
|
2739
|
-
if (node.callee.type ===
|
|
2880
|
+
if (node.callee.type === AST_NODE_TYPES10.Identifier && CLASS_FNS.has(node.callee.name)) {
|
|
2740
2881
|
for (const arg of node.arguments) {
|
|
2741
|
-
if (arg.type !==
|
|
2882
|
+
if (arg.type !== AST_NODE_TYPES10.SpreadElement) checkClassNode(arg);
|
|
2742
2883
|
}
|
|
2743
2884
|
}
|
|
2744
2885
|
},
|
|
2745
2886
|
VariableDeclarator(node) {
|
|
2746
|
-
if (node.id.type ===
|
|
2887
|
+
if (node.id.type === AST_NODE_TYPES10.Identifier && CLASS_NAME_RE.test(node.id.name)) {
|
|
2747
2888
|
checkClassNode(node.init);
|
|
2748
2889
|
}
|
|
2749
2890
|
},
|
|
@@ -2755,7 +2896,11 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2755
2896
|
// Neutral drawing literals and anything inside an SVG defs container are
|
|
2756
2897
|
// structural, not UI tokens, so they never fire.
|
|
2757
2898
|
"JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
|
|
2758
|
-
if (node.value?.type !==
|
|
2899
|
+
if (node.value?.type !== AST_NODE_TYPES10.Literal) return;
|
|
2900
|
+
const owner = node.parent.name;
|
|
2901
|
+
if (owner.type === AST_NODE_TYPES10.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
|
|
2902
|
+
return;
|
|
2903
|
+
}
|
|
2759
2904
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
2760
2905
|
return;
|
|
2761
2906
|
}
|
|
@@ -2772,7 +2917,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2772
2917
|
});
|
|
2773
2918
|
|
|
2774
2919
|
// src/rules/prefer-server-actions.ts
|
|
2775
|
-
import { ESLintUtils as
|
|
2920
|
+
import { ESLintUtils as ESLintUtils15 } from "@typescript-eslint/utils";
|
|
2776
2921
|
var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
|
|
2777
2922
|
var AXIOS_MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "delete", "patch"]);
|
|
2778
2923
|
var SKIP_FILE_REGEX = /(?:\.test\.[jt]sx?$|\.spec\.[jt]sx?$|-(?:test|spec)\.[jt]sx?$|\/tests?\/|\/__tests__\/|\/__testfixtures__\/|\/scripts?\/|\/app\/api\/.*\/route\.[jt]sx?$|\/pages\/api\/)/;
|
|
@@ -2852,7 +2997,7 @@ function getPropertyNode(objNode, propName2) {
|
|
|
2852
2997
|
}
|
|
2853
2998
|
return null;
|
|
2854
2999
|
}
|
|
2855
|
-
var prefer_server_actions_default =
|
|
3000
|
+
var prefer_server_actions_default = ESLintUtils15.RuleCreator(
|
|
2856
3001
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2857
3002
|
)({
|
|
2858
3003
|
name: "prefer-server-actions",
|
|
@@ -2928,38 +3073,38 @@ var prefer_server_actions_default = ESLintUtils16.RuleCreator(
|
|
|
2928
3073
|
|
|
2929
3074
|
// src/rules/require-assert-never.ts
|
|
2930
3075
|
import {
|
|
2931
|
-
ESLintUtils as
|
|
2932
|
-
AST_NODE_TYPES as
|
|
3076
|
+
ESLintUtils as ESLintUtils16,
|
|
3077
|
+
AST_NODE_TYPES as AST_NODE_TYPES11
|
|
2933
3078
|
} from "@typescript-eslint/utils";
|
|
2934
3079
|
var isAssertNeverCall = (expression) => {
|
|
2935
|
-
if (expression.type !==
|
|
3080
|
+
if (expression.type !== AST_NODE_TYPES11.CallExpression) return false;
|
|
2936
3081
|
const callee = expression.callee;
|
|
2937
|
-
if (callee.type ===
|
|
3082
|
+
if (callee.type === AST_NODE_TYPES11.Identifier) {
|
|
2938
3083
|
return callee.name === "assertNever";
|
|
2939
3084
|
}
|
|
2940
|
-
if (callee.type ===
|
|
3085
|
+
if (callee.type === AST_NODE_TYPES11.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES11.Identifier) {
|
|
2941
3086
|
return callee.property.name === "assertNever";
|
|
2942
3087
|
}
|
|
2943
3088
|
return false;
|
|
2944
3089
|
};
|
|
2945
3090
|
var statementContainsAssertNever = (statement) => {
|
|
2946
|
-
if (statement.type ===
|
|
3091
|
+
if (statement.type === AST_NODE_TYPES11.ExpressionStatement) {
|
|
2947
3092
|
return isAssertNeverCall(statement.expression);
|
|
2948
3093
|
}
|
|
2949
|
-
if (statement.type ===
|
|
3094
|
+
if (statement.type === AST_NODE_TYPES11.ThrowStatement) {
|
|
2950
3095
|
return isAssertNeverCall(statement.argument);
|
|
2951
3096
|
}
|
|
2952
|
-
if (statement.type ===
|
|
3097
|
+
if (statement.type === AST_NODE_TYPES11.ReturnStatement) {
|
|
2953
3098
|
return statement.argument !== null && isAssertNeverCall(statement.argument);
|
|
2954
3099
|
}
|
|
2955
|
-
if (statement.type ===
|
|
3100
|
+
if (statement.type === AST_NODE_TYPES11.BlockStatement) {
|
|
2956
3101
|
return statement.body.some(statementContainsAssertNever);
|
|
2957
3102
|
}
|
|
2958
3103
|
return false;
|
|
2959
3104
|
};
|
|
2960
3105
|
var isRuntimeHandlingStatement = (statement) => {
|
|
2961
|
-
if (statement.type ===
|
|
2962
|
-
if (statement.type ===
|
|
3106
|
+
if (statement.type === AST_NODE_TYPES11.EmptyStatement) return false;
|
|
3107
|
+
if (statement.type === AST_NODE_TYPES11.BlockStatement) {
|
|
2963
3108
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
2964
3109
|
}
|
|
2965
3110
|
return true;
|
|
@@ -2975,12 +3120,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
2975
3120
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
2976
3121
|
}
|
|
2977
3122
|
const only = defaultCase.consequent[0];
|
|
2978
|
-
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type ===
|
|
3123
|
+
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === AST_NODE_TYPES11.BlockStatement && only.body.length === 0) {
|
|
2979
3124
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
2980
3125
|
}
|
|
2981
3126
|
return false;
|
|
2982
3127
|
};
|
|
2983
|
-
var require_assert_never_default =
|
|
3128
|
+
var require_assert_never_default = ESLintUtils16.RuleCreator(
|
|
2984
3129
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2985
3130
|
)({
|
|
2986
3131
|
name: "require-assert-never",
|
|
@@ -3018,7 +3163,7 @@ var require_assert_never_default = ESLintUtils17.RuleCreator(
|
|
|
3018
3163
|
});
|
|
3019
3164
|
|
|
3020
3165
|
// src/rules/require-zod-form-validation.ts
|
|
3021
|
-
import { ESLintUtils as
|
|
3166
|
+
import { ESLintUtils as ESLintUtils17, AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
3022
3167
|
|
|
3023
3168
|
// src/rules/_zod.ts
|
|
3024
3169
|
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
@@ -3032,14 +3177,14 @@ function isZodModule(source) {
|
|
|
3032
3177
|
var looksLikeZodSchema = (node) => {
|
|
3033
3178
|
let current = node;
|
|
3034
3179
|
while (true) {
|
|
3035
|
-
if (current.type ===
|
|
3180
|
+
if (current.type === AST_NODE_TYPES12.Identifier) {
|
|
3036
3181
|
return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
|
|
3037
3182
|
}
|
|
3038
|
-
if (current.type ===
|
|
3183
|
+
if (current.type === AST_NODE_TYPES12.CallExpression) {
|
|
3039
3184
|
current = current.callee;
|
|
3040
3185
|
continue;
|
|
3041
3186
|
}
|
|
3042
|
-
if (current.type ===
|
|
3187
|
+
if (current.type === AST_NODE_TYPES12.MemberExpression) {
|
|
3043
3188
|
current = current.object;
|
|
3044
3189
|
continue;
|
|
3045
3190
|
}
|
|
@@ -3047,25 +3192,25 @@ var looksLikeZodSchema = (node) => {
|
|
|
3047
3192
|
}
|
|
3048
3193
|
};
|
|
3049
3194
|
var isZodParseCall = (node) => {
|
|
3050
|
-
if (node.type !==
|
|
3195
|
+
if (node.type !== AST_NODE_TYPES12.CallExpression) return false;
|
|
3051
3196
|
const callee = node.callee;
|
|
3052
|
-
if (callee.type !==
|
|
3197
|
+
if (callee.type !== AST_NODE_TYPES12.MemberExpression) return false;
|
|
3053
3198
|
if (callee.computed) return false;
|
|
3054
|
-
if (callee.property.type !==
|
|
3199
|
+
if (callee.property.type !== AST_NODE_TYPES12.Identifier) return false;
|
|
3055
3200
|
const method = callee.property.name;
|
|
3056
3201
|
if (method !== "parse" && method !== "safeParse") return false;
|
|
3057
3202
|
return looksLikeZodSchema(callee.object);
|
|
3058
3203
|
};
|
|
3059
3204
|
var isFormDataMethodCall = (node) => {
|
|
3060
3205
|
let current = node;
|
|
3061
|
-
if (current.type ===
|
|
3206
|
+
if (current.type === AST_NODE_TYPES12.AwaitExpression) {
|
|
3062
3207
|
current = current.argument;
|
|
3063
3208
|
}
|
|
3064
|
-
if (current.type !==
|
|
3209
|
+
if (current.type !== AST_NODE_TYPES12.CallExpression) return false;
|
|
3065
3210
|
const callee = current.callee;
|
|
3066
|
-
return callee.type ===
|
|
3211
|
+
return callee.type === AST_NODE_TYPES12.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES12.Identifier && callee.property.name === "formData";
|
|
3067
3212
|
};
|
|
3068
|
-
var require_zod_form_validation_default =
|
|
3213
|
+
var require_zod_form_validation_default = ESLintUtils17.RuleCreator(
|
|
3069
3214
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3070
3215
|
)({
|
|
3071
3216
|
name: "require-zod-form-validation",
|
|
@@ -3085,14 +3230,14 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3085
3230
|
return {};
|
|
3086
3231
|
}
|
|
3087
3232
|
const isFormSourceIdentifier = (node) => {
|
|
3088
|
-
if (node.type !==
|
|
3233
|
+
if (node.type !== AST_NODE_TYPES12.Identifier) return false;
|
|
3089
3234
|
if (/formdata/i.test(node.name)) return true;
|
|
3090
3235
|
let scope = context.sourceCode.getScope(node);
|
|
3091
3236
|
while (scope !== null) {
|
|
3092
3237
|
const variable = scope.set.get(node.name);
|
|
3093
3238
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
3094
3239
|
const def = variable.defs[0];
|
|
3095
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
3240
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES12.VariableDeclarator && def.node.init !== null) {
|
|
3096
3241
|
return isFormDataMethodCall(def.node.init);
|
|
3097
3242
|
}
|
|
3098
3243
|
return false;
|
|
@@ -3103,8 +3248,8 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3103
3248
|
};
|
|
3104
3249
|
const isFormDataGetCall = (node) => {
|
|
3105
3250
|
const callee = node.callee;
|
|
3106
|
-
if (callee.type !==
|
|
3107
|
-
if (callee.property.type !==
|
|
3251
|
+
if (callee.type !== AST_NODE_TYPES12.MemberExpression) return false;
|
|
3252
|
+
if (callee.property.type !== AST_NODE_TYPES12.Identifier || callee.property.name !== "get") {
|
|
3108
3253
|
return false;
|
|
3109
3254
|
}
|
|
3110
3255
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -3119,11 +3264,11 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3119
3264
|
};
|
|
3120
3265
|
const isInstanceofNarrowing = (node) => {
|
|
3121
3266
|
const parent = node.parent;
|
|
3122
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
3267
|
+
return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES12.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
|
|
3123
3268
|
};
|
|
3124
3269
|
const boundDeclarator = (node) => {
|
|
3125
3270
|
const parent = node.parent;
|
|
3126
|
-
if (parent.type ===
|
|
3271
|
+
if (parent.type === AST_NODE_TYPES12.VariableDeclarator && parent.init === node && parent.id.type === AST_NODE_TYPES12.Identifier) {
|
|
3127
3272
|
return parent;
|
|
3128
3273
|
}
|
|
3129
3274
|
return null;
|
|
@@ -3151,13 +3296,14 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3151
3296
|
});
|
|
3152
3297
|
|
|
3153
3298
|
// src/rules/zod-naming-convention.ts
|
|
3154
|
-
import { ESLintUtils as
|
|
3299
|
+
import { ESLintUtils as ESLintUtils18, AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
3155
3300
|
var CONVENTIONS = {
|
|
3156
3301
|
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
3157
3302
|
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
3158
3303
|
either: { test: ZOD_SCHEMA_NAME_RE, messageId: "zodSchemaName" }
|
|
3159
3304
|
};
|
|
3160
3305
|
var CONTAINS_SCHEMA_RE = /schema/i;
|
|
3306
|
+
var BENCHMARK_PATH_RE = /(^|[\\/])(?:benchmarks?|bench)[\\/]/;
|
|
3161
3307
|
var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
3162
3308
|
"parse",
|
|
3163
3309
|
"parseAsync",
|
|
@@ -3175,15 +3321,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
|
3175
3321
|
"registry",
|
|
3176
3322
|
"implement"
|
|
3177
3323
|
]);
|
|
3178
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
3324
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES13.Identifier ? callee.property.name : null;
|
|
3179
3325
|
var calleeChainStartsWithZ = (node) => {
|
|
3180
3326
|
let current = node;
|
|
3181
|
-
while (current.type ===
|
|
3327
|
+
while (current.type === AST_NODE_TYPES13.MemberExpression) {
|
|
3182
3328
|
const receiver = current.object;
|
|
3183
|
-
if (receiver.type ===
|
|
3329
|
+
if (receiver.type === AST_NODE_TYPES13.Identifier && receiver.name === "z") {
|
|
3184
3330
|
return true;
|
|
3185
3331
|
}
|
|
3186
|
-
if (receiver.type ===
|
|
3332
|
+
if (receiver.type === AST_NODE_TYPES13.CallExpression) {
|
|
3187
3333
|
current = receiver.callee;
|
|
3188
3334
|
continue;
|
|
3189
3335
|
}
|
|
@@ -3191,7 +3337,7 @@ var calleeChainStartsWithZ = (node) => {
|
|
|
3191
3337
|
}
|
|
3192
3338
|
return false;
|
|
3193
3339
|
};
|
|
3194
|
-
var zod_naming_convention_default =
|
|
3340
|
+
var zod_naming_convention_default = ESLintUtils18.RuleCreator(
|
|
3195
3341
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3196
3342
|
)({
|
|
3197
3343
|
name: "zod-naming-convention",
|
|
@@ -3223,20 +3369,20 @@ var zod_naming_convention_default = ESLintUtils19.RuleCreator(
|
|
|
3223
3369
|
const convention = optionsArg?.convention ?? "either";
|
|
3224
3370
|
const { test, messageId } = CONVENTIONS[convention];
|
|
3225
3371
|
const acceptsSchemaWord = convention !== "prefix";
|
|
3226
|
-
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3372
|
+
if (isTestFile(context.filename) || BENCHMARK_PATH_RE.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3227
3373
|
return {};
|
|
3228
3374
|
}
|
|
3229
3375
|
return {
|
|
3230
3376
|
VariableDeclarator(node) {
|
|
3231
3377
|
const init = node.init;
|
|
3232
3378
|
if (init === null || init === void 0) return;
|
|
3233
|
-
if (init.type !==
|
|
3379
|
+
if (init.type !== AST_NODE_TYPES13.CallExpression) return;
|
|
3234
3380
|
const callee = init.callee;
|
|
3235
|
-
if (callee.type !==
|
|
3381
|
+
if (callee.type !== AST_NODE_TYPES13.MemberExpression) return;
|
|
3236
3382
|
if (!calleeChainStartsWithZ(callee)) return;
|
|
3237
3383
|
const terminal = terminalMethodName(callee);
|
|
3238
3384
|
if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
|
|
3239
|
-
if (node.id.type !==
|
|
3385
|
+
if (node.id.type !== AST_NODE_TYPES13.Identifier) return;
|
|
3240
3386
|
if (test.test(node.id.name)) return;
|
|
3241
3387
|
if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
|
|
3242
3388
|
context.report({
|
|
@@ -3249,7 +3395,7 @@ var zod_naming_convention_default = ESLintUtils19.RuleCreator(
|
|
|
3249
3395
|
});
|
|
3250
3396
|
|
|
3251
3397
|
// src/rules/no-cors-wildcard-with-credentials.ts
|
|
3252
|
-
import { ESLintUtils as
|
|
3398
|
+
import { ESLintUtils as ESLintUtils19 } from "@typescript-eslint/utils";
|
|
3253
3399
|
var ACAO_HEADER = "access-control-allow-origin";
|
|
3254
3400
|
var ACAC_HEADER = "access-control-allow-credentials";
|
|
3255
3401
|
var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
|
|
@@ -3391,7 +3537,7 @@ function enclosingScope(node) {
|
|
|
3391
3537
|
}
|
|
3392
3538
|
return void 0;
|
|
3393
3539
|
}
|
|
3394
|
-
var no_cors_wildcard_with_credentials_default =
|
|
3540
|
+
var no_cors_wildcard_with_credentials_default = ESLintUtils19.RuleCreator(
|
|
3395
3541
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3396
3542
|
)({
|
|
3397
3543
|
name: "no-cors-wildcard-with-credentials",
|
|
@@ -3459,9 +3605,9 @@ var no_cors_wildcard_with_credentials_default = ESLintUtils20.RuleCreator(
|
|
|
3459
3605
|
});
|
|
3460
3606
|
|
|
3461
3607
|
// src/rules/no-silent-promise-catch.ts
|
|
3462
|
-
import { AST_NODE_TYPES as
|
|
3608
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES14, ESLintUtils as ESLintUtils20 } from "@typescript-eslint/utils";
|
|
3463
3609
|
function isBodyParseCall(node) {
|
|
3464
|
-
return node.type ===
|
|
3610
|
+
return node.type === AST_NODE_TYPES14.CallExpression && node.arguments.length === 0 && node.callee.type === AST_NODE_TYPES14.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES14.Identifier && (node.callee.property.name === "json" || node.callee.property.name === "text");
|
|
3465
3611
|
}
|
|
3466
3612
|
var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
3467
3613
|
"cancel",
|
|
@@ -3476,21 +3622,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
|
3476
3622
|
var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
|
|
3477
3623
|
var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
|
|
3478
3624
|
function isTeardownCall(node) {
|
|
3479
|
-
return node.type ===
|
|
3625
|
+
return node.type === AST_NODE_TYPES14.CallExpression && node.callee.type === AST_NODE_TYPES14.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES14.Identifier && TEARDOWN_METHODS.has(node.callee.property.name);
|
|
3480
3626
|
}
|
|
3481
3627
|
function isSilentExpression(node) {
|
|
3482
3628
|
switch (node.type) {
|
|
3483
|
-
case
|
|
3629
|
+
case AST_NODE_TYPES14.Literal:
|
|
3484
3630
|
return !("regex" in node);
|
|
3485
|
-
case
|
|
3631
|
+
case AST_NODE_TYPES14.Identifier:
|
|
3486
3632
|
return node.name === "undefined";
|
|
3487
|
-
case
|
|
3488
|
-
return node.operator === "void" && node.argument.type ===
|
|
3489
|
-
case
|
|
3633
|
+
case AST_NODE_TYPES14.UnaryExpression:
|
|
3634
|
+
return node.operator === "void" && node.argument.type === AST_NODE_TYPES14.Literal;
|
|
3635
|
+
case AST_NODE_TYPES14.ObjectExpression:
|
|
3490
3636
|
return node.properties.length === 0;
|
|
3491
|
-
case
|
|
3637
|
+
case AST_NODE_TYPES14.ArrayExpression:
|
|
3492
3638
|
return node.elements.length === 0;
|
|
3493
|
-
case
|
|
3639
|
+
case AST_NODE_TYPES14.TSAsExpression:
|
|
3494
3640
|
return isSilentExpression(node.expression);
|
|
3495
3641
|
default:
|
|
3496
3642
|
return false;
|
|
@@ -3498,7 +3644,7 @@ function isSilentExpression(node) {
|
|
|
3498
3644
|
}
|
|
3499
3645
|
function isSilentHandler(handler) {
|
|
3500
3646
|
const body = handler.body;
|
|
3501
|
-
if (body.type !==
|
|
3647
|
+
if (body.type !== AST_NODE_TYPES14.BlockStatement) {
|
|
3502
3648
|
return isSilentExpression(body);
|
|
3503
3649
|
}
|
|
3504
3650
|
if (body.body.length === 0) {
|
|
@@ -3506,13 +3652,13 @@ function isSilentHandler(handler) {
|
|
|
3506
3652
|
}
|
|
3507
3653
|
if (body.body.length === 1) {
|
|
3508
3654
|
const only = body.body[0];
|
|
3509
|
-
if (only !== void 0 && only.type ===
|
|
3655
|
+
if (only !== void 0 && only.type === AST_NODE_TYPES14.ReturnStatement) {
|
|
3510
3656
|
return only.argument === null || isSilentExpression(only.argument);
|
|
3511
3657
|
}
|
|
3512
3658
|
}
|
|
3513
3659
|
return false;
|
|
3514
3660
|
}
|
|
3515
|
-
var no_silent_promise_catch_default =
|
|
3661
|
+
var no_silent_promise_catch_default = ESLintUtils20.RuleCreator(
|
|
3516
3662
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3517
3663
|
)({
|
|
3518
3664
|
name: "no-silent-promise-catch",
|
|
@@ -3537,7 +3683,7 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3537
3683
|
return true;
|
|
3538
3684
|
}
|
|
3539
3685
|
let statement = call;
|
|
3540
|
-
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !==
|
|
3686
|
+
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== AST_NODE_TYPES14.VariableDeclaration) {
|
|
3541
3687
|
statement = statement.parent;
|
|
3542
3688
|
}
|
|
3543
3689
|
if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
|
|
@@ -3549,7 +3695,7 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3549
3695
|
};
|
|
3550
3696
|
return {
|
|
3551
3697
|
CallExpression(node) {
|
|
3552
|
-
if (node.callee.type !==
|
|
3698
|
+
if (node.callee.type !== AST_NODE_TYPES14.MemberExpression || node.callee.computed || node.callee.property.type !== AST_NODE_TYPES14.Identifier || node.callee.property.name !== "catch") {
|
|
3553
3699
|
return;
|
|
3554
3700
|
}
|
|
3555
3701
|
if (isBodyParseCall(node.callee.object)) {
|
|
@@ -3558,14 +3704,14 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3558
3704
|
if (isTeardownCall(node.callee.object)) {
|
|
3559
3705
|
return;
|
|
3560
3706
|
}
|
|
3561
|
-
if (node.parent.type ===
|
|
3707
|
+
if (node.parent.type === AST_NODE_TYPES14.MemberExpression && node.parent.object === node) {
|
|
3562
3708
|
return;
|
|
3563
3709
|
}
|
|
3564
3710
|
if (node.arguments.length !== 1) {
|
|
3565
3711
|
return;
|
|
3566
3712
|
}
|
|
3567
3713
|
const handler = node.arguments[0];
|
|
3568
|
-
if (handler === void 0 || handler.type !==
|
|
3714
|
+
if (handler === void 0 || handler.type !== AST_NODE_TYPES14.ArrowFunctionExpression && handler.type !== AST_NODE_TYPES14.FunctionExpression) {
|
|
3569
3715
|
return;
|
|
3570
3716
|
}
|
|
3571
3717
|
if (hasExplanatoryComment(node, handler)) {
|
|
@@ -3581,9 +3727,9 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3581
3727
|
|
|
3582
3728
|
// src/rules/require-fetch-timeout.ts
|
|
3583
3729
|
import {
|
|
3584
|
-
AST_NODE_TYPES as
|
|
3585
|
-
ASTUtils,
|
|
3586
|
-
ESLintUtils as
|
|
3730
|
+
AST_NODE_TYPES as AST_NODE_TYPES15,
|
|
3731
|
+
ASTUtils as ASTUtils2,
|
|
3732
|
+
ESLintUtils as ESLintUtils21
|
|
3587
3733
|
} from "@typescript-eslint/utils";
|
|
3588
3734
|
var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
|
|
3589
3735
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
|
|
@@ -3601,14 +3747,14 @@ function matchesAnyPattern2(filename, patterns) {
|
|
|
3601
3747
|
return false;
|
|
3602
3748
|
}
|
|
3603
3749
|
function initProvablyLacksSignal(init) {
|
|
3604
|
-
if (init.type !==
|
|
3750
|
+
if (init.type !== AST_NODE_TYPES15.ObjectExpression) {
|
|
3605
3751
|
return false;
|
|
3606
3752
|
}
|
|
3607
3753
|
for (const prop of init.properties) {
|
|
3608
|
-
if (prop.type ===
|
|
3754
|
+
if (prop.type === AST_NODE_TYPES15.SpreadElement) {
|
|
3609
3755
|
return false;
|
|
3610
3756
|
}
|
|
3611
|
-
if (prop.key.type ===
|
|
3757
|
+
if (prop.key.type === AST_NODE_TYPES15.Identifier && prop.key.name === "signal" || prop.key.type === AST_NODE_TYPES15.Literal && prop.key.value === "signal") {
|
|
3612
3758
|
return false;
|
|
3613
3759
|
}
|
|
3614
3760
|
if (prop.computed) {
|
|
@@ -3618,9 +3764,9 @@ function initProvablyLacksSignal(init) {
|
|
|
3618
3764
|
return true;
|
|
3619
3765
|
}
|
|
3620
3766
|
function isStringish(node) {
|
|
3621
|
-
return node.type ===
|
|
3767
|
+
return node.type === AST_NODE_TYPES15.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES15.TemplateLiteral;
|
|
3622
3768
|
}
|
|
3623
|
-
var require_fetch_timeout_default =
|
|
3769
|
+
var require_fetch_timeout_default = ESLintUtils21.RuleCreator(
|
|
3624
3770
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3625
3771
|
)({
|
|
3626
3772
|
name: "require-fetch-timeout",
|
|
@@ -3657,14 +3803,14 @@ var require_fetch_timeout_default = ESLintUtils22.RuleCreator(
|
|
|
3657
3803
|
}
|
|
3658
3804
|
function resolvesToGlobal(identifier) {
|
|
3659
3805
|
const scope = context.sourceCode.getScope(identifier);
|
|
3660
|
-
const variable =
|
|
3806
|
+
const variable = ASTUtils2.findVariable(scope, identifier.name);
|
|
3661
3807
|
return variable === null || variable.defs.length === 0;
|
|
3662
3808
|
}
|
|
3663
3809
|
function isGlobalFetchCall2(callee) {
|
|
3664
|
-
if (callee.type ===
|
|
3810
|
+
if (callee.type === AST_NODE_TYPES15.Identifier) {
|
|
3665
3811
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
3666
3812
|
}
|
|
3667
|
-
return callee.type ===
|
|
3813
|
+
return callee.type === AST_NODE_TYPES15.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES15.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES15.Identifier && GLOBAL_OBJECTS.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
3668
3814
|
}
|
|
3669
3815
|
return {
|
|
3670
3816
|
CallExpression(node) {
|
|
@@ -3685,14 +3831,14 @@ var require_fetch_timeout_default = ESLintUtils22.RuleCreator(
|
|
|
3685
3831
|
|
|
3686
3832
|
// src/rules/no-fat-try-blocks.ts
|
|
3687
3833
|
import {
|
|
3688
|
-
ESLintUtils as
|
|
3689
|
-
AST_NODE_TYPES as
|
|
3834
|
+
ESLintUtils as ESLintUtils22,
|
|
3835
|
+
AST_NODE_TYPES as AST_NODE_TYPES16
|
|
3690
3836
|
} from "@typescript-eslint/utils";
|
|
3691
3837
|
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
3692
3838
|
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3839
|
+
AST_NODE_TYPES16.FunctionDeclaration,
|
|
3840
|
+
AST_NODE_TYPES16.FunctionExpression,
|
|
3841
|
+
AST_NODE_TYPES16.ArrowFunctionExpression
|
|
3696
3842
|
]);
|
|
3697
3843
|
var PURE_METHODS = /* @__PURE__ */ new Set([
|
|
3698
3844
|
"map",
|
|
@@ -3790,22 +3936,22 @@ function isNode3(value) {
|
|
|
3790
3936
|
}
|
|
3791
3937
|
function isPureCall(node) {
|
|
3792
3938
|
const callee = node.callee;
|
|
3793
|
-
if (callee.type !==
|
|
3939
|
+
if (callee.type !== AST_NODE_TYPES16.MemberExpression) {
|
|
3794
3940
|
return false;
|
|
3795
3941
|
}
|
|
3796
3942
|
const property = callee.property;
|
|
3797
|
-
if (property.type !==
|
|
3943
|
+
if (property.type !== AST_NODE_TYPES16.Identifier) {
|
|
3798
3944
|
return false;
|
|
3799
3945
|
}
|
|
3800
|
-
if (callee.object.type ===
|
|
3946
|
+
if (callee.object.type === AST_NODE_TYPES16.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
|
|
3801
3947
|
return true;
|
|
3802
3948
|
}
|
|
3803
3949
|
return PURE_METHODS.has(property.name);
|
|
3804
3950
|
}
|
|
3805
3951
|
function isPureNew(node) {
|
|
3806
|
-
return node.callee.type ===
|
|
3952
|
+
return node.callee.type === AST_NODE_TYPES16.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
|
|
3807
3953
|
}
|
|
3808
|
-
function subtreeMatches(stmt, predicate) {
|
|
3954
|
+
function subtreeMatches(stmt, predicate, descendIntoFunctions = false) {
|
|
3809
3955
|
let found = false;
|
|
3810
3956
|
const visit = (current) => {
|
|
3811
3957
|
if (found) {
|
|
@@ -3819,7 +3965,7 @@ function subtreeMatches(stmt, predicate) {
|
|
|
3819
3965
|
if (key === "parent") {
|
|
3820
3966
|
continue;
|
|
3821
3967
|
}
|
|
3822
|
-
if (NESTED_FUNCTION_TYPES.has(current.type) && key === "body") {
|
|
3968
|
+
if (!descendIntoFunctions && NESTED_FUNCTION_TYPES.has(current.type) && key === "body") {
|
|
3823
3969
|
continue;
|
|
3824
3970
|
}
|
|
3825
3971
|
const value = current[key];
|
|
@@ -3840,20 +3986,20 @@ function subtreeMatches(stmt, predicate) {
|
|
|
3840
3986
|
visit(stmt);
|
|
3841
3987
|
return found;
|
|
3842
3988
|
}
|
|
3843
|
-
var hasAwait = (node) => subtreeMatches(node, (n) => n.type ===
|
|
3989
|
+
var hasAwait = (node) => subtreeMatches(node, (n) => n.type === AST_NODE_TYPES16.AwaitExpression);
|
|
3844
3990
|
var hasThrowingCallOrNew = (node) => subtreeMatches(
|
|
3845
3991
|
node,
|
|
3846
|
-
(n) => n.type ===
|
|
3992
|
+
(n) => n.type === AST_NODE_TYPES16.CallExpression && !isPureCall(n) || n.type === AST_NODE_TYPES16.NewExpression && !isPureNew(n)
|
|
3847
3993
|
);
|
|
3848
3994
|
function unwrap2(expr) {
|
|
3849
3995
|
let current = expr;
|
|
3850
|
-
while (current.type ===
|
|
3996
|
+
while (current.type === AST_NODE_TYPES16.ChainExpression || current.type === AST_NODE_TYPES16.TSNonNullExpression) {
|
|
3851
3997
|
current = current.expression;
|
|
3852
3998
|
}
|
|
3853
3999
|
return current;
|
|
3854
4000
|
}
|
|
3855
4001
|
function isBareCallStatement(stmt) {
|
|
3856
|
-
return stmt.type ===
|
|
4002
|
+
return stmt.type === AST_NODE_TYPES16.ExpressionStatement && unwrap2(stmt.expression).type === AST_NODE_TYPES16.CallExpression;
|
|
3857
4003
|
}
|
|
3858
4004
|
function canThrow(stmt) {
|
|
3859
4005
|
if (hasAwait(stmt)) {
|
|
@@ -3862,10 +4008,10 @@ function canThrow(stmt) {
|
|
|
3862
4008
|
if (isBareCallStatement(stmt)) {
|
|
3863
4009
|
return false;
|
|
3864
4010
|
}
|
|
3865
|
-
if (stmt.type ===
|
|
4011
|
+
if (stmt.type === AST_NODE_TYPES16.BlockStatement) {
|
|
3866
4012
|
return stmt.body.some(canThrow);
|
|
3867
4013
|
}
|
|
3868
|
-
if (stmt.type ===
|
|
4014
|
+
if (stmt.type === AST_NODE_TYPES16.IfStatement) {
|
|
3869
4015
|
return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
|
|
3870
4016
|
}
|
|
3871
4017
|
return hasThrowingCallOrNew(stmt);
|
|
@@ -3876,9 +4022,137 @@ function handlerRethrows(handler) {
|
|
|
3876
4022
|
}
|
|
3877
4023
|
const body = handler.body.body;
|
|
3878
4024
|
const last = body[body.length - 1];
|
|
3879
|
-
return last !== void 0 && last.type ===
|
|
4025
|
+
return last !== void 0 && last.type === AST_NODE_TYPES16.ThrowStatement;
|
|
4026
|
+
}
|
|
4027
|
+
var PASS_THROUGH_PARENTS = /* @__PURE__ */ new Set([
|
|
4028
|
+
AST_NODE_TYPES16.IfStatement,
|
|
4029
|
+
AST_NODE_TYPES16.TryStatement,
|
|
4030
|
+
AST_NODE_TYPES16.CatchClause,
|
|
4031
|
+
AST_NODE_TYPES16.LabeledStatement
|
|
4032
|
+
]);
|
|
4033
|
+
function isTerminalInFunction(node) {
|
|
4034
|
+
let current = node;
|
|
4035
|
+
let parent = current.parent;
|
|
4036
|
+
while (parent !== void 0) {
|
|
4037
|
+
if (parent.type === AST_NODE_TYPES16.BlockStatement) {
|
|
4038
|
+
if (parent.body[parent.body.length - 1] !== current) {
|
|
4039
|
+
return false;
|
|
4040
|
+
}
|
|
4041
|
+
} else if (parent.type === AST_NODE_TYPES16.Program) {
|
|
4042
|
+
return parent.body[parent.body.length - 1] === current;
|
|
4043
|
+
} else if (NESTED_FUNCTION_TYPES.has(parent.type)) {
|
|
4044
|
+
return true;
|
|
4045
|
+
} else if (!PASS_THROUGH_PARENTS.has(parent.type)) {
|
|
4046
|
+
return false;
|
|
4047
|
+
}
|
|
4048
|
+
current = parent;
|
|
4049
|
+
parent = current.parent;
|
|
4050
|
+
}
|
|
4051
|
+
return false;
|
|
4052
|
+
}
|
|
4053
|
+
function unwrapAwait(expr) {
|
|
4054
|
+
const inner = unwrap2(expr);
|
|
4055
|
+
return inner.type === AST_NODE_TYPES16.AwaitExpression ? unwrap2(inner.argument) : inner;
|
|
3880
4056
|
}
|
|
3881
|
-
|
|
4057
|
+
function handlerEndsByHandingOff(handler) {
|
|
4058
|
+
const body = handler.body.body;
|
|
4059
|
+
const last = body[body.length - 1];
|
|
4060
|
+
if (last === void 0) {
|
|
4061
|
+
return false;
|
|
4062
|
+
}
|
|
4063
|
+
if (last.type === AST_NODE_TYPES16.ReturnStatement || last.type === AST_NODE_TYPES16.ThrowStatement) {
|
|
4064
|
+
return true;
|
|
4065
|
+
}
|
|
4066
|
+
return last.type === AST_NODE_TYPES16.ExpressionStatement && unwrapAwait(last.expression).type === AST_NODE_TYPES16.CallExpression;
|
|
4067
|
+
}
|
|
4068
|
+
function collectBindingNames(pattern, names) {
|
|
4069
|
+
if (pattern.type === AST_NODE_TYPES16.Identifier) {
|
|
4070
|
+
names.add(pattern.name);
|
|
4071
|
+
return;
|
|
4072
|
+
}
|
|
4073
|
+
if (pattern.type === AST_NODE_TYPES16.ObjectPattern) {
|
|
4074
|
+
for (const property of pattern.properties) {
|
|
4075
|
+
collectBindingNames(
|
|
4076
|
+
property.type === AST_NODE_TYPES16.RestElement ? property.argument : property.value,
|
|
4077
|
+
names
|
|
4078
|
+
);
|
|
4079
|
+
}
|
|
4080
|
+
return;
|
|
4081
|
+
}
|
|
4082
|
+
if (pattern.type === AST_NODE_TYPES16.ArrayPattern) {
|
|
4083
|
+
for (const element of pattern.elements) {
|
|
4084
|
+
if (element !== null) {
|
|
4085
|
+
collectBindingNames(element, names);
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
return;
|
|
4089
|
+
}
|
|
4090
|
+
if (pattern.type === AST_NODE_TYPES16.AssignmentPattern || pattern.type === AST_NODE_TYPES16.RestElement) {
|
|
4091
|
+
collectBindingNames(
|
|
4092
|
+
pattern.type === AST_NODE_TYPES16.AssignmentPattern ? pattern.left : pattern.argument,
|
|
4093
|
+
names
|
|
4094
|
+
);
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
function caughtBindingNames(handler) {
|
|
4098
|
+
const names = /* @__PURE__ */ new Set();
|
|
4099
|
+
if (handler.param !== null) {
|
|
4100
|
+
collectBindingNames(handler.param, names);
|
|
4101
|
+
}
|
|
4102
|
+
return names;
|
|
4103
|
+
}
|
|
4104
|
+
function isPropertyName(node) {
|
|
4105
|
+
const parent = node.parent;
|
|
4106
|
+
if (parent.type === AST_NODE_TYPES16.MemberExpression) {
|
|
4107
|
+
return parent.property === node && !parent.computed;
|
|
4108
|
+
}
|
|
4109
|
+
if (parent.type === AST_NODE_TYPES16.Property) {
|
|
4110
|
+
return parent.key === node && !parent.computed;
|
|
4111
|
+
}
|
|
4112
|
+
return false;
|
|
4113
|
+
}
|
|
4114
|
+
function handlerMentionsCaughtBinding(handler) {
|
|
4115
|
+
const names = caughtBindingNames(handler);
|
|
4116
|
+
if (names.size === 0) {
|
|
4117
|
+
return false;
|
|
4118
|
+
}
|
|
4119
|
+
return subtreeMatches(
|
|
4120
|
+
handler.body,
|
|
4121
|
+
(n) => n.type === AST_NODE_TYPES16.Identifier && names.has(n.name) && !isPropertyName(n),
|
|
4122
|
+
true
|
|
4123
|
+
);
|
|
4124
|
+
}
|
|
4125
|
+
function isSuccessShapedValue(expr) {
|
|
4126
|
+
let current = expr;
|
|
4127
|
+
while (current.type === AST_NODE_TYPES16.TSAsExpression || current.type === AST_NODE_TYPES16.TSNonNullExpression) {
|
|
4128
|
+
current = current.expression;
|
|
4129
|
+
}
|
|
4130
|
+
if (current.type === AST_NODE_TYPES16.Literal) {
|
|
4131
|
+
return current.value === null || current.value === false;
|
|
4132
|
+
}
|
|
4133
|
+
if (current.type === AST_NODE_TYPES16.Identifier) {
|
|
4134
|
+
return current.name === "undefined";
|
|
4135
|
+
}
|
|
4136
|
+
if (current.type === AST_NODE_TYPES16.UnaryExpression) {
|
|
4137
|
+
return current.operator === "void";
|
|
4138
|
+
}
|
|
4139
|
+
if (current.type === AST_NODE_TYPES16.ArrayExpression) {
|
|
4140
|
+
return current.elements.length === 0;
|
|
4141
|
+
}
|
|
4142
|
+
if (current.type === AST_NODE_TYPES16.ObjectExpression) {
|
|
4143
|
+
return current.properties.length === 0;
|
|
4144
|
+
}
|
|
4145
|
+
return false;
|
|
4146
|
+
}
|
|
4147
|
+
var handlerReturnsSuccessShaped = (handler) => subtreeMatches(
|
|
4148
|
+
handler.body,
|
|
4149
|
+
(n) => n.type === AST_NODE_TYPES16.ReturnStatement && n.argument !== null && isSuccessShapedValue(n.argument)
|
|
4150
|
+
);
|
|
4151
|
+
function isTerminalErrorBoundary(node) {
|
|
4152
|
+
const handler = node.handler;
|
|
4153
|
+
return handler !== null && isTerminalInFunction(node) && handlerEndsByHandingOff(handler) && handlerMentionsCaughtBinding(handler) && !handlerReturnsSuccessShaped(handler);
|
|
4154
|
+
}
|
|
4155
|
+
var no_fat_try_blocks_default = ESLintUtils22.RuleCreator(
|
|
3882
4156
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3883
4157
|
)({
|
|
3884
4158
|
name: "no-fat-try-blocks",
|
|
@@ -3906,6 +4180,9 @@ var no_fat_try_blocks_default = ESLintUtils23.RuleCreator(
|
|
|
3906
4180
|
if (handlerRethrows(node.handler)) {
|
|
3907
4181
|
return;
|
|
3908
4182
|
}
|
|
4183
|
+
if (isTerminalErrorBoundary(node)) {
|
|
4184
|
+
return;
|
|
4185
|
+
}
|
|
3909
4186
|
const count = node.block.body.filter(canThrow).length;
|
|
3910
4187
|
if (count <= MAX_TRY_BODY_STATEMENTS) {
|
|
3911
4188
|
return;
|
|
@@ -3922,7 +4199,7 @@ var no_fat_try_blocks_default = ESLintUtils23.RuleCreator(
|
|
|
3922
4199
|
});
|
|
3923
4200
|
|
|
3924
4201
|
// src/rules/no-secret-in-log.ts
|
|
3925
|
-
import { ESLintUtils as
|
|
4202
|
+
import { ESLintUtils as ESLintUtils23 } from "@typescript-eslint/utils";
|
|
3926
4203
|
|
|
3927
4204
|
// src/rules/_secret_names.ts
|
|
3928
4205
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4184,7 +4461,7 @@ function propertyKeyName2(prop) {
|
|
|
4184
4461
|
}
|
|
4185
4462
|
return null;
|
|
4186
4463
|
}
|
|
4187
|
-
var no_secret_in_log_default =
|
|
4464
|
+
var no_secret_in_log_default = ESLintUtils23.RuleCreator(
|
|
4188
4465
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4189
4466
|
)({
|
|
4190
4467
|
name: "no-secret-in-log",
|
|
@@ -4261,24 +4538,24 @@ var no_secret_in_log_default = ESLintUtils24.RuleCreator(
|
|
|
4261
4538
|
});
|
|
4262
4539
|
|
|
4263
4540
|
// src/rules/no-unsafe-mock-casting.ts
|
|
4264
|
-
import { ESLintUtils as
|
|
4265
|
-
import { AST_NODE_TYPES as
|
|
4541
|
+
import { ESLintUtils as ESLintUtils24 } from "@typescript-eslint/utils";
|
|
4542
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17 } from "@typescript-eslint/utils";
|
|
4266
4543
|
function isMockTypeReference(node) {
|
|
4267
|
-
if (node.type !==
|
|
4544
|
+
if (node.type !== AST_NODE_TYPES17.TSTypeReference) {
|
|
4268
4545
|
return false;
|
|
4269
4546
|
}
|
|
4270
4547
|
const typeName = node.typeName;
|
|
4271
|
-
if (typeName.type ===
|
|
4548
|
+
if (typeName.type === AST_NODE_TYPES17.Identifier) {
|
|
4272
4549
|
const name = typeName.name;
|
|
4273
4550
|
return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
|
|
4274
4551
|
}
|
|
4275
|
-
if (typeName.type ===
|
|
4552
|
+
if (typeName.type === AST_NODE_TYPES17.TSQualifiedName) {
|
|
4276
4553
|
const rightName = typeName.right.name;
|
|
4277
4554
|
return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
|
|
4278
4555
|
}
|
|
4279
4556
|
return false;
|
|
4280
4557
|
}
|
|
4281
|
-
var no_unsafe_mock_casting_default =
|
|
4558
|
+
var no_unsafe_mock_casting_default = ESLintUtils24.RuleCreator(
|
|
4282
4559
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4283
4560
|
)({
|
|
4284
4561
|
name: "no-unsafe-mock-casting",
|
|
@@ -4311,8 +4588,8 @@ var no_unsafe_mock_casting_default = ESLintUtils25.RuleCreator(
|
|
|
4311
4588
|
|
|
4312
4589
|
// src/rules/prefer-string-literal-union.ts
|
|
4313
4590
|
import {
|
|
4314
|
-
ESLintUtils as
|
|
4315
|
-
AST_NODE_TYPES as
|
|
4591
|
+
ESLintUtils as ESLintUtils25,
|
|
4592
|
+
AST_NODE_TYPES as AST_NODE_TYPES18
|
|
4316
4593
|
} from "@typescript-eslint/utils";
|
|
4317
4594
|
import * as ts from "typescript";
|
|
4318
4595
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -4356,19 +4633,19 @@ function isChoiceLikeName(name) {
|
|
|
4356
4633
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
4357
4634
|
}
|
|
4358
4635
|
function keyName(key) {
|
|
4359
|
-
if (key.type ===
|
|
4636
|
+
if (key.type === AST_NODE_TYPES18.Identifier) {
|
|
4360
4637
|
return key.name;
|
|
4361
4638
|
}
|
|
4362
|
-
if (key.type ===
|
|
4639
|
+
if (key.type === AST_NODE_TYPES18.Literal && typeof key.value === "string") {
|
|
4363
4640
|
return key.value;
|
|
4364
4641
|
}
|
|
4365
4642
|
return null;
|
|
4366
4643
|
}
|
|
4367
4644
|
function isStringLiteralMember(t) {
|
|
4368
|
-
return t.type ===
|
|
4645
|
+
return t.type === AST_NODE_TYPES18.TSLiteralType && t.literal.type === AST_NODE_TYPES18.Literal && typeof t.literal.value === "string";
|
|
4369
4646
|
}
|
|
4370
4647
|
function isStringLiteralUnion(node) {
|
|
4371
|
-
if (node?.type !==
|
|
4648
|
+
if (node?.type !== AST_NODE_TYPES18.TSUnionType) {
|
|
4372
4649
|
return false;
|
|
4373
4650
|
}
|
|
4374
4651
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -4397,12 +4674,12 @@ function bindingSourceExpression(decl) {
|
|
|
4397
4674
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
4398
4675
|
}
|
|
4399
4676
|
function refKey(node) {
|
|
4400
|
-
if (node.type ===
|
|
4677
|
+
if (node.type === AST_NODE_TYPES18.Identifier) {
|
|
4401
4678
|
return node.name;
|
|
4402
4679
|
}
|
|
4403
|
-
if (node.type ===
|
|
4680
|
+
if (node.type === AST_NODE_TYPES18.MemberExpression && !node.computed) {
|
|
4404
4681
|
const inner = refKey(node.object);
|
|
4405
|
-
if (inner === null || node.property.type !==
|
|
4682
|
+
if (inner === null || node.property.type !== AST_NODE_TYPES18.Identifier) {
|
|
4406
4683
|
return null;
|
|
4407
4684
|
}
|
|
4408
4685
|
return `${inner}.${node.property.name}`;
|
|
@@ -4410,12 +4687,12 @@ function refKey(node) {
|
|
|
4410
4687
|
return null;
|
|
4411
4688
|
}
|
|
4412
4689
|
function strLiteral(node) {
|
|
4413
|
-
if (node.type ===
|
|
4690
|
+
if (node.type === AST_NODE_TYPES18.Literal && typeof node.value === "string") {
|
|
4414
4691
|
return node.value;
|
|
4415
4692
|
}
|
|
4416
4693
|
return null;
|
|
4417
4694
|
}
|
|
4418
|
-
var prefer_string_literal_union_default =
|
|
4695
|
+
var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
4419
4696
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4420
4697
|
)({
|
|
4421
4698
|
name: "prefer-string-literal-union",
|
|
@@ -4453,7 +4730,7 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4453
4730
|
);
|
|
4454
4731
|
let services;
|
|
4455
4732
|
try {
|
|
4456
|
-
services =
|
|
4733
|
+
services = ESLintUtils25.getParserServices(context);
|
|
4457
4734
|
} catch {
|
|
4458
4735
|
services = null;
|
|
4459
4736
|
}
|
|
@@ -4565,7 +4842,7 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4565
4842
|
containersWithUnion.add(container);
|
|
4566
4843
|
return;
|
|
4567
4844
|
}
|
|
4568
|
-
if (typeNode?.type !==
|
|
4845
|
+
if (typeNode?.type !== AST_NODE_TYPES18.TSStringKeyword) {
|
|
4569
4846
|
return;
|
|
4570
4847
|
}
|
|
4571
4848
|
const name = keyName(key);
|
|
@@ -4653,10 +4930,10 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4653
4930
|
}
|
|
4654
4931
|
};
|
|
4655
4932
|
function refKeyText(node) {
|
|
4656
|
-
if (node.type ===
|
|
4933
|
+
if (node.type === AST_NODE_TYPES18.BinaryExpression) {
|
|
4657
4934
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
4658
4935
|
}
|
|
4659
|
-
if (node.type ===
|
|
4936
|
+
if (node.type === AST_NODE_TYPES18.SwitchStatement) {
|
|
4660
4937
|
return refKey(node.discriminant) ?? "value";
|
|
4661
4938
|
}
|
|
4662
4939
|
return "value";
|
|
@@ -4666,10 +4943,10 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4666
4943
|
|
|
4667
4944
|
// src/rules/prefer-zod-enum.ts
|
|
4668
4945
|
import {
|
|
4669
|
-
AST_NODE_TYPES as
|
|
4670
|
-
ESLintUtils as
|
|
4946
|
+
AST_NODE_TYPES as AST_NODE_TYPES19,
|
|
4947
|
+
ESLintUtils as ESLintUtils26
|
|
4671
4948
|
} from "@typescript-eslint/utils";
|
|
4672
|
-
var prefer_zod_enum_default =
|
|
4949
|
+
var prefer_zod_enum_default = ESLintUtils26.RuleCreator(
|
|
4673
4950
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
4674
4951
|
)({
|
|
4675
4952
|
name: "prefer-zod-enum",
|
|
@@ -4690,20 +4967,20 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4690
4967
|
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
4691
4968
|
function enumValues(node) {
|
|
4692
4969
|
const callee = node.callee;
|
|
4693
|
-
if (callee.type !==
|
|
4970
|
+
if (callee.type !== AST_NODE_TYPES19.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES19.Identifier || !zodNamespaces.has(callee.object.name) || callee.property.type !== AST_NODE_TYPES19.Identifier || callee.property.name !== "union" || node.arguments.length !== 1) {
|
|
4694
4971
|
return null;
|
|
4695
4972
|
}
|
|
4696
4973
|
const argument = node.arguments[0];
|
|
4697
|
-
if (argument === void 0 || argument.type !==
|
|
4974
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES19.ArrayExpression || argument.elements.length === 0) {
|
|
4698
4975
|
return null;
|
|
4699
4976
|
}
|
|
4700
4977
|
const values = [];
|
|
4701
4978
|
for (const element of argument.elements) {
|
|
4702
|
-
if (element === null || element.type !==
|
|
4979
|
+
if (element === null || element.type !== AST_NODE_TYPES19.CallExpression || element.arguments.length !== 1 || element.callee.type !== AST_NODE_TYPES19.MemberExpression || element.callee.computed || element.callee.object.type !== AST_NODE_TYPES19.Identifier || !zodNamespaces.has(element.callee.object.name) || element.callee.property.type !== AST_NODE_TYPES19.Identifier || element.callee.property.name !== "literal") {
|
|
4703
4980
|
return null;
|
|
4704
4981
|
}
|
|
4705
4982
|
const value = element.arguments[0];
|
|
4706
|
-
if (value === void 0 || value.type !==
|
|
4983
|
+
if (value === void 0 || value.type !== AST_NODE_TYPES19.Literal || typeof value.value !== "string") {
|
|
4707
4984
|
return null;
|
|
4708
4985
|
}
|
|
4709
4986
|
values.push(value);
|
|
@@ -4712,11 +4989,11 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4712
4989
|
}
|
|
4713
4990
|
function buildFix(node, values) {
|
|
4714
4991
|
const argument = node.arguments[0];
|
|
4715
|
-
if (argument === void 0 || argument.type !==
|
|
4992
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES19.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
|
|
4716
4993
|
return void 0;
|
|
4717
4994
|
}
|
|
4718
4995
|
const callee = node.callee;
|
|
4719
|
-
if (callee.type !==
|
|
4996
|
+
if (callee.type !== AST_NODE_TYPES19.MemberExpression || callee.property.type !== AST_NODE_TYPES19.Identifier) {
|
|
4720
4997
|
return void 0;
|
|
4721
4998
|
}
|
|
4722
4999
|
return (fixer) => [
|
|
@@ -4733,7 +5010,7 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4733
5010
|
return;
|
|
4734
5011
|
}
|
|
4735
5012
|
for (const specifier of node.specifiers) {
|
|
4736
|
-
if (specifier.type ===
|
|
5013
|
+
if (specifier.type === AST_NODE_TYPES19.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES19.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES19.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES19.Identifier && specifier.imported.name === "z") {
|
|
4737
5014
|
zodNamespaces.add(specifier.local.name);
|
|
4738
5015
|
}
|
|
4739
5016
|
}
|
|
@@ -4756,8 +5033,8 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4756
5033
|
|
|
4757
5034
|
// src/rules/prefer-zod-infer.ts
|
|
4758
5035
|
import {
|
|
4759
|
-
AST_NODE_TYPES as
|
|
4760
|
-
ESLintUtils as
|
|
5036
|
+
AST_NODE_TYPES as AST_NODE_TYPES20,
|
|
5037
|
+
ESLintUtils as ESLintUtils27
|
|
4761
5038
|
} from "@typescript-eslint/utils";
|
|
4762
5039
|
var SHAPE_PRESERVING_METHODS = /* @__PURE__ */ new Set([
|
|
4763
5040
|
"describe",
|
|
@@ -4795,44 +5072,44 @@ var ZOD_TYPE_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
|
4795
5072
|
"Schema"
|
|
4796
5073
|
]);
|
|
4797
5074
|
var LEAF_NODE_TYPES = {
|
|
4798
|
-
string: [
|
|
4799
|
-
email: [
|
|
4800
|
-
url: [
|
|
4801
|
-
uuid: [
|
|
4802
|
-
ulid: [
|
|
4803
|
-
cuid: [
|
|
4804
|
-
cuid2: [
|
|
4805
|
-
nanoid: [
|
|
4806
|
-
iso: [
|
|
4807
|
-
number: [
|
|
4808
|
-
int: [
|
|
4809
|
-
float32: [
|
|
4810
|
-
float64: [
|
|
4811
|
-
boolean: [
|
|
4812
|
-
bigint: [
|
|
4813
|
-
symbol: [
|
|
4814
|
-
any: [
|
|
4815
|
-
unknown: [
|
|
4816
|
-
never: [
|
|
4817
|
-
void: [
|
|
4818
|
-
null: [
|
|
4819
|
-
undefined: [
|
|
4820
|
-
literal: [
|
|
4821
|
-
date: [
|
|
4822
|
-
array: [
|
|
4823
|
-
tuple: [
|
|
4824
|
-
object: [
|
|
4825
|
-
strictObject: [
|
|
4826
|
-
looseObject: [
|
|
4827
|
-
record: [
|
|
4828
|
-
map: [
|
|
4829
|
-
set: [
|
|
4830
|
-
promise: [
|
|
4831
|
-
enum: [
|
|
4832
|
-
nativeEnum: [
|
|
4833
|
-
union: [
|
|
4834
|
-
discriminatedUnion: [
|
|
4835
|
-
intersection: [
|
|
5075
|
+
string: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5076
|
+
email: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5077
|
+
url: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5078
|
+
uuid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5079
|
+
ulid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5080
|
+
cuid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5081
|
+
cuid2: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5082
|
+
nanoid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5083
|
+
iso: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5084
|
+
number: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5085
|
+
int: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5086
|
+
float32: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5087
|
+
float64: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5088
|
+
boolean: [AST_NODE_TYPES20.TSBooleanKeyword],
|
|
5089
|
+
bigint: [AST_NODE_TYPES20.TSBigIntKeyword],
|
|
5090
|
+
symbol: [AST_NODE_TYPES20.TSSymbolKeyword],
|
|
5091
|
+
any: [AST_NODE_TYPES20.TSAnyKeyword],
|
|
5092
|
+
unknown: [AST_NODE_TYPES20.TSUnknownKeyword],
|
|
5093
|
+
never: [AST_NODE_TYPES20.TSNeverKeyword],
|
|
5094
|
+
void: [AST_NODE_TYPES20.TSVoidKeyword],
|
|
5095
|
+
null: [AST_NODE_TYPES20.TSNullKeyword],
|
|
5096
|
+
undefined: [AST_NODE_TYPES20.TSUndefinedKeyword],
|
|
5097
|
+
literal: [AST_NODE_TYPES20.TSLiteralType],
|
|
5098
|
+
date: [AST_NODE_TYPES20.TSTypeReference],
|
|
5099
|
+
array: [AST_NODE_TYPES20.TSArrayType, AST_NODE_TYPES20.TSTypeReference],
|
|
5100
|
+
tuple: [AST_NODE_TYPES20.TSTupleType],
|
|
5101
|
+
object: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5102
|
+
strictObject: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5103
|
+
looseObject: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5104
|
+
record: [AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSTypeLiteral],
|
|
5105
|
+
map: [AST_NODE_TYPES20.TSTypeReference],
|
|
5106
|
+
set: [AST_NODE_TYPES20.TSTypeReference],
|
|
5107
|
+
promise: [AST_NODE_TYPES20.TSTypeReference],
|
|
5108
|
+
enum: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSLiteralType],
|
|
5109
|
+
nativeEnum: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSLiteralType],
|
|
5110
|
+
union: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference],
|
|
5111
|
+
discriminatedUnion: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference],
|
|
5112
|
+
intersection: [AST_NODE_TYPES20.TSIntersectionType, AST_NODE_TYPES20.TSTypeReference]
|
|
4836
5113
|
};
|
|
4837
5114
|
function normalizeSchemaName(name) {
|
|
4838
5115
|
return name.replace(/Schema$/i, "").replace(/^Z(?=[A-Z])/, "").toLowerCase();
|
|
@@ -4841,20 +5118,20 @@ function normalizeTypeName(name) {
|
|
|
4841
5118
|
return name.replace(/Type$/, "").toLowerCase();
|
|
4842
5119
|
}
|
|
4843
5120
|
function unwrapNullish(annotation) {
|
|
4844
|
-
if (annotation.type !==
|
|
5121
|
+
if (annotation.type !== AST_NODE_TYPES20.TSUnionType) {
|
|
4845
5122
|
return {
|
|
4846
5123
|
core: annotation,
|
|
4847
|
-
nullable: annotation.type ===
|
|
5124
|
+
nullable: annotation.type === AST_NODE_TYPES20.TSNullKeyword
|
|
4848
5125
|
};
|
|
4849
5126
|
}
|
|
4850
5127
|
const rest = [];
|
|
4851
5128
|
let nullable = false;
|
|
4852
5129
|
for (const member of annotation.types) {
|
|
4853
|
-
if (member.type ===
|
|
5130
|
+
if (member.type === AST_NODE_TYPES20.TSNullKeyword) {
|
|
4854
5131
|
nullable = true;
|
|
4855
5132
|
continue;
|
|
4856
5133
|
}
|
|
4857
|
-
if (member.type ===
|
|
5134
|
+
if (member.type === AST_NODE_TYPES20.TSUndefinedKeyword) {
|
|
4858
5135
|
continue;
|
|
4859
5136
|
}
|
|
4860
5137
|
rest.push(member);
|
|
@@ -4878,7 +5155,7 @@ function leafAgrees(leaf, annotation) {
|
|
|
4878
5155
|
}
|
|
4879
5156
|
return expected.includes(core.type);
|
|
4880
5157
|
}
|
|
4881
|
-
var prefer_zod_infer_default =
|
|
5158
|
+
var prefer_zod_infer_default = ESLintUtils27.RuleCreator(
|
|
4882
5159
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
4883
5160
|
)({
|
|
4884
5161
|
name: "prefer-zod-infer",
|
|
@@ -4921,14 +5198,14 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
4921
5198
|
function zodCallChain(node) {
|
|
4922
5199
|
const chain = [];
|
|
4923
5200
|
let current = node;
|
|
4924
|
-
while (current.type ===
|
|
5201
|
+
while (current.type === AST_NODE_TYPES20.CallExpression) {
|
|
4925
5202
|
const callee = current.callee;
|
|
4926
|
-
if (callee.type !==
|
|
5203
|
+
if (callee.type !== AST_NODE_TYPES20.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES20.Identifier) {
|
|
4927
5204
|
return null;
|
|
4928
5205
|
}
|
|
4929
5206
|
chain.push(current);
|
|
4930
5207
|
const receiver = callee.object;
|
|
4931
|
-
if (receiver.type ===
|
|
5208
|
+
if (receiver.type === AST_NODE_TYPES20.Identifier) {
|
|
4932
5209
|
return zodNamespaces.has(receiver.name) ? chain.reverse() : null;
|
|
4933
5210
|
}
|
|
4934
5211
|
current = receiver;
|
|
@@ -4937,19 +5214,19 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
4937
5214
|
}
|
|
4938
5215
|
function methodName(call) {
|
|
4939
5216
|
const callee = call.callee;
|
|
4940
|
-
return callee.type ===
|
|
5217
|
+
return callee.type === AST_NODE_TYPES20.MemberExpression && callee.property.type === AST_NODE_TYPES20.Identifier ? callee.property.name : "";
|
|
4941
5218
|
}
|
|
4942
5219
|
function schemaField(node) {
|
|
4943
5220
|
const modifiers = [];
|
|
4944
5221
|
let current = node;
|
|
4945
5222
|
let leaf = null;
|
|
4946
|
-
while (current.type ===
|
|
5223
|
+
while (current.type === AST_NODE_TYPES20.CallExpression) {
|
|
4947
5224
|
const callee = current.callee;
|
|
4948
|
-
if (callee.type !==
|
|
5225
|
+
if (callee.type !== AST_NODE_TYPES20.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES20.Identifier) {
|
|
4949
5226
|
break;
|
|
4950
5227
|
}
|
|
4951
5228
|
const receiver = callee.object;
|
|
4952
|
-
if (receiver.type ===
|
|
5229
|
+
if (receiver.type === AST_NODE_TYPES20.Identifier && zodNamespaces.has(receiver.name)) {
|
|
4953
5230
|
leaf = callee.property.name;
|
|
4954
5231
|
break;
|
|
4955
5232
|
}
|
|
@@ -4980,16 +5257,16 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
4980
5257
|
return null;
|
|
4981
5258
|
}
|
|
4982
5259
|
const shape = base.arguments[0];
|
|
4983
|
-
if (shape === void 0 || shape.type !==
|
|
5260
|
+
if (shape === void 0 || shape.type !== AST_NODE_TYPES20.ObjectExpression) {
|
|
4984
5261
|
return null;
|
|
4985
5262
|
}
|
|
4986
5263
|
const fields = /* @__PURE__ */ new Map();
|
|
4987
5264
|
for (const property of shape.properties) {
|
|
4988
|
-
if (property.type !==
|
|
5265
|
+
if (property.type !== AST_NODE_TYPES20.Property || property.computed) {
|
|
4989
5266
|
return null;
|
|
4990
5267
|
}
|
|
4991
5268
|
const { key } = property;
|
|
4992
|
-
const name = key.type ===
|
|
5269
|
+
const name = key.type === AST_NODE_TYPES20.Identifier ? key.name : key.type === AST_NODE_TYPES20.Literal && typeof key.value === "string" ? key.value : null;
|
|
4993
5270
|
if (name === null) {
|
|
4994
5271
|
return null;
|
|
4995
5272
|
}
|
|
@@ -5000,11 +5277,11 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5000
5277
|
function typeMembers(members) {
|
|
5001
5278
|
const result = /* @__PURE__ */ new Map();
|
|
5002
5279
|
for (const member of members) {
|
|
5003
|
-
if (member.type !==
|
|
5280
|
+
if (member.type !== AST_NODE_TYPES20.TSPropertySignature || member.computed) {
|
|
5004
5281
|
return null;
|
|
5005
5282
|
}
|
|
5006
5283
|
const { key } = member;
|
|
5007
|
-
const name = key.type ===
|
|
5284
|
+
const name = key.type === AST_NODE_TYPES20.Identifier ? key.name : key.type === AST_NODE_TYPES20.Literal && typeof key.value === "string" ? key.value : null;
|
|
5008
5285
|
if (name === null) {
|
|
5009
5286
|
return null;
|
|
5010
5287
|
}
|
|
@@ -5018,8 +5295,8 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5018
5295
|
return result.size === 0 ? null : result;
|
|
5019
5296
|
}
|
|
5020
5297
|
function collectConstrainedNames(node) {
|
|
5021
|
-
if (node.type ===
|
|
5022
|
-
if (node.typeName.type ===
|
|
5298
|
+
if (node.type === AST_NODE_TYPES20.TSTypeReference) {
|
|
5299
|
+
if (node.typeName.type === AST_NODE_TYPES20.Identifier) {
|
|
5023
5300
|
constrainedTypeNames.add(node.typeName.name);
|
|
5024
5301
|
}
|
|
5025
5302
|
for (const argument of node.typeArguments?.params ?? []) {
|
|
@@ -5027,11 +5304,11 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5027
5304
|
}
|
|
5028
5305
|
return;
|
|
5029
5306
|
}
|
|
5030
|
-
if (node.type ===
|
|
5307
|
+
if (node.type === AST_NODE_TYPES20.TSArrayType) {
|
|
5031
5308
|
collectConstrainedNames(node.elementType);
|
|
5032
5309
|
return;
|
|
5033
5310
|
}
|
|
5034
|
-
if (node.type ===
|
|
5311
|
+
if (node.type === AST_NODE_TYPES20.TSUnionType || node.type === AST_NODE_TYPES20.TSIntersectionType) {
|
|
5035
5312
|
for (const member of node.types) {
|
|
5036
5313
|
collectConstrainedNames(member);
|
|
5037
5314
|
}
|
|
@@ -5075,13 +5352,13 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5075
5352
|
return;
|
|
5076
5353
|
}
|
|
5077
5354
|
for (const specifier of node.specifiers) {
|
|
5078
|
-
if (specifier.type ===
|
|
5355
|
+
if (specifier.type === AST_NODE_TYPES20.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES20.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES20.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES20.Identifier && specifier.imported.name === "z") {
|
|
5079
5356
|
zodNamespaces.add(specifier.local.name);
|
|
5080
5357
|
}
|
|
5081
5358
|
}
|
|
5082
5359
|
},
|
|
5083
5360
|
VariableDeclarator(node) {
|
|
5084
|
-
if (node.id.type !==
|
|
5361
|
+
if (node.id.type !== AST_NODE_TYPES20.Identifier || node.init == null) {
|
|
5085
5362
|
return;
|
|
5086
5363
|
}
|
|
5087
5364
|
const fields = schemaFields(node.init);
|
|
@@ -5091,14 +5368,14 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5091
5368
|
},
|
|
5092
5369
|
/** Guard (f): `XSchema.transform(...)` anywhere in the module. */
|
|
5093
5370
|
"MemberExpression[computed=false]"(node) {
|
|
5094
|
-
if (node.object.type ===
|
|
5371
|
+
if (node.object.type === AST_NODE_TYPES20.Identifier && node.property.type === AST_NODE_TYPES20.Identifier && MODULE_LEVEL_RESHAPERS.has(node.property.name)) {
|
|
5095
5372
|
reshapedSchemaNames.add(node.object.name);
|
|
5096
5373
|
}
|
|
5097
5374
|
},
|
|
5098
5375
|
/** Guard (c): `z.ZodType<T>` and every other type argument it carries. */
|
|
5099
5376
|
TSTypeReference(node) {
|
|
5100
5377
|
const { typeName } = node;
|
|
5101
|
-
const referenced = typeName.type ===
|
|
5378
|
+
const referenced = typeName.type === AST_NODE_TYPES20.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES20.TSQualifiedName && typeName.right.type === AST_NODE_TYPES20.Identifier ? typeName.right.name : null;
|
|
5102
5379
|
if (referenced === null || !ZOD_TYPE_CONSTRAINTS.has(referenced)) {
|
|
5103
5380
|
return;
|
|
5104
5381
|
}
|
|
@@ -5116,7 +5393,7 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5116
5393
|
}
|
|
5117
5394
|
},
|
|
5118
5395
|
TSTypeAliasDeclaration(node) {
|
|
5119
|
-
if (node.typeParameters !== void 0 || node.typeAnnotation.type !==
|
|
5396
|
+
if (node.typeParameters !== void 0 || node.typeAnnotation.type !== AST_NODE_TYPES20.TSTypeLiteral) {
|
|
5120
5397
|
return;
|
|
5121
5398
|
}
|
|
5122
5399
|
const members = typeMembers(node.typeAnnotation.members);
|
|
@@ -5161,10 +5438,10 @@ var prefer_zod_infer_default = ESLintUtils28.RuleCreator(
|
|
|
5161
5438
|
});
|
|
5162
5439
|
|
|
5163
5440
|
// src/rules/no-offset-pagination.ts
|
|
5164
|
-
import { ESLintUtils as
|
|
5441
|
+
import { ESLintUtils as ESLintUtils28 } from "@typescript-eslint/utils";
|
|
5165
5442
|
|
|
5166
5443
|
// src/rules/_sql.ts
|
|
5167
|
-
import { AST_NODE_TYPES as
|
|
5444
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
|
|
5168
5445
|
function stripSqlNoise(text) {
|
|
5169
5446
|
const out = [...text];
|
|
5170
5447
|
const n = text.length;
|
|
@@ -5225,13 +5502,13 @@ function stripSqlNoise(text) {
|
|
|
5225
5502
|
var SUBSTITUTION_MARKER = "?";
|
|
5226
5503
|
function sqlTextOf(node) {
|
|
5227
5504
|
switch (node.type) {
|
|
5228
|
-
case
|
|
5505
|
+
case AST_NODE_TYPES21.Literal:
|
|
5229
5506
|
return typeof node.value === "string" ? node.value : null;
|
|
5230
|
-
case
|
|
5507
|
+
case AST_NODE_TYPES21.TemplateLiteral:
|
|
5231
5508
|
return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
|
|
5232
|
-
case
|
|
5509
|
+
case AST_NODE_TYPES21.TaggedTemplateExpression:
|
|
5233
5510
|
return sqlTextOf(node.quasi);
|
|
5234
|
-
case
|
|
5511
|
+
case AST_NODE_TYPES21.BinaryExpression: {
|
|
5235
5512
|
if (node.operator !== "+") {
|
|
5236
5513
|
return null;
|
|
5237
5514
|
}
|
|
@@ -5239,7 +5516,7 @@ function sqlTextOf(node) {
|
|
|
5239
5516
|
const right = sqlTextOf(node.right);
|
|
5240
5517
|
return left !== null && right !== null ? left + right : null;
|
|
5241
5518
|
}
|
|
5242
|
-
case
|
|
5519
|
+
case AST_NODE_TYPES21.ArrayExpression: {
|
|
5243
5520
|
const parts = [];
|
|
5244
5521
|
for (const element of node.elements) {
|
|
5245
5522
|
if (element === null) {
|
|
@@ -5259,7 +5536,7 @@ function sqlTextOf(node) {
|
|
|
5259
5536
|
}
|
|
5260
5537
|
function isJoinedFragmentArray(node) {
|
|
5261
5538
|
const parent = node.parent;
|
|
5262
|
-
return parent?.type ===
|
|
5539
|
+
return parent?.type === AST_NODE_TYPES21.MemberExpression && parent.object === node && !parent.computed && parent.property.type === AST_NODE_TYPES21.Identifier && parent.property.name === "join" && parent.parent?.type === AST_NODE_TYPES21.CallExpression;
|
|
5263
5540
|
}
|
|
5264
5541
|
function markConsumed(node, consumed) {
|
|
5265
5542
|
consumed.add(node);
|
|
@@ -5309,7 +5586,7 @@ function createSqlListener(handler) {
|
|
|
5309
5586
|
// src/rules/no-offset-pagination.ts
|
|
5310
5587
|
var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
|
|
5311
5588
|
var OFFSET_GATE = /offset/i;
|
|
5312
|
-
var no_offset_pagination_default =
|
|
5589
|
+
var no_offset_pagination_default = ESLintUtils28.RuleCreator(
|
|
5313
5590
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5314
5591
|
)({
|
|
5315
5592
|
name: "no-offset-pagination",
|
|
@@ -5338,15 +5615,15 @@ var no_offset_pagination_default = ESLintUtils29.RuleCreator(
|
|
|
5338
5615
|
});
|
|
5339
5616
|
|
|
5340
5617
|
// src/rules/no-positional-tuple-return.ts
|
|
5341
|
-
import { AST_NODE_TYPES as
|
|
5618
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES22, ESLintUtils as ESLintUtils29 } from "@typescript-eslint/utils";
|
|
5342
5619
|
var MIN_ELEMENTS = 2;
|
|
5343
5620
|
var ACCESSOR_PAIR_LENGTH = 2;
|
|
5344
5621
|
var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
|
|
5345
5622
|
function tupleReturnType(node) {
|
|
5346
|
-
if (node.type ===
|
|
5623
|
+
if (node.type === AST_NODE_TYPES22.TSTupleType) {
|
|
5347
5624
|
return node;
|
|
5348
5625
|
}
|
|
5349
|
-
if (node.type ===
|
|
5626
|
+
if (node.type === AST_NODE_TYPES22.TSTypeReference && node.typeName.type === AST_NODE_TYPES22.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
|
|
5350
5627
|
const argument = node.typeArguments?.params[0];
|
|
5351
5628
|
return argument === void 0 ? null : tupleReturnType(argument);
|
|
5352
5629
|
}
|
|
@@ -5360,30 +5637,30 @@ function isPermittedTuple(tuple, sourceCode) {
|
|
|
5360
5637
|
if (elements.length < MIN_ELEMENTS) {
|
|
5361
5638
|
return true;
|
|
5362
5639
|
}
|
|
5363
|
-
if (elements.some((element) => element.type ===
|
|
5640
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES22.TSRestType)) {
|
|
5364
5641
|
return true;
|
|
5365
5642
|
}
|
|
5366
|
-
if (elements.some((element) => element.type ===
|
|
5643
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES22.TSNamedTupleMember)) {
|
|
5367
5644
|
return true;
|
|
5368
5645
|
}
|
|
5369
|
-
if (elements[0]?.type ===
|
|
5646
|
+
if (elements[0]?.type === AST_NODE_TYPES22.TSLiteralType) {
|
|
5370
5647
|
return true;
|
|
5371
5648
|
}
|
|
5372
|
-
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type ===
|
|
5649
|
+
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === AST_NODE_TYPES22.TSFunctionType)) {
|
|
5373
5650
|
return true;
|
|
5374
5651
|
}
|
|
5375
5652
|
const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
|
|
5376
5653
|
return texts.size === 1;
|
|
5377
5654
|
}
|
|
5378
5655
|
function functionName(node) {
|
|
5379
|
-
if (node.type ===
|
|
5656
|
+
if (node.type === AST_NODE_TYPES22.FunctionDeclaration) {
|
|
5380
5657
|
return node.id?.name ?? null;
|
|
5381
5658
|
}
|
|
5382
5659
|
const parent = node.parent;
|
|
5383
|
-
if (parent?.type ===
|
|
5660
|
+
if (parent?.type === AST_NODE_TYPES22.VariableDeclarator && parent.id.type === AST_NODE_TYPES22.Identifier) {
|
|
5384
5661
|
return parent.id.name;
|
|
5385
5662
|
}
|
|
5386
|
-
if ((parent?.type ===
|
|
5663
|
+
if ((parent?.type === AST_NODE_TYPES22.MethodDefinition || parent?.type === AST_NODE_TYPES22.PropertyDefinition || parent?.type === AST_NODE_TYPES22.Property) && parent.key.type === AST_NODE_TYPES22.Identifier) {
|
|
5387
5664
|
return parent.key.name;
|
|
5388
5665
|
}
|
|
5389
5666
|
return null;
|
|
@@ -5391,7 +5668,7 @@ function functionName(node) {
|
|
|
5391
5668
|
function isInlineExported(node) {
|
|
5392
5669
|
for (let current = node; current != null; current = current.parent) {
|
|
5393
5670
|
const parent = current.parent;
|
|
5394
|
-
if (parent?.type ===
|
|
5671
|
+
if (parent?.type === AST_NODE_TYPES22.ExportNamedDeclaration || parent?.type === AST_NODE_TYPES22.ExportDefaultDeclaration) {
|
|
5395
5672
|
return true;
|
|
5396
5673
|
}
|
|
5397
5674
|
}
|
|
@@ -5400,18 +5677,18 @@ function isInlineExported(node) {
|
|
|
5400
5677
|
function moduleScopeBindingName(node) {
|
|
5401
5678
|
let current = node;
|
|
5402
5679
|
let child = node;
|
|
5403
|
-
while (current.parent != null && current.parent.type !==
|
|
5680
|
+
while (current.parent != null && current.parent.type !== AST_NODE_TYPES22.Program) {
|
|
5404
5681
|
child = current;
|
|
5405
5682
|
current = current.parent;
|
|
5406
5683
|
}
|
|
5407
|
-
if (current.parent?.type !==
|
|
5684
|
+
if (current.parent?.type !== AST_NODE_TYPES22.Program) {
|
|
5408
5685
|
return null;
|
|
5409
5686
|
}
|
|
5410
|
-
if (current.type ===
|
|
5687
|
+
if (current.type === AST_NODE_TYPES22.FunctionDeclaration || current.type === AST_NODE_TYPES22.ClassDeclaration) {
|
|
5411
5688
|
return current.id?.name ?? null;
|
|
5412
5689
|
}
|
|
5413
|
-
if (current.type ===
|
|
5414
|
-
if (child.type !==
|
|
5690
|
+
if (current.type === AST_NODE_TYPES22.VariableDeclaration) {
|
|
5691
|
+
if (child.type !== AST_NODE_TYPES22.VariableDeclarator || child.id.type !== AST_NODE_TYPES22.Identifier) {
|
|
5415
5692
|
return null;
|
|
5416
5693
|
}
|
|
5417
5694
|
return child.id.name;
|
|
@@ -5421,19 +5698,19 @@ function moduleScopeBindingName(node) {
|
|
|
5421
5698
|
function specifierExportedNames(program) {
|
|
5422
5699
|
const names = /* @__PURE__ */ new Set();
|
|
5423
5700
|
for (const statement of program.body) {
|
|
5424
|
-
if (statement.type ===
|
|
5701
|
+
if (statement.type === AST_NODE_TYPES22.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
|
|
5425
5702
|
for (const specifier of statement.specifiers) {
|
|
5426
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
5703
|
+
if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES22.Identifier) {
|
|
5427
5704
|
names.add(specifier.local.name);
|
|
5428
5705
|
}
|
|
5429
5706
|
}
|
|
5430
5707
|
continue;
|
|
5431
5708
|
}
|
|
5432
|
-
if (statement.type ===
|
|
5709
|
+
if (statement.type === AST_NODE_TYPES22.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES22.Identifier) {
|
|
5433
5710
|
names.add(statement.declaration.name);
|
|
5434
5711
|
continue;
|
|
5435
5712
|
}
|
|
5436
|
-
if (statement.type ===
|
|
5713
|
+
if (statement.type === AST_NODE_TYPES22.TSExportAssignment && statement.expression.type === AST_NODE_TYPES22.Identifier) {
|
|
5437
5714
|
names.add(statement.expression.name);
|
|
5438
5715
|
}
|
|
5439
5716
|
}
|
|
@@ -5449,7 +5726,7 @@ function isExported(node, specifierExports) {
|
|
|
5449
5726
|
const binding = moduleScopeBindingName(node);
|
|
5450
5727
|
return binding !== null && specifierExports.has(binding);
|
|
5451
5728
|
}
|
|
5452
|
-
var no_positional_tuple_return_default =
|
|
5729
|
+
var no_positional_tuple_return_default = ESLintUtils29.RuleCreator(
|
|
5453
5730
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5454
5731
|
)({
|
|
5455
5732
|
name: "no-positional-tuple-return",
|
|
@@ -5497,16 +5774,16 @@ var no_positional_tuple_return_default = ESLintUtils30.RuleCreator(
|
|
|
5497
5774
|
});
|
|
5498
5775
|
|
|
5499
5776
|
// src/rules/no-repeated-string-literal.ts
|
|
5500
|
-
import { AST_NODE_TYPES as
|
|
5777
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23, ESLintUtils as ESLintUtils30 } from "@typescript-eslint/utils";
|
|
5501
5778
|
var MIN_LENGTH = 40;
|
|
5502
5779
|
var MIN_DISTINCT_SCOPES = 2;
|
|
5503
5780
|
var PREVIEW_LENGTH = 40;
|
|
5504
5781
|
var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
|
|
5505
5782
|
var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
|
|
5506
|
-
var
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5783
|
+
var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
|
|
5784
|
+
AST_NODE_TYPES23.FunctionDeclaration,
|
|
5785
|
+
AST_NODE_TYPES23.FunctionExpression,
|
|
5786
|
+
AST_NODE_TYPES23.ArrowFunctionExpression
|
|
5510
5787
|
]);
|
|
5511
5788
|
function isStructured(value) {
|
|
5512
5789
|
return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
|
|
@@ -5517,7 +5794,7 @@ function preview(value) {
|
|
|
5517
5794
|
}
|
|
5518
5795
|
function enclosingFunction(node) {
|
|
5519
5796
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5520
|
-
if (
|
|
5797
|
+
if (FUNCTION_TYPES2.has(current.type)) {
|
|
5521
5798
|
return current;
|
|
5522
5799
|
}
|
|
5523
5800
|
}
|
|
@@ -5528,9 +5805,9 @@ function isScaffolding(node) {
|
|
|
5528
5805
|
if (parent === void 0) {
|
|
5529
5806
|
return true;
|
|
5530
5807
|
}
|
|
5531
|
-
return parent.type ===
|
|
5808
|
+
return parent.type === AST_NODE_TYPES23.ImportDeclaration || parent.type === AST_NODE_TYPES23.ExportNamedDeclaration || parent.type === AST_NODE_TYPES23.ExportAllDeclaration || parent.type === AST_NODE_TYPES23.TSImportType || parent.type === AST_NODE_TYPES23.JSXAttribute || parent.type === AST_NODE_TYPES23.TSLiteralType;
|
|
5532
5809
|
}
|
|
5533
|
-
var no_repeated_string_literal_default =
|
|
5810
|
+
var no_repeated_string_literal_default = ESLintUtils30.RuleCreator(
|
|
5534
5811
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5535
5812
|
)({
|
|
5536
5813
|
name: "no-repeated-string-literal",
|
|
@@ -5570,7 +5847,7 @@ var no_repeated_string_literal_default = ESLintUtils31.RuleCreator(
|
|
|
5570
5847
|
}
|
|
5571
5848
|
},
|
|
5572
5849
|
TemplateLiteral(node) {
|
|
5573
|
-
if (node.parent.type ===
|
|
5850
|
+
if (node.parent.type === AST_NODE_TYPES23.TaggedTemplateExpression) {
|
|
5574
5851
|
return;
|
|
5575
5852
|
}
|
|
5576
5853
|
const [only] = node.quasis;
|
|
@@ -5604,7 +5881,7 @@ var no_repeated_string_literal_default = ESLintUtils31.RuleCreator(
|
|
|
5604
5881
|
});
|
|
5605
5882
|
|
|
5606
5883
|
// src/rules/no-select-star.ts
|
|
5607
|
-
import { ESLintUtils as
|
|
5884
|
+
import { ESLintUtils as ESLintUtils31 } from "@typescript-eslint/utils";
|
|
5608
5885
|
var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
|
|
5609
5886
|
var SELECT_KEYWORD = /\bSELECT\b/gi;
|
|
5610
5887
|
var FROM_KEYWORD = /^FROM\b/i;
|
|
@@ -5644,7 +5921,7 @@ function hasRealSelectStar(sql) {
|
|
|
5644
5921
|
}
|
|
5645
5922
|
return false;
|
|
5646
5923
|
}
|
|
5647
|
-
var no_select_star_default =
|
|
5924
|
+
var no_select_star_default = ESLintUtils31.RuleCreator(
|
|
5648
5925
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5649
5926
|
)({
|
|
5650
5927
|
name: "no-select-star",
|
|
@@ -5673,7 +5950,7 @@ var no_select_star_default = ESLintUtils32.RuleCreator(
|
|
|
5673
5950
|
});
|
|
5674
5951
|
|
|
5675
5952
|
// src/rules/no-sleep-in-test-body.ts
|
|
5676
|
-
import { AST_NODE_TYPES as
|
|
5953
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ESLintUtils as ESLintUtils32 } from "@typescript-eslint/utils";
|
|
5677
5954
|
var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
|
|
5678
5955
|
var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
5679
5956
|
"it",
|
|
@@ -5681,43 +5958,43 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
|
5681
5958
|
"beforeEach",
|
|
5682
5959
|
"afterEach"
|
|
5683
5960
|
]);
|
|
5684
|
-
var
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5961
|
+
var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
|
|
5962
|
+
AST_NODE_TYPES24.FunctionDeclaration,
|
|
5963
|
+
AST_NODE_TYPES24.FunctionExpression,
|
|
5964
|
+
AST_NODE_TYPES24.ArrowFunctionExpression
|
|
5688
5965
|
]);
|
|
5689
5966
|
function isNonzeroNumericLiteral(node) {
|
|
5690
|
-
return node?.type ===
|
|
5967
|
+
return node?.type === AST_NODE_TYPES24.Literal && typeof node.value === "number" && node.value !== 0;
|
|
5691
5968
|
}
|
|
5692
5969
|
function isTimedSetTimeout(node) {
|
|
5693
|
-
return node.type ===
|
|
5970
|
+
return node.type === AST_NODE_TYPES24.CallExpression && node.callee.type === AST_NODE_TYPES24.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
|
|
5694
5971
|
}
|
|
5695
5972
|
function isPromiseSleep(node) {
|
|
5696
|
-
if (node.callee.type !==
|
|
5973
|
+
if (node.callee.type !== AST_NODE_TYPES24.Identifier || node.callee.name !== "Promise") {
|
|
5697
5974
|
return false;
|
|
5698
5975
|
}
|
|
5699
5976
|
const executor = node.arguments[0];
|
|
5700
|
-
if (executor?.type !==
|
|
5977
|
+
if (executor?.type !== AST_NODE_TYPES24.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES24.FunctionExpression) {
|
|
5701
5978
|
return false;
|
|
5702
5979
|
}
|
|
5703
5980
|
const body = executor.body;
|
|
5704
|
-
if (body.type !==
|
|
5981
|
+
if (body.type !== AST_NODE_TYPES24.BlockStatement) {
|
|
5705
5982
|
return isTimedSetTimeout(body);
|
|
5706
5983
|
}
|
|
5707
5984
|
return body.body.some(
|
|
5708
|
-
(stmt) => stmt.type ===
|
|
5985
|
+
(stmt) => stmt.type === AST_NODE_TYPES24.ExpressionStatement && isTimedSetTimeout(stmt.expression)
|
|
5709
5986
|
);
|
|
5710
5987
|
}
|
|
5711
5988
|
function isHelperSleep(node) {
|
|
5712
|
-
return node.callee.type ===
|
|
5989
|
+
return node.callee.type === AST_NODE_TYPES24.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
|
|
5713
5990
|
}
|
|
5714
5991
|
function nearestEnclosingFunction(node) {
|
|
5715
5992
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5716
|
-
if (!
|
|
5993
|
+
if (!FUNCTION_TYPES3.has(current.type)) {
|
|
5717
5994
|
continue;
|
|
5718
5995
|
}
|
|
5719
5996
|
const grandparent = current.parent;
|
|
5720
|
-
const isPromiseExecutor = grandparent?.type ===
|
|
5997
|
+
const isPromiseExecutor = grandparent?.type === AST_NODE_TYPES24.NewExpression && isPromiseSleep(grandparent);
|
|
5721
5998
|
if (!isPromiseExecutor) {
|
|
5722
5999
|
return current;
|
|
5723
6000
|
}
|
|
@@ -5725,29 +6002,29 @@ function nearestEnclosingFunction(node) {
|
|
|
5725
6002
|
return null;
|
|
5726
6003
|
}
|
|
5727
6004
|
function testCallerName(callee) {
|
|
5728
|
-
if (callee.type ===
|
|
6005
|
+
if (callee.type === AST_NODE_TYPES24.Identifier) {
|
|
5729
6006
|
return callee.name;
|
|
5730
6007
|
}
|
|
5731
|
-
if (callee.type ===
|
|
6008
|
+
if (callee.type === AST_NODE_TYPES24.MemberExpression) {
|
|
5732
6009
|
return testCallerName(callee.object);
|
|
5733
6010
|
}
|
|
5734
|
-
if (callee.type ===
|
|
6011
|
+
if (callee.type === AST_NODE_TYPES24.CallExpression) {
|
|
5735
6012
|
return testCallerName(callee.callee);
|
|
5736
6013
|
}
|
|
5737
|
-
if (callee.type ===
|
|
6014
|
+
if (callee.type === AST_NODE_TYPES24.TaggedTemplateExpression) {
|
|
5738
6015
|
return testCallerName(callee.tag);
|
|
5739
6016
|
}
|
|
5740
6017
|
return null;
|
|
5741
6018
|
}
|
|
5742
6019
|
function isTestBody(fn) {
|
|
5743
6020
|
const call = fn.parent;
|
|
5744
|
-
if (call?.type !==
|
|
6021
|
+
if (call?.type !== AST_NODE_TYPES24.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5745
6022
|
return false;
|
|
5746
6023
|
}
|
|
5747
6024
|
const name = testCallerName(call.callee);
|
|
5748
6025
|
return name !== null && TEST_CALLERS.has(name);
|
|
5749
6026
|
}
|
|
5750
|
-
var no_sleep_in_test_body_default =
|
|
6027
|
+
var no_sleep_in_test_body_default = ESLintUtils32.RuleCreator(
|
|
5751
6028
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5752
6029
|
)({
|
|
5753
6030
|
name: "no-sleep-in-test-body",
|
|
@@ -5789,45 +6066,215 @@ var no_sleep_in_test_body_default = ESLintUtils33.RuleCreator(
|
|
|
5789
6066
|
});
|
|
5790
6067
|
|
|
5791
6068
|
// src/rules/no-conditional-in-test.ts
|
|
5792
|
-
import { AST_NODE_TYPES as
|
|
6069
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ESLintUtils as ESLintUtils33 } from "@typescript-eslint/utils";
|
|
5793
6070
|
var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
5794
|
-
var
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
6071
|
+
var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
6072
|
+
AST_NODE_TYPES25.FunctionDeclaration,
|
|
6073
|
+
AST_NODE_TYPES25.FunctionExpression,
|
|
6074
|
+
AST_NODE_TYPES25.ArrowFunctionExpression
|
|
6075
|
+
]);
|
|
6076
|
+
var ASSERTION_ROOTS = /* @__PURE__ */ new Set([
|
|
6077
|
+
"expect",
|
|
6078
|
+
"expectTypeOf",
|
|
6079
|
+
"assert",
|
|
6080
|
+
"assertType"
|
|
6081
|
+
]);
|
|
6082
|
+
var TYPE_ASSERTION_ROOTS = /* @__PURE__ */ new Set([
|
|
6083
|
+
"expectTypeOf",
|
|
6084
|
+
"assertType"
|
|
5798
6085
|
]);
|
|
5799
6086
|
function nearestEnclosingFunction2(node) {
|
|
5800
6087
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5801
|
-
if (
|
|
6088
|
+
if (FUNCTION_TYPES4.has(current.type)) {
|
|
5802
6089
|
return current;
|
|
5803
6090
|
}
|
|
5804
6091
|
}
|
|
5805
6092
|
return null;
|
|
5806
6093
|
}
|
|
5807
6094
|
function testCallerName2(callee) {
|
|
5808
|
-
if (callee.type ===
|
|
6095
|
+
if (callee.type === AST_NODE_TYPES25.Identifier) {
|
|
5809
6096
|
return callee.name;
|
|
5810
6097
|
}
|
|
5811
|
-
if (callee.type ===
|
|
6098
|
+
if (callee.type === AST_NODE_TYPES25.MemberExpression) {
|
|
5812
6099
|
return testCallerName2(callee.object);
|
|
5813
6100
|
}
|
|
5814
|
-
if (callee.type ===
|
|
6101
|
+
if (callee.type === AST_NODE_TYPES25.CallExpression) {
|
|
5815
6102
|
return testCallerName2(callee.callee);
|
|
5816
6103
|
}
|
|
5817
|
-
if (callee.type ===
|
|
6104
|
+
if (callee.type === AST_NODE_TYPES25.TaggedTemplateExpression) {
|
|
5818
6105
|
return testCallerName2(callee.tag);
|
|
5819
6106
|
}
|
|
5820
6107
|
return null;
|
|
5821
6108
|
}
|
|
5822
6109
|
function isTestBody2(fn) {
|
|
5823
6110
|
const call = fn.parent;
|
|
5824
|
-
if (call?.type !==
|
|
6111
|
+
if (call?.type !== AST_NODE_TYPES25.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5825
6112
|
return false;
|
|
5826
6113
|
}
|
|
5827
6114
|
const name = testCallerName2(call.callee);
|
|
5828
6115
|
return name !== null && TEST_CALLERS2.has(name);
|
|
5829
6116
|
}
|
|
5830
|
-
|
|
6117
|
+
function subtreeMatches2(node, predicate, descendIntoFunctions = true) {
|
|
6118
|
+
let found = false;
|
|
6119
|
+
const visit = (current) => {
|
|
6120
|
+
if (found) {
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
if (predicate(current)) {
|
|
6124
|
+
found = true;
|
|
6125
|
+
return;
|
|
6126
|
+
}
|
|
6127
|
+
for (const key of Object.keys(current)) {
|
|
6128
|
+
if (key === "parent") {
|
|
6129
|
+
continue;
|
|
6130
|
+
}
|
|
6131
|
+
if (!descendIntoFunctions && FUNCTION_TYPES4.has(current.type) && key === "body") {
|
|
6132
|
+
continue;
|
|
6133
|
+
}
|
|
6134
|
+
const value = current[key];
|
|
6135
|
+
if (Array.isArray(value)) {
|
|
6136
|
+
for (const child of value) {
|
|
6137
|
+
if (typeof child === "object" && child !== null && typeof child.type === "string") {
|
|
6138
|
+
visit(child);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
} else if (typeof value === "object" && value !== null && typeof value.type === "string") {
|
|
6142
|
+
visit(value);
|
|
6143
|
+
}
|
|
6144
|
+
if (found) {
|
|
6145
|
+
return;
|
|
6146
|
+
}
|
|
6147
|
+
}
|
|
6148
|
+
};
|
|
6149
|
+
visit(node);
|
|
6150
|
+
return found;
|
|
6151
|
+
}
|
|
6152
|
+
function rootIdentifier(node) {
|
|
6153
|
+
switch (node.type) {
|
|
6154
|
+
case AST_NODE_TYPES25.Identifier:
|
|
6155
|
+
return node.name;
|
|
6156
|
+
case AST_NODE_TYPES25.MemberExpression:
|
|
6157
|
+
return rootIdentifier(node.object);
|
|
6158
|
+
case AST_NODE_TYPES25.UnaryExpression:
|
|
6159
|
+
return rootIdentifier(node.argument);
|
|
6160
|
+
case AST_NODE_TYPES25.AwaitExpression:
|
|
6161
|
+
return rootIdentifier(node.argument);
|
|
6162
|
+
case AST_NODE_TYPES25.ChainExpression:
|
|
6163
|
+
case AST_NODE_TYPES25.TSNonNullExpression:
|
|
6164
|
+
case AST_NODE_TYPES25.TSAsExpression:
|
|
6165
|
+
return rootIdentifier(node.expression);
|
|
6166
|
+
case AST_NODE_TYPES25.BinaryExpression:
|
|
6167
|
+
case AST_NODE_TYPES25.LogicalExpression:
|
|
6168
|
+
return rootIdentifier(node.left);
|
|
6169
|
+
case AST_NODE_TYPES25.CallExpression:
|
|
6170
|
+
return rootIdentifier(node.callee);
|
|
6171
|
+
default:
|
|
6172
|
+
return null;
|
|
6173
|
+
}
|
|
6174
|
+
}
|
|
6175
|
+
function calleeRootName(call) {
|
|
6176
|
+
let current = call.callee;
|
|
6177
|
+
for (; ; ) {
|
|
6178
|
+
if (current.type === AST_NODE_TYPES25.Identifier) {
|
|
6179
|
+
return current.name;
|
|
6180
|
+
}
|
|
6181
|
+
if (current.type === AST_NODE_TYPES25.MemberExpression) {
|
|
6182
|
+
current = current.object;
|
|
6183
|
+
continue;
|
|
6184
|
+
}
|
|
6185
|
+
if (current.type === AST_NODE_TYPES25.CallExpression) {
|
|
6186
|
+
current = current.callee;
|
|
6187
|
+
continue;
|
|
6188
|
+
}
|
|
6189
|
+
if (current.type === AST_NODE_TYPES25.ChainExpression || current.type === AST_NODE_TYPES25.TSNonNullExpression) {
|
|
6190
|
+
current = current.expression;
|
|
6191
|
+
continue;
|
|
6192
|
+
}
|
|
6193
|
+
return null;
|
|
6194
|
+
}
|
|
6195
|
+
}
|
|
6196
|
+
var isAssertionCall = (node) => node.type === AST_NODE_TYPES25.CallExpression && ASSERTION_ROOTS.has(calleeRootName(node) ?? "");
|
|
6197
|
+
var isTypeAssertionCall = (node) => node.type === AST_NODE_TYPES25.CallExpression && TYPE_ASSERTION_ROOTS.has(calleeRootName(node) ?? "");
|
|
6198
|
+
var containsAssertion = (node) => subtreeMatches2(node, isAssertionCall);
|
|
6199
|
+
var containsSkipCall = (node) => subtreeMatches2(
|
|
6200
|
+
node,
|
|
6201
|
+
(current) => current.type === AST_NODE_TYPES25.CallExpression && current.callee.type === AST_NODE_TYPES25.MemberExpression && !current.callee.computed && current.callee.property.type === AST_NODE_TYPES25.Identifier && current.callee.property.name === "skip"
|
|
6202
|
+
);
|
|
6203
|
+
var containsEscape = (node) => subtreeMatches2(
|
|
6204
|
+
node,
|
|
6205
|
+
(current) => current.type === AST_NODE_TYPES25.ReturnStatement || current.type === AST_NODE_TYPES25.ContinueStatement || current.type === AST_NODE_TYPES25.BreakStatement,
|
|
6206
|
+
false
|
|
6207
|
+
);
|
|
6208
|
+
function branchStatements(branch) {
|
|
6209
|
+
return branch.type === AST_NODE_TYPES25.BlockStatement ? branch.body : [branch];
|
|
6210
|
+
}
|
|
6211
|
+
function previousSibling(node) {
|
|
6212
|
+
const parent = node.parent;
|
|
6213
|
+
let siblings = null;
|
|
6214
|
+
if (parent.type === AST_NODE_TYPES25.BlockStatement || parent.type === AST_NODE_TYPES25.Program || parent.type === AST_NODE_TYPES25.StaticBlock) {
|
|
6215
|
+
siblings = parent.body;
|
|
6216
|
+
} else if (parent.type === AST_NODE_TYPES25.SwitchCase) {
|
|
6217
|
+
siblings = parent.consequent;
|
|
6218
|
+
}
|
|
6219
|
+
if (siblings === null) {
|
|
6220
|
+
return null;
|
|
6221
|
+
}
|
|
6222
|
+
const index = siblings.indexOf(node);
|
|
6223
|
+
return index > 0 ? siblings[index - 1] ?? null : null;
|
|
6224
|
+
}
|
|
6225
|
+
function isPinnedNarrowingGuard(node) {
|
|
6226
|
+
const testRoot = rootIdentifier(node.test);
|
|
6227
|
+
if (testRoot === null) {
|
|
6228
|
+
return false;
|
|
6229
|
+
}
|
|
6230
|
+
const previous = previousSibling(node);
|
|
6231
|
+
if (previous === null || previous.type !== AST_NODE_TYPES25.ExpressionStatement) {
|
|
6232
|
+
return false;
|
|
6233
|
+
}
|
|
6234
|
+
let matched = false;
|
|
6235
|
+
subtreeMatches2(previous, (current) => {
|
|
6236
|
+
if (current.type !== AST_NODE_TYPES25.CallExpression || current.callee.type !== AST_NODE_TYPES25.Identifier || current.callee.name !== "expect") {
|
|
6237
|
+
return false;
|
|
6238
|
+
}
|
|
6239
|
+
const subject = current.arguments[0];
|
|
6240
|
+
if (subject === void 0) {
|
|
6241
|
+
return false;
|
|
6242
|
+
}
|
|
6243
|
+
if (rootIdentifier(subject) === testRoot) {
|
|
6244
|
+
matched = true;
|
|
6245
|
+
return true;
|
|
6246
|
+
}
|
|
6247
|
+
return false;
|
|
6248
|
+
});
|
|
6249
|
+
return matched;
|
|
6250
|
+
}
|
|
6251
|
+
function isThrowingGuard(node) {
|
|
6252
|
+
if (node.alternate !== null) {
|
|
6253
|
+
return false;
|
|
6254
|
+
}
|
|
6255
|
+
const statements = branchStatements(node.consequent);
|
|
6256
|
+
return statements.length === 1 && statements[0]?.type === AST_NODE_TYPES25.ThrowStatement;
|
|
6257
|
+
}
|
|
6258
|
+
function isTypeAssertionBranch(branch) {
|
|
6259
|
+
const statements = branchStatements(branch);
|
|
6260
|
+
return statements.length > 0 && statements.every(
|
|
6261
|
+
(statement) => statement.type === AST_NODE_TYPES25.ExpressionStatement && isTypeAssertionCall(statement.expression)
|
|
6262
|
+
);
|
|
6263
|
+
}
|
|
6264
|
+
function isTypeLevelNarrowing(node) {
|
|
6265
|
+
return isTypeAssertionBranch(node.consequent) && (node.alternate === null || isTypeAssertionBranch(node.alternate));
|
|
6266
|
+
}
|
|
6267
|
+
var isInertBranch = (branch) => !containsAssertion(branch) && !containsEscape(branch) && !containsSkipCall(branch);
|
|
6268
|
+
function isInertNormalization(node) {
|
|
6269
|
+
return isInertBranch(node.consequent) && (node.alternate === null || isInertBranch(node.alternate));
|
|
6270
|
+
}
|
|
6271
|
+
function isExemptIfStatement(node) {
|
|
6272
|
+
return isPinnedNarrowingGuard(node) || isThrowingGuard(node) || isTypeLevelNarrowing(node) || isInertNormalization(node);
|
|
6273
|
+
}
|
|
6274
|
+
function isShortCircuitedAssertion(node) {
|
|
6275
|
+
return node.operator !== "??" && node.parent.type === AST_NODE_TYPES25.ExpressionStatement && containsAssertion(node.right);
|
|
6276
|
+
}
|
|
6277
|
+
var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
5831
6278
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5832
6279
|
)({
|
|
5833
6280
|
name: "no-conditional-in-test",
|
|
@@ -5855,6 +6302,9 @@ var no_conditional_in_test_default = ESLintUtils34.RuleCreator(
|
|
|
5855
6302
|
};
|
|
5856
6303
|
return {
|
|
5857
6304
|
IfStatement(node) {
|
|
6305
|
+
if (isExemptIfStatement(node)) {
|
|
6306
|
+
return;
|
|
6307
|
+
}
|
|
5858
6308
|
report(node);
|
|
5859
6309
|
},
|
|
5860
6310
|
SwitchStatement(node) {
|
|
@@ -5864,6 +6314,9 @@ var no_conditional_in_test_default = ESLintUtils34.RuleCreator(
|
|
|
5864
6314
|
report(node);
|
|
5865
6315
|
},
|
|
5866
6316
|
LogicalExpression(node) {
|
|
6317
|
+
if (!isShortCircuitedAssertion(node)) {
|
|
6318
|
+
return;
|
|
6319
|
+
}
|
|
5867
6320
|
report(node);
|
|
5868
6321
|
}
|
|
5869
6322
|
};
|
|
@@ -5871,7 +6324,7 @@ var no_conditional_in_test_default = ESLintUtils34.RuleCreator(
|
|
|
5871
6324
|
});
|
|
5872
6325
|
|
|
5873
6326
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
5874
|
-
import { AST_NODE_TYPES as
|
|
6327
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ESLintUtils as ESLintUtils34 } from "@typescript-eslint/utils";
|
|
5875
6328
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
5876
6329
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5877
6330
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
@@ -5884,36 +6337,36 @@ function isConstantReference(identifier) {
|
|
|
5884
6337
|
}
|
|
5885
6338
|
function isExcludedOperand(node) {
|
|
5886
6339
|
switch (node.type) {
|
|
5887
|
-
case
|
|
6340
|
+
case AST_NODE_TYPES26.Literal:
|
|
5888
6341
|
return true;
|
|
5889
|
-
case
|
|
6342
|
+
case AST_NODE_TYPES26.TemplateLiteral:
|
|
5890
6343
|
return node.expressions.length === 0;
|
|
5891
|
-
case
|
|
6344
|
+
case AST_NODE_TYPES26.Identifier:
|
|
5892
6345
|
return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
|
|
5893
|
-
case
|
|
5894
|
-
return !node.computed && node.property.type ===
|
|
6346
|
+
case AST_NODE_TYPES26.MemberExpression:
|
|
6347
|
+
return !node.computed && node.property.type === AST_NODE_TYPES26.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
|
|
5895
6348
|
default:
|
|
5896
6349
|
return false;
|
|
5897
6350
|
}
|
|
5898
6351
|
}
|
|
5899
6352
|
function operandName(node) {
|
|
5900
|
-
if (node.type ===
|
|
6353
|
+
if (node.type === AST_NODE_TYPES26.Identifier) {
|
|
5901
6354
|
return node.name;
|
|
5902
6355
|
}
|
|
5903
|
-
if (node.type ===
|
|
6356
|
+
if (node.type === AST_NODE_TYPES26.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES26.Identifier) {
|
|
5904
6357
|
return node.property.name;
|
|
5905
6358
|
}
|
|
5906
6359
|
return null;
|
|
5907
6360
|
}
|
|
5908
6361
|
function isSecretOperand(node) {
|
|
5909
|
-
if (node.type ===
|
|
6362
|
+
if (node.type === AST_NODE_TYPES26.TemplateLiteral) {
|
|
5910
6363
|
return node.expressions.some((expression) => isSecretOperand(expression));
|
|
5911
6364
|
}
|
|
5912
6365
|
const name = operandName(node);
|
|
5913
6366
|
return name !== null && isAuthSecretName(name);
|
|
5914
6367
|
}
|
|
5915
6368
|
function secretNameOf(node) {
|
|
5916
|
-
if (node.type ===
|
|
6369
|
+
if (node.type === AST_NODE_TYPES26.TemplateLiteral) {
|
|
5917
6370
|
for (const expression of node.expressions) {
|
|
5918
6371
|
const nested = secretNameOf(expression);
|
|
5919
6372
|
if (nested !== null) {
|
|
@@ -5924,7 +6377,7 @@ function secretNameOf(node) {
|
|
|
5924
6377
|
}
|
|
5925
6378
|
return operandName(node);
|
|
5926
6379
|
}
|
|
5927
|
-
var prefer_constant_time_secret_compare_default =
|
|
6380
|
+
var prefer_constant_time_secret_compare_default = ESLintUtils34.RuleCreator(
|
|
5928
6381
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5929
6382
|
)({
|
|
5930
6383
|
name: "prefer-constant-time-secret-compare",
|
|
@@ -5967,11 +6420,11 @@ var prefer_constant_time_secret_compare_default = ESLintUtils35.RuleCreator(
|
|
|
5967
6420
|
});
|
|
5968
6421
|
|
|
5969
6422
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
5970
|
-
import { ESLintUtils as
|
|
6423
|
+
import { ESLintUtils as ESLintUtils35 } from "@typescript-eslint/utils";
|
|
5971
6424
|
var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
|
|
5972
6425
|
var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
|
|
5973
6426
|
var INSERT_GATE = /insert/i;
|
|
5974
|
-
var store_insert_requires_on_conflict_default =
|
|
6427
|
+
var store_insert_requires_on_conflict_default = ESLintUtils35.RuleCreator(
|
|
5975
6428
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5976
6429
|
)({
|
|
5977
6430
|
name: "store-insert-requires-on-conflict",
|
|
@@ -6000,17 +6453,17 @@ var store_insert_requires_on_conflict_default = ESLintUtils36.RuleCreator(
|
|
|
6000
6453
|
});
|
|
6001
6454
|
|
|
6002
6455
|
// src/rules/no-dynamic-sql.ts
|
|
6003
|
-
import { AST_NODE_TYPES as
|
|
6456
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES27, ESLintUtils as ESLintUtils36 } from "@typescript-eslint/utils";
|
|
6004
6457
|
var DEFAULT_METHODS = ["prepare", "exec", "query"];
|
|
6005
6458
|
var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
6006
6459
|
function isStaticFragment(expression) {
|
|
6007
|
-
if (expression.type ===
|
|
6460
|
+
if (expression.type === AST_NODE_TYPES27.Identifier) {
|
|
6008
6461
|
return CONSTANT_CASE_RE.test(expression.name);
|
|
6009
6462
|
}
|
|
6010
|
-
if (expression.type ===
|
|
6463
|
+
if (expression.type === AST_NODE_TYPES27.MemberExpression && !expression.computed && expression.property.type === AST_NODE_TYPES27.Identifier) {
|
|
6011
6464
|
return CONSTANT_CASE_RE.test(expression.property.name);
|
|
6012
6465
|
}
|
|
6013
|
-
if (expression.type ===
|
|
6466
|
+
if (expression.type === AST_NODE_TYPES27.Literal) {
|
|
6014
6467
|
return typeof expression.value === "string";
|
|
6015
6468
|
}
|
|
6016
6469
|
return false;
|
|
@@ -6021,36 +6474,36 @@ function runtimeInterpolations(template) {
|
|
|
6021
6474
|
);
|
|
6022
6475
|
}
|
|
6023
6476
|
function concatOperands(node) {
|
|
6024
|
-
if (node.type ===
|
|
6477
|
+
if (node.type === AST_NODE_TYPES27.BinaryExpression && node.operator === "+") {
|
|
6025
6478
|
return [...concatOperands(node.left), ...concatOperands(node.right)];
|
|
6026
6479
|
}
|
|
6027
6480
|
return [node];
|
|
6028
6481
|
}
|
|
6029
6482
|
function runtimeConcatOperands(node) {
|
|
6030
|
-
if (node.type !==
|
|
6483
|
+
if (node.type !== AST_NODE_TYPES27.BinaryExpression || node.operator !== "+") {
|
|
6031
6484
|
return [];
|
|
6032
6485
|
}
|
|
6033
6486
|
const operands = concatOperands(node);
|
|
6034
6487
|
const hasStringLiteral = operands.some(
|
|
6035
|
-
(operand) => operand.type ===
|
|
6488
|
+
(operand) => operand.type === AST_NODE_TYPES27.Literal && typeof operand.value === "string"
|
|
6036
6489
|
);
|
|
6037
6490
|
if (!hasStringLiteral) {
|
|
6038
6491
|
return [];
|
|
6039
6492
|
}
|
|
6040
6493
|
return operands.filter(
|
|
6041
|
-
(operand) => operand.type !==
|
|
6494
|
+
(operand) => operand.type !== AST_NODE_TYPES27.Literal && !isStaticFragment(operand)
|
|
6042
6495
|
);
|
|
6043
6496
|
}
|
|
6044
6497
|
var SQL_STATEMENT_RE = /\b(?:select\s|insert\s+into\b|insert\s+or\b|update\s+\w|delete\s+from\b|replace\s+into\b|merge\s+into\b|upsert\s+into\b|create\s+(?:temp(?:orary)?\s+)?(?:table|index|view|trigger|schema|database)\b|alter\s+table\b|drop\s+(?:table|index|view|trigger)\b|truncate\s+table\b|pragma\s+\w|with\s+\w+\s+as\s*\(|from\s+\w+\s+where\b)/i;
|
|
6045
6498
|
var RUNTIME_MARKER = " ? ";
|
|
6046
6499
|
function staticStatementText(node) {
|
|
6047
|
-
if (node.type ===
|
|
6500
|
+
if (node.type === AST_NODE_TYPES27.TemplateLiteral) {
|
|
6048
6501
|
return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
|
|
6049
6502
|
}
|
|
6050
|
-
if (node.type ===
|
|
6503
|
+
if (node.type === AST_NODE_TYPES27.Literal) {
|
|
6051
6504
|
return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
|
|
6052
6505
|
}
|
|
6053
|
-
if (node.type ===
|
|
6506
|
+
if (node.type === AST_NODE_TYPES27.BinaryExpression && node.operator === "+") {
|
|
6054
6507
|
return staticStatementText(node.left) + staticStatementText(node.right);
|
|
6055
6508
|
}
|
|
6056
6509
|
return RUNTIME_MARKER;
|
|
@@ -6060,13 +6513,13 @@ function looksLikeSql(node) {
|
|
|
6060
6513
|
}
|
|
6061
6514
|
function statementMethodName(node, methods) {
|
|
6062
6515
|
const callee = node.callee;
|
|
6063
|
-
if (callee.type !==
|
|
6516
|
+
if (callee.type !== AST_NODE_TYPES27.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES27.Identifier) {
|
|
6064
6517
|
return null;
|
|
6065
6518
|
}
|
|
6066
6519
|
const name = callee.property.name;
|
|
6067
6520
|
return methods.has(name) ? name : null;
|
|
6068
6521
|
}
|
|
6069
|
-
var no_dynamic_sql_default =
|
|
6522
|
+
var no_dynamic_sql_default = ESLintUtils36.RuleCreator(
|
|
6070
6523
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6071
6524
|
)({
|
|
6072
6525
|
name: "no-dynamic-sql",
|
|
@@ -6105,7 +6558,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6105
6558
|
if (statement === void 0 || !looksLikeSql(statement)) {
|
|
6106
6559
|
return;
|
|
6107
6560
|
}
|
|
6108
|
-
const offenders = statement.type ===
|
|
6561
|
+
const offenders = statement.type === AST_NODE_TYPES27.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
|
|
6109
6562
|
for (const offender of offenders) {
|
|
6110
6563
|
context.report({
|
|
6111
6564
|
node: offender,
|
|
@@ -6119,7 +6572,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6119
6572
|
});
|
|
6120
6573
|
|
|
6121
6574
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
6122
|
-
import { ESLintUtils as
|
|
6575
|
+
import { ESLintUtils as ESLintUtils37, AST_NODE_TYPES as AST_NODE_TYPES28 } from "@typescript-eslint/utils";
|
|
6123
6576
|
var DEFAULT_ALLOW = [
|
|
6124
6577
|
"[\\\\/]clients?[\\\\/]",
|
|
6125
6578
|
"-client\\.[cm]?[jt]sx?$",
|
|
@@ -6129,17 +6582,15 @@ var DEFAULT_ALLOW = [
|
|
|
6129
6582
|
"[\\\\/]api[\\\\/]",
|
|
6130
6583
|
"[\\\\/]api\\.[cm]?[jt]sx?$",
|
|
6131
6584
|
"[-.]api\\.[cm]?[jt]sx?$",
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
"
|
|
6136
|
-
"
|
|
6137
|
-
"[
|
|
6138
|
-
"[
|
|
6139
|
-
"[\\\\/]tests?[\\\\/]",
|
|
6140
|
-
// jscodeshift input/output fixtures — text a codemod transforms, not code.
|
|
6141
|
-
"[\\\\/]__testfixtures__[\\\\/]"
|
|
6585
|
+
// Vendor wrapper conventions: a module that exists to own one third-party
|
|
6586
|
+
// origin's HTTP. See the SECOND SWEEP note in the file header.
|
|
6587
|
+
"[\\\\/]services?[\\\\/]",
|
|
6588
|
+
"[\\\\/](connectors|providers|integrations|adapters|fetchers)[\\\\/]",
|
|
6589
|
+
"[\\\\/]notifications[\\\\/]",
|
|
6590
|
+
"[Ss]ervice\\.[cm]?[jt]sx?$",
|
|
6591
|
+
"-(service|connector|adapter|sdk|fetcher)\\.[cm]?[jt]sx?$"
|
|
6142
6592
|
];
|
|
6593
|
+
var NON_PRODUCTION_TREE_RE = /[\\/](playwright|cypress|__testfixtures__)[\\/]/;
|
|
6143
6594
|
var GLOBAL_RECEIVERS = /* @__PURE__ */ new Set([
|
|
6144
6595
|
"globalThis",
|
|
6145
6596
|
"window",
|
|
@@ -6165,6 +6616,10 @@ function identifierLikeName(node) {
|
|
|
6165
6616
|
}
|
|
6166
6617
|
return null;
|
|
6167
6618
|
}
|
|
6619
|
+
function isConstructedArgumentHandoff(node) {
|
|
6620
|
+
const [first] = node.arguments;
|
|
6621
|
+
return node.arguments.length === 1 && first !== void 0 && first.type === AST_NODE_TYPES28.NewExpression;
|
|
6622
|
+
}
|
|
6168
6623
|
function isPresignedUrlTransfer(node) {
|
|
6169
6624
|
const first = node.arguments[0];
|
|
6170
6625
|
if (first === void 0) {
|
|
@@ -6183,7 +6638,7 @@ function compile(patterns) {
|
|
|
6183
6638
|
}
|
|
6184
6639
|
return compiled;
|
|
6185
6640
|
}
|
|
6186
|
-
var no_raw_fetch_outside_clients_default =
|
|
6641
|
+
var no_raw_fetch_outside_clients_default = ESLintUtils37.RuleCreator(
|
|
6187
6642
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6188
6643
|
)({
|
|
6189
6644
|
name: "no-raw-fetch-outside-clients",
|
|
@@ -6211,15 +6666,18 @@ var no_raw_fetch_outside_clients_default = ESLintUtils38.RuleCreator(
|
|
|
6211
6666
|
},
|
|
6212
6667
|
defaultOptions: [{}],
|
|
6213
6668
|
create(context, [options]) {
|
|
6669
|
+
const filename = context.filename;
|
|
6670
|
+
if (isTestFile(filename) || NON_PRODUCTION_TREE_RE.test(filename)) {
|
|
6671
|
+
return {};
|
|
6672
|
+
}
|
|
6214
6673
|
const patterns = options?.allow ?? DEFAULT_ALLOW;
|
|
6215
6674
|
const allowed = compile(patterns);
|
|
6216
|
-
const filename = context.filename;
|
|
6217
6675
|
if (allowed.some((re) => re.test(filename))) {
|
|
6218
6676
|
return {};
|
|
6219
6677
|
}
|
|
6220
6678
|
return {
|
|
6221
6679
|
CallExpression(node) {
|
|
6222
|
-
if (isPresignedUrlTransfer(node)) {
|
|
6680
|
+
if (isPresignedUrlTransfer(node) || isConstructedArgumentHandoff(node)) {
|
|
6223
6681
|
return;
|
|
6224
6682
|
}
|
|
6225
6683
|
if (isGlobalFetchCall(node)) {
|
|
@@ -6231,7 +6689,7 @@ var no_raw_fetch_outside_clients_default = ESLintUtils38.RuleCreator(
|
|
|
6231
6689
|
});
|
|
6232
6690
|
|
|
6233
6691
|
// src/rules/no-storage-in-stateless-modules.ts
|
|
6234
|
-
import { AST_NODE_TYPES as
|
|
6692
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29, ESLintUtils as ESLintUtils38 } from "@typescript-eslint/utils";
|
|
6235
6693
|
var DEFAULT_METHODS2 = [
|
|
6236
6694
|
"prepare",
|
|
6237
6695
|
"put",
|
|
@@ -6250,7 +6708,7 @@ function compile2(patterns) {
|
|
|
6250
6708
|
}
|
|
6251
6709
|
function storageMethodName(node, methods) {
|
|
6252
6710
|
const callee = node.callee;
|
|
6253
|
-
if (callee.type !==
|
|
6711
|
+
if (callee.type !== AST_NODE_TYPES29.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES29.Identifier) {
|
|
6254
6712
|
return null;
|
|
6255
6713
|
}
|
|
6256
6714
|
const name = callee.property.name;
|
|
@@ -6262,7 +6720,7 @@ function storageMethodName(node, methods) {
|
|
|
6262
6720
|
}
|
|
6263
6721
|
return name;
|
|
6264
6722
|
}
|
|
6265
|
-
var no_storage_in_stateless_modules_default =
|
|
6723
|
+
var no_storage_in_stateless_modules_default = ESLintUtils38.RuleCreator(
|
|
6266
6724
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6267
6725
|
)({
|
|
6268
6726
|
name: "no-storage-in-stateless-modules",
|
|
@@ -6321,8 +6779,8 @@ var no_storage_in_stateless_modules_default = ESLintUtils39.RuleCreator(
|
|
|
6321
6779
|
|
|
6322
6780
|
// src/rules/no-zod-native-enum.ts
|
|
6323
6781
|
import {
|
|
6324
|
-
ESLintUtils as
|
|
6325
|
-
AST_NODE_TYPES as
|
|
6782
|
+
ESLintUtils as ESLintUtils39,
|
|
6783
|
+
AST_NODE_TYPES as AST_NODE_TYPES30
|
|
6326
6784
|
} from "@typescript-eslint/utils";
|
|
6327
6785
|
import * as ts2 from "typescript";
|
|
6328
6786
|
var IGNORE_PATTERNS2 = [
|
|
@@ -6341,7 +6799,7 @@ function isZodModule2(source) {
|
|
|
6341
6799
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
6342
6800
|
}
|
|
6343
6801
|
function unwrap3(node) {
|
|
6344
|
-
if (node.type ===
|
|
6802
|
+
if (node.type === AST_NODE_TYPES30.TSAsExpression || node.type === AST_NODE_TYPES30.TSSatisfiesExpression) {
|
|
6345
6803
|
return unwrap3(node.expression);
|
|
6346
6804
|
}
|
|
6347
6805
|
return node;
|
|
@@ -6349,14 +6807,14 @@ function unwrap3(node) {
|
|
|
6349
6807
|
function stringValueTexts(node, sourceCode) {
|
|
6350
6808
|
const texts = [];
|
|
6351
6809
|
for (const prop of node.properties) {
|
|
6352
|
-
if (prop.type !==
|
|
6810
|
+
if (prop.type !== AST_NODE_TYPES30.Property) {
|
|
6353
6811
|
return null;
|
|
6354
6812
|
}
|
|
6355
6813
|
if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6356
6814
|
return null;
|
|
6357
6815
|
}
|
|
6358
6816
|
const value = prop.value;
|
|
6359
|
-
if (value.type !==
|
|
6817
|
+
if (value.type !== AST_NODE_TYPES30.Literal || typeof value.value !== "string") {
|
|
6360
6818
|
return null;
|
|
6361
6819
|
}
|
|
6362
6820
|
const text = sourceCode.getText(value);
|
|
@@ -6372,7 +6830,7 @@ function resolvesToLocalEnum(node, scope) {
|
|
|
6372
6830
|
const variable = current.variables.find((v) => v.name === node.name);
|
|
6373
6831
|
if (variable !== void 0) {
|
|
6374
6832
|
return variable.defs.some(
|
|
6375
|
-
(def) => def.node.type ===
|
|
6833
|
+
(def) => def.node.type === AST_NODE_TYPES30.TSEnumDeclaration
|
|
6376
6834
|
);
|
|
6377
6835
|
}
|
|
6378
6836
|
current = current.upper;
|
|
@@ -6392,7 +6850,7 @@ function resolvesToImportedEnum(node, services) {
|
|
|
6392
6850
|
}
|
|
6393
6851
|
return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
|
|
6394
6852
|
}
|
|
6395
|
-
var no_zod_native_enum_default =
|
|
6853
|
+
var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
6396
6854
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6397
6855
|
)({
|
|
6398
6856
|
name: "no-zod-native-enum",
|
|
@@ -6419,32 +6877,32 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6419
6877
|
}
|
|
6420
6878
|
let services;
|
|
6421
6879
|
try {
|
|
6422
|
-
services =
|
|
6880
|
+
services = ESLintUtils39.getParserServices(context);
|
|
6423
6881
|
} catch {
|
|
6424
6882
|
services = null;
|
|
6425
6883
|
}
|
|
6426
6884
|
const zodImportedNames = /* @__PURE__ */ new Map();
|
|
6427
6885
|
function isZodMemberCall(node, api) {
|
|
6428
6886
|
const callee = node.callee;
|
|
6429
|
-
if (callee.type ===
|
|
6887
|
+
if (callee.type === AST_NODE_TYPES30.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES30.Identifier) {
|
|
6430
6888
|
return callee.property.name === api;
|
|
6431
6889
|
}
|
|
6432
|
-
if (callee.type ===
|
|
6890
|
+
if (callee.type === AST_NODE_TYPES30.Identifier) {
|
|
6433
6891
|
return zodImportedNames.get(callee.name) === api;
|
|
6434
6892
|
}
|
|
6435
6893
|
return false;
|
|
6436
6894
|
}
|
|
6437
6895
|
function buildFix(node) {
|
|
6438
6896
|
const callee = node.callee;
|
|
6439
|
-
if (callee.type !==
|
|
6897
|
+
if (callee.type !== AST_NODE_TYPES30.MemberExpression || callee.property.type !== AST_NODE_TYPES30.Identifier) {
|
|
6440
6898
|
return null;
|
|
6441
6899
|
}
|
|
6442
6900
|
const arg = node.arguments[0];
|
|
6443
|
-
if (arg === void 0 || node.arguments.length !== 1 || arg.type ===
|
|
6901
|
+
if (arg === void 0 || node.arguments.length !== 1 || arg.type === AST_NODE_TYPES30.SpreadElement) {
|
|
6444
6902
|
return null;
|
|
6445
6903
|
}
|
|
6446
6904
|
const inner = unwrap3(arg);
|
|
6447
|
-
if (inner.type !==
|
|
6905
|
+
if (inner.type !== AST_NODE_TYPES30.ObjectExpression) {
|
|
6448
6906
|
return null;
|
|
6449
6907
|
}
|
|
6450
6908
|
const values = stringValueTexts(inner, sourceCode);
|
|
@@ -6464,7 +6922,7 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6464
6922
|
return;
|
|
6465
6923
|
}
|
|
6466
6924
|
for (const spec of node.specifiers) {
|
|
6467
|
-
if (spec.type ===
|
|
6925
|
+
if (spec.type === AST_NODE_TYPES30.ImportSpecifier && spec.imported.type === AST_NODE_TYPES30.Identifier) {
|
|
6468
6926
|
zodImportedNames.set(spec.local.name, spec.imported.name);
|
|
6469
6927
|
}
|
|
6470
6928
|
}
|
|
@@ -6483,7 +6941,7 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6483
6941
|
return;
|
|
6484
6942
|
}
|
|
6485
6943
|
const arg = node.arguments[0];
|
|
6486
|
-
if (arg === void 0 || arg.type !==
|
|
6944
|
+
if (arg === void 0 || arg.type !== AST_NODE_TYPES30.Identifier) {
|
|
6487
6945
|
return;
|
|
6488
6946
|
}
|
|
6489
6947
|
const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
|
|
@@ -6501,8 +6959,8 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6501
6959
|
|
|
6502
6960
|
// src/rules/prefer-module-level-constant.ts
|
|
6503
6961
|
import {
|
|
6504
|
-
ESLintUtils as
|
|
6505
|
-
AST_NODE_TYPES as
|
|
6962
|
+
ESLintUtils as ESLintUtils40,
|
|
6963
|
+
AST_NODE_TYPES as AST_NODE_TYPES31
|
|
6506
6964
|
} from "@typescript-eslint/utils";
|
|
6507
6965
|
var DEFAULT_MIN_ELEMENTS = 3;
|
|
6508
6966
|
var MAX_LITERAL_DEPTH = 4;
|
|
@@ -6512,13 +6970,6 @@ var IGNORE_PATTERNS3 = [
|
|
|
6512
6970
|
/\.generated\.tsx?$/,
|
|
6513
6971
|
/\.d\.ts$/
|
|
6514
6972
|
];
|
|
6515
|
-
var TEST_FILE_PATTERNS = [
|
|
6516
|
-
/\.(?:test|spec)\.[cm]?[jt]sx?$/,
|
|
6517
|
-
/[\\/]__tests__[\\/]/,
|
|
6518
|
-
/[\\/]__mocks__[\\/]/,
|
|
6519
|
-
/[\\/]tests?[\\/]/,
|
|
6520
|
-
/\.stories\.[cm]?[jt]sx?$/
|
|
6521
|
-
];
|
|
6522
6973
|
var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
6523
6974
|
// Array
|
|
6524
6975
|
"push",
|
|
@@ -6538,10 +6989,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
6538
6989
|
// Object-ish escape hatches
|
|
6539
6990
|
"assign"
|
|
6540
6991
|
]);
|
|
6541
|
-
var
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6992
|
+
var FUNCTION_TYPES5 = /* @__PURE__ */ new Set([
|
|
6993
|
+
AST_NODE_TYPES31.FunctionDeclaration,
|
|
6994
|
+
AST_NODE_TYPES31.FunctionExpression,
|
|
6995
|
+
AST_NODE_TYPES31.ArrowFunctionExpression
|
|
6545
6996
|
]);
|
|
6546
6997
|
var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
|
|
6547
6998
|
function isIgnoredFile3(filename, sourceText) {
|
|
@@ -6550,17 +7001,18 @@ function isIgnoredFile3(filename, sourceText) {
|
|
|
6550
7001
|
}
|
|
6551
7002
|
return /@generated\b/.test(sourceText.slice(0, 1024));
|
|
6552
7003
|
}
|
|
6553
|
-
function
|
|
6554
|
-
return
|
|
7004
|
+
function isLocalFixtureFile(filename) {
|
|
7005
|
+
return isTestFile(filename) || isStoryFile(filename);
|
|
6555
7006
|
}
|
|
6556
7007
|
function unwrap4(node) {
|
|
6557
|
-
if (node.type ===
|
|
7008
|
+
if (node.type === AST_NODE_TYPES31.TSAsExpression || node.type === AST_NODE_TYPES31.TSSatisfiesExpression || node.type === AST_NODE_TYPES31.TSNonNullExpression) {
|
|
6558
7009
|
return unwrap4(node.expression);
|
|
6559
7010
|
}
|
|
6560
7011
|
return node;
|
|
6561
7012
|
}
|
|
7013
|
+
var HAS_STATEFUL_FLAG_RE = /[gy]/;
|
|
6562
7014
|
function isRegexLiteral(node) {
|
|
6563
|
-
return node.type ===
|
|
7015
|
+
return node.type === AST_NODE_TYPES31.Literal && "regex" in node && node.regex !== void 0;
|
|
6564
7016
|
}
|
|
6565
7017
|
function isLiteralOnly(node, depth) {
|
|
6566
7018
|
if (depth > MAX_LITERAL_DEPTH) {
|
|
@@ -6568,29 +7020,29 @@ function isLiteralOnly(node, depth) {
|
|
|
6568
7020
|
}
|
|
6569
7021
|
const inner = unwrap4(node);
|
|
6570
7022
|
switch (inner.type) {
|
|
6571
|
-
case
|
|
6572
|
-
return
|
|
7023
|
+
case AST_NODE_TYPES31.Literal: {
|
|
7024
|
+
return !(isRegexLiteral(inner) && HAS_STATEFUL_FLAG_RE.test(inner.regex.flags));
|
|
6573
7025
|
}
|
|
6574
|
-
case
|
|
7026
|
+
case AST_NODE_TYPES31.TemplateLiteral: {
|
|
6575
7027
|
return inner.expressions.length === 0;
|
|
6576
7028
|
}
|
|
6577
|
-
case
|
|
6578
|
-
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type ===
|
|
7029
|
+
case AST_NODE_TYPES31.UnaryExpression: {
|
|
7030
|
+
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === AST_NODE_TYPES31.Literal && typeof inner.argument.value === "number";
|
|
6579
7031
|
}
|
|
6580
|
-
case
|
|
7032
|
+
case AST_NODE_TYPES31.ArrayExpression: {
|
|
6581
7033
|
return inner.elements.every(
|
|
6582
|
-
(el) => el !== null && el.type !==
|
|
7034
|
+
(el) => el !== null && el.type !== AST_NODE_TYPES31.SpreadElement && isLiteralOnly(el, depth + 1)
|
|
6583
7035
|
);
|
|
6584
7036
|
}
|
|
6585
|
-
case
|
|
7037
|
+
case AST_NODE_TYPES31.ObjectExpression: {
|
|
6586
7038
|
return inner.properties.every((prop) => {
|
|
6587
|
-
if (prop.type !==
|
|
7039
|
+
if (prop.type !== AST_NODE_TYPES31.Property) {
|
|
6588
7040
|
return false;
|
|
6589
7041
|
}
|
|
6590
7042
|
if (prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6591
7043
|
return false;
|
|
6592
7044
|
}
|
|
6593
|
-
if (prop.computed && prop.key.type !==
|
|
7045
|
+
if (prop.computed && prop.key.type !== AST_NODE_TYPES31.Literal) {
|
|
6594
7046
|
return false;
|
|
6595
7047
|
}
|
|
6596
7048
|
return isLiteralOnly(prop.value, depth + 1);
|
|
@@ -6603,7 +7055,7 @@ function isLiteralOnly(node, depth) {
|
|
|
6603
7055
|
}
|
|
6604
7056
|
function unwrapObjectFreeze(node) {
|
|
6605
7057
|
const inner = unwrap4(node);
|
|
6606
|
-
if (inner.type ===
|
|
7058
|
+
if (inner.type === AST_NODE_TYPES31.CallExpression && inner.callee.type === AST_NODE_TYPES31.MemberExpression && !inner.callee.computed && inner.callee.object.type === AST_NODE_TYPES31.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === AST_NODE_TYPES31.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== AST_NODE_TYPES31.SpreadElement) {
|
|
6607
7059
|
return unwrap4(inner.arguments[0]);
|
|
6608
7060
|
}
|
|
6609
7061
|
return inner;
|
|
@@ -6614,24 +7066,24 @@ function classify(init, checkRegex) {
|
|
|
6614
7066
|
if (!checkRegex) {
|
|
6615
7067
|
return null;
|
|
6616
7068
|
}
|
|
6617
|
-
if (
|
|
7069
|
+
if (HAS_STATEFUL_FLAG_RE.test(node.regex.flags)) {
|
|
6618
7070
|
return null;
|
|
6619
7071
|
}
|
|
6620
7072
|
return { kind: "regex", size: 1 };
|
|
6621
7073
|
}
|
|
6622
|
-
if (node.type ===
|
|
7074
|
+
if (node.type === AST_NODE_TYPES31.ArrayExpression) {
|
|
6623
7075
|
return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
|
|
6624
7076
|
}
|
|
6625
|
-
if (node.type ===
|
|
7077
|
+
if (node.type === AST_NODE_TYPES31.ObjectExpression) {
|
|
6626
7078
|
return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
|
|
6627
7079
|
}
|
|
6628
|
-
if (node.type ===
|
|
7080
|
+
if (node.type === AST_NODE_TYPES31.NewExpression && node.callee.type === AST_NODE_TYPES31.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
|
|
6629
7081
|
const arg = node.arguments[0];
|
|
6630
|
-
if (node.arguments.length !== 1 || arg === void 0 || arg.type ===
|
|
7082
|
+
if (node.arguments.length !== 1 || arg === void 0 || arg.type === AST_NODE_TYPES31.SpreadElement) {
|
|
6631
7083
|
return null;
|
|
6632
7084
|
}
|
|
6633
7085
|
const entries = unwrap4(arg);
|
|
6634
|
-
if (entries.type !==
|
|
7086
|
+
if (entries.type !== AST_NODE_TYPES31.ArrayExpression) {
|
|
6635
7087
|
return null;
|
|
6636
7088
|
}
|
|
6637
7089
|
return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
|
|
@@ -6641,7 +7093,7 @@ function classify(init, checkRegex) {
|
|
|
6641
7093
|
function enclosingFunction2(node) {
|
|
6642
7094
|
let current = node.parent;
|
|
6643
7095
|
while (current !== void 0 && current !== null) {
|
|
6644
|
-
if (
|
|
7096
|
+
if (FUNCTION_TYPES5.has(current.type)) {
|
|
6645
7097
|
return current;
|
|
6646
7098
|
}
|
|
6647
7099
|
current = current.parent;
|
|
@@ -6660,10 +7112,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
|
|
|
6660
7112
|
);
|
|
6661
7113
|
function isNonRetainingBuiltinCall(node, argument) {
|
|
6662
7114
|
const callee = node.callee;
|
|
6663
|
-
if (callee.type ===
|
|
7115
|
+
if (callee.type === AST_NODE_TYPES31.Identifier && callee.name === "structuredClone") {
|
|
6664
7116
|
return true;
|
|
6665
7117
|
}
|
|
6666
|
-
if (callee.type !==
|
|
7118
|
+
if (callee.type !== AST_NODE_TYPES31.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES31.Identifier || callee.property.type !== AST_NODE_TYPES31.Identifier) {
|
|
6667
7119
|
return false;
|
|
6668
7120
|
}
|
|
6669
7121
|
const members = NON_RETAINING_BUILTINS.get(callee.object.name);
|
|
@@ -6677,43 +7129,43 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
6677
7129
|
}
|
|
6678
7130
|
function isSafeRead(identifier) {
|
|
6679
7131
|
const parent = identifier.parent;
|
|
6680
|
-
if (parent.type ===
|
|
7132
|
+
if (parent.type === AST_NODE_TYPES31.MemberExpression) {
|
|
6681
7133
|
if (parent.object !== identifier) {
|
|
6682
7134
|
return true;
|
|
6683
7135
|
}
|
|
6684
7136
|
const grandparent = parent.parent;
|
|
6685
|
-
if (grandparent.type ===
|
|
7137
|
+
if (grandparent.type === AST_NODE_TYPES31.AssignmentExpression && grandparent.left === parent) {
|
|
6686
7138
|
return false;
|
|
6687
7139
|
}
|
|
6688
|
-
if (grandparent.type ===
|
|
7140
|
+
if (grandparent.type === AST_NODE_TYPES31.UpdateExpression) {
|
|
6689
7141
|
return false;
|
|
6690
7142
|
}
|
|
6691
|
-
if (grandparent.type ===
|
|
7143
|
+
if (grandparent.type === AST_NODE_TYPES31.UnaryExpression && grandparent.operator === "delete") {
|
|
6692
7144
|
return false;
|
|
6693
7145
|
}
|
|
6694
|
-
if (!parent.computed && parent.property.type ===
|
|
7146
|
+
if (!parent.computed && parent.property.type === AST_NODE_TYPES31.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === AST_NODE_TYPES31.CallExpression && grandparent.callee === parent) {
|
|
6695
7147
|
return false;
|
|
6696
7148
|
}
|
|
6697
7149
|
return true;
|
|
6698
7150
|
}
|
|
6699
|
-
if (parent.type ===
|
|
7151
|
+
if (parent.type === AST_NODE_TYPES31.ForOfStatement && parent.right === identifier) {
|
|
6700
7152
|
return true;
|
|
6701
7153
|
}
|
|
6702
|
-
if (parent.type ===
|
|
7154
|
+
if (parent.type === AST_NODE_TYPES31.SpreadElement) {
|
|
6703
7155
|
return true;
|
|
6704
7156
|
}
|
|
6705
|
-
if (parent.type ===
|
|
7157
|
+
if (parent.type === AST_NODE_TYPES31.BinaryExpression) {
|
|
6706
7158
|
return true;
|
|
6707
7159
|
}
|
|
6708
|
-
if (parent.type ===
|
|
7160
|
+
if (parent.type === AST_NODE_TYPES31.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
|
|
6709
7161
|
return true;
|
|
6710
7162
|
}
|
|
6711
|
-
if (parent.type ===
|
|
7163
|
+
if (parent.type === AST_NODE_TYPES31.UnaryExpression && parent.operator !== "delete") {
|
|
6712
7164
|
return true;
|
|
6713
7165
|
}
|
|
6714
7166
|
return false;
|
|
6715
7167
|
}
|
|
6716
|
-
var prefer_module_level_constant_default =
|
|
7168
|
+
var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
6717
7169
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6718
7170
|
)({
|
|
6719
7171
|
name: "prefer-module-level-constant",
|
|
@@ -6749,7 +7201,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6749
7201
|
if (isIgnoredFile3(filename, sourceCode.getText())) {
|
|
6750
7202
|
return {};
|
|
6751
7203
|
}
|
|
6752
|
-
if (ignoreTestFiles &&
|
|
7204
|
+
if (ignoreTestFiles && isLocalFixtureFile(filename)) {
|
|
6753
7205
|
return {};
|
|
6754
7206
|
}
|
|
6755
7207
|
function allReferencesAreSafeReads(declarator) {
|
|
@@ -6765,7 +7217,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6765
7217
|
if (reference.isWrite()) {
|
|
6766
7218
|
return false;
|
|
6767
7219
|
}
|
|
6768
|
-
if (reference.identifier.type !==
|
|
7220
|
+
if (reference.identifier.type !== AST_NODE_TYPES31.Identifier) {
|
|
6769
7221
|
return false;
|
|
6770
7222
|
}
|
|
6771
7223
|
if (!isSafeRead(reference.identifier)) {
|
|
@@ -6777,10 +7229,10 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6777
7229
|
return {
|
|
6778
7230
|
VariableDeclarator(node) {
|
|
6779
7231
|
const declaration = node.parent;
|
|
6780
|
-
if (declaration.type !==
|
|
7232
|
+
if (declaration.type !== AST_NODE_TYPES31.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
|
|
6781
7233
|
return;
|
|
6782
7234
|
}
|
|
6783
|
-
if (node.id.type !==
|
|
7235
|
+
if (node.id.type !== AST_NODE_TYPES31.Identifier || node.init === null) {
|
|
6784
7236
|
return;
|
|
6785
7237
|
}
|
|
6786
7238
|
if (enclosingFunction2(node) === null) {
|
|
@@ -6807,7 +7259,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6807
7259
|
});
|
|
6808
7260
|
|
|
6809
7261
|
// src/rules/jsdoc-restates-signature.ts
|
|
6810
|
-
import { AST_NODE_TYPES as
|
|
7262
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES32, ESLintUtils as ESLintUtils41 } from "@typescript-eslint/utils";
|
|
6811
7263
|
var VALUE_TAGS = /* @__PURE__ */ new Set([
|
|
6812
7264
|
"alpha",
|
|
6813
7265
|
"author",
|
|
@@ -6890,30 +7342,30 @@ function declarationNames(node) {
|
|
|
6890
7342
|
switch (node.type) {
|
|
6891
7343
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
6892
7344
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
6893
|
-
case
|
|
6894
|
-
case
|
|
7345
|
+
case AST_NODE_TYPES32.ExportNamedDeclaration:
|
|
7346
|
+
case AST_NODE_TYPES32.ExportDefaultDeclaration:
|
|
6895
7347
|
return node.declaration == null ? null : declarationNames(node.declaration);
|
|
6896
|
-
case
|
|
6897
|
-
case
|
|
7348
|
+
case AST_NODE_TYPES32.FunctionDeclaration:
|
|
7349
|
+
case AST_NODE_TYPES32.TSDeclareFunction:
|
|
6898
7350
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
6899
|
-
case
|
|
6900
|
-
case
|
|
6901
|
-
case
|
|
6902
|
-
case
|
|
7351
|
+
case AST_NODE_TYPES32.ClassDeclaration:
|
|
7352
|
+
case AST_NODE_TYPES32.TSInterfaceDeclaration:
|
|
7353
|
+
case AST_NODE_TYPES32.TSTypeAliasDeclaration:
|
|
7354
|
+
case AST_NODE_TYPES32.TSEnumDeclaration:
|
|
6903
7355
|
return node.id === null ? null : { name: node.id.name, params: [] };
|
|
6904
|
-
case
|
|
7356
|
+
case AST_NODE_TYPES32.VariableDeclaration: {
|
|
6905
7357
|
const declarator = node.declarations[0];
|
|
6906
|
-
if (declarator === void 0 || declarator.id.type !==
|
|
7358
|
+
if (declarator === void 0 || declarator.id.type !== AST_NODE_TYPES32.Identifier) return null;
|
|
6907
7359
|
const init = declarator.init;
|
|
6908
|
-
const params = init != null && (init.type ===
|
|
7360
|
+
const params = init != null && (init.type === AST_NODE_TYPES32.ArrowFunctionExpression || init.type === AST_NODE_TYPES32.FunctionExpression) ? paramNames(init.params) : [];
|
|
6909
7361
|
return { name: declarator.id.name, params };
|
|
6910
7362
|
}
|
|
6911
|
-
case
|
|
6912
|
-
case
|
|
6913
|
-
case
|
|
6914
|
-
case
|
|
6915
|
-
if (node.key.type !==
|
|
6916
|
-
const params = node.type ===
|
|
7363
|
+
case AST_NODE_TYPES32.MethodDefinition:
|
|
7364
|
+
case AST_NODE_TYPES32.PropertyDefinition:
|
|
7365
|
+
case AST_NODE_TYPES32.TSMethodSignature:
|
|
7366
|
+
case AST_NODE_TYPES32.TSPropertySignature: {
|
|
7367
|
+
if (node.key.type !== AST_NODE_TYPES32.Identifier) return null;
|
|
7368
|
+
const params = node.type === AST_NODE_TYPES32.MethodDefinition ? paramNames(node.value.params) : node.type === AST_NODE_TYPES32.TSMethodSignature ? paramNames(node.params) : [];
|
|
6917
7369
|
return { name: node.key.name, params };
|
|
6918
7370
|
}
|
|
6919
7371
|
default:
|
|
@@ -6923,9 +7375,9 @@ function declarationNames(node) {
|
|
|
6923
7375
|
function paramNames(params) {
|
|
6924
7376
|
const names = [];
|
|
6925
7377
|
for (const param of params) {
|
|
6926
|
-
const target = param.type ===
|
|
6927
|
-
if (target.type ===
|
|
6928
|
-
else if (target.type ===
|
|
7378
|
+
const target = param.type === AST_NODE_TYPES32.AssignmentPattern ? param.left : param;
|
|
7379
|
+
if (target.type === AST_NODE_TYPES32.Identifier) names.push(target.name);
|
|
7380
|
+
else if (target.type === AST_NODE_TYPES32.TSParameterProperty) continue;
|
|
6929
7381
|
}
|
|
6930
7382
|
return names;
|
|
6931
7383
|
}
|
|
@@ -6934,7 +7386,7 @@ function tokensOf(names) {
|
|
|
6934
7386
|
for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
|
|
6935
7387
|
return tokens;
|
|
6936
7388
|
}
|
|
6937
|
-
var jsdoc_restates_signature_default =
|
|
7389
|
+
var jsdoc_restates_signature_default = ESLintUtils41.RuleCreator(
|
|
6938
7390
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6939
7391
|
)({
|
|
6940
7392
|
name: "jsdoc-restates-signature",
|
|
@@ -6970,7 +7422,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
6970
7422
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
|
|
6971
7423
|
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
|
6972
7424
|
let declaration = null;
|
|
6973
|
-
while (node != null && node.type !==
|
|
7425
|
+
while (node != null && node.type !== AST_NODE_TYPES32.Program) {
|
|
6974
7426
|
declaration = declarationNames(node);
|
|
6975
7427
|
if (declaration !== null) break;
|
|
6976
7428
|
node = node.parent ?? null;
|
|
@@ -7025,7 +7477,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
7025
7477
|
});
|
|
7026
7478
|
|
|
7027
7479
|
// src/rules/no-restated-comment.ts
|
|
7028
|
-
import { AST_NODE_TYPES as
|
|
7480
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES33, ESLintUtils as ESLintUtils42 } from "@typescript-eslint/utils";
|
|
7029
7481
|
var MAX_WORDS = 8;
|
|
7030
7482
|
var MIN_CONTENT_TOKENS = 2;
|
|
7031
7483
|
var DIRECTIVE_RE3 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
|
|
@@ -7049,7 +7501,7 @@ function headsSiblingRun(node) {
|
|
|
7049
7501
|
const next = index >= 0 ? body[index + 1] : void 0;
|
|
7050
7502
|
return next !== void 0 && next.type === node.type;
|
|
7051
7503
|
}
|
|
7052
|
-
var no_restated_comment_default =
|
|
7504
|
+
var no_restated_comment_default = ESLintUtils42.RuleCreator(
|
|
7053
7505
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7054
7506
|
)({
|
|
7055
7507
|
name: "no-restated-comment",
|
|
@@ -7077,7 +7529,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
7077
7529
|
function labelsASiblingRun(comment) {
|
|
7078
7530
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
7079
7531
|
if (token === null) return false;
|
|
7080
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
7532
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES33.Program; node = node.parent) {
|
|
7081
7533
|
if (headsSiblingRun(node)) return true;
|
|
7082
7534
|
}
|
|
7083
7535
|
return false;
|
|
@@ -7117,7 +7569,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
7117
7569
|
});
|
|
7118
7570
|
|
|
7119
7571
|
// src/rules/trailing-value-narration.ts
|
|
7120
|
-
import { ESLintUtils as
|
|
7572
|
+
import { ESLintUtils as ESLintUtils43 } from "@typescript-eslint/utils";
|
|
7121
7573
|
var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
|
|
7122
7574
|
var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
|
|
7123
7575
|
var UNIT_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -7201,7 +7653,7 @@ function narratesValue(body, code) {
|
|
|
7201
7653
|
(word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
|
|
7202
7654
|
);
|
|
7203
7655
|
}
|
|
7204
|
-
var trailing_value_narration_default =
|
|
7656
|
+
var trailing_value_narration_default = ESLintUtils43.RuleCreator(
|
|
7205
7657
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7206
7658
|
)({
|
|
7207
7659
|
name: "trailing-value-narration",
|
|
@@ -7241,8 +7693,190 @@ var trailing_value_narration_default = ESLintUtils44.RuleCreator(
|
|
|
7241
7693
|
}
|
|
7242
7694
|
});
|
|
7243
7695
|
|
|
7696
|
+
// src/rules/no-type-member-comment-wall.ts
|
|
7697
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES34, ESLintUtils as ESLintUtils44 } from "@typescript-eslint/utils";
|
|
7698
|
+
var DEFAULTS = {
|
|
7699
|
+
// Below three rows "a wall" is not a fair description of what the reader sees.
|
|
7700
|
+
minCommentedMembers: 3,
|
|
7701
|
+
// A minority of commented members is a GROUP LABEL, not a wall.
|
|
7702
|
+
minCommentedRatio: 0.6,
|
|
7703
|
+
// Room for one substantive row in four; a type where a quarter of the comments
|
|
7704
|
+
// say something real is a type someone was documenting, not decorating.
|
|
7705
|
+
minRestatedRatio: 0.75,
|
|
7706
|
+
// One word beyond the member's own text. Zero is `jsdoc-restates-signature`'s
|
|
7707
|
+
// test and is already covered there; two admits definitions ("Partial match"
|
|
7708
|
+
// beside "Exact match"), which the evidence file counts.
|
|
7709
|
+
maxNovelWords: 1
|
|
7710
|
+
};
|
|
7711
|
+
var VALUE_TAG_RE = /@(?:deprecated|see|example|throws|remarks|since|default|defaultvalue|link|internal|alpha|beta|experimental|template|typeparam|inheritdoc|todo|fixme|override)\b/i;
|
|
7712
|
+
var DEFAULT_RE = /^\s*@?default\b|\bdefaults? (?:to|:)/i;
|
|
7713
|
+
var DIGIT_RE = /\d/;
|
|
7714
|
+
var UNIT_WORD_RE = /\b(?:ms|milliseconds?|seconds?|minutes?|hours?|days?|weeks?|months?|years?|bytes?|kb|mb|gb|percent|pixels?|px|utc|epoch)\b/i;
|
|
7715
|
+
var EXAMPLE_RE = /["'`]|\be\.g\.|\bi\.e\./;
|
|
7716
|
+
var BANNER_RE = /[=\-─-╿*#~_.]{3,}/;
|
|
7717
|
+
var NON_ASCII_LETTER_RE2 = /[^\p{ASCII}\p{N}\p{P}\p{Z}]/u;
|
|
7718
|
+
var STOPWORDS4 = new Set(
|
|
7719
|
+
`the a an of to for in on with and or as at by is are was be been being
|
|
7720
|
+
this that it its if whether when where which what will would can could should
|
|
7721
|
+
must may into from over about not no does do done has have had used use uses
|
|
7722
|
+
using given provided specified current new existing all any each per via
|
|
7723
|
+
instance object value values data item
|
|
7724
|
+
items element callback handler prop props param arg return
|
|
7725
|
+
returns returning result optional required true false null undefined
|
|
7726
|
+
string number boolean array list promise set map record type name`.split(/\s+/)
|
|
7727
|
+
);
|
|
7728
|
+
var WORD_RE4 = /[A-Za-z][A-Za-z0-9]*/g;
|
|
7729
|
+
var BARE_LABEL_RE = /^[A-Za-z][A-Za-z0-9]*$/;
|
|
7730
|
+
function labelStems(body) {
|
|
7731
|
+
return splitIdentifier(body).map(stem).join(" ");
|
|
7732
|
+
}
|
|
7733
|
+
function isNamedMember(node) {
|
|
7734
|
+
return (node.type === AST_NODE_TYPES34.TSPropertySignature || node.type === AST_NODE_TYPES34.TSMethodSignature) && !node.computed;
|
|
7735
|
+
}
|
|
7736
|
+
function commentBody(comment) {
|
|
7737
|
+
return comment.value.replace(/^\*+/, "").replace(/^[ \t]*\*[ \t]?/gm, "").trim();
|
|
7738
|
+
}
|
|
7739
|
+
function carriesValue(body) {
|
|
7740
|
+
return isProtected(body) || VALUE_TAG_RE.test(body) || DEFAULT_RE.test(body) || DIGIT_RE.test(body) || UNIT_WORD_RE.test(body) || EXAMPLE_RE.test(body) || BANNER_RE.test(body) || NON_ASCII_LETTER_RE2.test(body);
|
|
7741
|
+
}
|
|
7742
|
+
function knownTokens(source) {
|
|
7743
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
7744
|
+
for (const identifier of source.match(/[A-Za-z_$][\w$]*/g) ?? []) {
|
|
7745
|
+
for (const part of splitIdentifier(identifier)) {
|
|
7746
|
+
tokens.add(part);
|
|
7747
|
+
tokens.add(stem(part));
|
|
7748
|
+
}
|
|
7749
|
+
}
|
|
7750
|
+
return tokens;
|
|
7751
|
+
}
|
|
7752
|
+
function novelWords(body, known) {
|
|
7753
|
+
let novel = 0;
|
|
7754
|
+
for (const word of body.match(WORD_RE4) ?? []) {
|
|
7755
|
+
const lower = word.toLowerCase();
|
|
7756
|
+
if (lower.length < 2 || STOPWORDS4.has(lower)) continue;
|
|
7757
|
+
if (!known.has(lower) && !known.has(stem(lower))) novel += 1;
|
|
7758
|
+
}
|
|
7759
|
+
return novel;
|
|
7760
|
+
}
|
|
7761
|
+
var no_type_member_comment_wall_default = ESLintUtils44.RuleCreator(
|
|
7762
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7763
|
+
)({
|
|
7764
|
+
name: "no-type-member-comment-wall",
|
|
7765
|
+
meta: {
|
|
7766
|
+
type: "suggestion",
|
|
7767
|
+
docs: {
|
|
7768
|
+
description: "Flag an object type whose member comments mostly re-spell the members' own names and types."
|
|
7769
|
+
},
|
|
7770
|
+
schema: [
|
|
7771
|
+
{
|
|
7772
|
+
type: "object",
|
|
7773
|
+
additionalProperties: false,
|
|
7774
|
+
properties: {
|
|
7775
|
+
minCommentedMembers: {
|
|
7776
|
+
type: "integer",
|
|
7777
|
+
minimum: 2,
|
|
7778
|
+
description: "Fewest commented members that can count as a wall."
|
|
7779
|
+
},
|
|
7780
|
+
minCommentedRatio: {
|
|
7781
|
+
type: "number",
|
|
7782
|
+
minimum: 0,
|
|
7783
|
+
maximum: 1,
|
|
7784
|
+
description: "Least share of the type's members that must be commented; below it the comments are group labels."
|
|
7785
|
+
},
|
|
7786
|
+
minRestatedRatio: {
|
|
7787
|
+
type: "number",
|
|
7788
|
+
minimum: 0,
|
|
7789
|
+
maximum: 1,
|
|
7790
|
+
description: "Least share of the member comments that must be restatements."
|
|
7791
|
+
},
|
|
7792
|
+
maxNovelWords: {
|
|
7793
|
+
type: "integer",
|
|
7794
|
+
minimum: 0,
|
|
7795
|
+
description: "Most content words a comment may add beyond its member's own source and still count as a restatement."
|
|
7796
|
+
}
|
|
7797
|
+
}
|
|
7798
|
+
}
|
|
7799
|
+
],
|
|
7800
|
+
messages: {
|
|
7801
|
+
commentWall: "{{restated}} of this type's {{commented}} member comments only re-spell the member's own name and type \u2014 delete them, and keep the rows that say what the name cannot."
|
|
7802
|
+
}
|
|
7803
|
+
},
|
|
7804
|
+
defaultOptions: [DEFAULTS],
|
|
7805
|
+
create(context, [provided]) {
|
|
7806
|
+
const options = { ...DEFAULTS, ...provided };
|
|
7807
|
+
const sourceCode = context.sourceCode;
|
|
7808
|
+
if (isGeneratedFile(context.filename, sourceCode.text) || isTestFile(context.filename) || isStoryFile(context.filename)) {
|
|
7809
|
+
return {};
|
|
7810
|
+
}
|
|
7811
|
+
const endingOn = /* @__PURE__ */ new Map();
|
|
7812
|
+
const startingOn = /* @__PURE__ */ new Map();
|
|
7813
|
+
for (const comment of sourceCode.getAllComments()) {
|
|
7814
|
+
endingOn.set(comment.loc.end.line, comment);
|
|
7815
|
+
if (!startingOn.has(comment.loc.start.line)) startingOn.set(comment.loc.start.line, comment);
|
|
7816
|
+
}
|
|
7817
|
+
function documentingComment(member) {
|
|
7818
|
+
const beforeMember = sourceCode.getTokenBefore(member, { includeComments: false });
|
|
7819
|
+
const ownsItsLine = beforeMember === null || beforeMember.loc.end.line < member.loc.start.line;
|
|
7820
|
+
const lead = ownsItsLine ? endingOn.get(member.loc.start.line - 1) : void 0;
|
|
7821
|
+
if (lead !== void 0) {
|
|
7822
|
+
const before = sourceCode.getTokenBefore(lead, { includeComments: false });
|
|
7823
|
+
if (before === null || before.loc.end.line < lead.loc.start.line) return lead;
|
|
7824
|
+
}
|
|
7825
|
+
const trail = startingOn.get(member.loc.end.line);
|
|
7826
|
+
return trail !== void 0 && trail.range[0] > member.range[0] ? trail : void 0;
|
|
7827
|
+
}
|
|
7828
|
+
function isGroupLabel(comment, member, headsRun) {
|
|
7829
|
+
if (comment.loc.end.line >= member.loc.start.line) return false;
|
|
7830
|
+
const body = commentBody(comment);
|
|
7831
|
+
if (!BARE_LABEL_RE.test(body)) return false;
|
|
7832
|
+
if (labelStems(body) === labelStems(sourceCode.getText(member.key))) return false;
|
|
7833
|
+
const lineAbove = sourceCode.lines[comment.loc.start.line - 2];
|
|
7834
|
+
return headsRun || lineAbove !== void 0 && lineAbove.trim().length === 0;
|
|
7835
|
+
}
|
|
7836
|
+
function check(node) {
|
|
7837
|
+
const members = node.type === AST_NODE_TYPES34.TSInterfaceBody ? node.body : node.members;
|
|
7838
|
+
const named = members.filter(isNamedMember);
|
|
7839
|
+
if (named.length === 0) return;
|
|
7840
|
+
const documented = named.map((member) => ({ member, comment: documentingComment(member) }));
|
|
7841
|
+
let commented = 0;
|
|
7842
|
+
let restated = 0;
|
|
7843
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
7844
|
+
for (const [index, { member, comment }] of documented.entries()) {
|
|
7845
|
+
if (comment === void 0 || claimed.has(comment)) continue;
|
|
7846
|
+
const next = documented[index + 1];
|
|
7847
|
+
if (isGroupLabel(comment, member, next !== void 0 && next.comment === void 0)) {
|
|
7848
|
+
continue;
|
|
7849
|
+
}
|
|
7850
|
+
claimed.add(comment);
|
|
7851
|
+
commented += 1;
|
|
7852
|
+
const body = commentBody(comment);
|
|
7853
|
+
if (body.length === 0 || carriesValue(body)) continue;
|
|
7854
|
+
if (novelWords(body, knownTokens(sourceCode.getText(member))) <= options.maxNovelWords) {
|
|
7855
|
+
restated += 1;
|
|
7856
|
+
}
|
|
7857
|
+
}
|
|
7858
|
+
if (commented < options.minCommentedMembers || commented / named.length < options.minCommentedRatio || restated / commented < options.minRestatedRatio) {
|
|
7859
|
+
return;
|
|
7860
|
+
}
|
|
7861
|
+
context.report({
|
|
7862
|
+
node,
|
|
7863
|
+
loc: {
|
|
7864
|
+
start: node.loc.start,
|
|
7865
|
+
end: { line: node.loc.start.line, column: node.loc.start.column + 1 }
|
|
7866
|
+
},
|
|
7867
|
+
messageId: "commentWall",
|
|
7868
|
+
data: { restated: String(restated), commented: String(commented) }
|
|
7869
|
+
});
|
|
7870
|
+
}
|
|
7871
|
+
return {
|
|
7872
|
+
TSInterfaceBody: check,
|
|
7873
|
+
TSTypeLiteral: check
|
|
7874
|
+
};
|
|
7875
|
+
}
|
|
7876
|
+
});
|
|
7877
|
+
|
|
7244
7878
|
// src/rules/no-tautological-expect.ts
|
|
7245
|
-
import { AST_NODE_TYPES as
|
|
7879
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES35, ESLintUtils as ESLintUtils45 } from "@typescript-eslint/utils";
|
|
7246
7880
|
var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
7247
7881
|
var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
|
|
7248
7882
|
"toBeDefined",
|
|
@@ -7256,17 +7890,17 @@ var OPERAND_PREVIEW_CHARS = 40;
|
|
|
7256
7890
|
var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
|
|
7257
7891
|
function isLiteral(node) {
|
|
7258
7892
|
switch (node.type) {
|
|
7259
|
-
case
|
|
7893
|
+
case AST_NODE_TYPES35.Literal:
|
|
7260
7894
|
return true;
|
|
7261
|
-
case
|
|
7895
|
+
case AST_NODE_TYPES35.TemplateLiteral:
|
|
7262
7896
|
return node.expressions.length === 0;
|
|
7263
|
-
case
|
|
7897
|
+
case AST_NODE_TYPES35.UnaryExpression:
|
|
7264
7898
|
return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
|
|
7265
|
-
case
|
|
7899
|
+
case AST_NODE_TYPES35.ArrayExpression:
|
|
7266
7900
|
return node.elements.every((element) => element !== null && isLiteral(element));
|
|
7267
|
-
case
|
|
7901
|
+
case AST_NODE_TYPES35.ObjectExpression:
|
|
7268
7902
|
return node.properties.every(
|
|
7269
|
-
(property) => property.type ===
|
|
7903
|
+
(property) => property.type === AST_NODE_TYPES35.Property && !property.computed && isLiteral(property.value)
|
|
7270
7904
|
);
|
|
7271
7905
|
default:
|
|
7272
7906
|
return false;
|
|
@@ -7274,7 +7908,7 @@ function isLiteral(node) {
|
|
|
7274
7908
|
}
|
|
7275
7909
|
function expectOperand(callee) {
|
|
7276
7910
|
const receiver = callee.object;
|
|
7277
|
-
if (receiver.type !==
|
|
7911
|
+
if (receiver.type !== AST_NODE_TYPES35.CallExpression || receiver.callee.type !== AST_NODE_TYPES35.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
|
|
7278
7912
|
return null;
|
|
7279
7913
|
}
|
|
7280
7914
|
return receiver.arguments[0] ?? null;
|
|
@@ -7306,10 +7940,10 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7306
7940
|
return {
|
|
7307
7941
|
CallExpression(node) {
|
|
7308
7942
|
const callee = node.callee;
|
|
7309
|
-
if (callee.type !==
|
|
7943
|
+
if (callee.type !== AST_NODE_TYPES35.MemberExpression || callee.computed) {
|
|
7310
7944
|
return;
|
|
7311
7945
|
}
|
|
7312
|
-
if (callee.property.type !==
|
|
7946
|
+
if (callee.property.type !== AST_NODE_TYPES35.Identifier) {
|
|
7313
7947
|
return;
|
|
7314
7948
|
}
|
|
7315
7949
|
const matcher = callee.property.name;
|
|
@@ -7343,26 +7977,26 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7343
7977
|
});
|
|
7344
7978
|
|
|
7345
7979
|
// src/rules/require-interface-for-injected-service.ts
|
|
7346
|
-
import { AST_NODE_TYPES as
|
|
7980
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES36, ESLintUtils as ESLintUtils46 } from "@typescript-eslint/utils";
|
|
7347
7981
|
var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
|
|
7348
7982
|
var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
|
|
7349
7983
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
7350
7984
|
var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
|
|
7351
7985
|
var ROUTER_FACTORY_NAME = "Router";
|
|
7352
7986
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
7353
|
-
var isExportedClass = (node) => node.parent.type ===
|
|
7354
|
-
var qualifiedName = (name) => name.type ===
|
|
7987
|
+
var isExportedClass = (node) => node.parent.type === AST_NODE_TYPES36.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES36.ExportDefaultDeclaration;
|
|
7988
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES36.Identifier ? name.name : name.type === AST_NODE_TYPES36.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
7355
7989
|
var typeReferenceName = (annotated) => {
|
|
7356
7990
|
let target = annotated;
|
|
7357
|
-
if (target.type ===
|
|
7358
|
-
if (target.type ===
|
|
7359
|
-
if (target.type !==
|
|
7991
|
+
if (target.type === AST_NODE_TYPES36.TSParameterProperty) target = target.parameter;
|
|
7992
|
+
if (target.type === AST_NODE_TYPES36.AssignmentPattern) target = target.left;
|
|
7993
|
+
if (target.type !== AST_NODE_TYPES36.Identifier) return null;
|
|
7360
7994
|
const annotation = target.typeAnnotation?.typeAnnotation;
|
|
7361
|
-
if (annotation === void 0 || annotation.type !==
|
|
7995
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES36.TSTypeReference) {
|
|
7362
7996
|
return null;
|
|
7363
7997
|
}
|
|
7364
7998
|
const { typeName } = annotation;
|
|
7365
|
-
const rightmost = typeName.type ===
|
|
7999
|
+
const rightmost = typeName.type === AST_NODE_TYPES36.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES36.TSQualifiedName ? typeName.right.name : null;
|
|
7366
8000
|
if (rightmost === null) return null;
|
|
7367
8001
|
return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
|
|
7368
8002
|
};
|
|
@@ -7372,17 +8006,17 @@ var readConstructor = (ctor) => {
|
|
|
7372
8006
|
let constructedFields = 0;
|
|
7373
8007
|
if (body !== null && body !== void 0) {
|
|
7374
8008
|
for (const statement of body.body) {
|
|
7375
|
-
if (statement.type !==
|
|
8009
|
+
if (statement.type !== AST_NODE_TYPES36.ExpressionStatement) continue;
|
|
7376
8010
|
const expression = statement.expression;
|
|
7377
|
-
if (expression.type !==
|
|
8011
|
+
if (expression.type !== AST_NODE_TYPES36.AssignmentExpression || expression.operator !== "=" || expression.left.type !== AST_NODE_TYPES36.MemberExpression || expression.left.object.type !== AST_NODE_TYPES36.ThisExpression) {
|
|
7378
8012
|
continue;
|
|
7379
8013
|
}
|
|
7380
8014
|
const source = expression.right;
|
|
7381
|
-
if (source.type ===
|
|
8015
|
+
if (source.type === AST_NODE_TYPES36.NewExpression) {
|
|
7382
8016
|
constructedFields += 1;
|
|
7383
|
-
} else if (source.type ===
|
|
8017
|
+
} else if (source.type === AST_NODE_TYPES36.Identifier) {
|
|
7384
8018
|
storedFrom.add(source.name);
|
|
7385
|
-
} else if (source.type ===
|
|
8019
|
+
} else if (source.type === AST_NODE_TYPES36.MemberExpression && source.object.type === AST_NODE_TYPES36.Identifier) {
|
|
7386
8020
|
storedFrom.add(source.object.name);
|
|
7387
8021
|
}
|
|
7388
8022
|
}
|
|
@@ -7391,7 +8025,7 @@ var readConstructor = (ctor) => {
|
|
|
7391
8025
|
for (const parameter of ctor.value.params) {
|
|
7392
8026
|
const reference = typeReferenceName(parameter);
|
|
7393
8027
|
if (reference === null) continue;
|
|
7394
|
-
const stored = parameter.type ===
|
|
8028
|
+
const stored = parameter.type === AST_NODE_TYPES36.TSParameterProperty || storedFrom.has(reference.name);
|
|
7395
8029
|
if (!stored) continue;
|
|
7396
8030
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
7397
8031
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -7421,19 +8055,19 @@ var subtreeHas = (root, found) => {
|
|
|
7421
8055
|
return hit;
|
|
7422
8056
|
};
|
|
7423
8057
|
var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
|
|
7424
|
-
if (node.type ===
|
|
8058
|
+
if (node.type === AST_NODE_TYPES36.CallExpression) {
|
|
7425
8059
|
const { callee } = node;
|
|
7426
|
-
if (callee.type ===
|
|
7427
|
-
return callee.type ===
|
|
8060
|
+
if (callee.type === AST_NODE_TYPES36.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
8061
|
+
return callee.type === AST_NODE_TYPES36.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES36.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
7428
8062
|
}
|
|
7429
|
-
return node.type ===
|
|
8063
|
+
return node.type === AST_NODE_TYPES36.TSTypeReference && node.typeName.type === AST_NODE_TYPES36.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
7430
8064
|
});
|
|
7431
8065
|
var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
|
|
7432
8066
|
var fileInterfaceNames = (program) => {
|
|
7433
8067
|
const names = [];
|
|
7434
8068
|
for (const statement of program.body) {
|
|
7435
|
-
const declaration = statement.type ===
|
|
7436
|
-
if (declaration?.type ===
|
|
8069
|
+
const declaration = statement.type === AST_NODE_TYPES36.ExportNamedDeclaration ? statement.declaration : statement;
|
|
8070
|
+
if (declaration?.type === AST_NODE_TYPES36.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
7437
8071
|
}
|
|
7438
8072
|
return names;
|
|
7439
8073
|
};
|
|
@@ -7451,11 +8085,11 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
7451
8085
|
var publicMethodNames = (body) => {
|
|
7452
8086
|
const names = [];
|
|
7453
8087
|
for (const member of body.body) {
|
|
7454
|
-
if (member.type !==
|
|
8088
|
+
if (member.type !== AST_NODE_TYPES36.MethodDefinition) continue;
|
|
7455
8089
|
if (member.kind !== "method" || member.static) continue;
|
|
7456
8090
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
7457
|
-
if (member.key.type ===
|
|
7458
|
-
if (member.key.type ===
|
|
8091
|
+
if (member.key.type === AST_NODE_TYPES36.PrivateIdentifier) continue;
|
|
8092
|
+
if (member.key.type === AST_NODE_TYPES36.Identifier) names.push(member.key.name);
|
|
7459
8093
|
else names.push("\u2026");
|
|
7460
8094
|
}
|
|
7461
8095
|
return names;
|
|
@@ -7488,7 +8122,7 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7488
8122
|
if (node.implements.length > 0) return;
|
|
7489
8123
|
if (node.decorators.length > 0) return;
|
|
7490
8124
|
const ctor = node.body.body.find(
|
|
7491
|
-
(member) => member.type ===
|
|
8125
|
+
(member) => member.type === AST_NODE_TYPES36.MethodDefinition && member.kind === "constructor"
|
|
7492
8126
|
);
|
|
7493
8127
|
if (ctor === void 0) return;
|
|
7494
8128
|
const { collaborators, constructedFields } = readConstructor(ctor);
|
|
@@ -7513,20 +8147,20 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7513
8147
|
});
|
|
7514
8148
|
|
|
7515
8149
|
// src/rules/prefer-non-nullable-collection.ts
|
|
7516
|
-
import { AST_NODE_TYPES as
|
|
8150
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES37, ESLintUtils as ESLintUtils47 } from "@typescript-eslint/utils";
|
|
7517
8151
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
7518
8152
|
function propertyName(node) {
|
|
7519
8153
|
const key = node.key;
|
|
7520
|
-
if (key.type ===
|
|
7521
|
-
if (key.type ===
|
|
8154
|
+
if (key.type === AST_NODE_TYPES37.Identifier) return key.name;
|
|
8155
|
+
if (key.type === AST_NODE_TYPES37.Literal) return String(key.value);
|
|
7522
8156
|
return "collection";
|
|
7523
8157
|
}
|
|
7524
8158
|
function isArrayType(node) {
|
|
7525
|
-
if (node.type ===
|
|
7526
|
-
return node.type ===
|
|
8159
|
+
if (node.type === AST_NODE_TYPES37.TSArrayType) return true;
|
|
8160
|
+
return node.type === AST_NODE_TYPES37.TSTypeReference && node.typeName.type === AST_NODE_TYPES37.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
7527
8161
|
}
|
|
7528
8162
|
function isNullishType(node) {
|
|
7529
|
-
return node.type ===
|
|
8163
|
+
return node.type === AST_NODE_TYPES37.TSNullKeyword || node.type === AST_NODE_TYPES37.TSUndefinedKeyword;
|
|
7530
8164
|
}
|
|
7531
8165
|
function isNullableArrayOnly(node) {
|
|
7532
8166
|
const values = node.types.filter((member) => !isNullishType(member));
|
|
@@ -7555,7 +8189,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7555
8189
|
function checkOptionalProperty(node) {
|
|
7556
8190
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
7557
8191
|
if (annotation === void 0) return;
|
|
7558
|
-
if (annotation.type !==
|
|
8192
|
+
if (annotation.type !== AST_NODE_TYPES37.TSUnionType || !isNullableArrayOnly(annotation)) {
|
|
7559
8193
|
return;
|
|
7560
8194
|
}
|
|
7561
8195
|
context.report({
|
|
@@ -7568,7 +8202,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7568
8202
|
TSPropertySignature: checkOptionalProperty,
|
|
7569
8203
|
PropertyDefinition: checkOptionalProperty,
|
|
7570
8204
|
TSTypeAliasDeclaration(node) {
|
|
7571
|
-
if (node.typeAnnotation.type !==
|
|
8205
|
+
if (node.typeAnnotation.type !== AST_NODE_TYPES37.TSUnionType) return;
|
|
7572
8206
|
if (!isNullableArrayOnly(node.typeAnnotation)) return;
|
|
7573
8207
|
context.report({
|
|
7574
8208
|
node,
|
|
@@ -7580,174 +8214,217 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7580
8214
|
}
|
|
7581
8215
|
});
|
|
7582
8216
|
|
|
7583
|
-
// src/rules/
|
|
7584
|
-
import { AST_NODE_TYPES as
|
|
7585
|
-
var
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
if (node.type === AST_NODE_TYPES35.Identifier) {
|
|
7601
|
-
return node.name;
|
|
8217
|
+
// src/rules/strict-test-assertions.ts
|
|
8218
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES38, ESLintUtils as ESLintUtils48 } from "@typescript-eslint/utils";
|
|
8219
|
+
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
8220
|
+
var ARRAY_MATCHERS = /* @__PURE__ */ new Set(["toEqual", "toStrictEqual"]);
|
|
8221
|
+
var COLLECTION_PROPERTIES = /* @__PURE__ */ new Set(["length", "size"]);
|
|
8222
|
+
var NUMERIC_SIGNS2 = /* @__PURE__ */ new Set(["-", "+"]);
|
|
8223
|
+
var MIN_RUN_LENGTH = 2;
|
|
8224
|
+
function literalText(node, getText) {
|
|
8225
|
+
switch (node.type) {
|
|
8226
|
+
case AST_NODE_TYPES38.Literal:
|
|
8227
|
+
return "regex" in node ? null : getText(node);
|
|
8228
|
+
case AST_NODE_TYPES38.TemplateLiteral:
|
|
8229
|
+
return node.expressions.length === 0 ? getText(node) : null;
|
|
8230
|
+
case AST_NODE_TYPES38.UnaryExpression:
|
|
8231
|
+
return NUMERIC_SIGNS2.has(node.operator) && literalText(node.argument, getText) !== null ? getText(node) : null;
|
|
8232
|
+
default:
|
|
8233
|
+
return null;
|
|
7602
8234
|
}
|
|
7603
|
-
|
|
7604
|
-
|
|
8235
|
+
}
|
|
8236
|
+
function isPureReceiver(node) {
|
|
8237
|
+
switch (node.type) {
|
|
8238
|
+
case AST_NODE_TYPES38.Identifier:
|
|
8239
|
+
case AST_NODE_TYPES38.ThisExpression:
|
|
8240
|
+
return true;
|
|
8241
|
+
case AST_NODE_TYPES38.MemberExpression:
|
|
8242
|
+
if (node.optional) {
|
|
8243
|
+
return false;
|
|
8244
|
+
}
|
|
8245
|
+
if (node.computed) {
|
|
8246
|
+
return node.property.type === AST_NODE_TYPES38.Literal && isPureReceiver(node.object);
|
|
8247
|
+
}
|
|
8248
|
+
return isPureReceiver(node.object);
|
|
8249
|
+
default:
|
|
8250
|
+
return false;
|
|
7605
8251
|
}
|
|
7606
|
-
return null;
|
|
7607
8252
|
}
|
|
7608
|
-
|
|
8253
|
+
function literalIndex(node) {
|
|
8254
|
+
if (node.type !== AST_NODE_TYPES38.Literal || typeof node.value !== "number") {
|
|
8255
|
+
return null;
|
|
8256
|
+
}
|
|
8257
|
+
return Number.isInteger(node.value) && node.value >= 0 ? node.value : null;
|
|
8258
|
+
}
|
|
8259
|
+
var strict_test_assertions_default = ESLintUtils48.RuleCreator(
|
|
7609
8260
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7610
8261
|
)({
|
|
7611
|
-
name: "
|
|
7612
|
-
meta: {
|
|
7613
|
-
type: "problem",
|
|
7614
|
-
docs: {
|
|
7615
|
-
description: "Disallow imperative dictionary access with string literals; use declarative Zod schemas."
|
|
7616
|
-
},
|
|
7617
|
-
schema: [],
|
|
7618
|
-
messages: {
|
|
7619
|
-
noImplicitAttributeAccess: "Imperative lookup for '{{key}}' \u2014 if the key is known, parse the object declaratively with a Zod schema instead."
|
|
7620
|
-
}
|
|
7621
|
-
},
|
|
7622
|
-
defaultOptions: [],
|
|
7623
|
-
create(context) {
|
|
7624
|
-
return {
|
|
7625
|
-
MemberExpression(node) {
|
|
7626
|
-
if (!node.computed) {
|
|
7627
|
-
return;
|
|
7628
|
-
}
|
|
7629
|
-
if (node.property.type === AST_NODE_TYPES35.Literal && typeof node.property.value === "string") {
|
|
7630
|
-
const baseName = getBaseName(node.object);
|
|
7631
|
-
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7632
|
-
context.report({
|
|
7633
|
-
node,
|
|
7634
|
-
messageId: "noImplicitAttributeAccess",
|
|
7635
|
-
data: { key: node.property.value }
|
|
7636
|
-
});
|
|
7637
|
-
}
|
|
7638
|
-
}
|
|
7639
|
-
},
|
|
7640
|
-
CallExpression(node) {
|
|
7641
|
-
const callee = node.callee;
|
|
7642
|
-
if (callee.type === AST_NODE_TYPES35.MemberExpression) {
|
|
7643
|
-
const method = callee.property.type === AST_NODE_TYPES35.Identifier ? callee.property.name : null;
|
|
7644
|
-
if (method === "get") {
|
|
7645
|
-
const arg = node.arguments[0];
|
|
7646
|
-
if (arg && arg.type === AST_NODE_TYPES35.Literal && typeof arg.value === "string") {
|
|
7647
|
-
const baseName = getBaseName(callee.object);
|
|
7648
|
-
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7649
|
-
context.report({
|
|
7650
|
-
node,
|
|
7651
|
-
messageId: "noImplicitAttributeAccess",
|
|
7652
|
-
data: { key: arg.value }
|
|
7653
|
-
});
|
|
7654
|
-
}
|
|
7655
|
-
}
|
|
7656
|
-
}
|
|
7657
|
-
}
|
|
7658
|
-
}
|
|
7659
|
-
};
|
|
7660
|
-
}
|
|
7661
|
-
});
|
|
7662
|
-
|
|
7663
|
-
// src/rules/strict-test-assertions.ts
|
|
7664
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES36, ESLintUtils as ESLintUtils49 } from "@typescript-eslint/utils";
|
|
7665
|
-
var strict_test_assertions_default = ESLintUtils49.RuleCreator.withoutDocs({
|
|
8262
|
+
name: "strict-test-assertions",
|
|
7666
8263
|
meta: {
|
|
7667
8264
|
type: "suggestion",
|
|
7668
8265
|
docs: {
|
|
7669
|
-
description: "
|
|
8266
|
+
description: "Collapse a run of consecutive assertions on the same object into one assertion about the whole object, so every mismatch is reported and nothing outside the asserted keys goes unchecked."
|
|
7670
8267
|
},
|
|
7671
8268
|
fixable: "code",
|
|
7672
8269
|
messages: {
|
|
7673
|
-
combineAssertions: "
|
|
8270
|
+
combineAssertions: "These {{count}} assertions each check one property of `{{receiver}}` against a literal, so the first mismatch hides the rest. Assert the object once: `expect({{receiver}}).toMatchObject({ \u2026 })`.",
|
|
8271
|
+
assertArrayOnce: "These {{count}} assertions check `{{receiver}}[0]`\u2026`{{receiver}}[{{last}}]` one at a time, which never checks how long `{{receiver}}` is \u2014 extra elements pass unnoticed. Assert the array once: `expect({{receiver}}).{{matcher}}([ \u2026 ])`."
|
|
7674
8272
|
},
|
|
7675
8273
|
schema: []
|
|
7676
8274
|
},
|
|
7677
8275
|
defaultOptions: [],
|
|
7678
8276
|
create(context) {
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
8277
|
+
if (!isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
8278
|
+
return {};
|
|
8279
|
+
}
|
|
8280
|
+
const { sourceCode } = context;
|
|
8281
|
+
function parseAssertion(statement) {
|
|
8282
|
+
if (statement.type !== AST_NODE_TYPES38.ExpressionStatement) {
|
|
8283
|
+
return null;
|
|
8284
|
+
}
|
|
8285
|
+
const call = statement.expression;
|
|
8286
|
+
if (call.type !== AST_NODE_TYPES38.CallExpression) {
|
|
8287
|
+
return null;
|
|
8288
|
+
}
|
|
8289
|
+
const callee = call.callee;
|
|
8290
|
+
if (callee.type !== AST_NODE_TYPES38.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES38.Identifier) {
|
|
8291
|
+
return null;
|
|
8292
|
+
}
|
|
8293
|
+
const matcher = callee.property.name;
|
|
8294
|
+
const expectCall = callee.object;
|
|
8295
|
+
if (expectCall.type !== AST_NODE_TYPES38.CallExpression || expectCall.callee.type !== AST_NODE_TYPES38.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
8296
|
+
return null;
|
|
8297
|
+
}
|
|
8298
|
+
const actual = expectCall.arguments[0];
|
|
8299
|
+
if (actual === void 0 || actual.type !== AST_NODE_TYPES38.MemberExpression || actual.optional) {
|
|
8300
|
+
return null;
|
|
8301
|
+
}
|
|
8302
|
+
if (!isPureReceiver(actual.object)) {
|
|
8303
|
+
return null;
|
|
8304
|
+
}
|
|
8305
|
+
let key;
|
|
8306
|
+
if (actual.computed) {
|
|
8307
|
+
const index = literalIndex(actual.property);
|
|
8308
|
+
if (index === null) {
|
|
8309
|
+
return null;
|
|
7688
8310
|
}
|
|
8311
|
+
key = { kind: "index", index };
|
|
8312
|
+
} else {
|
|
8313
|
+
if (actual.property.type !== AST_NODE_TYPES38.Identifier || COLLECTION_PROPERTIES.has(actual.property.name)) {
|
|
8314
|
+
return null;
|
|
8315
|
+
}
|
|
8316
|
+
key = { kind: "property", name: actual.property.name };
|
|
8317
|
+
}
|
|
8318
|
+
if (matcher === "toBeNull" && call.arguments.length === 0) {
|
|
8319
|
+
return { statement, receiver: actual.object, key, matcher, expectedText: "null", expectedIsLiteral: true };
|
|
8320
|
+
}
|
|
8321
|
+
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
7689
8322
|
return null;
|
|
7690
8323
|
}
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
fixer.replaceText(first, replacement),
|
|
7717
|
-
...sequence.slice(1).map((stmt) => fixer.remove(stmt))
|
|
7718
|
-
];
|
|
7719
|
-
}
|
|
7720
|
-
});
|
|
8324
|
+
const expected = call.arguments[0];
|
|
8325
|
+
if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES38.SpreadElement) {
|
|
8326
|
+
return null;
|
|
8327
|
+
}
|
|
8328
|
+
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
8329
|
+
return {
|
|
8330
|
+
statement,
|
|
8331
|
+
receiver: actual.object,
|
|
8332
|
+
key,
|
|
8333
|
+
matcher,
|
|
8334
|
+
expectedText: literal ?? sourceCode.getText(expected),
|
|
8335
|
+
expectedIsLiteral: literal !== null
|
|
8336
|
+
};
|
|
8337
|
+
}
|
|
8338
|
+
function reportPropertyRun(run) {
|
|
8339
|
+
const names = /* @__PURE__ */ new Set();
|
|
8340
|
+
for (const assertion of run) {
|
|
8341
|
+
if (assertion.key.kind !== "property" || !assertion.expectedIsLiteral) {
|
|
8342
|
+
return;
|
|
8343
|
+
}
|
|
8344
|
+
if (!MERGEABLE_MATCHERS.has(assertion.matcher) && assertion.matcher !== "toBeNull") {
|
|
8345
|
+
return;
|
|
8346
|
+
}
|
|
8347
|
+
if (names.has(assertion.key.name)) {
|
|
8348
|
+
return;
|
|
7721
8349
|
}
|
|
8350
|
+
names.add(assertion.key.name);
|
|
7722
8351
|
}
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
8352
|
+
const first = run[0];
|
|
8353
|
+
if (first === void 0) {
|
|
8354
|
+
return;
|
|
8355
|
+
}
|
|
8356
|
+
const receiverText = sourceCode.getText(first.receiver);
|
|
8357
|
+
const properties = run.map(
|
|
8358
|
+
(assertion) => assertion.key.kind === "property" ? `${assertion.key.name}: ${assertion.expectedText}` : ""
|
|
8359
|
+
).join(", ");
|
|
8360
|
+
context.report({
|
|
8361
|
+
node: first.statement,
|
|
8362
|
+
messageId: "combineAssertions",
|
|
8363
|
+
data: { count: String(run.length), receiver: receiverText },
|
|
8364
|
+
fix: (fixer) => [
|
|
8365
|
+
fixer.replaceText(first.statement, `expect(${receiverText}).toMatchObject({ ${properties} });`),
|
|
8366
|
+
...run.slice(1).map((assertion) => fixer.remove(assertion.statement))
|
|
8367
|
+
]
|
|
8368
|
+
});
|
|
8369
|
+
}
|
|
8370
|
+
function reportIndexRun(run) {
|
|
8371
|
+
const first = run[0];
|
|
8372
|
+
if (first === void 0 || !ARRAY_MATCHERS.has(first.matcher)) {
|
|
8373
|
+
return;
|
|
8374
|
+
}
|
|
8375
|
+
const indices = /* @__PURE__ */ new Set();
|
|
8376
|
+
for (const assertion of run) {
|
|
8377
|
+
if (assertion.key.kind !== "index" || assertion.matcher !== first.matcher) {
|
|
8378
|
+
return;
|
|
8379
|
+
}
|
|
8380
|
+
indices.add(assertion.key.index);
|
|
8381
|
+
}
|
|
8382
|
+
if (indices.size !== run.length || Math.max(...indices) !== run.length - 1) {
|
|
8383
|
+
return;
|
|
8384
|
+
}
|
|
8385
|
+
context.report({
|
|
8386
|
+
node: first.statement,
|
|
8387
|
+
messageId: "assertArrayOnce",
|
|
8388
|
+
data: {
|
|
8389
|
+
count: String(run.length),
|
|
8390
|
+
receiver: sourceCode.getText(first.receiver),
|
|
8391
|
+
last: String(run.length - 1),
|
|
8392
|
+
matcher: first.matcher
|
|
8393
|
+
}
|
|
8394
|
+
});
|
|
8395
|
+
}
|
|
8396
|
+
function checkBody(body) {
|
|
8397
|
+
let run = [];
|
|
8398
|
+
const flush = () => {
|
|
8399
|
+
const first = run[0];
|
|
8400
|
+
if (first !== void 0 && run.length >= MIN_RUN_LENGTH) {
|
|
8401
|
+
if (first.key.kind === "property") {
|
|
8402
|
+
reportPropertyRun(run);
|
|
7728
8403
|
} else {
|
|
7729
|
-
|
|
7730
|
-
if (obj) {
|
|
7731
|
-
currentObject = obj;
|
|
7732
|
-
sequence = [statement];
|
|
7733
|
-
} else {
|
|
7734
|
-
currentObject = null;
|
|
7735
|
-
sequence = [];
|
|
7736
|
-
}
|
|
8404
|
+
reportIndexRun(run);
|
|
7737
8405
|
}
|
|
7738
|
-
}
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
8406
|
+
}
|
|
8407
|
+
run = [];
|
|
8408
|
+
};
|
|
8409
|
+
for (const statement of body) {
|
|
8410
|
+
const assertion = parseAssertion(statement);
|
|
8411
|
+
const previous = run.at(-1);
|
|
8412
|
+
if (assertion !== null && previous !== void 0 && previous.key.kind === assertion.key.kind && sourceCode.getText(previous.receiver) === sourceCode.getText(assertion.receiver)) {
|
|
8413
|
+
run.push(assertion);
|
|
8414
|
+
continue;
|
|
8415
|
+
}
|
|
8416
|
+
flush();
|
|
8417
|
+
if (assertion !== null) {
|
|
8418
|
+
run = [assertion];
|
|
7742
8419
|
}
|
|
7743
8420
|
}
|
|
7744
|
-
|
|
8421
|
+
flush();
|
|
7745
8422
|
}
|
|
7746
8423
|
return {
|
|
7747
|
-
BlockStatement(node) {
|
|
8424
|
+
BlockStatement: (node) => {
|
|
7748
8425
|
checkBody(node.body);
|
|
7749
8426
|
},
|
|
7750
|
-
Program(node) {
|
|
8427
|
+
Program: (node) => {
|
|
7751
8428
|
checkBody(node.body);
|
|
7752
8429
|
}
|
|
7753
8430
|
};
|
|
@@ -7755,8 +8432,8 @@ var strict_test_assertions_default = ESLintUtils49.RuleCreator.withoutDocs({
|
|
|
7755
8432
|
});
|
|
7756
8433
|
|
|
7757
8434
|
// src/rules/no-async-callback-in-waitfor.ts
|
|
7758
|
-
import { AST_NODE_TYPES as
|
|
7759
|
-
var no_async_callback_in_waitfor_default =
|
|
8435
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES39, ESLintUtils as ESLintUtils49 } from "@typescript-eslint/utils";
|
|
8436
|
+
var no_async_callback_in_waitfor_default = ESLintUtils49.RuleCreator(
|
|
7760
8437
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7761
8438
|
)({
|
|
7762
8439
|
name: "no-async-callback-in-waitfor",
|
|
@@ -7777,9 +8454,9 @@ var no_async_callback_in_waitfor_default = ESLintUtils50.RuleCreator(
|
|
|
7777
8454
|
}
|
|
7778
8455
|
return {
|
|
7779
8456
|
CallExpression(node) {
|
|
7780
|
-
if (node.callee.type ===
|
|
8457
|
+
if (node.callee.type === AST_NODE_TYPES39.Identifier && node.callee.name === "waitFor") {
|
|
7781
8458
|
const callback = node.arguments[0];
|
|
7782
|
-
if (callback && (callback.type ===
|
|
8459
|
+
if (callback && (callback.type === AST_NODE_TYPES39.ArrowFunctionExpression || callback.type === AST_NODE_TYPES39.FunctionExpression) && callback.async) {
|
|
7783
8460
|
context.report({
|
|
7784
8461
|
node: callback,
|
|
7785
8462
|
messageId: "noAsyncCallbackInWaitFor"
|
|
@@ -7792,7 +8469,7 @@ var no_async_callback_in_waitfor_default = ESLintUtils50.RuleCreator(
|
|
|
7792
8469
|
});
|
|
7793
8470
|
|
|
7794
8471
|
// src/rules/no-hand-rolled-sleep.ts
|
|
7795
|
-
import { AST_NODE_TYPES as
|
|
8472
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES40, ESLintUtils as ESLintUtils50 } from "@typescript-eslint/utils";
|
|
7796
8473
|
var GLOBAL_OBJECTS2 = /* @__PURE__ */ new Set([
|
|
7797
8474
|
"globalThis",
|
|
7798
8475
|
"window",
|
|
@@ -7811,66 +8488,66 @@ function matchesAnyPattern3(filename, patterns) {
|
|
|
7811
8488
|
return false;
|
|
7812
8489
|
}
|
|
7813
8490
|
function isSetTimeoutCallee(callee) {
|
|
7814
|
-
if (callee.type ===
|
|
8491
|
+
if (callee.type === AST_NODE_TYPES40.Identifier) {
|
|
7815
8492
|
return callee.name === "setTimeout";
|
|
7816
8493
|
}
|
|
7817
|
-
return callee.type ===
|
|
8494
|
+
return callee.type === AST_NODE_TYPES40.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES40.Identifier && callee.property.name === "setTimeout" && callee.object.type === AST_NODE_TYPES40.Identifier && GLOBAL_OBJECTS2.has(callee.object.name);
|
|
7818
8495
|
}
|
|
7819
8496
|
function soleCall(fn) {
|
|
7820
|
-
if (fn.body.type !==
|
|
7821
|
-
return fn.body.type ===
|
|
8497
|
+
if (fn.body.type !== AST_NODE_TYPES40.BlockStatement) {
|
|
8498
|
+
return fn.body.type === AST_NODE_TYPES40.CallExpression ? fn.body : null;
|
|
7822
8499
|
}
|
|
7823
8500
|
if (fn.body.body.length !== 1) {
|
|
7824
8501
|
return null;
|
|
7825
8502
|
}
|
|
7826
8503
|
const [only] = fn.body.body;
|
|
7827
|
-
if (only?.type !==
|
|
8504
|
+
if (only?.type !== AST_NODE_TYPES40.ExpressionStatement) {
|
|
7828
8505
|
return null;
|
|
7829
8506
|
}
|
|
7830
|
-
return only.expression.type ===
|
|
8507
|
+
return only.expression.type === AST_NODE_TYPES40.CallExpression ? only.expression : null;
|
|
7831
8508
|
}
|
|
7832
8509
|
function isTimedDelay(delay) {
|
|
7833
8510
|
if (delay === void 0) {
|
|
7834
8511
|
return false;
|
|
7835
8512
|
}
|
|
7836
|
-
if (delay.type ===
|
|
8513
|
+
if (delay.type === AST_NODE_TYPES40.Literal && typeof delay.value === "number") {
|
|
7837
8514
|
return delay.value !== 0;
|
|
7838
8515
|
}
|
|
7839
8516
|
return true;
|
|
7840
8517
|
}
|
|
7841
8518
|
function settlesWithoutValue(callback, name) {
|
|
7842
|
-
if (callback.type ===
|
|
8519
|
+
if (callback.type === AST_NODE_TYPES40.Identifier) {
|
|
7843
8520
|
return callback.name === name;
|
|
7844
8521
|
}
|
|
7845
|
-
if (callback.type !==
|
|
8522
|
+
if (callback.type !== AST_NODE_TYPES40.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES40.FunctionExpression) {
|
|
7846
8523
|
return false;
|
|
7847
8524
|
}
|
|
7848
8525
|
const call = soleCall(callback);
|
|
7849
|
-
return call !== null && call.arguments.length === 0 && call.callee.type ===
|
|
8526
|
+
return call !== null && call.arguments.length === 0 && call.callee.type === AST_NODE_TYPES40.Identifier && call.callee.name === name;
|
|
7850
8527
|
}
|
|
7851
8528
|
function rejectsInCallback(callback, name) {
|
|
7852
|
-
if (callback.type ===
|
|
8529
|
+
if (callback.type === AST_NODE_TYPES40.Identifier) {
|
|
7853
8530
|
return callback.name === name;
|
|
7854
8531
|
}
|
|
7855
|
-
if (callback.type !==
|
|
8532
|
+
if (callback.type !== AST_NODE_TYPES40.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES40.FunctionExpression) {
|
|
7856
8533
|
return false;
|
|
7857
8534
|
}
|
|
7858
8535
|
const call = soleCall(callback);
|
|
7859
|
-
return call !== null && call.callee.type ===
|
|
8536
|
+
return call !== null && call.callee.type === AST_NODE_TYPES40.Identifier && call.callee.name === name;
|
|
7860
8537
|
}
|
|
7861
8538
|
function parameterName(fn, index) {
|
|
7862
8539
|
const parameter = fn.params[index];
|
|
7863
|
-
return parameter?.type ===
|
|
8540
|
+
return parameter?.type === AST_NODE_TYPES40.Identifier ? parameter.name : null;
|
|
7864
8541
|
}
|
|
7865
8542
|
function isRaceArm(node) {
|
|
7866
8543
|
const array = node.parent;
|
|
7867
|
-
if (array?.type !==
|
|
8544
|
+
if (array?.type !== AST_NODE_TYPES40.ArrayExpression) {
|
|
7868
8545
|
return false;
|
|
7869
8546
|
}
|
|
7870
8547
|
const call = array.parent;
|
|
7871
|
-
return call?.type ===
|
|
8548
|
+
return call?.type === AST_NODE_TYPES40.CallExpression && call.arguments[0] === array && call.callee.type === AST_NODE_TYPES40.MemberExpression && !call.callee.computed && call.callee.object.type === AST_NODE_TYPES40.Identifier && call.callee.object.name === "Promise" && call.callee.property.type === AST_NODE_TYPES40.Identifier && RACE_METHODS.has(call.callee.property.name);
|
|
7872
8549
|
}
|
|
7873
|
-
var no_hand_rolled_sleep_default =
|
|
8550
|
+
var no_hand_rolled_sleep_default = ESLintUtils50.RuleCreator(
|
|
7874
8551
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7875
8552
|
)({
|
|
7876
8553
|
name: "no-hand-rolled-sleep",
|
|
@@ -7918,10 +8595,10 @@ var no_hand_rolled_sleep_default = ESLintUtils51.RuleCreator(
|
|
|
7918
8595
|
}
|
|
7919
8596
|
const program = sourceCode.ast;
|
|
7920
8597
|
for (const statement of program.body) {
|
|
7921
|
-
if (statement.type ===
|
|
8598
|
+
if (statement.type === AST_NODE_TYPES40.ExpressionStatement && statement.expression.type === AST_NODE_TYPES40.Literal && statement.expression.value === "use client") {
|
|
7922
8599
|
return true;
|
|
7923
8600
|
}
|
|
7924
|
-
if (statement.type ===
|
|
8601
|
+
if (statement.type === AST_NODE_TYPES40.ImportDeclaration && typeof statement.source.value === "string" && CLIENT_ONLY_MODULES.test(statement.source.value)) {
|
|
7925
8602
|
return true;
|
|
7926
8603
|
}
|
|
7927
8604
|
}
|
|
@@ -7937,11 +8614,11 @@ var no_hand_rolled_sleep_default = ESLintUtils51.RuleCreator(
|
|
|
7937
8614
|
};
|
|
7938
8615
|
return {
|
|
7939
8616
|
NewExpression(node) {
|
|
7940
|
-
if (node.callee.type !==
|
|
8617
|
+
if (node.callee.type !== AST_NODE_TYPES40.Identifier || node.callee.name !== "Promise") {
|
|
7941
8618
|
return;
|
|
7942
8619
|
}
|
|
7943
8620
|
const executor = node.arguments[0];
|
|
7944
|
-
if (executor?.type !==
|
|
8621
|
+
if (executor?.type !== AST_NODE_TYPES40.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES40.FunctionExpression) {
|
|
7945
8622
|
return;
|
|
7946
8623
|
}
|
|
7947
8624
|
const call = soleCall(executor);
|
|
@@ -7968,43 +8645,8 @@ var no_hand_rolled_sleep_default = ESLintUtils51.RuleCreator(
|
|
|
7968
8645
|
}
|
|
7969
8646
|
});
|
|
7970
8647
|
|
|
7971
|
-
// src/rules/prefer-setup-file-mocks.ts
|
|
7972
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES39, ESLintUtils as ESLintUtils52 } from "@typescript-eslint/utils";
|
|
7973
|
-
var prefer_setup_file_mocks_default = ESLintUtils52.RuleCreator(
|
|
7974
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7975
|
-
)({
|
|
7976
|
-
name: "prefer-setup-file-mocks",
|
|
7977
|
-
meta: {
|
|
7978
|
-
type: "suggestion",
|
|
7979
|
-
docs: {
|
|
7980
|
-
description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
|
|
7981
|
-
},
|
|
7982
|
-
schema: [],
|
|
7983
|
-
messages: {
|
|
7984
|
-
preferSetupFileMocks: "Define module mocks in a setup file (e.g. vitest.setup.ts) instead of using vi.mock or jest.mock directly in test files."
|
|
7985
|
-
}
|
|
7986
|
-
},
|
|
7987
|
-
defaultOptions: [],
|
|
7988
|
-
create(context) {
|
|
7989
|
-
if (!isTestFile(context.filename)) {
|
|
7990
|
-
return {};
|
|
7991
|
-
}
|
|
7992
|
-
return {
|
|
7993
|
-
CallExpression(node) {
|
|
7994
|
-
if (node.callee.type === AST_NODE_TYPES39.MemberExpression && node.callee.object.type === AST_NODE_TYPES39.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === AST_NODE_TYPES39.Identifier && node.callee.property.name === "mock") {
|
|
7995
|
-
context.report({
|
|
7996
|
-
node,
|
|
7997
|
-
messageId: "preferSetupFileMocks"
|
|
7998
|
-
});
|
|
7999
|
-
}
|
|
8000
|
-
}
|
|
8001
|
-
};
|
|
8002
|
-
}
|
|
8003
|
-
});
|
|
8004
|
-
|
|
8005
8648
|
// src/index.ts
|
|
8006
8649
|
var rules = {
|
|
8007
|
-
"ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
|
|
8008
8650
|
"enforce-file-structure": enforce_file_structure_default,
|
|
8009
8651
|
"no-client-side-data-fetching": no_client_side_data_fetching_default,
|
|
8010
8652
|
"no-comment-cruft": no_comment_cruft_default,
|
|
@@ -8049,18 +8691,17 @@ var rules = {
|
|
|
8049
8691
|
"jsdoc-restates-signature": jsdoc_restates_signature_default,
|
|
8050
8692
|
"no-restated-comment": no_restated_comment_default,
|
|
8051
8693
|
"trailing-value-narration": trailing_value_narration_default,
|
|
8694
|
+
"no-type-member-comment-wall": no_type_member_comment_wall_default,
|
|
8052
8695
|
"no-tautological-expect": no_tautological_expect_default,
|
|
8053
8696
|
"require-interface-for-injected-service": require_interface_for_injected_service_default,
|
|
8054
8697
|
"strict-test-assertions": strict_test_assertions_default,
|
|
8055
8698
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
8056
|
-
"no-
|
|
8057
|
-
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
|
|
8058
|
-
"prefer-setup-file-mocks": prefer_setup_file_mocks_default
|
|
8699
|
+
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default
|
|
8059
8700
|
};
|
|
8060
8701
|
var plugin = {
|
|
8061
8702
|
meta: {
|
|
8062
8703
|
name: "@sarj/eslint-plugin",
|
|
8063
|
-
version: "
|
|
8704
|
+
version: "5.1.0"
|
|
8064
8705
|
},
|
|
8065
8706
|
rules,
|
|
8066
8707
|
configs: {
|
|
@@ -8070,7 +8711,6 @@ var plugin = {
|
|
|
8070
8711
|
"@sarj/zod-naming-convention": "warn",
|
|
8071
8712
|
"@sarj/require-assert-never": "error",
|
|
8072
8713
|
"@sarj/require-zod-form-validation": "error",
|
|
8073
|
-
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
8074
8714
|
"@sarj/enforce-file-structure": "warn",
|
|
8075
8715
|
"@sarj/no-client-side-data-fetching": "warn",
|
|
8076
8716
|
"@sarj/prefer-server-actions": "warn",
|
|
@@ -8141,6 +8781,14 @@ var plugin = {
|
|
|
8141
8781
|
"@sarj/no-restated-comment": "warn",
|
|
8142
8782
|
"@sarj/jsdoc-restates-signature": "warn",
|
|
8143
8783
|
"@sarj/trailing-value-narration": "warn",
|
|
8784
|
+
// The VOLUME arm of the same family (2026-07). Its siblings judge one
|
|
8785
|
+
// comment at a time and can only condemn one that adds nothing; this
|
|
8786
|
+
// one judges a TYPE, so it can report ten rows that each add a word.
|
|
8787
|
+
// 33 OSS TS repos / 46,861 files: 22 findings, all read, 0 false; zero
|
|
8788
|
+
// across ten first-party repos, where the generated-file sniff alone
|
|
8789
|
+
// removed 321 of the 407 raw hits. Measurements and the six false
|
|
8790
|
+
// positives that shaped the guards: docs/rules/no-type-member-comment-wall.md
|
|
8791
|
+
"@sarj/no-type-member-comment-wall": "warn",
|
|
8144
8792
|
// The TS half of SARJ057 (2026-07). Python has caught the
|
|
8145
8793
|
// assertion-FREE test since 0.15.0 (SARJ043) and had no TS
|
|
8146
8794
|
// counterpart, which is how `expect(true).toBe(true); // placeholder`
|
|
@@ -8155,9 +8803,7 @@ var plugin = {
|
|
|
8155
8803
|
// port, 29 fire, 28 of them true positives.
|
|
8156
8804
|
"@sarj/require-interface-for-injected-service": "warn",
|
|
8157
8805
|
"@sarj/prefer-non-nullable-collection": "warn",
|
|
8158
|
-
"@sarj/no-
|
|
8159
|
-
"@sarj/no-async-callback-in-waitfor": "warn",
|
|
8160
|
-
"@sarj/prefer-setup-file-mocks": "warn"
|
|
8806
|
+
"@sarj/no-async-callback-in-waitfor": "warn"
|
|
8161
8807
|
}
|
|
8162
8808
|
},
|
|
8163
8809
|
strict: {
|
|
@@ -8166,7 +8812,6 @@ var plugin = {
|
|
|
8166
8812
|
"@sarj/zod-naming-convention": "error",
|
|
8167
8813
|
"@sarj/require-assert-never": "error",
|
|
8168
8814
|
"@sarj/require-zod-form-validation": "error",
|
|
8169
|
-
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
8170
8815
|
"@sarj/enforce-file-structure": "error",
|
|
8171
8816
|
"@sarj/no-raw-env": "error",
|
|
8172
8817
|
"@sarj/no-enum": "error",
|
|
@@ -8234,6 +8879,7 @@ var plugin = {
|
|
|
8234
8879
|
"@sarj/no-restated-comment": "error",
|
|
8235
8880
|
"@sarj/jsdoc-restates-signature": "error",
|
|
8236
8881
|
"@sarj/trailing-value-narration": "error",
|
|
8882
|
+
"@sarj/no-type-member-comment-wall": "error",
|
|
8237
8883
|
// TS half of SARJ057 — see the `recommended` block for the measurement.
|
|
8238
8884
|
"@sarj/no-tautological-expect": "error",
|
|
8239
8885
|
// Substitutability: the TS sibling of the Python `prefer-real-store-in-tests`
|
|
@@ -8241,9 +8887,7 @@ var plugin = {
|
|
|
8241
8887
|
// corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
|
|
8242
8888
|
"@sarj/require-interface-for-injected-service": "error",
|
|
8243
8889
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
8244
|
-
"@sarj/no-
|
|
8245
|
-
"@sarj/no-async-callback-in-waitfor": "error",
|
|
8246
|
-
"@sarj/prefer-setup-file-mocks": "error"
|
|
8890
|
+
"@sarj/no-async-callback-in-waitfor": "error"
|
|
8247
8891
|
}
|
|
8248
8892
|
}
|
|
8249
8893
|
}
|