@sarj/eslint-plugin 4.1.0 → 5.0.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 +27 -3
- package/dist/index.cjs +1503 -644
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -26
- package/dist/index.d.ts +60 -26
- package/dist/index.js +1709 -847
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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$)/;
|
|
@@ -24,43 +24,7 @@ function isScriptFile(filename) {
|
|
|
24
24
|
return SCRIPT_FILE_RE.test(filename);
|
|
25
25
|
}
|
|
26
26
|
|
|
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
27
|
// src/rules/enforce-file-structure.ts
|
|
63
|
-
import { ESLintUtils as ESLintUtils2, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
64
28
|
var classifyStatement = (statement) => {
|
|
65
29
|
switch (statement.type) {
|
|
66
30
|
case AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -80,7 +44,7 @@ var isUseServerDirective = (statement) => {
|
|
|
80
44
|
if (expr.type !== AST_NODE_TYPES.Literal) return false;
|
|
81
45
|
return expr.value === "use server";
|
|
82
46
|
};
|
|
83
|
-
var enforce_file_structure_default =
|
|
47
|
+
var enforce_file_structure_default = ESLintUtils.RuleCreator(
|
|
84
48
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
85
49
|
)({
|
|
86
50
|
name: "enforce-file-structure",
|
|
@@ -142,7 +106,7 @@ var enforce_file_structure_default = ESLintUtils2.RuleCreator(
|
|
|
142
106
|
// src/rules/no-client-side-data-fetching.ts
|
|
143
107
|
import {
|
|
144
108
|
AST_NODE_TYPES as AST_NODE_TYPES2,
|
|
145
|
-
ESLintUtils as
|
|
109
|
+
ESLintUtils as ESLintUtils2
|
|
146
110
|
} from "@typescript-eslint/utils";
|
|
147
111
|
var FETCH_LIBS = /* @__PURE__ */ new Set(["axios", "ky", "superagent"]);
|
|
148
112
|
var HTTP_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -240,7 +204,7 @@ function isAnalyticsCall(node) {
|
|
|
240
204
|
if (url === "") return false;
|
|
241
205
|
return url.split(/[/.]/).some((segment) => ANALYTICS_SEGMENTS.has(segment));
|
|
242
206
|
}
|
|
243
|
-
var no_client_side_data_fetching_default =
|
|
207
|
+
var no_client_side_data_fetching_default = ESLintUtils2.RuleCreator(
|
|
244
208
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
245
209
|
)({
|
|
246
210
|
name: "no-client-side-data-fetching",
|
|
@@ -278,7 +242,7 @@ var no_client_side_data_fetching_default = ESLintUtils3.RuleCreator(
|
|
|
278
242
|
});
|
|
279
243
|
|
|
280
244
|
// src/rules/no-comment-cruft.ts
|
|
281
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as
|
|
245
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
|
|
282
246
|
|
|
283
247
|
// src/rules/_comments.ts
|
|
284
248
|
import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
|
|
@@ -542,7 +506,8 @@ var DUMMY_TRANSLATION_RE = /^(?:increment|return|returns|get|gets|set\b(?! up\b)
|
|
|
542
506
|
var DIAGRAM_ARROW_RE = /[-=~]{2,}>|<[-=~]{2,}/;
|
|
543
507
|
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
508
|
var CODE_TAIL_RE = /[;{}()]\s*$|=>\s*$|,\s*$/;
|
|
545
|
-
var
|
|
509
|
+
var ASSIGN_RE = /^[A-Za-z_$][\w.$[\]]*\s*(?:=(?![=>])|\+=|-=|\*=)\s*\S.*[;)}\]]\s*$/;
|
|
510
|
+
var CALL_RE = /^[A-Za-z_$][\w.$]*\([^)]*\)\s*;?\s*$/;
|
|
546
511
|
var PSEUDOCODE_RE = /%\w+%|\[opt\]|(?:^|\s)<[A-Za-z]\w*>|…|\.\.\./;
|
|
547
512
|
function stripCommentMarker(line) {
|
|
548
513
|
return line.replace(/^\s*\/{1,2}/, "").replace(/^\s*\*+/, "").trim();
|
|
@@ -556,11 +521,12 @@ function isBanner(text) {
|
|
|
556
521
|
if (BANNER_FULL_RE.test(t) || isRegionMarker(t)) return true;
|
|
557
522
|
return BANNER_RUN_RE.test(t) && !DIAGRAM_ARROW_RE.test(t);
|
|
558
523
|
}
|
|
559
|
-
function looksLikeCode(text) {
|
|
524
|
+
function looksLikeCode(text, allowCall = true) {
|
|
560
525
|
const t = text.trim();
|
|
561
526
|
if (!t) return false;
|
|
562
527
|
if (CODE_KEYWORD_RE.test(t) && CODE_TAIL_RE.test(t)) return true;
|
|
563
|
-
|
|
528
|
+
if (ASSIGN_RE.test(t)) return true;
|
|
529
|
+
return allowCall && CALL_RE.test(t);
|
|
564
530
|
}
|
|
565
531
|
function hasPseudocode(text) {
|
|
566
532
|
return PSEUDOCODE_RE.test(text);
|
|
@@ -578,20 +544,24 @@ function isProse(text) {
|
|
|
578
544
|
}
|
|
579
545
|
return false;
|
|
580
546
|
}
|
|
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;
|
|
547
|
+
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;
|
|
548
|
+
function restatesWholeStatement(body, statement) {
|
|
549
|
+
return statement !== null && restatesStatementHead(body, statement.replaceAll("(", " "));
|
|
550
|
+
}
|
|
582
551
|
function isRedundantNarration(body, statementBelow, standalone, isolatedEnumeration, nested) {
|
|
583
552
|
const t = body.trim();
|
|
584
553
|
if (!t || looksLikeCode(t) || hasPseudocode(t)) return false;
|
|
585
554
|
if (standalone) {
|
|
586
|
-
|
|
587
|
-
if (
|
|
555
|
+
const justified = JUSTIFICATION_RE.test(t);
|
|
556
|
+
if (STEP_NARRATION_RE.test(t) && !justified) return true;
|
|
557
|
+
if (META_COMMENTARY_RE.test(t) && !justified) return true;
|
|
588
558
|
if (HELPER_OPENER_RE.test(t) || LETS_RE.test(t)) return true;
|
|
589
559
|
const words = t.split(/\s+/);
|
|
590
|
-
if (words.length <= 4 && DUMMY_TRANSLATION_RE.test(t) && !/[():=]/.test(t)) {
|
|
560
|
+
if (words.length > 1 && words.length <= 4 && DUMMY_TRANSLATION_RE.test(t) && !/[():=]/.test(t)) {
|
|
591
561
|
const lowerT = t.toLowerCase();
|
|
592
562
|
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
|
-
|
|
563
|
+
if (!rationaleWords.some((w) => lowerT.includes(w)) && restatesWholeStatement(t, statementBelow)) {
|
|
564
|
+
return true;
|
|
595
565
|
}
|
|
596
566
|
}
|
|
597
567
|
if (!nested && isSectionLabel(t)) return true;
|
|
@@ -608,6 +578,10 @@ var STATEMENT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
|
608
578
|
AST_NODE_TYPES4.TSModuleBlock,
|
|
609
579
|
AST_NODE_TYPES4.TSInterfaceBody
|
|
610
580
|
]);
|
|
581
|
+
var TYPE_MEMBER_CONTAINERS = /* @__PURE__ */ new Set([
|
|
582
|
+
AST_NODE_TYPES4.TSInterfaceBody,
|
|
583
|
+
AST_NODE_TYPES4.TSTypeLiteral
|
|
584
|
+
]);
|
|
611
585
|
function runCitesAReference(comments, index) {
|
|
612
586
|
for (let i = index; i >= 0; i--) {
|
|
613
587
|
if (i < index && !areAdjacentLineComments(comments[i], comments[i + 1])) break;
|
|
@@ -635,10 +609,10 @@ function hasIllustrationLeadInAbove(comments, index) {
|
|
|
635
609
|
}
|
|
636
610
|
return false;
|
|
637
611
|
}
|
|
638
|
-
function hasCommentedOutCode(texts, precedingProse) {
|
|
612
|
+
function hasCommentedOutCode(texts, precedingProse, allowCall) {
|
|
639
613
|
for (let i = 0; i < texts.length; i++) {
|
|
640
614
|
const line = texts[i];
|
|
641
|
-
if (line === void 0 || !looksLikeCode(line) || hasPseudocode(line)) {
|
|
615
|
+
if (line === void 0 || !looksLikeCode(line, allowCall) || hasPseudocode(line)) {
|
|
642
616
|
continue;
|
|
643
617
|
}
|
|
644
618
|
const prev = i > 0 ? texts[i - 1] : void 0;
|
|
@@ -647,7 +621,7 @@ function hasCommentedOutCode(texts, precedingProse) {
|
|
|
647
621
|
}
|
|
648
622
|
return false;
|
|
649
623
|
}
|
|
650
|
-
var no_comment_cruft_default =
|
|
624
|
+
var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
651
625
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
652
626
|
)({
|
|
653
627
|
name: "no-comment-cruft",
|
|
@@ -732,7 +706,9 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
732
706
|
}
|
|
733
707
|
const prev = comments[i - 1];
|
|
734
708
|
const precedingProse = prev !== void 0 && prev.type === "Line" && prev.loc.end.line === comment.loc.start.line - 1 && isProse(stripCommentMarker(prev.value));
|
|
735
|
-
|
|
709
|
+
const container = sourceCode.getNodeByRangeIndex(comment.range[0]);
|
|
710
|
+
const inTypeMembers = container !== null && TYPE_MEMBER_CONTAINERS.has(container.type);
|
|
711
|
+
if (hasCommentedOutCode(texts, precedingProse, !inTypeMembers) && !hasIllustrationLeadInAbove(comments, i)) {
|
|
736
712
|
context.report({ node: comment, messageId: "commentedOutCode" });
|
|
737
713
|
continue;
|
|
738
714
|
}
|
|
@@ -740,7 +716,6 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
740
716
|
const body = texts[0];
|
|
741
717
|
const statement = restatableStatementBelow(comment, sourceCode);
|
|
742
718
|
const standalone = !isInsideCommentRun(comments, i);
|
|
743
|
-
const container = sourceCode.getNodeByRangeIndex(comment.range[0]);
|
|
744
719
|
const nested = container !== null && !STATEMENT_CONTAINERS.has(container.type);
|
|
745
720
|
if (body !== void 0 && !runCitesAReference(comments, i) && isRedundantNarration(body, statement, standalone, enumerated.length === 1, nested)) {
|
|
746
721
|
context.report({ node: comment, messageId: "redundantNarration" });
|
|
@@ -754,7 +729,7 @@ var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
|
754
729
|
});
|
|
755
730
|
|
|
756
731
|
// src/rules/no-enum.ts
|
|
757
|
-
import { ESLintUtils as
|
|
732
|
+
import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
758
733
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
759
734
|
/[\\/]generated[\\/]/,
|
|
760
735
|
/[\\/]openapi-gen[\\/]/,
|
|
@@ -774,7 +749,7 @@ function hasGeneratedMarker(sourceText) {
|
|
|
774
749
|
const head = sourceText.slice(0, 1024);
|
|
775
750
|
return /@generated\b/.test(head);
|
|
776
751
|
}
|
|
777
|
-
var no_enum_default =
|
|
752
|
+
var no_enum_default = ESLintUtils4.RuleCreator(
|
|
778
753
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
779
754
|
)({
|
|
780
755
|
name: "no-enum",
|
|
@@ -825,7 +800,7 @@ var no_enum_default = ESLintUtils5.RuleCreator(
|
|
|
825
800
|
});
|
|
826
801
|
|
|
827
802
|
// src/rules/no-insecure-random-id.ts
|
|
828
|
-
import { ESLintUtils as
|
|
803
|
+
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
829
804
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
830
805
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
831
806
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -966,7 +941,7 @@ function isConcatenatedIntoPathOrDomId(node) {
|
|
|
966
941
|
collectStaticStringParts(top, parts);
|
|
967
942
|
return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
|
|
968
943
|
}
|
|
969
|
-
var no_insecure_random_id_default =
|
|
944
|
+
var no_insecure_random_id_default = ESLintUtils5.RuleCreator(
|
|
970
945
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
971
946
|
)({
|
|
972
947
|
name: "no-insecure-random-id",
|
|
@@ -1010,7 +985,7 @@ var no_insecure_random_id_default = ESLintUtils6.RuleCreator(
|
|
|
1010
985
|
});
|
|
1011
986
|
|
|
1012
987
|
// src/rules/no-json-stringify-error.ts
|
|
1013
|
-
import { ESLintUtils as
|
|
988
|
+
import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
|
|
1014
989
|
var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
|
|
1015
990
|
var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
|
|
1016
991
|
var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
|
|
@@ -1144,7 +1119,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
1144
1119
|
function isJsonStringify(callee) {
|
|
1145
1120
|
return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
|
|
1146
1121
|
}
|
|
1147
|
-
var no_json_stringify_error_default =
|
|
1122
|
+
var no_json_stringify_error_default = ESLintUtils6.RuleCreator(
|
|
1148
1123
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1149
1124
|
)({
|
|
1150
1125
|
name: "no-json-stringify-error",
|
|
@@ -1194,7 +1169,7 @@ var no_json_stringify_error_default = ESLintUtils7.RuleCreator(
|
|
|
1194
1169
|
});
|
|
1195
1170
|
|
|
1196
1171
|
// src/rules/no-log-only-catch.ts
|
|
1197
|
-
import { ESLintUtils as
|
|
1172
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES5, ASTUtils, ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
|
|
1198
1173
|
|
|
1199
1174
|
// src/rules/_logging.ts
|
|
1200
1175
|
import "@typescript-eslint/utils";
|
|
@@ -1299,12 +1274,92 @@ function createLogMatcher(options = {}) {
|
|
|
1299
1274
|
}
|
|
1300
1275
|
|
|
1301
1276
|
// src/rules/no-log-only-catch.ts
|
|
1302
|
-
var
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1277
|
+
var BENCHMARK_DIR_RE = /(?:^|[\\/])benchmarks?[\\/]/;
|
|
1278
|
+
var SINGLE_STATEMENT_HOSTS = /* @__PURE__ */ new Set([
|
|
1279
|
+
AST_NODE_TYPES5.DoWhileStatement,
|
|
1280
|
+
AST_NODE_TYPES5.ForInStatement,
|
|
1281
|
+
AST_NODE_TYPES5.ForOfStatement,
|
|
1282
|
+
AST_NODE_TYPES5.ForStatement,
|
|
1283
|
+
AST_NODE_TYPES5.IfStatement,
|
|
1284
|
+
AST_NODE_TYPES5.WhileStatement
|
|
1285
|
+
]);
|
|
1286
|
+
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
1287
|
+
AST_NODE_TYPES5.ArrowFunctionExpression,
|
|
1288
|
+
AST_NODE_TYPES5.FunctionDeclaration,
|
|
1289
|
+
AST_NODE_TYPES5.FunctionExpression
|
|
1290
|
+
]);
|
|
1291
|
+
function statementSlot(node) {
|
|
1292
|
+
const parent = node.parent;
|
|
1293
|
+
if (parent === void 0) return null;
|
|
1294
|
+
let list;
|
|
1295
|
+
switch (parent.type) {
|
|
1296
|
+
case AST_NODE_TYPES5.BlockStatement:
|
|
1297
|
+
case AST_NODE_TYPES5.Program:
|
|
1298
|
+
case AST_NODE_TYPES5.StaticBlock:
|
|
1299
|
+
list = parent.body;
|
|
1300
|
+
break;
|
|
1301
|
+
case AST_NODE_TYPES5.SwitchCase:
|
|
1302
|
+
list = parent.consequent;
|
|
1303
|
+
break;
|
|
1304
|
+
default:
|
|
1305
|
+
return null;
|
|
1306
|
+
}
|
|
1307
|
+
const index = list.indexOf(node);
|
|
1308
|
+
return index === -1 ? null : { list, index };
|
|
1309
|
+
}
|
|
1310
|
+
function hasFollowingStatement(node) {
|
|
1311
|
+
for (let current = node; current !== void 0 && !FUNCTION_TYPES.has(current.type); current = current.parent) {
|
|
1312
|
+
const slot = statementSlot(current);
|
|
1313
|
+
if (slot !== null && slot.index < slot.list.length - 1) return true;
|
|
1314
|
+
}
|
|
1315
|
+
return false;
|
|
1316
|
+
}
|
|
1317
|
+
function fallbackFollowsTry(tryStatement) {
|
|
1318
|
+
const body = tryStatement.block.body;
|
|
1319
|
+
const last = body.at(-1);
|
|
1320
|
+
return last?.type === AST_NODE_TYPES5.ReturnStatement && hasFollowingStatement(tryStatement);
|
|
1321
|
+
}
|
|
1322
|
+
function isSeedValue(node) {
|
|
1323
|
+
const inner = node.type === AST_NODE_TYPES5.TSAsExpression ? node.expression : node;
|
|
1324
|
+
switch (inner.type) {
|
|
1325
|
+
case AST_NODE_TYPES5.Literal:
|
|
1326
|
+
return true;
|
|
1327
|
+
case AST_NODE_TYPES5.Identifier:
|
|
1328
|
+
return inner.name === "undefined";
|
|
1329
|
+
case AST_NODE_TYPES5.UnaryExpression:
|
|
1330
|
+
return inner.argument.type === AST_NODE_TYPES5.Literal;
|
|
1331
|
+
case AST_NODE_TYPES5.ArrayExpression:
|
|
1332
|
+
return inner.elements.length === 0;
|
|
1333
|
+
case AST_NODE_TYPES5.ObjectExpression:
|
|
1334
|
+
return inner.properties.length === 0;
|
|
1335
|
+
default:
|
|
1336
|
+
return false;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
function seededFallbackHandled(tryStatement, scope) {
|
|
1340
|
+
const slot = statementSlot(tryStatement);
|
|
1341
|
+
if (slot === null || slot.index === 0) return false;
|
|
1342
|
+
const previous = slot.list[slot.index - 1];
|
|
1343
|
+
if (previous?.type !== AST_NODE_TYPES5.VariableDeclaration || previous.kind === "const") {
|
|
1344
|
+
return false;
|
|
1345
|
+
}
|
|
1346
|
+
const declarator = previous.declarations[0];
|
|
1347
|
+
if (previous.declarations.length !== 1 || declarator === void 0) return false;
|
|
1348
|
+
if (declarator.id.type !== AST_NODE_TYPES5.Identifier) return false;
|
|
1349
|
+
if (declarator.init == null || !isSeedValue(declarator.init)) return false;
|
|
1350
|
+
const variable = ASTUtils.findVariable(scope, declarator.id.name);
|
|
1351
|
+
if (variable === null) return false;
|
|
1352
|
+
const [tryStart, tryEnd] = tryStatement.block.range;
|
|
1353
|
+
let writtenInTry = false;
|
|
1354
|
+
let readAfter = false;
|
|
1355
|
+
for (const reference of variable.references) {
|
|
1356
|
+
const [start] = reference.identifier.range;
|
|
1357
|
+
if (reference.isWrite() && start >= tryStart && start < tryEnd) writtenInTry = true;
|
|
1358
|
+
if (reference.isRead() && start >= tryStatement.range[1]) readAfter = true;
|
|
1359
|
+
}
|
|
1360
|
+
return writtenInTry && readAfter;
|
|
1361
|
+
}
|
|
1362
|
+
var no_log_only_catch_default = ESLintUtils7.RuleCreator(
|
|
1308
1363
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1309
1364
|
)({
|
|
1310
1365
|
name: "no-log-only-catch",
|
|
@@ -1329,26 +1384,40 @@ var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
|
1329
1384
|
create(context, [loggingOptions]) {
|
|
1330
1385
|
const matcher = createLogMatcher(loggingOptions);
|
|
1331
1386
|
const filename = context.filename;
|
|
1387
|
+
const sourceCode = context.sourceCode;
|
|
1332
1388
|
function isLoggingCallStatement(statement) {
|
|
1333
1389
|
if (statement.type !== "ExpressionStatement") {
|
|
1334
1390
|
return false;
|
|
1335
1391
|
}
|
|
1336
1392
|
return matcher.isLoggingCall(statement.expression);
|
|
1337
1393
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1394
|
+
function hasCommentDirectlyAbove(node) {
|
|
1395
|
+
const above = sourceCode.getCommentsBefore(node).at(-1);
|
|
1396
|
+
return above !== void 0 && above.loc.end.line === node.loc.start.line - 1;
|
|
1397
|
+
}
|
|
1398
|
+
function hasAdjacentRationale(node) {
|
|
1399
|
+
const tryStatement = node.parent;
|
|
1400
|
+
if (hasCommentDirectlyAbove(tryStatement) || hasCommentDirectlyAbove(node)) return true;
|
|
1401
|
+
const block = tryStatement.parent;
|
|
1402
|
+
if (block?.type !== AST_NODE_TYPES5.BlockStatement || block.body.length !== 1 || block.parent === void 0 || !SINGLE_STATEMENT_HOSTS.has(block.parent.type)) {
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
return hasCommentDirectlyAbove(block.parent);
|
|
1406
|
+
}
|
|
1407
|
+
if (isTestFile(filename) || BENCHMARK_DIR_RE.test(filename.replaceAll("\\", "/"))) {
|
|
1342
1408
|
return {};
|
|
1343
1409
|
}
|
|
1344
1410
|
return {
|
|
1345
1411
|
CatchClause(node) {
|
|
1346
1412
|
const statements = node.body.body;
|
|
1347
|
-
const isDocumented =
|
|
1413
|
+
const isDocumented = sourceCode.getCommentsInside(node.body).length > 0 || hasAdjacentRationale(node);
|
|
1348
1414
|
if (statements.length === 0) {
|
|
1349
1415
|
if (isDocumented) {
|
|
1350
1416
|
return;
|
|
1351
1417
|
}
|
|
1418
|
+
if (fallbackFollowsTry(node.parent) || seededFallbackHandled(node.parent, sourceCode.getScope(node))) {
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1352
1421
|
context.report({ node, messageId: "emptyCatch" });
|
|
1353
1422
|
return;
|
|
1354
1423
|
}
|
|
@@ -1367,11 +1436,12 @@ var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
|
1367
1436
|
});
|
|
1368
1437
|
|
|
1369
1438
|
// src/rules/no-raw-env.ts
|
|
1370
|
-
import { ESLintUtils as
|
|
1439
|
+
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
1371
1440
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1372
1441
|
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1442
|
+
var ENV_VALIDATION_MARKER_RE = /\bcreateEnv\s*\(|\bz\.object\s*\(|\.(?:safeParse|parse)\s*\(/;
|
|
1373
1443
|
function isValidatedEnvBoundary(filename, sourceText) {
|
|
1374
|
-
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) &&
|
|
1444
|
+
return ENV_BOUNDARY_FILE_RE.test(filename.replaceAll("\\", "/")) && ENV_VALIDATION_MARKER_RE.test(sourceText);
|
|
1375
1445
|
}
|
|
1376
1446
|
function isProcessEnv(node) {
|
|
1377
1447
|
return !node.computed && node.object.type === "Identifier" && node.object.name === "process" && node.property.type === "Identifier" && node.property.name === "env";
|
|
@@ -1386,9 +1456,15 @@ var BUILD_TIME_CONSTANTS = /* @__PURE__ */ new Set([
|
|
|
1386
1456
|
"PROD",
|
|
1387
1457
|
"SSR"
|
|
1388
1458
|
]);
|
|
1389
|
-
|
|
1459
|
+
var PLATFORM_MARKERS = /* @__PURE__ */ new Set([
|
|
1460
|
+
"NEXT_RUNTIME",
|
|
1461
|
+
"VERCEL",
|
|
1462
|
+
"VERCEL_ENV",
|
|
1463
|
+
"CI"
|
|
1464
|
+
]);
|
|
1465
|
+
function isExemptVariableAccess(node) {
|
|
1390
1466
|
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);
|
|
1467
|
+
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
1468
|
}
|
|
1393
1469
|
function isWriteTarget(node) {
|
|
1394
1470
|
const access = node.parent.type === "MemberExpression" && node.parent.object === node ? node.parent : node;
|
|
@@ -1405,7 +1481,7 @@ function isWholeEnvSpread(node) {
|
|
|
1405
1481
|
const parent = node.parent;
|
|
1406
1482
|
return parent.type === "SpreadElement" && parent.argument === node;
|
|
1407
1483
|
}
|
|
1408
|
-
var no_raw_env_default =
|
|
1484
|
+
var no_raw_env_default = ESLintUtils8.RuleCreator(
|
|
1409
1485
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1410
1486
|
)({
|
|
1411
1487
|
name: "no-raw-env",
|
|
@@ -1427,7 +1503,7 @@ var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
|
1427
1503
|
}
|
|
1428
1504
|
return {
|
|
1429
1505
|
MemberExpression(node) {
|
|
1430
|
-
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !
|
|
1506
|
+
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !isExemptVariableAccess(node) && !isWriteTarget(node) && !isWholeEnvSpread(node)) {
|
|
1431
1507
|
context.report({
|
|
1432
1508
|
node,
|
|
1433
1509
|
messageId: "noRawEnv"
|
|
@@ -1440,14 +1516,14 @@ var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
|
1440
1516
|
|
|
1441
1517
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
1442
1518
|
import {
|
|
1443
|
-
ESLintUtils as
|
|
1444
|
-
AST_NODE_TYPES as
|
|
1519
|
+
ESLintUtils as ESLintUtils9,
|
|
1520
|
+
AST_NODE_TYPES as AST_NODE_TYPES6
|
|
1445
1521
|
} from "@typescript-eslint/utils";
|
|
1446
1522
|
function sentinelKind(arg) {
|
|
1447
1523
|
if (arg === null) {
|
|
1448
1524
|
return null;
|
|
1449
1525
|
}
|
|
1450
|
-
if (arg.type ===
|
|
1526
|
+
if (arg.type === AST_NODE_TYPES6.Literal) {
|
|
1451
1527
|
if (arg.value === null) {
|
|
1452
1528
|
return "nullish";
|
|
1453
1529
|
}
|
|
@@ -1459,13 +1535,13 @@ function sentinelKind(arg) {
|
|
|
1459
1535
|
}
|
|
1460
1536
|
return null;
|
|
1461
1537
|
}
|
|
1462
|
-
if (arg.type ===
|
|
1538
|
+
if (arg.type === AST_NODE_TYPES6.Identifier && arg.name === "undefined") {
|
|
1463
1539
|
return "nullish";
|
|
1464
1540
|
}
|
|
1465
|
-
if (arg.type ===
|
|
1541
|
+
if (arg.type === AST_NODE_TYPES6.ArrayExpression) {
|
|
1466
1542
|
return "array";
|
|
1467
1543
|
}
|
|
1468
|
-
if (arg.type ===
|
|
1544
|
+
if (arg.type === AST_NODE_TYPES6.ObjectExpression) {
|
|
1469
1545
|
return "object";
|
|
1470
1546
|
}
|
|
1471
1547
|
return null;
|
|
@@ -1474,25 +1550,25 @@ function isSentinelArgument(arg) {
|
|
|
1474
1550
|
if (arg === null) {
|
|
1475
1551
|
return false;
|
|
1476
1552
|
}
|
|
1477
|
-
if (arg.type ===
|
|
1553
|
+
if (arg.type === AST_NODE_TYPES6.Literal && arg.value === null) {
|
|
1478
1554
|
return true;
|
|
1479
1555
|
}
|
|
1480
|
-
if (arg.type ===
|
|
1556
|
+
if (arg.type === AST_NODE_TYPES6.Literal && arg.value === false) {
|
|
1481
1557
|
return true;
|
|
1482
1558
|
}
|
|
1483
|
-
if (arg.type ===
|
|
1559
|
+
if (arg.type === AST_NODE_TYPES6.Identifier && arg.name === "undefined") {
|
|
1484
1560
|
return true;
|
|
1485
1561
|
}
|
|
1486
|
-
if (arg.type ===
|
|
1562
|
+
if (arg.type === AST_NODE_TYPES6.ArrayExpression && arg.elements.length === 0) {
|
|
1487
1563
|
return true;
|
|
1488
1564
|
}
|
|
1489
|
-
if (arg.type ===
|
|
1565
|
+
if (arg.type === AST_NODE_TYPES6.ObjectExpression && arg.properties.length === 0) {
|
|
1490
1566
|
return true;
|
|
1491
1567
|
}
|
|
1492
1568
|
return false;
|
|
1493
1569
|
}
|
|
1494
1570
|
function isFunctionNode(node) {
|
|
1495
|
-
return node.type ===
|
|
1571
|
+
return node.type === AST_NODE_TYPES6.FunctionDeclaration || node.type === AST_NODE_TYPES6.FunctionExpression || node.type === AST_NODE_TYPES6.ArrowFunctionExpression;
|
|
1496
1572
|
}
|
|
1497
1573
|
function isNode(value) {
|
|
1498
1574
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
@@ -1532,24 +1608,24 @@ function walkWithinScope(node, visit) {
|
|
|
1532
1608
|
function containsThrow(node) {
|
|
1533
1609
|
return walkWithinScope(
|
|
1534
1610
|
node,
|
|
1535
|
-
(current) => current.type ===
|
|
1611
|
+
(current) => current.type === AST_NODE_TYPES6.ThrowStatement
|
|
1536
1612
|
);
|
|
1537
1613
|
}
|
|
1538
1614
|
function bindsName(param, name) {
|
|
1539
1615
|
switch (param.type) {
|
|
1540
|
-
case
|
|
1616
|
+
case AST_NODE_TYPES6.Identifier:
|
|
1541
1617
|
return param.name === name;
|
|
1542
|
-
case
|
|
1618
|
+
case AST_NODE_TYPES6.AssignmentPattern:
|
|
1543
1619
|
return bindsName(param.left, name);
|
|
1544
|
-
case
|
|
1620
|
+
case AST_NODE_TYPES6.RestElement:
|
|
1545
1621
|
return bindsName(param.argument, name);
|
|
1546
|
-
case
|
|
1622
|
+
case AST_NODE_TYPES6.ArrayPattern:
|
|
1547
1623
|
return param.elements.some(
|
|
1548
1624
|
(element) => element !== null && bindsName(element, name)
|
|
1549
1625
|
);
|
|
1550
|
-
case
|
|
1626
|
+
case AST_NODE_TYPES6.ObjectPattern:
|
|
1551
1627
|
return param.properties.some(
|
|
1552
|
-
(property) => property.type ===
|
|
1628
|
+
(property) => property.type === AST_NODE_TYPES6.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
|
|
1553
1629
|
);
|
|
1554
1630
|
default:
|
|
1555
1631
|
return false;
|
|
@@ -1564,7 +1640,7 @@ function subtreeReadsName(node, name) {
|
|
|
1564
1640
|
if (found) {
|
|
1565
1641
|
return;
|
|
1566
1642
|
}
|
|
1567
|
-
if (current.type ===
|
|
1643
|
+
if (current.type === AST_NODE_TYPES6.Identifier && current.name === name) {
|
|
1568
1644
|
found = true;
|
|
1569
1645
|
return;
|
|
1570
1646
|
}
|
|
@@ -1575,10 +1651,10 @@ function subtreeReadsName(node, name) {
|
|
|
1575
1651
|
if (key === "parent") {
|
|
1576
1652
|
continue;
|
|
1577
1653
|
}
|
|
1578
|
-
if (key === "key" && current.type ===
|
|
1654
|
+
if (key === "key" && current.type === AST_NODE_TYPES6.Property && !current.computed) {
|
|
1579
1655
|
continue;
|
|
1580
1656
|
}
|
|
1581
|
-
if (key === "property" && current.type ===
|
|
1657
|
+
if (key === "property" && current.type === AST_NODE_TYPES6.MemberExpression && !current.computed) {
|
|
1582
1658
|
continue;
|
|
1583
1659
|
}
|
|
1584
1660
|
const value = current[key];
|
|
@@ -1611,10 +1687,10 @@ var SAFE_PARSE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
1611
1687
|
"URLPattern"
|
|
1612
1688
|
]);
|
|
1613
1689
|
function isParseShapedNode(node) {
|
|
1614
|
-
if (node.type ===
|
|
1690
|
+
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
1691
|
return node.callee.property.name === "parse";
|
|
1616
1692
|
}
|
|
1617
|
-
if (node.type ===
|
|
1693
|
+
if (node.type === AST_NODE_TYPES6.NewExpression && node.callee.type === AST_NODE_TYPES6.Identifier) {
|
|
1618
1694
|
return SAFE_PARSE_CONSTRUCTORS.has(node.callee.name);
|
|
1619
1695
|
}
|
|
1620
1696
|
return false;
|
|
@@ -1625,10 +1701,10 @@ var BODY_DECODE_METHODS = /* @__PURE__ */ new Set([
|
|
|
1625
1701
|
"arrayBuffer"
|
|
1626
1702
|
]);
|
|
1627
1703
|
function isBodyDecodeNode(node) {
|
|
1628
|
-
return node.type ===
|
|
1704
|
+
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
1705
|
}
|
|
1630
1706
|
function returnsMatching(stmt, predicate) {
|
|
1631
|
-
return stmt.type ===
|
|
1707
|
+
return stmt.type === AST_NODE_TYPES6.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
|
|
1632
1708
|
}
|
|
1633
1709
|
function enclosingReturnTypeNode(node) {
|
|
1634
1710
|
let current = node.parent;
|
|
@@ -1646,11 +1722,11 @@ function enclosingFunctionName(node) {
|
|
|
1646
1722
|
let current = node.parent;
|
|
1647
1723
|
while (current !== void 0 && current !== null) {
|
|
1648
1724
|
if (isFunctionNode(current)) {
|
|
1649
|
-
if ("id" in current && isNode(current.id) && current.id.type ===
|
|
1725
|
+
if ("id" in current && isNode(current.id) && current.id.type === AST_NODE_TYPES6.Identifier) {
|
|
1650
1726
|
return current.id.name;
|
|
1651
1727
|
}
|
|
1652
1728
|
const parent = current.parent;
|
|
1653
|
-
if (parent?.type ===
|
|
1729
|
+
if (parent?.type === AST_NODE_TYPES6.VariableDeclarator && parent.id.type === AST_NODE_TYPES6.Identifier) {
|
|
1654
1730
|
return parent.id.name;
|
|
1655
1731
|
}
|
|
1656
1732
|
return null;
|
|
@@ -1671,10 +1747,10 @@ function isDeclaredBooleanPredicate(catchNode, kind) {
|
|
|
1671
1747
|
return false;
|
|
1672
1748
|
}
|
|
1673
1749
|
let declared = enclosingReturnTypeNode(catchNode);
|
|
1674
|
-
if (declared?.type ===
|
|
1750
|
+
if (declared?.type === AST_NODE_TYPES6.TSTypeReference && declared.typeName.type === AST_NODE_TYPES6.Identifier && declared.typeName.name === "Promise") {
|
|
1675
1751
|
declared = declared.typeArguments?.params[0] ?? null;
|
|
1676
1752
|
}
|
|
1677
|
-
return declared?.type ===
|
|
1753
|
+
return declared?.type === AST_NODE_TYPES6.TSBooleanKeyword;
|
|
1678
1754
|
}
|
|
1679
1755
|
function tryReturnsSafeParse(catchNode) {
|
|
1680
1756
|
const tryBlock = tryBlockOf(catchNode);
|
|
@@ -1690,7 +1766,7 @@ function tryReturnsSafeParse(catchNode) {
|
|
|
1690
1766
|
function enclosingFunctionBody(node) {
|
|
1691
1767
|
let current = node.parent;
|
|
1692
1768
|
while (current !== void 0 && current !== null) {
|
|
1693
|
-
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type ===
|
|
1769
|
+
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === AST_NODE_TYPES6.BlockStatement) {
|
|
1694
1770
|
return current.body;
|
|
1695
1771
|
}
|
|
1696
1772
|
current = current.parent;
|
|
@@ -1703,7 +1779,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
|
|
|
1703
1779
|
return false;
|
|
1704
1780
|
}
|
|
1705
1781
|
return walkWithinScope(functionBody, (current) => {
|
|
1706
|
-
if (current.type !==
|
|
1782
|
+
if (current.type !== AST_NODE_TYPES6.ReturnStatement) {
|
|
1707
1783
|
return false;
|
|
1708
1784
|
}
|
|
1709
1785
|
if (isWithin(current, catchNode.body)) {
|
|
@@ -1722,13 +1798,13 @@ function returnedSentinelKinds(arg) {
|
|
|
1722
1798
|
kinds.add(direct);
|
|
1723
1799
|
return kinds;
|
|
1724
1800
|
}
|
|
1725
|
-
if (arg.type ===
|
|
1801
|
+
if (arg.type === AST_NODE_TYPES6.ConditionalExpression) {
|
|
1726
1802
|
for (const branch of [arg.consequent, arg.alternate]) {
|
|
1727
1803
|
for (const nested of returnedSentinelKinds(branch)) {
|
|
1728
1804
|
kinds.add(nested);
|
|
1729
1805
|
}
|
|
1730
1806
|
}
|
|
1731
|
-
} else if (arg.type ===
|
|
1807
|
+
} else if (arg.type === AST_NODE_TYPES6.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
|
|
1732
1808
|
for (const nested of returnedSentinelKinds(arg.right)) {
|
|
1733
1809
|
kinds.add(nested);
|
|
1734
1810
|
}
|
|
@@ -1745,7 +1821,7 @@ function isWithin(node, ancestor) {
|
|
|
1745
1821
|
}
|
|
1746
1822
|
return false;
|
|
1747
1823
|
}
|
|
1748
|
-
var no_sentinel_return_on_catch_default =
|
|
1824
|
+
var no_sentinel_return_on_catch_default = ESLintUtils9.RuleCreator(
|
|
1749
1825
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1750
1826
|
)({
|
|
1751
1827
|
name: "no-sentinel-return-on-catch",
|
|
@@ -1773,7 +1849,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1773
1849
|
const matcher = createLogMatcher(loggingOptions);
|
|
1774
1850
|
function logsOrReportsError(catchBody, caughtName) {
|
|
1775
1851
|
return walkWithinScope(catchBody, (current) => {
|
|
1776
|
-
if (current.type !==
|
|
1852
|
+
if (current.type !== AST_NODE_TYPES6.CallExpression) {
|
|
1777
1853
|
return false;
|
|
1778
1854
|
}
|
|
1779
1855
|
if (matcher.isLoggingCall(current)) {
|
|
@@ -1790,7 +1866,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1790
1866
|
return;
|
|
1791
1867
|
}
|
|
1792
1868
|
const last = body[body.length - 1];
|
|
1793
|
-
if (last === void 0 || last.type !==
|
|
1869
|
+
if (last === void 0 || last.type !== AST_NODE_TYPES6.ReturnStatement) {
|
|
1794
1870
|
return;
|
|
1795
1871
|
}
|
|
1796
1872
|
if (!isSentinelArgument(last.argument)) {
|
|
@@ -1799,7 +1875,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1799
1875
|
if (containsThrow(node.body)) {
|
|
1800
1876
|
return;
|
|
1801
1877
|
}
|
|
1802
|
-
const caughtName = node.param?.type ===
|
|
1878
|
+
const caughtName = node.param?.type === AST_NODE_TYPES6.Identifier ? node.param.name : null;
|
|
1803
1879
|
if (logsOrReportsError(node.body, caughtName)) {
|
|
1804
1880
|
return;
|
|
1805
1881
|
}
|
|
@@ -1826,7 +1902,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
|
1826
1902
|
});
|
|
1827
1903
|
|
|
1828
1904
|
// src/rules/no-string-concat-in-loop.ts
|
|
1829
|
-
import { ESLintUtils as
|
|
1905
|
+
import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
1830
1906
|
var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
1831
1907
|
"ForStatement",
|
|
1832
1908
|
"ForOfStatement",
|
|
@@ -1911,7 +1987,7 @@ function enclosingLoop(node) {
|
|
|
1911
1987
|
}
|
|
1912
1988
|
return null;
|
|
1913
1989
|
}
|
|
1914
|
-
var no_string_concat_in_loop_default =
|
|
1990
|
+
var no_string_concat_in_loop_default = ESLintUtils10.RuleCreator(
|
|
1915
1991
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1916
1992
|
)({
|
|
1917
1993
|
name: "no-string-concat-in-loop",
|
|
@@ -1975,8 +2051,8 @@ var no_string_concat_in_loop_default = ESLintUtils11.RuleCreator(
|
|
|
1975
2051
|
|
|
1976
2052
|
// src/rules/no-unnecessary-use-client.ts
|
|
1977
2053
|
import {
|
|
1978
|
-
AST_NODE_TYPES as
|
|
1979
|
-
ESLintUtils as
|
|
2054
|
+
AST_NODE_TYPES as AST_NODE_TYPES7,
|
|
2055
|
+
ESLintUtils as ESLintUtils11
|
|
1980
2056
|
} from "@typescript-eslint/utils";
|
|
1981
2057
|
var HOOK_REGEX = /^use([A-Z]|$)/;
|
|
1982
2058
|
var EVENT_PROP_REGEX = /^on[A-Z]/;
|
|
@@ -2003,13 +2079,13 @@ var CLIENT_ONLY_PACKAGES_REGEX = /^(?:@radix-ui\/|framer-motion|react-dom|react-
|
|
|
2003
2079
|
var isBareSpecifier = (source) => !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("@/") && !source.startsWith("~");
|
|
2004
2080
|
var jsxRootName = (name) => {
|
|
2005
2081
|
let current = name;
|
|
2006
|
-
while (current.type ===
|
|
2082
|
+
while (current.type === AST_NODE_TYPES7.JSXMemberExpression) {
|
|
2007
2083
|
current = current.object;
|
|
2008
2084
|
}
|
|
2009
|
-
return current.type ===
|
|
2085
|
+
return current.type === AST_NODE_TYPES7.JSXIdentifier ? current.name : "";
|
|
2010
2086
|
};
|
|
2011
2087
|
var subtreeReadsImportedBinding = (node, imported) => {
|
|
2012
|
-
if (node.type ===
|
|
2088
|
+
if (node.type === AST_NODE_TYPES7.Identifier) {
|
|
2013
2089
|
return imported.has(node.name);
|
|
2014
2090
|
}
|
|
2015
2091
|
for (const key of Object.keys(node)) {
|
|
@@ -2024,16 +2100,16 @@ var subtreeReadsImportedBinding = (node, imported) => {
|
|
|
2024
2100
|
return false;
|
|
2025
2101
|
};
|
|
2026
2102
|
var isUseClientDirective = (node) => {
|
|
2027
|
-
return node.type ===
|
|
2103
|
+
return node.type === AST_NODE_TYPES7.ExpressionStatement && node.expression.type === AST_NODE_TYPES7.Literal && node.expression.value === "use client";
|
|
2028
2104
|
};
|
|
2029
2105
|
var isGlobalReference = (node, context) => {
|
|
2030
2106
|
if (!BROWSER_GLOBALS.has(node.name)) return false;
|
|
2031
2107
|
const parent = node.parent;
|
|
2032
2108
|
if (parent !== void 0) {
|
|
2033
|
-
if (parent.type ===
|
|
2109
|
+
if (parent.type === AST_NODE_TYPES7.MemberExpression && parent.property === node && !parent.computed) {
|
|
2034
2110
|
return false;
|
|
2035
2111
|
}
|
|
2036
|
-
if (parent.type ===
|
|
2112
|
+
if (parent.type === AST_NODE_TYPES7.Property && parent.key === node && !parent.computed) {
|
|
2037
2113
|
return false;
|
|
2038
2114
|
}
|
|
2039
2115
|
if (parent.type.startsWith("TS")) {
|
|
@@ -2050,7 +2126,7 @@ var isGlobalReference = (node, context) => {
|
|
|
2050
2126
|
}
|
|
2051
2127
|
return true;
|
|
2052
2128
|
};
|
|
2053
|
-
var no_unnecessary_use_client_default =
|
|
2129
|
+
var no_unnecessary_use_client_default = ESLintUtils11.RuleCreator(
|
|
2054
2130
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2055
2131
|
)({
|
|
2056
2132
|
name: "no-unnecessary-use-client",
|
|
@@ -2075,13 +2151,13 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2075
2151
|
const importedLocals = /* @__PURE__ */ new Set();
|
|
2076
2152
|
const externalLocals = /* @__PURE__ */ new Set();
|
|
2077
2153
|
const markIfHookOrContext = (callee) => {
|
|
2078
|
-
if (callee.type ===
|
|
2154
|
+
if (callee.type === AST_NODE_TYPES7.Identifier) {
|
|
2079
2155
|
if (HOOK_REGEX.test(callee.name) || callee.name === "createContext") {
|
|
2080
2156
|
hasClientIndicator = true;
|
|
2081
2157
|
}
|
|
2082
2158
|
return;
|
|
2083
2159
|
}
|
|
2084
|
-
if (callee.type ===
|
|
2160
|
+
if (callee.type === AST_NODE_TYPES7.MemberExpression && callee.property.type === AST_NODE_TYPES7.Identifier) {
|
|
2085
2161
|
const name = callee.property.name;
|
|
2086
2162
|
if (HOOK_REGEX.test(name) || name === "createContext") {
|
|
2087
2163
|
hasClientIndicator = true;
|
|
@@ -2091,7 +2167,7 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2091
2167
|
return {
|
|
2092
2168
|
Program(node) {
|
|
2093
2169
|
for (const stmt of node.body) {
|
|
2094
|
-
if (stmt.type !==
|
|
2170
|
+
if (stmt.type !== AST_NODE_TYPES7.ExpressionStatement) break;
|
|
2095
2171
|
if (isUseClientDirective(stmt)) {
|
|
2096
2172
|
directiveNode = stmt;
|
|
2097
2173
|
break;
|
|
@@ -2104,7 +2180,7 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2104
2180
|
},
|
|
2105
2181
|
JSXAttribute(node) {
|
|
2106
2182
|
if (directiveNode === null) return;
|
|
2107
|
-
if (node.name.type ===
|
|
2183
|
+
if (node.name.type === AST_NODE_TYPES7.JSXIdentifier && EVENT_PROP_REGEX.test(node.name.name)) {
|
|
2108
2184
|
hasClientIndicator = true;
|
|
2109
2185
|
}
|
|
2110
2186
|
},
|
|
@@ -2171,8 +2247,8 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2171
2247
|
});
|
|
2172
2248
|
|
|
2173
2249
|
// src/rules/prefer-discriminated-union.ts
|
|
2174
|
-
import { ESLintUtils as
|
|
2175
|
-
import { AST_NODE_TYPES as
|
|
2250
|
+
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
2251
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES8 } from "@typescript-eslint/utils";
|
|
2176
2252
|
var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
2177
2253
|
"success",
|
|
2178
2254
|
"ok",
|
|
@@ -2182,27 +2258,27 @@ var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
|
2182
2258
|
]);
|
|
2183
2259
|
var MIN_OPTIONAL_MEMBERS = 2;
|
|
2184
2260
|
function getMemberName(member) {
|
|
2185
|
-
if (member.type !==
|
|
2261
|
+
if (member.type !== AST_NODE_TYPES8.TSPropertySignature) {
|
|
2186
2262
|
return null;
|
|
2187
2263
|
}
|
|
2188
2264
|
const { key } = member;
|
|
2189
|
-
if (key.type ===
|
|
2265
|
+
if (key.type === AST_NODE_TYPES8.Identifier) {
|
|
2190
2266
|
return key.name;
|
|
2191
2267
|
}
|
|
2192
|
-
if (key.type ===
|
|
2268
|
+
if (key.type === AST_NODE_TYPES8.Literal && typeof key.value === "string") {
|
|
2193
2269
|
return key.value;
|
|
2194
2270
|
}
|
|
2195
2271
|
return null;
|
|
2196
2272
|
}
|
|
2197
2273
|
function isBooleanTyped(member) {
|
|
2198
|
-
return member.typeAnnotation?.typeAnnotation.type ===
|
|
2274
|
+
return member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES8.TSBooleanKeyword;
|
|
2199
2275
|
}
|
|
2200
2276
|
function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
2201
2277
|
let hasStatusBoolean = false;
|
|
2202
2278
|
let optionalCount = 0;
|
|
2203
2279
|
let optionalPayloadCount = 0;
|
|
2204
2280
|
for (const member of typeLiteral.members) {
|
|
2205
|
-
if (member.type !==
|
|
2281
|
+
if (member.type !== AST_NODE_TYPES8.TSPropertySignature) {
|
|
2206
2282
|
continue;
|
|
2207
2283
|
}
|
|
2208
2284
|
if (member.optional) {
|
|
@@ -2218,7 +2294,7 @@ function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
|
2218
2294
|
}
|
|
2219
2295
|
return hasStatusBoolean && optionalCount >= MIN_OPTIONAL_MEMBERS && optionalPayloadCount >= 1;
|
|
2220
2296
|
}
|
|
2221
|
-
var prefer_discriminated_union_default =
|
|
2297
|
+
var prefer_discriminated_union_default = ESLintUtils12.RuleCreator(
|
|
2222
2298
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2223
2299
|
)({
|
|
2224
2300
|
name: "prefer-discriminated-union",
|
|
@@ -2246,7 +2322,7 @@ var prefer_discriminated_union_default = ESLintUtils13.RuleCreator(
|
|
|
2246
2322
|
TSInterfaceDeclaration(node) {
|
|
2247
2323
|
const synthetic = {
|
|
2248
2324
|
...node.body,
|
|
2249
|
-
type:
|
|
2325
|
+
type: AST_NODE_TYPES8.TSTypeLiteral,
|
|
2250
2326
|
members: node.body.body
|
|
2251
2327
|
};
|
|
2252
2328
|
checkTypeLiteral(synthetic, node);
|
|
@@ -2260,15 +2336,15 @@ var prefer_discriminated_union_default = ESLintUtils13.RuleCreator(
|
|
|
2260
2336
|
|
|
2261
2337
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
2262
2338
|
import {
|
|
2263
|
-
AST_NODE_TYPES as
|
|
2264
|
-
ESLintUtils as
|
|
2339
|
+
AST_NODE_TYPES as AST_NODE_TYPES9,
|
|
2340
|
+
ESLintUtils as ESLintUtils13
|
|
2265
2341
|
} from "@typescript-eslint/utils";
|
|
2266
2342
|
var unwrap = (node) => {
|
|
2267
2343
|
let current = node;
|
|
2268
2344
|
while (current !== null && current !== void 0) {
|
|
2269
|
-
if (current.type ===
|
|
2345
|
+
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
2346
|
current = current.expression;
|
|
2271
|
-
} else if (current.type ===
|
|
2347
|
+
} else if (current.type === AST_NODE_TYPES9.ChainExpression) {
|
|
2272
2348
|
current = current.expression;
|
|
2273
2349
|
} else {
|
|
2274
2350
|
break;
|
|
@@ -2276,28 +2352,40 @@ var unwrap = (node) => {
|
|
|
2276
2352
|
}
|
|
2277
2353
|
return current ?? null;
|
|
2278
2354
|
};
|
|
2355
|
+
var PROMISE_CHAIN_METHODS = /* @__PURE__ */ new Set([
|
|
2356
|
+
"then",
|
|
2357
|
+
"catch",
|
|
2358
|
+
"finally"
|
|
2359
|
+
]);
|
|
2360
|
+
var isSchemaParseReference = (node) => {
|
|
2361
|
+
const inner = unwrap(node);
|
|
2362
|
+
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");
|
|
2363
|
+
};
|
|
2279
2364
|
var isRawPayloadSource = (node) => {
|
|
2280
2365
|
let current = unwrap(node);
|
|
2281
2366
|
if (current === null) return false;
|
|
2282
|
-
if (current.type ===
|
|
2367
|
+
if (current.type === AST_NODE_TYPES9.AwaitExpression) {
|
|
2283
2368
|
current = unwrap(current.argument);
|
|
2284
2369
|
}
|
|
2285
|
-
if (current === null || current.type !==
|
|
2370
|
+
if (current === null || current.type !== AST_NODE_TYPES9.CallExpression) {
|
|
2286
2371
|
return false;
|
|
2287
2372
|
}
|
|
2288
2373
|
const callee = unwrap(current.callee);
|
|
2289
|
-
if (callee === null || callee.type !==
|
|
2374
|
+
if (callee === null || callee.type !== AST_NODE_TYPES9.MemberExpression) {
|
|
2290
2375
|
return false;
|
|
2291
2376
|
}
|
|
2292
2377
|
const property = unwrap(callee.property);
|
|
2293
|
-
if (property === null || property.type !==
|
|
2378
|
+
if (property === null || property.type !== AST_NODE_TYPES9.Identifier) {
|
|
2294
2379
|
return false;
|
|
2295
2380
|
}
|
|
2296
2381
|
if (property.name === "json") {
|
|
2297
2382
|
return true;
|
|
2298
2383
|
}
|
|
2384
|
+
if (PROMISE_CHAIN_METHODS.has(property.name)) {
|
|
2385
|
+
return !current.arguments.some(isSchemaParseReference) && isRawPayloadSource(callee.object);
|
|
2386
|
+
}
|
|
2299
2387
|
const object = unwrap(callee.object);
|
|
2300
|
-
return property.name === "parse" && object !== null && object.type ===
|
|
2388
|
+
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
2389
|
!isLocalFileRead(current.arguments[0]);
|
|
2302
2390
|
};
|
|
2303
2391
|
var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
|
|
@@ -2305,9 +2393,9 @@ var isLocalFileRead = (node) => {
|
|
|
2305
2393
|
let found = false;
|
|
2306
2394
|
const visit = (current) => {
|
|
2307
2395
|
if (found || current === null || current === void 0) return;
|
|
2308
|
-
if (current.type ===
|
|
2396
|
+
if (current.type === AST_NODE_TYPES9.CallExpression) {
|
|
2309
2397
|
const callee = unwrap(current.callee);
|
|
2310
|
-
const name = callee?.type ===
|
|
2398
|
+
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
2399
|
if (name !== null && FILE_READ_RE.test(name)) {
|
|
2312
2400
|
found = true;
|
|
2313
2401
|
return;
|
|
@@ -2329,15 +2417,15 @@ var isLocalFileRead = (node) => {
|
|
|
2329
2417
|
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
2330
2418
|
var isInsideAssertion = (node) => {
|
|
2331
2419
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
2332
|
-
if (current.type !==
|
|
2420
|
+
if (current.type !== AST_NODE_TYPES9.CallExpression) continue;
|
|
2333
2421
|
let callee = current.callee;
|
|
2334
|
-
while (callee.type ===
|
|
2422
|
+
while (callee.type === AST_NODE_TYPES9.MemberExpression) {
|
|
2335
2423
|
callee = callee.object;
|
|
2336
2424
|
}
|
|
2337
|
-
if (callee.type ===
|
|
2425
|
+
if (callee.type === AST_NODE_TYPES9.CallExpression) {
|
|
2338
2426
|
callee = callee.callee;
|
|
2339
2427
|
}
|
|
2340
|
-
if (callee.type ===
|
|
2428
|
+
if (callee.type === AST_NODE_TYPES9.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
2341
2429
|
return true;
|
|
2342
2430
|
}
|
|
2343
2431
|
}
|
|
@@ -2352,23 +2440,43 @@ var findVariable2 = (scope, name) => {
|
|
|
2352
2440
|
}
|
|
2353
2441
|
return null;
|
|
2354
2442
|
};
|
|
2355
|
-
var GUARD_NAME_RE = /^is[A-Z]/;
|
|
2443
|
+
var GUARD_NAME_RE = /^(?:is|validate|parse|assert|decode|coerce)[A-Z]/;
|
|
2444
|
+
var isValidationRead = (node) => {
|
|
2445
|
+
let current = node;
|
|
2446
|
+
let parent = current.parent;
|
|
2447
|
+
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)) {
|
|
2448
|
+
current = parent;
|
|
2449
|
+
parent = parent.parent;
|
|
2450
|
+
}
|
|
2451
|
+
if (parent === null || parent === void 0) return false;
|
|
2452
|
+
if (parent.type === AST_NODE_TYPES9.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
|
|
2453
|
+
return true;
|
|
2454
|
+
}
|
|
2455
|
+
if (parent.type !== AST_NODE_TYPES9.CallExpression || !parent.arguments.some((arg) => arg === current)) {
|
|
2456
|
+
return false;
|
|
2457
|
+
}
|
|
2458
|
+
const callee = parent.callee;
|
|
2459
|
+
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") {
|
|
2460
|
+
return parent.arguments.length === 1;
|
|
2461
|
+
}
|
|
2462
|
+
return callee.type === AST_NODE_TYPES9.Identifier && GUARD_NAME_RE.test(callee.name);
|
|
2463
|
+
};
|
|
2356
2464
|
var isGuardTestPosition = (node) => {
|
|
2357
2465
|
let current = node;
|
|
2358
2466
|
let parent = current.parent;
|
|
2359
2467
|
while (parent !== void 0 && parent !== null) {
|
|
2360
2468
|
switch (parent.type) {
|
|
2361
|
-
case
|
|
2362
|
-
case
|
|
2363
|
-
case
|
|
2469
|
+
case AST_NODE_TYPES9.UnaryExpression:
|
|
2470
|
+
case AST_NODE_TYPES9.LogicalExpression:
|
|
2471
|
+
case AST_NODE_TYPES9.ChainExpression:
|
|
2364
2472
|
current = parent;
|
|
2365
2473
|
parent = parent.parent;
|
|
2366
2474
|
continue;
|
|
2367
|
-
case
|
|
2368
|
-
case
|
|
2369
|
-
case
|
|
2370
|
-
case
|
|
2371
|
-
case
|
|
2475
|
+
case AST_NODE_TYPES9.IfStatement:
|
|
2476
|
+
case AST_NODE_TYPES9.ConditionalExpression:
|
|
2477
|
+
case AST_NODE_TYPES9.WhileStatement:
|
|
2478
|
+
case AST_NODE_TYPES9.DoWhileStatement:
|
|
2479
|
+
case AST_NODE_TYPES9.ForStatement:
|
|
2372
2480
|
return parent.test === current;
|
|
2373
2481
|
default:
|
|
2374
2482
|
return false;
|
|
@@ -2378,13 +2486,13 @@ var isGuardTestPosition = (node) => {
|
|
|
2378
2486
|
};
|
|
2379
2487
|
var isUnvalidatedVariableRef = (node, scope, tracked) => {
|
|
2380
2488
|
const unwrapped = unwrap(node);
|
|
2381
|
-
if (unwrapped === null || unwrapped.type !==
|
|
2489
|
+
if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES9.Identifier) {
|
|
2382
2490
|
return false;
|
|
2383
2491
|
}
|
|
2384
2492
|
const variable = findVariable2(scope, unwrapped.name);
|
|
2385
2493
|
return variable !== null && tracked.has(variable);
|
|
2386
2494
|
};
|
|
2387
|
-
var prefer_schema_for_api_payload_default =
|
|
2495
|
+
var prefer_schema_for_api_payload_default = ESLintUtils13.RuleCreator(
|
|
2388
2496
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2389
2497
|
)({
|
|
2390
2498
|
name: "prefer-schema-for-api-payload",
|
|
@@ -2404,6 +2512,14 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2404
2512
|
return {};
|
|
2405
2513
|
}
|
|
2406
2514
|
const unvalidatedVariables = /* @__PURE__ */ new Set();
|
|
2515
|
+
const isFullyNarrowedPattern = (declarator) => {
|
|
2516
|
+
const declared = context.sourceCode.getDeclaredVariables(declarator);
|
|
2517
|
+
return declared.length > 0 && declared.every(
|
|
2518
|
+
(variable) => variable.references.some(
|
|
2519
|
+
(reference) => isValidationRead(reference.identifier)
|
|
2520
|
+
)
|
|
2521
|
+
);
|
|
2522
|
+
};
|
|
2407
2523
|
const trackInitializer = (declarator) => {
|
|
2408
2524
|
if (!isRawPayloadSource(declarator.init)) return;
|
|
2409
2525
|
const declaredVars = context.sourceCode.getDeclaredVariables(declarator);
|
|
@@ -2415,13 +2531,15 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2415
2531
|
return {
|
|
2416
2532
|
VariableDeclarator(node) {
|
|
2417
2533
|
const scope = context.sourceCode.getScope(node);
|
|
2418
|
-
if (node.id.type ===
|
|
2534
|
+
if (node.id.type === AST_NODE_TYPES9.Identifier) {
|
|
2419
2535
|
trackInitializer(node);
|
|
2420
2536
|
return;
|
|
2421
2537
|
}
|
|
2422
|
-
if (node.id.type ===
|
|
2538
|
+
if (node.id.type === AST_NODE_TYPES9.ObjectPattern || node.id.type === AST_NODE_TYPES9.ArrayPattern) {
|
|
2423
2539
|
if (isRawPayloadSource(node.init)) {
|
|
2424
|
-
|
|
2540
|
+
if (!isFullyNarrowedPattern(node)) {
|
|
2541
|
+
context.report({ node: node.id, messageId: "unparsedJsonAccess" });
|
|
2542
|
+
}
|
|
2425
2543
|
return;
|
|
2426
2544
|
}
|
|
2427
2545
|
if (isUnvalidatedVariableRef(node.init, scope, unvalidatedVariables)) {
|
|
@@ -2431,7 +2549,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2431
2549
|
},
|
|
2432
2550
|
AssignmentExpression(node) {
|
|
2433
2551
|
const scope = context.sourceCode.getScope(node);
|
|
2434
|
-
if (node.left.type ===
|
|
2552
|
+
if (node.left.type === AST_NODE_TYPES9.Identifier) {
|
|
2435
2553
|
const variable = findVariable2(scope, node.left.name);
|
|
2436
2554
|
if (variable === null) return;
|
|
2437
2555
|
if (isRawPayloadSource(node.right)) {
|
|
@@ -2441,7 +2559,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2441
2559
|
}
|
|
2442
2560
|
return;
|
|
2443
2561
|
}
|
|
2444
|
-
if (node.left.type ===
|
|
2562
|
+
if (node.left.type === AST_NODE_TYPES9.ObjectPattern || node.left.type === AST_NODE_TYPES9.ArrayPattern) {
|
|
2445
2563
|
if (isRawPayloadSource(node.right)) {
|
|
2446
2564
|
context.report({
|
|
2447
2565
|
node: node.left,
|
|
@@ -2458,15 +2576,15 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2458
2576
|
}
|
|
2459
2577
|
},
|
|
2460
2578
|
CallExpression(node) {
|
|
2461
|
-
if (node.callee.type !==
|
|
2579
|
+
if (node.callee.type !== AST_NODE_TYPES9.Identifier) return;
|
|
2462
2580
|
if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
|
|
2463
2581
|
return;
|
|
2464
2582
|
}
|
|
2465
2583
|
const scope = context.sourceCode.getScope(node);
|
|
2466
2584
|
for (const arg of node.arguments) {
|
|
2467
|
-
if (arg.type ===
|
|
2585
|
+
if (arg.type === AST_NODE_TYPES9.SpreadElement) continue;
|
|
2468
2586
|
const unwrapped = unwrap(arg);
|
|
2469
|
-
if (unwrapped === null || unwrapped.type !==
|
|
2587
|
+
if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES9.Identifier) {
|
|
2470
2588
|
continue;
|
|
2471
2589
|
}
|
|
2472
2590
|
const variable = findVariable2(scope, unwrapped.name);
|
|
@@ -2475,17 +2593,18 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2475
2593
|
},
|
|
2476
2594
|
MemberExpression(node) {
|
|
2477
2595
|
if (isInsideAssertion(node)) return;
|
|
2596
|
+
if (isValidationRead(node)) return;
|
|
2478
2597
|
const scope = context.sourceCode.getScope(node);
|
|
2479
2598
|
const obj = unwrap(node.object);
|
|
2480
2599
|
if (isRawPayloadSource(obj)) {
|
|
2481
2600
|
const parent = node.parent;
|
|
2482
|
-
if (parent.type ===
|
|
2601
|
+
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
2602
|
return;
|
|
2484
2603
|
}
|
|
2485
2604
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
2486
2605
|
return;
|
|
2487
2606
|
}
|
|
2488
|
-
if (obj !== null && obj.type ===
|
|
2607
|
+
if (obj !== null && obj.type === AST_NODE_TYPES9.Identifier && isUnvalidatedVariableRef(obj, scope, unvalidatedVariables)) {
|
|
2489
2608
|
context.report({ node, messageId: "unparsedJsonAccess" });
|
|
2490
2609
|
const variable = findVariable2(scope, obj.name);
|
|
2491
2610
|
if (variable !== null) {
|
|
@@ -2498,7 +2617,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2498
2617
|
});
|
|
2499
2618
|
|
|
2500
2619
|
// src/rules/prefer-semantic-colors.ts
|
|
2501
|
-
import { AST_NODE_TYPES as
|
|
2620
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES10, ESLintUtils as ESLintUtils14 } from "@typescript-eslint/utils";
|
|
2502
2621
|
import { existsSync, readFileSync } from "fs";
|
|
2503
2622
|
import { dirname, join, parse } from "path";
|
|
2504
2623
|
|
|
@@ -2510,7 +2629,8 @@ var classTokens = (value) => value.split(/\s+/).filter(Boolean);
|
|
|
2510
2629
|
var COLOR_PREFIXES = "text|bg|border(?:-[trblxyse])?|ring(?:-offset)?|fill|stroke|from|via|to|divide|decoration|placeholder|accent|caret|shadow|outline";
|
|
2511
2630
|
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
2631
|
var COLOR_FN = "rgba?|hsla?|hwb|oklch|oklab|lab|lch|color";
|
|
2513
|
-
var
|
|
2632
|
+
var PALETTE_STEP = "50|[1-9]00|950";
|
|
2633
|
+
var RAW_PALETTE_RE = new RegExp(`^(?:${COLOR_PREFIXES})-(?:${PALETTE})-(?:${PALETTE_STEP})(?:/\\d{1,3})?$`);
|
|
2514
2634
|
var ARBITRARY_COLOR_RE = new RegExp(
|
|
2515
2635
|
`^(?:${COLOR_PREFIXES})-\\[(?:#[0-9a-fA-F]{3,8}|(?:${COLOR_FN})\\([^\\]]*\\))\\]$`,
|
|
2516
2636
|
"i"
|
|
@@ -2537,6 +2657,7 @@ var STYLE_COLOR_PROPS = /* @__PURE__ */ new Set([
|
|
|
2537
2657
|
"lightingColor"
|
|
2538
2658
|
]);
|
|
2539
2659
|
var RAW_COLOR_VALUE_RE = new RegExp(`#[0-9a-fA-F]{3,8}\\b|\\b(?:${COLOR_FN})\\s*\\(`, "i");
|
|
2660
|
+
var CSS_VAR_REFERENCE_RE = /var\(\s*--/;
|
|
2540
2661
|
var STORIES_FILE_RE = /\.stories\.[cm]?[jt]sx?$/i;
|
|
2541
2662
|
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
2663
|
var DETECTION_FILES = [
|
|
@@ -2573,8 +2694,8 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
2573
2694
|
]);
|
|
2574
2695
|
function jsxElementName(node) {
|
|
2575
2696
|
const name = node.openingElement.name;
|
|
2576
|
-
if (name.type ===
|
|
2577
|
-
if (name.type ===
|
|
2697
|
+
if (name.type === AST_NODE_TYPES10.JSXIdentifier) return name.name;
|
|
2698
|
+
if (name.type === AST_NODE_TYPES10.JSXMemberExpression && name.property.type === AST_NODE_TYPES10.JSXIdentifier) {
|
|
2578
2699
|
return name.property.name;
|
|
2579
2700
|
}
|
|
2580
2701
|
return null;
|
|
@@ -2582,10 +2703,25 @@ function jsxElementName(node) {
|
|
|
2582
2703
|
function isSvgLikeElementName(name) {
|
|
2583
2704
|
return name === "svg" || SVG_DEFS_CONTAINERS.has(name) || /svg$/i.test(name);
|
|
2584
2705
|
}
|
|
2706
|
+
var SVG_SHAPE_PRIMITIVES = /* @__PURE__ */ new Set([
|
|
2707
|
+
"circle",
|
|
2708
|
+
"ellipse",
|
|
2709
|
+
"g",
|
|
2710
|
+
"line",
|
|
2711
|
+
"path",
|
|
2712
|
+
"polygon",
|
|
2713
|
+
"polyline",
|
|
2714
|
+
"rect",
|
|
2715
|
+
"stop",
|
|
2716
|
+
"text",
|
|
2717
|
+
"tspan",
|
|
2718
|
+
"use"
|
|
2719
|
+
]);
|
|
2720
|
+
var EMAIL_OR_PDF_IMPORT_RE = /@react-(?:email|pdf)\//;
|
|
2585
2721
|
var isInsideSvg = (node) => {
|
|
2586
2722
|
let current = node.parent;
|
|
2587
2723
|
while (current !== void 0 && current !== null) {
|
|
2588
|
-
if (current.type ===
|
|
2724
|
+
if (current.type === AST_NODE_TYPES10.JSXElement) {
|
|
2589
2725
|
const name = jsxElementName(current);
|
|
2590
2726
|
if (name !== null && isSvgLikeElementName(name)) return true;
|
|
2591
2727
|
}
|
|
@@ -2596,7 +2732,7 @@ var isInsideSvg = (node) => {
|
|
|
2596
2732
|
var isInsideIconFactoryPath = (node) => {
|
|
2597
2733
|
let current = node.parent;
|
|
2598
2734
|
while (current !== void 0 && current !== null) {
|
|
2599
|
-
if (current.type ===
|
|
2735
|
+
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
2736
|
return true;
|
|
2601
2737
|
}
|
|
2602
2738
|
current = current.parent;
|
|
@@ -2646,11 +2782,11 @@ var hasSemanticTokenSystem = (filename) => {
|
|
|
2646
2782
|
return answer;
|
|
2647
2783
|
};
|
|
2648
2784
|
var propName = (key) => {
|
|
2649
|
-
if (key.type ===
|
|
2650
|
-
if (key.type ===
|
|
2785
|
+
if (key.type === AST_NODE_TYPES10.Identifier) return key.name;
|
|
2786
|
+
if (key.type === AST_NODE_TYPES10.Literal && typeof key.value === "string") return key.value;
|
|
2651
2787
|
return null;
|
|
2652
2788
|
};
|
|
2653
|
-
var prefer_semantic_colors_default =
|
|
2789
|
+
var prefer_semantic_colors_default = ESLintUtils14.RuleCreator(
|
|
2654
2790
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2655
2791
|
)({
|
|
2656
2792
|
name: "prefer-semantic-colors",
|
|
@@ -2677,6 +2813,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2677
2813
|
defaultOptions: [{}],
|
|
2678
2814
|
create(context, [options]) {
|
|
2679
2815
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
2816
|
+
if (EMAIL_OR_PDF_IMPORT_RE.test(context.sourceCode.getText())) return {};
|
|
2680
2817
|
if (options?.requireSemanticTokens === true && !hasSemanticTokenSystem(context.filename)) {
|
|
2681
2818
|
return {};
|
|
2682
2819
|
}
|
|
@@ -2685,7 +2822,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2685
2822
|
const base = tailwindBase(token);
|
|
2686
2823
|
if (RAW_PALETTE_RE.test(base)) {
|
|
2687
2824
|
context.report({ node, messageId: "rawPalette", data: { class: token } });
|
|
2688
|
-
} else if (ARBITRARY_COLOR_RE.test(base)) {
|
|
2825
|
+
} else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
|
|
2689
2826
|
context.report({ node, messageId: "arbitraryColor", data: { class: token } });
|
|
2690
2827
|
}
|
|
2691
2828
|
}
|
|
@@ -2693,27 +2830,27 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2693
2830
|
const checkClassNode = (node) => {
|
|
2694
2831
|
if (node === null) return;
|
|
2695
2832
|
switch (node.type) {
|
|
2696
|
-
case
|
|
2833
|
+
case AST_NODE_TYPES10.Literal:
|
|
2697
2834
|
if (typeof node.value === "string") reportClasses(node.value, node);
|
|
2698
2835
|
break;
|
|
2699
|
-
case
|
|
2836
|
+
case AST_NODE_TYPES10.TemplateLiteral:
|
|
2700
2837
|
for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
|
|
2701
2838
|
break;
|
|
2702
|
-
case
|
|
2839
|
+
case AST_NODE_TYPES10.ArrayExpression:
|
|
2703
2840
|
for (const element of node.elements) {
|
|
2704
|
-
if (element !== null && element.type !==
|
|
2841
|
+
if (element !== null && element.type !== AST_NODE_TYPES10.SpreadElement) checkClassNode(element);
|
|
2705
2842
|
}
|
|
2706
2843
|
break;
|
|
2707
|
-
case
|
|
2844
|
+
case AST_NODE_TYPES10.ObjectExpression:
|
|
2708
2845
|
for (const property of node.properties) {
|
|
2709
|
-
if (property.type ===
|
|
2846
|
+
if (property.type === AST_NODE_TYPES10.Property) checkClassNode(property.value);
|
|
2710
2847
|
}
|
|
2711
2848
|
break;
|
|
2712
|
-
case
|
|
2849
|
+
case AST_NODE_TYPES10.ConditionalExpression:
|
|
2713
2850
|
checkClassNode(node.consequent);
|
|
2714
2851
|
checkClassNode(node.alternate);
|
|
2715
2852
|
break;
|
|
2716
|
-
case
|
|
2853
|
+
case AST_NODE_TYPES10.LogicalExpression:
|
|
2717
2854
|
checkClassNode(node.right);
|
|
2718
2855
|
break;
|
|
2719
2856
|
default:
|
|
@@ -2721,29 +2858,29 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2721
2858
|
}
|
|
2722
2859
|
};
|
|
2723
2860
|
const checkColorValueNode = (node) => {
|
|
2724
|
-
if (node.type ===
|
|
2861
|
+
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
2862
|
context.report({ node, messageId: "inlineColor", data: { value: node.value } });
|
|
2726
2863
|
}
|
|
2727
2864
|
};
|
|
2728
2865
|
return {
|
|
2729
2866
|
"JSXAttribute[name.name='className']"(node) {
|
|
2730
2867
|
if (node.value === null) return;
|
|
2731
|
-
if (node.value.type ===
|
|
2732
|
-
else if (node.value.type ===
|
|
2733
|
-
if (node.value.expression.type !==
|
|
2868
|
+
if (node.value.type === AST_NODE_TYPES10.Literal) checkClassNode(node.value);
|
|
2869
|
+
else if (node.value.type === AST_NODE_TYPES10.JSXExpressionContainer) {
|
|
2870
|
+
if (node.value.expression.type !== AST_NODE_TYPES10.JSXEmptyExpression) {
|
|
2734
2871
|
checkClassNode(node.value.expression);
|
|
2735
2872
|
}
|
|
2736
2873
|
}
|
|
2737
2874
|
},
|
|
2738
2875
|
CallExpression(node) {
|
|
2739
|
-
if (node.callee.type ===
|
|
2876
|
+
if (node.callee.type === AST_NODE_TYPES10.Identifier && CLASS_FNS.has(node.callee.name)) {
|
|
2740
2877
|
for (const arg of node.arguments) {
|
|
2741
|
-
if (arg.type !==
|
|
2878
|
+
if (arg.type !== AST_NODE_TYPES10.SpreadElement) checkClassNode(arg);
|
|
2742
2879
|
}
|
|
2743
2880
|
}
|
|
2744
2881
|
},
|
|
2745
2882
|
VariableDeclarator(node) {
|
|
2746
|
-
if (node.id.type ===
|
|
2883
|
+
if (node.id.type === AST_NODE_TYPES10.Identifier && CLASS_NAME_RE.test(node.id.name)) {
|
|
2747
2884
|
checkClassNode(node.init);
|
|
2748
2885
|
}
|
|
2749
2886
|
},
|
|
@@ -2755,7 +2892,11 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2755
2892
|
// Neutral drawing literals and anything inside an SVG defs container are
|
|
2756
2893
|
// structural, not UI tokens, so they never fire.
|
|
2757
2894
|
"JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
|
|
2758
|
-
if (node.value?.type !==
|
|
2895
|
+
if (node.value?.type !== AST_NODE_TYPES10.Literal) return;
|
|
2896
|
+
const owner = node.parent.name;
|
|
2897
|
+
if (owner.type === AST_NODE_TYPES10.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
|
|
2898
|
+
return;
|
|
2899
|
+
}
|
|
2759
2900
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
2760
2901
|
return;
|
|
2761
2902
|
}
|
|
@@ -2772,7 +2913,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2772
2913
|
});
|
|
2773
2914
|
|
|
2774
2915
|
// src/rules/prefer-server-actions.ts
|
|
2775
|
-
import { ESLintUtils as
|
|
2916
|
+
import { ESLintUtils as ESLintUtils15 } from "@typescript-eslint/utils";
|
|
2776
2917
|
var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
|
|
2777
2918
|
var AXIOS_MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "delete", "patch"]);
|
|
2778
2919
|
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 +2993,7 @@ function getPropertyNode(objNode, propName2) {
|
|
|
2852
2993
|
}
|
|
2853
2994
|
return null;
|
|
2854
2995
|
}
|
|
2855
|
-
var prefer_server_actions_default =
|
|
2996
|
+
var prefer_server_actions_default = ESLintUtils15.RuleCreator(
|
|
2856
2997
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2857
2998
|
)({
|
|
2858
2999
|
name: "prefer-server-actions",
|
|
@@ -2928,38 +3069,38 @@ var prefer_server_actions_default = ESLintUtils16.RuleCreator(
|
|
|
2928
3069
|
|
|
2929
3070
|
// src/rules/require-assert-never.ts
|
|
2930
3071
|
import {
|
|
2931
|
-
ESLintUtils as
|
|
2932
|
-
AST_NODE_TYPES as
|
|
3072
|
+
ESLintUtils as ESLintUtils16,
|
|
3073
|
+
AST_NODE_TYPES as AST_NODE_TYPES11
|
|
2933
3074
|
} from "@typescript-eslint/utils";
|
|
2934
3075
|
var isAssertNeverCall = (expression) => {
|
|
2935
|
-
if (expression.type !==
|
|
3076
|
+
if (expression.type !== AST_NODE_TYPES11.CallExpression) return false;
|
|
2936
3077
|
const callee = expression.callee;
|
|
2937
|
-
if (callee.type ===
|
|
3078
|
+
if (callee.type === AST_NODE_TYPES11.Identifier) {
|
|
2938
3079
|
return callee.name === "assertNever";
|
|
2939
3080
|
}
|
|
2940
|
-
if (callee.type ===
|
|
3081
|
+
if (callee.type === AST_NODE_TYPES11.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES11.Identifier) {
|
|
2941
3082
|
return callee.property.name === "assertNever";
|
|
2942
3083
|
}
|
|
2943
3084
|
return false;
|
|
2944
3085
|
};
|
|
2945
3086
|
var statementContainsAssertNever = (statement) => {
|
|
2946
|
-
if (statement.type ===
|
|
3087
|
+
if (statement.type === AST_NODE_TYPES11.ExpressionStatement) {
|
|
2947
3088
|
return isAssertNeverCall(statement.expression);
|
|
2948
3089
|
}
|
|
2949
|
-
if (statement.type ===
|
|
3090
|
+
if (statement.type === AST_NODE_TYPES11.ThrowStatement) {
|
|
2950
3091
|
return isAssertNeverCall(statement.argument);
|
|
2951
3092
|
}
|
|
2952
|
-
if (statement.type ===
|
|
3093
|
+
if (statement.type === AST_NODE_TYPES11.ReturnStatement) {
|
|
2953
3094
|
return statement.argument !== null && isAssertNeverCall(statement.argument);
|
|
2954
3095
|
}
|
|
2955
|
-
if (statement.type ===
|
|
3096
|
+
if (statement.type === AST_NODE_TYPES11.BlockStatement) {
|
|
2956
3097
|
return statement.body.some(statementContainsAssertNever);
|
|
2957
3098
|
}
|
|
2958
3099
|
return false;
|
|
2959
3100
|
};
|
|
2960
3101
|
var isRuntimeHandlingStatement = (statement) => {
|
|
2961
|
-
if (statement.type ===
|
|
2962
|
-
if (statement.type ===
|
|
3102
|
+
if (statement.type === AST_NODE_TYPES11.EmptyStatement) return false;
|
|
3103
|
+
if (statement.type === AST_NODE_TYPES11.BlockStatement) {
|
|
2963
3104
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
2964
3105
|
}
|
|
2965
3106
|
return true;
|
|
@@ -2975,12 +3116,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
2975
3116
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
2976
3117
|
}
|
|
2977
3118
|
const only = defaultCase.consequent[0];
|
|
2978
|
-
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type ===
|
|
3119
|
+
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === AST_NODE_TYPES11.BlockStatement && only.body.length === 0) {
|
|
2979
3120
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
2980
3121
|
}
|
|
2981
3122
|
return false;
|
|
2982
3123
|
};
|
|
2983
|
-
var require_assert_never_default =
|
|
3124
|
+
var require_assert_never_default = ESLintUtils16.RuleCreator(
|
|
2984
3125
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2985
3126
|
)({
|
|
2986
3127
|
name: "require-assert-never",
|
|
@@ -3018,25 +3159,28 @@ var require_assert_never_default = ESLintUtils17.RuleCreator(
|
|
|
3018
3159
|
});
|
|
3019
3160
|
|
|
3020
3161
|
// src/rules/require-zod-form-validation.ts
|
|
3021
|
-
import { ESLintUtils as
|
|
3162
|
+
import { ESLintUtils as ESLintUtils17, AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
3022
3163
|
|
|
3023
3164
|
// src/rules/_zod.ts
|
|
3024
3165
|
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
3025
3166
|
var ZOD_SUFFIX_RE = /Schema$/;
|
|
3026
3167
|
var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
|
|
3168
|
+
function isZodModule(source) {
|
|
3169
|
+
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
3170
|
+
}
|
|
3027
3171
|
|
|
3028
3172
|
// src/rules/require-zod-form-validation.ts
|
|
3029
3173
|
var looksLikeZodSchema = (node) => {
|
|
3030
3174
|
let current = node;
|
|
3031
3175
|
while (true) {
|
|
3032
|
-
if (current.type ===
|
|
3176
|
+
if (current.type === AST_NODE_TYPES12.Identifier) {
|
|
3033
3177
|
return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
|
|
3034
3178
|
}
|
|
3035
|
-
if (current.type ===
|
|
3179
|
+
if (current.type === AST_NODE_TYPES12.CallExpression) {
|
|
3036
3180
|
current = current.callee;
|
|
3037
3181
|
continue;
|
|
3038
3182
|
}
|
|
3039
|
-
if (current.type ===
|
|
3183
|
+
if (current.type === AST_NODE_TYPES12.MemberExpression) {
|
|
3040
3184
|
current = current.object;
|
|
3041
3185
|
continue;
|
|
3042
3186
|
}
|
|
@@ -3044,25 +3188,25 @@ var looksLikeZodSchema = (node) => {
|
|
|
3044
3188
|
}
|
|
3045
3189
|
};
|
|
3046
3190
|
var isZodParseCall = (node) => {
|
|
3047
|
-
if (node.type !==
|
|
3191
|
+
if (node.type !== AST_NODE_TYPES12.CallExpression) return false;
|
|
3048
3192
|
const callee = node.callee;
|
|
3049
|
-
if (callee.type !==
|
|
3193
|
+
if (callee.type !== AST_NODE_TYPES12.MemberExpression) return false;
|
|
3050
3194
|
if (callee.computed) return false;
|
|
3051
|
-
if (callee.property.type !==
|
|
3195
|
+
if (callee.property.type !== AST_NODE_TYPES12.Identifier) return false;
|
|
3052
3196
|
const method = callee.property.name;
|
|
3053
3197
|
if (method !== "parse" && method !== "safeParse") return false;
|
|
3054
3198
|
return looksLikeZodSchema(callee.object);
|
|
3055
3199
|
};
|
|
3056
3200
|
var isFormDataMethodCall = (node) => {
|
|
3057
3201
|
let current = node;
|
|
3058
|
-
if (current.type ===
|
|
3202
|
+
if (current.type === AST_NODE_TYPES12.AwaitExpression) {
|
|
3059
3203
|
current = current.argument;
|
|
3060
3204
|
}
|
|
3061
|
-
if (current.type !==
|
|
3205
|
+
if (current.type !== AST_NODE_TYPES12.CallExpression) return false;
|
|
3062
3206
|
const callee = current.callee;
|
|
3063
|
-
return callee.type ===
|
|
3207
|
+
return callee.type === AST_NODE_TYPES12.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES12.Identifier && callee.property.name === "formData";
|
|
3064
3208
|
};
|
|
3065
|
-
var require_zod_form_validation_default =
|
|
3209
|
+
var require_zod_form_validation_default = ESLintUtils17.RuleCreator(
|
|
3066
3210
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3067
3211
|
)({
|
|
3068
3212
|
name: "require-zod-form-validation",
|
|
@@ -3082,14 +3226,14 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3082
3226
|
return {};
|
|
3083
3227
|
}
|
|
3084
3228
|
const isFormSourceIdentifier = (node) => {
|
|
3085
|
-
if (node.type !==
|
|
3229
|
+
if (node.type !== AST_NODE_TYPES12.Identifier) return false;
|
|
3086
3230
|
if (/formdata/i.test(node.name)) return true;
|
|
3087
3231
|
let scope = context.sourceCode.getScope(node);
|
|
3088
3232
|
while (scope !== null) {
|
|
3089
3233
|
const variable = scope.set.get(node.name);
|
|
3090
3234
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
3091
3235
|
const def = variable.defs[0];
|
|
3092
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
3236
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES12.VariableDeclarator && def.node.init !== null) {
|
|
3093
3237
|
return isFormDataMethodCall(def.node.init);
|
|
3094
3238
|
}
|
|
3095
3239
|
return false;
|
|
@@ -3100,8 +3244,8 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3100
3244
|
};
|
|
3101
3245
|
const isFormDataGetCall = (node) => {
|
|
3102
3246
|
const callee = node.callee;
|
|
3103
|
-
if (callee.type !==
|
|
3104
|
-
if (callee.property.type !==
|
|
3247
|
+
if (callee.type !== AST_NODE_TYPES12.MemberExpression) return false;
|
|
3248
|
+
if (callee.property.type !== AST_NODE_TYPES12.Identifier || callee.property.name !== "get") {
|
|
3105
3249
|
return false;
|
|
3106
3250
|
}
|
|
3107
3251
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -3116,11 +3260,11 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3116
3260
|
};
|
|
3117
3261
|
const isInstanceofNarrowing = (node) => {
|
|
3118
3262
|
const parent = node.parent;
|
|
3119
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
3263
|
+
return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES12.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
|
|
3120
3264
|
};
|
|
3121
3265
|
const boundDeclarator = (node) => {
|
|
3122
3266
|
const parent = node.parent;
|
|
3123
|
-
if (parent.type ===
|
|
3267
|
+
if (parent.type === AST_NODE_TYPES12.VariableDeclarator && parent.init === node && parent.id.type === AST_NODE_TYPES12.Identifier) {
|
|
3124
3268
|
return parent;
|
|
3125
3269
|
}
|
|
3126
3270
|
return null;
|
|
@@ -3148,13 +3292,14 @@ var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
|
3148
3292
|
});
|
|
3149
3293
|
|
|
3150
3294
|
// src/rules/zod-naming-convention.ts
|
|
3151
|
-
import { ESLintUtils as
|
|
3295
|
+
import { ESLintUtils as ESLintUtils18, AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
3152
3296
|
var CONVENTIONS = {
|
|
3153
3297
|
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
3154
3298
|
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
3155
3299
|
either: { test: ZOD_SCHEMA_NAME_RE, messageId: "zodSchemaName" }
|
|
3156
3300
|
};
|
|
3157
3301
|
var CONTAINS_SCHEMA_RE = /schema/i;
|
|
3302
|
+
var BENCHMARK_PATH_RE = /(^|[\\/])(?:benchmarks?|bench)[\\/]/;
|
|
3158
3303
|
var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
3159
3304
|
"parse",
|
|
3160
3305
|
"parseAsync",
|
|
@@ -3172,15 +3317,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
|
3172
3317
|
"registry",
|
|
3173
3318
|
"implement"
|
|
3174
3319
|
]);
|
|
3175
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
3320
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES13.Identifier ? callee.property.name : null;
|
|
3176
3321
|
var calleeChainStartsWithZ = (node) => {
|
|
3177
3322
|
let current = node;
|
|
3178
|
-
while (current.type ===
|
|
3323
|
+
while (current.type === AST_NODE_TYPES13.MemberExpression) {
|
|
3179
3324
|
const receiver = current.object;
|
|
3180
|
-
if (receiver.type ===
|
|
3325
|
+
if (receiver.type === AST_NODE_TYPES13.Identifier && receiver.name === "z") {
|
|
3181
3326
|
return true;
|
|
3182
3327
|
}
|
|
3183
|
-
if (receiver.type ===
|
|
3328
|
+
if (receiver.type === AST_NODE_TYPES13.CallExpression) {
|
|
3184
3329
|
current = receiver.callee;
|
|
3185
3330
|
continue;
|
|
3186
3331
|
}
|
|
@@ -3188,7 +3333,7 @@ var calleeChainStartsWithZ = (node) => {
|
|
|
3188
3333
|
}
|
|
3189
3334
|
return false;
|
|
3190
3335
|
};
|
|
3191
|
-
var zod_naming_convention_default =
|
|
3336
|
+
var zod_naming_convention_default = ESLintUtils18.RuleCreator(
|
|
3192
3337
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3193
3338
|
)({
|
|
3194
3339
|
name: "zod-naming-convention",
|
|
@@ -3220,20 +3365,20 @@ var zod_naming_convention_default = ESLintUtils19.RuleCreator(
|
|
|
3220
3365
|
const convention = optionsArg?.convention ?? "either";
|
|
3221
3366
|
const { test, messageId } = CONVENTIONS[convention];
|
|
3222
3367
|
const acceptsSchemaWord = convention !== "prefix";
|
|
3223
|
-
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3368
|
+
if (isTestFile(context.filename) || BENCHMARK_PATH_RE.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
3224
3369
|
return {};
|
|
3225
3370
|
}
|
|
3226
3371
|
return {
|
|
3227
3372
|
VariableDeclarator(node) {
|
|
3228
3373
|
const init = node.init;
|
|
3229
3374
|
if (init === null || init === void 0) return;
|
|
3230
|
-
if (init.type !==
|
|
3375
|
+
if (init.type !== AST_NODE_TYPES13.CallExpression) return;
|
|
3231
3376
|
const callee = init.callee;
|
|
3232
|
-
if (callee.type !==
|
|
3377
|
+
if (callee.type !== AST_NODE_TYPES13.MemberExpression) return;
|
|
3233
3378
|
if (!calleeChainStartsWithZ(callee)) return;
|
|
3234
3379
|
const terminal = terminalMethodName(callee);
|
|
3235
3380
|
if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
|
|
3236
|
-
if (node.id.type !==
|
|
3381
|
+
if (node.id.type !== AST_NODE_TYPES13.Identifier) return;
|
|
3237
3382
|
if (test.test(node.id.name)) return;
|
|
3238
3383
|
if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
|
|
3239
3384
|
context.report({
|
|
@@ -3246,7 +3391,7 @@ var zod_naming_convention_default = ESLintUtils19.RuleCreator(
|
|
|
3246
3391
|
});
|
|
3247
3392
|
|
|
3248
3393
|
// src/rules/no-cors-wildcard-with-credentials.ts
|
|
3249
|
-
import { ESLintUtils as
|
|
3394
|
+
import { ESLintUtils as ESLintUtils19 } from "@typescript-eslint/utils";
|
|
3250
3395
|
var ACAO_HEADER = "access-control-allow-origin";
|
|
3251
3396
|
var ACAC_HEADER = "access-control-allow-credentials";
|
|
3252
3397
|
var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
|
|
@@ -3388,7 +3533,7 @@ function enclosingScope(node) {
|
|
|
3388
3533
|
}
|
|
3389
3534
|
return void 0;
|
|
3390
3535
|
}
|
|
3391
|
-
var no_cors_wildcard_with_credentials_default =
|
|
3536
|
+
var no_cors_wildcard_with_credentials_default = ESLintUtils19.RuleCreator(
|
|
3392
3537
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3393
3538
|
)({
|
|
3394
3539
|
name: "no-cors-wildcard-with-credentials",
|
|
@@ -3456,9 +3601,9 @@ var no_cors_wildcard_with_credentials_default = ESLintUtils20.RuleCreator(
|
|
|
3456
3601
|
});
|
|
3457
3602
|
|
|
3458
3603
|
// src/rules/no-silent-promise-catch.ts
|
|
3459
|
-
import { AST_NODE_TYPES as
|
|
3604
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES14, ESLintUtils as ESLintUtils20 } from "@typescript-eslint/utils";
|
|
3460
3605
|
function isBodyParseCall(node) {
|
|
3461
|
-
return node.type ===
|
|
3606
|
+
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");
|
|
3462
3607
|
}
|
|
3463
3608
|
var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
3464
3609
|
"cancel",
|
|
@@ -3473,21 +3618,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
|
3473
3618
|
var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
|
|
3474
3619
|
var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
|
|
3475
3620
|
function isTeardownCall(node) {
|
|
3476
|
-
return node.type ===
|
|
3621
|
+
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);
|
|
3477
3622
|
}
|
|
3478
3623
|
function isSilentExpression(node) {
|
|
3479
3624
|
switch (node.type) {
|
|
3480
|
-
case
|
|
3625
|
+
case AST_NODE_TYPES14.Literal:
|
|
3481
3626
|
return !("regex" in node);
|
|
3482
|
-
case
|
|
3627
|
+
case AST_NODE_TYPES14.Identifier:
|
|
3483
3628
|
return node.name === "undefined";
|
|
3484
|
-
case
|
|
3485
|
-
return node.operator === "void" && node.argument.type ===
|
|
3486
|
-
case
|
|
3629
|
+
case AST_NODE_TYPES14.UnaryExpression:
|
|
3630
|
+
return node.operator === "void" && node.argument.type === AST_NODE_TYPES14.Literal;
|
|
3631
|
+
case AST_NODE_TYPES14.ObjectExpression:
|
|
3487
3632
|
return node.properties.length === 0;
|
|
3488
|
-
case
|
|
3633
|
+
case AST_NODE_TYPES14.ArrayExpression:
|
|
3489
3634
|
return node.elements.length === 0;
|
|
3490
|
-
case
|
|
3635
|
+
case AST_NODE_TYPES14.TSAsExpression:
|
|
3491
3636
|
return isSilentExpression(node.expression);
|
|
3492
3637
|
default:
|
|
3493
3638
|
return false;
|
|
@@ -3495,7 +3640,7 @@ function isSilentExpression(node) {
|
|
|
3495
3640
|
}
|
|
3496
3641
|
function isSilentHandler(handler) {
|
|
3497
3642
|
const body = handler.body;
|
|
3498
|
-
if (body.type !==
|
|
3643
|
+
if (body.type !== AST_NODE_TYPES14.BlockStatement) {
|
|
3499
3644
|
return isSilentExpression(body);
|
|
3500
3645
|
}
|
|
3501
3646
|
if (body.body.length === 0) {
|
|
@@ -3503,13 +3648,13 @@ function isSilentHandler(handler) {
|
|
|
3503
3648
|
}
|
|
3504
3649
|
if (body.body.length === 1) {
|
|
3505
3650
|
const only = body.body[0];
|
|
3506
|
-
if (only !== void 0 && only.type ===
|
|
3651
|
+
if (only !== void 0 && only.type === AST_NODE_TYPES14.ReturnStatement) {
|
|
3507
3652
|
return only.argument === null || isSilentExpression(only.argument);
|
|
3508
3653
|
}
|
|
3509
3654
|
}
|
|
3510
3655
|
return false;
|
|
3511
3656
|
}
|
|
3512
|
-
var no_silent_promise_catch_default =
|
|
3657
|
+
var no_silent_promise_catch_default = ESLintUtils20.RuleCreator(
|
|
3513
3658
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3514
3659
|
)({
|
|
3515
3660
|
name: "no-silent-promise-catch",
|
|
@@ -3534,7 +3679,7 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3534
3679
|
return true;
|
|
3535
3680
|
}
|
|
3536
3681
|
let statement = call;
|
|
3537
|
-
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !==
|
|
3682
|
+
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== AST_NODE_TYPES14.VariableDeclaration) {
|
|
3538
3683
|
statement = statement.parent;
|
|
3539
3684
|
}
|
|
3540
3685
|
if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
|
|
@@ -3546,7 +3691,7 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3546
3691
|
};
|
|
3547
3692
|
return {
|
|
3548
3693
|
CallExpression(node) {
|
|
3549
|
-
if (node.callee.type !==
|
|
3694
|
+
if (node.callee.type !== AST_NODE_TYPES14.MemberExpression || node.callee.computed || node.callee.property.type !== AST_NODE_TYPES14.Identifier || node.callee.property.name !== "catch") {
|
|
3550
3695
|
return;
|
|
3551
3696
|
}
|
|
3552
3697
|
if (isBodyParseCall(node.callee.object)) {
|
|
@@ -3555,14 +3700,14 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3555
3700
|
if (isTeardownCall(node.callee.object)) {
|
|
3556
3701
|
return;
|
|
3557
3702
|
}
|
|
3558
|
-
if (node.parent.type ===
|
|
3703
|
+
if (node.parent.type === AST_NODE_TYPES14.MemberExpression && node.parent.object === node) {
|
|
3559
3704
|
return;
|
|
3560
3705
|
}
|
|
3561
3706
|
if (node.arguments.length !== 1) {
|
|
3562
3707
|
return;
|
|
3563
3708
|
}
|
|
3564
3709
|
const handler = node.arguments[0];
|
|
3565
|
-
if (handler === void 0 || handler.type !==
|
|
3710
|
+
if (handler === void 0 || handler.type !== AST_NODE_TYPES14.ArrowFunctionExpression && handler.type !== AST_NODE_TYPES14.FunctionExpression) {
|
|
3566
3711
|
return;
|
|
3567
3712
|
}
|
|
3568
3713
|
if (hasExplanatoryComment(node, handler)) {
|
|
@@ -3578,9 +3723,9 @@ var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
|
3578
3723
|
|
|
3579
3724
|
// src/rules/require-fetch-timeout.ts
|
|
3580
3725
|
import {
|
|
3581
|
-
AST_NODE_TYPES as
|
|
3582
|
-
ASTUtils,
|
|
3583
|
-
ESLintUtils as
|
|
3726
|
+
AST_NODE_TYPES as AST_NODE_TYPES15,
|
|
3727
|
+
ASTUtils as ASTUtils2,
|
|
3728
|
+
ESLintUtils as ESLintUtils21
|
|
3584
3729
|
} from "@typescript-eslint/utils";
|
|
3585
3730
|
var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
|
|
3586
3731
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
|
|
@@ -3598,14 +3743,14 @@ function matchesAnyPattern2(filename, patterns) {
|
|
|
3598
3743
|
return false;
|
|
3599
3744
|
}
|
|
3600
3745
|
function initProvablyLacksSignal(init) {
|
|
3601
|
-
if (init.type !==
|
|
3746
|
+
if (init.type !== AST_NODE_TYPES15.ObjectExpression) {
|
|
3602
3747
|
return false;
|
|
3603
3748
|
}
|
|
3604
3749
|
for (const prop of init.properties) {
|
|
3605
|
-
if (prop.type ===
|
|
3750
|
+
if (prop.type === AST_NODE_TYPES15.SpreadElement) {
|
|
3606
3751
|
return false;
|
|
3607
3752
|
}
|
|
3608
|
-
if (prop.key.type ===
|
|
3753
|
+
if (prop.key.type === AST_NODE_TYPES15.Identifier && prop.key.name === "signal" || prop.key.type === AST_NODE_TYPES15.Literal && prop.key.value === "signal") {
|
|
3609
3754
|
return false;
|
|
3610
3755
|
}
|
|
3611
3756
|
if (prop.computed) {
|
|
@@ -3615,9 +3760,9 @@ function initProvablyLacksSignal(init) {
|
|
|
3615
3760
|
return true;
|
|
3616
3761
|
}
|
|
3617
3762
|
function isStringish(node) {
|
|
3618
|
-
return node.type ===
|
|
3763
|
+
return node.type === AST_NODE_TYPES15.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES15.TemplateLiteral;
|
|
3619
3764
|
}
|
|
3620
|
-
var require_fetch_timeout_default =
|
|
3765
|
+
var require_fetch_timeout_default = ESLintUtils21.RuleCreator(
|
|
3621
3766
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3622
3767
|
)({
|
|
3623
3768
|
name: "require-fetch-timeout",
|
|
@@ -3654,14 +3799,14 @@ var require_fetch_timeout_default = ESLintUtils22.RuleCreator(
|
|
|
3654
3799
|
}
|
|
3655
3800
|
function resolvesToGlobal(identifier) {
|
|
3656
3801
|
const scope = context.sourceCode.getScope(identifier);
|
|
3657
|
-
const variable =
|
|
3802
|
+
const variable = ASTUtils2.findVariable(scope, identifier.name);
|
|
3658
3803
|
return variable === null || variable.defs.length === 0;
|
|
3659
3804
|
}
|
|
3660
3805
|
function isGlobalFetchCall2(callee) {
|
|
3661
|
-
if (callee.type ===
|
|
3806
|
+
if (callee.type === AST_NODE_TYPES15.Identifier) {
|
|
3662
3807
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
3663
3808
|
}
|
|
3664
|
-
return callee.type ===
|
|
3809
|
+
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);
|
|
3665
3810
|
}
|
|
3666
3811
|
return {
|
|
3667
3812
|
CallExpression(node) {
|
|
@@ -3682,14 +3827,14 @@ var require_fetch_timeout_default = ESLintUtils22.RuleCreator(
|
|
|
3682
3827
|
|
|
3683
3828
|
// src/rules/no-fat-try-blocks.ts
|
|
3684
3829
|
import {
|
|
3685
|
-
ESLintUtils as
|
|
3686
|
-
AST_NODE_TYPES as
|
|
3830
|
+
ESLintUtils as ESLintUtils22,
|
|
3831
|
+
AST_NODE_TYPES as AST_NODE_TYPES16
|
|
3687
3832
|
} from "@typescript-eslint/utils";
|
|
3688
3833
|
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
3689
3834
|
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3835
|
+
AST_NODE_TYPES16.FunctionDeclaration,
|
|
3836
|
+
AST_NODE_TYPES16.FunctionExpression,
|
|
3837
|
+
AST_NODE_TYPES16.ArrowFunctionExpression
|
|
3693
3838
|
]);
|
|
3694
3839
|
var PURE_METHODS = /* @__PURE__ */ new Set([
|
|
3695
3840
|
"map",
|
|
@@ -3787,22 +3932,22 @@ function isNode3(value) {
|
|
|
3787
3932
|
}
|
|
3788
3933
|
function isPureCall(node) {
|
|
3789
3934
|
const callee = node.callee;
|
|
3790
|
-
if (callee.type !==
|
|
3935
|
+
if (callee.type !== AST_NODE_TYPES16.MemberExpression) {
|
|
3791
3936
|
return false;
|
|
3792
3937
|
}
|
|
3793
3938
|
const property = callee.property;
|
|
3794
|
-
if (property.type !==
|
|
3939
|
+
if (property.type !== AST_NODE_TYPES16.Identifier) {
|
|
3795
3940
|
return false;
|
|
3796
3941
|
}
|
|
3797
|
-
if (callee.object.type ===
|
|
3942
|
+
if (callee.object.type === AST_NODE_TYPES16.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
|
|
3798
3943
|
return true;
|
|
3799
3944
|
}
|
|
3800
3945
|
return PURE_METHODS.has(property.name);
|
|
3801
3946
|
}
|
|
3802
3947
|
function isPureNew(node) {
|
|
3803
|
-
return node.callee.type ===
|
|
3948
|
+
return node.callee.type === AST_NODE_TYPES16.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
|
|
3804
3949
|
}
|
|
3805
|
-
function subtreeMatches(stmt, predicate) {
|
|
3950
|
+
function subtreeMatches(stmt, predicate, descendIntoFunctions = false) {
|
|
3806
3951
|
let found = false;
|
|
3807
3952
|
const visit = (current) => {
|
|
3808
3953
|
if (found) {
|
|
@@ -3816,7 +3961,7 @@ function subtreeMatches(stmt, predicate) {
|
|
|
3816
3961
|
if (key === "parent") {
|
|
3817
3962
|
continue;
|
|
3818
3963
|
}
|
|
3819
|
-
if (NESTED_FUNCTION_TYPES.has(current.type) && key === "body") {
|
|
3964
|
+
if (!descendIntoFunctions && NESTED_FUNCTION_TYPES.has(current.type) && key === "body") {
|
|
3820
3965
|
continue;
|
|
3821
3966
|
}
|
|
3822
3967
|
const value = current[key];
|
|
@@ -3837,20 +3982,20 @@ function subtreeMatches(stmt, predicate) {
|
|
|
3837
3982
|
visit(stmt);
|
|
3838
3983
|
return found;
|
|
3839
3984
|
}
|
|
3840
|
-
var hasAwait = (node) => subtreeMatches(node, (n) => n.type ===
|
|
3985
|
+
var hasAwait = (node) => subtreeMatches(node, (n) => n.type === AST_NODE_TYPES16.AwaitExpression);
|
|
3841
3986
|
var hasThrowingCallOrNew = (node) => subtreeMatches(
|
|
3842
3987
|
node,
|
|
3843
|
-
(n) => n.type ===
|
|
3988
|
+
(n) => n.type === AST_NODE_TYPES16.CallExpression && !isPureCall(n) || n.type === AST_NODE_TYPES16.NewExpression && !isPureNew(n)
|
|
3844
3989
|
);
|
|
3845
3990
|
function unwrap2(expr) {
|
|
3846
3991
|
let current = expr;
|
|
3847
|
-
while (current.type ===
|
|
3992
|
+
while (current.type === AST_NODE_TYPES16.ChainExpression || current.type === AST_NODE_TYPES16.TSNonNullExpression) {
|
|
3848
3993
|
current = current.expression;
|
|
3849
3994
|
}
|
|
3850
3995
|
return current;
|
|
3851
3996
|
}
|
|
3852
3997
|
function isBareCallStatement(stmt) {
|
|
3853
|
-
return stmt.type ===
|
|
3998
|
+
return stmt.type === AST_NODE_TYPES16.ExpressionStatement && unwrap2(stmt.expression).type === AST_NODE_TYPES16.CallExpression;
|
|
3854
3999
|
}
|
|
3855
4000
|
function canThrow(stmt) {
|
|
3856
4001
|
if (hasAwait(stmt)) {
|
|
@@ -3859,10 +4004,10 @@ function canThrow(stmt) {
|
|
|
3859
4004
|
if (isBareCallStatement(stmt)) {
|
|
3860
4005
|
return false;
|
|
3861
4006
|
}
|
|
3862
|
-
if (stmt.type ===
|
|
4007
|
+
if (stmt.type === AST_NODE_TYPES16.BlockStatement) {
|
|
3863
4008
|
return stmt.body.some(canThrow);
|
|
3864
4009
|
}
|
|
3865
|
-
if (stmt.type ===
|
|
4010
|
+
if (stmt.type === AST_NODE_TYPES16.IfStatement) {
|
|
3866
4011
|
return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
|
|
3867
4012
|
}
|
|
3868
4013
|
return hasThrowingCallOrNew(stmt);
|
|
@@ -3873,9 +4018,137 @@ function handlerRethrows(handler) {
|
|
|
3873
4018
|
}
|
|
3874
4019
|
const body = handler.body.body;
|
|
3875
4020
|
const last = body[body.length - 1];
|
|
3876
|
-
return last !== void 0 && last.type ===
|
|
4021
|
+
return last !== void 0 && last.type === AST_NODE_TYPES16.ThrowStatement;
|
|
4022
|
+
}
|
|
4023
|
+
var PASS_THROUGH_PARENTS = /* @__PURE__ */ new Set([
|
|
4024
|
+
AST_NODE_TYPES16.IfStatement,
|
|
4025
|
+
AST_NODE_TYPES16.TryStatement,
|
|
4026
|
+
AST_NODE_TYPES16.CatchClause,
|
|
4027
|
+
AST_NODE_TYPES16.LabeledStatement
|
|
4028
|
+
]);
|
|
4029
|
+
function isTerminalInFunction(node) {
|
|
4030
|
+
let current = node;
|
|
4031
|
+
let parent = current.parent;
|
|
4032
|
+
while (parent !== void 0) {
|
|
4033
|
+
if (parent.type === AST_NODE_TYPES16.BlockStatement) {
|
|
4034
|
+
if (parent.body[parent.body.length - 1] !== current) {
|
|
4035
|
+
return false;
|
|
4036
|
+
}
|
|
4037
|
+
} else if (parent.type === AST_NODE_TYPES16.Program) {
|
|
4038
|
+
return parent.body[parent.body.length - 1] === current;
|
|
4039
|
+
} else if (NESTED_FUNCTION_TYPES.has(parent.type)) {
|
|
4040
|
+
return true;
|
|
4041
|
+
} else if (!PASS_THROUGH_PARENTS.has(parent.type)) {
|
|
4042
|
+
return false;
|
|
4043
|
+
}
|
|
4044
|
+
current = parent;
|
|
4045
|
+
parent = current.parent;
|
|
4046
|
+
}
|
|
4047
|
+
return false;
|
|
4048
|
+
}
|
|
4049
|
+
function unwrapAwait(expr) {
|
|
4050
|
+
const inner = unwrap2(expr);
|
|
4051
|
+
return inner.type === AST_NODE_TYPES16.AwaitExpression ? unwrap2(inner.argument) : inner;
|
|
4052
|
+
}
|
|
4053
|
+
function handlerEndsByHandingOff(handler) {
|
|
4054
|
+
const body = handler.body.body;
|
|
4055
|
+
const last = body[body.length - 1];
|
|
4056
|
+
if (last === void 0) {
|
|
4057
|
+
return false;
|
|
4058
|
+
}
|
|
4059
|
+
if (last.type === AST_NODE_TYPES16.ReturnStatement || last.type === AST_NODE_TYPES16.ThrowStatement) {
|
|
4060
|
+
return true;
|
|
4061
|
+
}
|
|
4062
|
+
return last.type === AST_NODE_TYPES16.ExpressionStatement && unwrapAwait(last.expression).type === AST_NODE_TYPES16.CallExpression;
|
|
4063
|
+
}
|
|
4064
|
+
function collectBindingNames(pattern, names) {
|
|
4065
|
+
if (pattern.type === AST_NODE_TYPES16.Identifier) {
|
|
4066
|
+
names.add(pattern.name);
|
|
4067
|
+
return;
|
|
4068
|
+
}
|
|
4069
|
+
if (pattern.type === AST_NODE_TYPES16.ObjectPattern) {
|
|
4070
|
+
for (const property of pattern.properties) {
|
|
4071
|
+
collectBindingNames(
|
|
4072
|
+
property.type === AST_NODE_TYPES16.RestElement ? property.argument : property.value,
|
|
4073
|
+
names
|
|
4074
|
+
);
|
|
4075
|
+
}
|
|
4076
|
+
return;
|
|
4077
|
+
}
|
|
4078
|
+
if (pattern.type === AST_NODE_TYPES16.ArrayPattern) {
|
|
4079
|
+
for (const element of pattern.elements) {
|
|
4080
|
+
if (element !== null) {
|
|
4081
|
+
collectBindingNames(element, names);
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
return;
|
|
4085
|
+
}
|
|
4086
|
+
if (pattern.type === AST_NODE_TYPES16.AssignmentPattern || pattern.type === AST_NODE_TYPES16.RestElement) {
|
|
4087
|
+
collectBindingNames(
|
|
4088
|
+
pattern.type === AST_NODE_TYPES16.AssignmentPattern ? pattern.left : pattern.argument,
|
|
4089
|
+
names
|
|
4090
|
+
);
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
function caughtBindingNames(handler) {
|
|
4094
|
+
const names = /* @__PURE__ */ new Set();
|
|
4095
|
+
if (handler.param !== null) {
|
|
4096
|
+
collectBindingNames(handler.param, names);
|
|
4097
|
+
}
|
|
4098
|
+
return names;
|
|
4099
|
+
}
|
|
4100
|
+
function isPropertyName(node) {
|
|
4101
|
+
const parent = node.parent;
|
|
4102
|
+
if (parent.type === AST_NODE_TYPES16.MemberExpression) {
|
|
4103
|
+
return parent.property === node && !parent.computed;
|
|
4104
|
+
}
|
|
4105
|
+
if (parent.type === AST_NODE_TYPES16.Property) {
|
|
4106
|
+
return parent.key === node && !parent.computed;
|
|
4107
|
+
}
|
|
4108
|
+
return false;
|
|
4109
|
+
}
|
|
4110
|
+
function handlerMentionsCaughtBinding(handler) {
|
|
4111
|
+
const names = caughtBindingNames(handler);
|
|
4112
|
+
if (names.size === 0) {
|
|
4113
|
+
return false;
|
|
4114
|
+
}
|
|
4115
|
+
return subtreeMatches(
|
|
4116
|
+
handler.body,
|
|
4117
|
+
(n) => n.type === AST_NODE_TYPES16.Identifier && names.has(n.name) && !isPropertyName(n),
|
|
4118
|
+
true
|
|
4119
|
+
);
|
|
4120
|
+
}
|
|
4121
|
+
function isSuccessShapedValue(expr) {
|
|
4122
|
+
let current = expr;
|
|
4123
|
+
while (current.type === AST_NODE_TYPES16.TSAsExpression || current.type === AST_NODE_TYPES16.TSNonNullExpression) {
|
|
4124
|
+
current = current.expression;
|
|
4125
|
+
}
|
|
4126
|
+
if (current.type === AST_NODE_TYPES16.Literal) {
|
|
4127
|
+
return current.value === null || current.value === false;
|
|
4128
|
+
}
|
|
4129
|
+
if (current.type === AST_NODE_TYPES16.Identifier) {
|
|
4130
|
+
return current.name === "undefined";
|
|
4131
|
+
}
|
|
4132
|
+
if (current.type === AST_NODE_TYPES16.UnaryExpression) {
|
|
4133
|
+
return current.operator === "void";
|
|
4134
|
+
}
|
|
4135
|
+
if (current.type === AST_NODE_TYPES16.ArrayExpression) {
|
|
4136
|
+
return current.elements.length === 0;
|
|
4137
|
+
}
|
|
4138
|
+
if (current.type === AST_NODE_TYPES16.ObjectExpression) {
|
|
4139
|
+
return current.properties.length === 0;
|
|
4140
|
+
}
|
|
4141
|
+
return false;
|
|
3877
4142
|
}
|
|
3878
|
-
var
|
|
4143
|
+
var handlerReturnsSuccessShaped = (handler) => subtreeMatches(
|
|
4144
|
+
handler.body,
|
|
4145
|
+
(n) => n.type === AST_NODE_TYPES16.ReturnStatement && n.argument !== null && isSuccessShapedValue(n.argument)
|
|
4146
|
+
);
|
|
4147
|
+
function isTerminalErrorBoundary(node) {
|
|
4148
|
+
const handler = node.handler;
|
|
4149
|
+
return handler !== null && isTerminalInFunction(node) && handlerEndsByHandingOff(handler) && handlerMentionsCaughtBinding(handler) && !handlerReturnsSuccessShaped(handler);
|
|
4150
|
+
}
|
|
4151
|
+
var no_fat_try_blocks_default = ESLintUtils22.RuleCreator(
|
|
3879
4152
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3880
4153
|
)({
|
|
3881
4154
|
name: "no-fat-try-blocks",
|
|
@@ -3903,6 +4176,9 @@ var no_fat_try_blocks_default = ESLintUtils23.RuleCreator(
|
|
|
3903
4176
|
if (handlerRethrows(node.handler)) {
|
|
3904
4177
|
return;
|
|
3905
4178
|
}
|
|
4179
|
+
if (isTerminalErrorBoundary(node)) {
|
|
4180
|
+
return;
|
|
4181
|
+
}
|
|
3906
4182
|
const count = node.block.body.filter(canThrow).length;
|
|
3907
4183
|
if (count <= MAX_TRY_BODY_STATEMENTS) {
|
|
3908
4184
|
return;
|
|
@@ -3919,7 +4195,7 @@ var no_fat_try_blocks_default = ESLintUtils23.RuleCreator(
|
|
|
3919
4195
|
});
|
|
3920
4196
|
|
|
3921
4197
|
// src/rules/no-secret-in-log.ts
|
|
3922
|
-
import { ESLintUtils as
|
|
4198
|
+
import { ESLintUtils as ESLintUtils23 } from "@typescript-eslint/utils";
|
|
3923
4199
|
|
|
3924
4200
|
// src/rules/_secret_names.ts
|
|
3925
4201
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4181,7 +4457,7 @@ function propertyKeyName2(prop) {
|
|
|
4181
4457
|
}
|
|
4182
4458
|
return null;
|
|
4183
4459
|
}
|
|
4184
|
-
var no_secret_in_log_default =
|
|
4460
|
+
var no_secret_in_log_default = ESLintUtils23.RuleCreator(
|
|
4185
4461
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4186
4462
|
)({
|
|
4187
4463
|
name: "no-secret-in-log",
|
|
@@ -4258,24 +4534,24 @@ var no_secret_in_log_default = ESLintUtils24.RuleCreator(
|
|
|
4258
4534
|
});
|
|
4259
4535
|
|
|
4260
4536
|
// src/rules/no-unsafe-mock-casting.ts
|
|
4261
|
-
import { ESLintUtils as
|
|
4262
|
-
import { AST_NODE_TYPES as
|
|
4537
|
+
import { ESLintUtils as ESLintUtils24 } from "@typescript-eslint/utils";
|
|
4538
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17 } from "@typescript-eslint/utils";
|
|
4263
4539
|
function isMockTypeReference(node) {
|
|
4264
|
-
if (node.type !==
|
|
4540
|
+
if (node.type !== AST_NODE_TYPES17.TSTypeReference) {
|
|
4265
4541
|
return false;
|
|
4266
4542
|
}
|
|
4267
4543
|
const typeName = node.typeName;
|
|
4268
|
-
if (typeName.type ===
|
|
4544
|
+
if (typeName.type === AST_NODE_TYPES17.Identifier) {
|
|
4269
4545
|
const name = typeName.name;
|
|
4270
4546
|
return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
|
|
4271
4547
|
}
|
|
4272
|
-
if (typeName.type ===
|
|
4548
|
+
if (typeName.type === AST_NODE_TYPES17.TSQualifiedName) {
|
|
4273
4549
|
const rightName = typeName.right.name;
|
|
4274
4550
|
return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
|
|
4275
4551
|
}
|
|
4276
4552
|
return false;
|
|
4277
4553
|
}
|
|
4278
|
-
var no_unsafe_mock_casting_default =
|
|
4554
|
+
var no_unsafe_mock_casting_default = ESLintUtils24.RuleCreator(
|
|
4279
4555
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4280
4556
|
)({
|
|
4281
4557
|
name: "no-unsafe-mock-casting",
|
|
@@ -4308,8 +4584,8 @@ var no_unsafe_mock_casting_default = ESLintUtils25.RuleCreator(
|
|
|
4308
4584
|
|
|
4309
4585
|
// src/rules/prefer-string-literal-union.ts
|
|
4310
4586
|
import {
|
|
4311
|
-
ESLintUtils as
|
|
4312
|
-
AST_NODE_TYPES as
|
|
4587
|
+
ESLintUtils as ESLintUtils25,
|
|
4588
|
+
AST_NODE_TYPES as AST_NODE_TYPES18
|
|
4313
4589
|
} from "@typescript-eslint/utils";
|
|
4314
4590
|
import * as ts from "typescript";
|
|
4315
4591
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -4353,19 +4629,19 @@ function isChoiceLikeName(name) {
|
|
|
4353
4629
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
4354
4630
|
}
|
|
4355
4631
|
function keyName(key) {
|
|
4356
|
-
if (key.type ===
|
|
4632
|
+
if (key.type === AST_NODE_TYPES18.Identifier) {
|
|
4357
4633
|
return key.name;
|
|
4358
4634
|
}
|
|
4359
|
-
if (key.type ===
|
|
4635
|
+
if (key.type === AST_NODE_TYPES18.Literal && typeof key.value === "string") {
|
|
4360
4636
|
return key.value;
|
|
4361
4637
|
}
|
|
4362
4638
|
return null;
|
|
4363
4639
|
}
|
|
4364
4640
|
function isStringLiteralMember(t) {
|
|
4365
|
-
return t.type ===
|
|
4641
|
+
return t.type === AST_NODE_TYPES18.TSLiteralType && t.literal.type === AST_NODE_TYPES18.Literal && typeof t.literal.value === "string";
|
|
4366
4642
|
}
|
|
4367
4643
|
function isStringLiteralUnion(node) {
|
|
4368
|
-
if (node?.type !==
|
|
4644
|
+
if (node?.type !== AST_NODE_TYPES18.TSUnionType) {
|
|
4369
4645
|
return false;
|
|
4370
4646
|
}
|
|
4371
4647
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -4394,12 +4670,12 @@ function bindingSourceExpression(decl) {
|
|
|
4394
4670
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
4395
4671
|
}
|
|
4396
4672
|
function refKey(node) {
|
|
4397
|
-
if (node.type ===
|
|
4673
|
+
if (node.type === AST_NODE_TYPES18.Identifier) {
|
|
4398
4674
|
return node.name;
|
|
4399
4675
|
}
|
|
4400
|
-
if (node.type ===
|
|
4676
|
+
if (node.type === AST_NODE_TYPES18.MemberExpression && !node.computed) {
|
|
4401
4677
|
const inner = refKey(node.object);
|
|
4402
|
-
if (inner === null || node.property.type !==
|
|
4678
|
+
if (inner === null || node.property.type !== AST_NODE_TYPES18.Identifier) {
|
|
4403
4679
|
return null;
|
|
4404
4680
|
}
|
|
4405
4681
|
return `${inner}.${node.property.name}`;
|
|
@@ -4407,12 +4683,12 @@ function refKey(node) {
|
|
|
4407
4683
|
return null;
|
|
4408
4684
|
}
|
|
4409
4685
|
function strLiteral(node) {
|
|
4410
|
-
if (node.type ===
|
|
4686
|
+
if (node.type === AST_NODE_TYPES18.Literal && typeof node.value === "string") {
|
|
4411
4687
|
return node.value;
|
|
4412
4688
|
}
|
|
4413
4689
|
return null;
|
|
4414
4690
|
}
|
|
4415
|
-
var prefer_string_literal_union_default =
|
|
4691
|
+
var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
4416
4692
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4417
4693
|
)({
|
|
4418
4694
|
name: "prefer-string-literal-union",
|
|
@@ -4450,7 +4726,7 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4450
4726
|
);
|
|
4451
4727
|
let services;
|
|
4452
4728
|
try {
|
|
4453
|
-
services =
|
|
4729
|
+
services = ESLintUtils25.getParserServices(context);
|
|
4454
4730
|
} catch {
|
|
4455
4731
|
services = null;
|
|
4456
4732
|
}
|
|
@@ -4562,7 +4838,7 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4562
4838
|
containersWithUnion.add(container);
|
|
4563
4839
|
return;
|
|
4564
4840
|
}
|
|
4565
|
-
if (typeNode?.type !==
|
|
4841
|
+
if (typeNode?.type !== AST_NODE_TYPES18.TSStringKeyword) {
|
|
4566
4842
|
return;
|
|
4567
4843
|
}
|
|
4568
4844
|
const name = keyName(key);
|
|
@@ -4650,10 +4926,10 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4650
4926
|
}
|
|
4651
4927
|
};
|
|
4652
4928
|
function refKeyText(node) {
|
|
4653
|
-
if (node.type ===
|
|
4929
|
+
if (node.type === AST_NODE_TYPES18.BinaryExpression) {
|
|
4654
4930
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
4655
4931
|
}
|
|
4656
|
-
if (node.type ===
|
|
4932
|
+
if (node.type === AST_NODE_TYPES18.SwitchStatement) {
|
|
4657
4933
|
return refKey(node.discriminant) ?? "value";
|
|
4658
4934
|
}
|
|
4659
4935
|
return "value";
|
|
@@ -4663,13 +4939,10 @@ var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
|
4663
4939
|
|
|
4664
4940
|
// src/rules/prefer-zod-enum.ts
|
|
4665
4941
|
import {
|
|
4666
|
-
AST_NODE_TYPES as
|
|
4667
|
-
ESLintUtils as
|
|
4942
|
+
AST_NODE_TYPES as AST_NODE_TYPES19,
|
|
4943
|
+
ESLintUtils as ESLintUtils26
|
|
4668
4944
|
} from "@typescript-eslint/utils";
|
|
4669
|
-
|
|
4670
|
-
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
4671
|
-
}
|
|
4672
|
-
var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
4945
|
+
var prefer_zod_enum_default = ESLintUtils26.RuleCreator(
|
|
4673
4946
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
4674
4947
|
)({
|
|
4675
4948
|
name: "prefer-zod-enum",
|
|
@@ -4690,20 +4963,20 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4690
4963
|
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
4691
4964
|
function enumValues(node) {
|
|
4692
4965
|
const callee = node.callee;
|
|
4693
|
-
if (callee.type !==
|
|
4966
|
+
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
4967
|
return null;
|
|
4695
4968
|
}
|
|
4696
4969
|
const argument = node.arguments[0];
|
|
4697
|
-
if (argument === void 0 || argument.type !==
|
|
4970
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES19.ArrayExpression || argument.elements.length === 0) {
|
|
4698
4971
|
return null;
|
|
4699
4972
|
}
|
|
4700
4973
|
const values = [];
|
|
4701
4974
|
for (const element of argument.elements) {
|
|
4702
|
-
if (element === null || element.type !==
|
|
4975
|
+
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
4976
|
return null;
|
|
4704
4977
|
}
|
|
4705
4978
|
const value = element.arguments[0];
|
|
4706
|
-
if (value === void 0 || value.type !==
|
|
4979
|
+
if (value === void 0 || value.type !== AST_NODE_TYPES19.Literal || typeof value.value !== "string") {
|
|
4707
4980
|
return null;
|
|
4708
4981
|
}
|
|
4709
4982
|
values.push(value);
|
|
@@ -4712,11 +4985,11 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4712
4985
|
}
|
|
4713
4986
|
function buildFix(node, values) {
|
|
4714
4987
|
const argument = node.arguments[0];
|
|
4715
|
-
if (argument === void 0 || argument.type !==
|
|
4988
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES19.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
|
|
4716
4989
|
return void 0;
|
|
4717
4990
|
}
|
|
4718
4991
|
const callee = node.callee;
|
|
4719
|
-
if (callee.type !==
|
|
4992
|
+
if (callee.type !== AST_NODE_TYPES19.MemberExpression || callee.property.type !== AST_NODE_TYPES19.Identifier) {
|
|
4720
4993
|
return void 0;
|
|
4721
4994
|
}
|
|
4722
4995
|
return (fixer) => [
|
|
@@ -4733,7 +5006,7 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4733
5006
|
return;
|
|
4734
5007
|
}
|
|
4735
5008
|
for (const specifier of node.specifiers) {
|
|
4736
|
-
if (specifier.type ===
|
|
5009
|
+
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
5010
|
zodNamespaces.add(specifier.local.name);
|
|
4738
5011
|
}
|
|
4739
5012
|
}
|
|
@@ -4754,91 +5027,497 @@ var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
|
4754
5027
|
}
|
|
4755
5028
|
});
|
|
4756
5029
|
|
|
4757
|
-
// src/rules/
|
|
4758
|
-
import {
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
5030
|
+
// src/rules/prefer-zod-infer.ts
|
|
5031
|
+
import {
|
|
5032
|
+
AST_NODE_TYPES as AST_NODE_TYPES20,
|
|
5033
|
+
ESLintUtils as ESLintUtils27
|
|
5034
|
+
} from "@typescript-eslint/utils";
|
|
5035
|
+
var SHAPE_PRESERVING_METHODS = /* @__PURE__ */ new Set([
|
|
5036
|
+
"describe",
|
|
5037
|
+
"refine",
|
|
5038
|
+
"superRefine",
|
|
5039
|
+
"check",
|
|
5040
|
+
"meta",
|
|
5041
|
+
"register"
|
|
5042
|
+
]);
|
|
5043
|
+
var OPTIONAL_MODIFIERS = /* @__PURE__ */ new Set([
|
|
5044
|
+
"optional",
|
|
5045
|
+
"nullish",
|
|
5046
|
+
"default",
|
|
5047
|
+
"prefault",
|
|
5048
|
+
"catch"
|
|
5049
|
+
]);
|
|
5050
|
+
var NULLABLE_MODIFIERS = /* @__PURE__ */ new Set(["nullable", "nullish"]);
|
|
5051
|
+
var RESHAPING_MODIFIERS = /* @__PURE__ */ new Set([
|
|
5052
|
+
"transform",
|
|
5053
|
+
"pipe",
|
|
5054
|
+
"preprocess",
|
|
5055
|
+
"brand",
|
|
5056
|
+
"overwrite"
|
|
5057
|
+
]);
|
|
5058
|
+
var MODULE_LEVEL_RESHAPERS = /* @__PURE__ */ new Set([
|
|
5059
|
+
"transform",
|
|
5060
|
+
"pipe",
|
|
5061
|
+
"preprocess"
|
|
5062
|
+
]);
|
|
5063
|
+
var ZOD_TYPE_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
5064
|
+
"ZodType",
|
|
5065
|
+
"ZodSchema",
|
|
5066
|
+
"ZodTypeAny",
|
|
5067
|
+
"ZodMiniType",
|
|
5068
|
+
"Schema"
|
|
5069
|
+
]);
|
|
5070
|
+
var LEAF_NODE_TYPES = {
|
|
5071
|
+
string: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5072
|
+
email: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5073
|
+
url: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5074
|
+
uuid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5075
|
+
ulid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5076
|
+
cuid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5077
|
+
cuid2: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5078
|
+
nanoid: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5079
|
+
iso: [AST_NODE_TYPES20.TSStringKeyword],
|
|
5080
|
+
number: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5081
|
+
int: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5082
|
+
float32: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5083
|
+
float64: [AST_NODE_TYPES20.TSNumberKeyword],
|
|
5084
|
+
boolean: [AST_NODE_TYPES20.TSBooleanKeyword],
|
|
5085
|
+
bigint: [AST_NODE_TYPES20.TSBigIntKeyword],
|
|
5086
|
+
symbol: [AST_NODE_TYPES20.TSSymbolKeyword],
|
|
5087
|
+
any: [AST_NODE_TYPES20.TSAnyKeyword],
|
|
5088
|
+
unknown: [AST_NODE_TYPES20.TSUnknownKeyword],
|
|
5089
|
+
never: [AST_NODE_TYPES20.TSNeverKeyword],
|
|
5090
|
+
void: [AST_NODE_TYPES20.TSVoidKeyword],
|
|
5091
|
+
null: [AST_NODE_TYPES20.TSNullKeyword],
|
|
5092
|
+
undefined: [AST_NODE_TYPES20.TSUndefinedKeyword],
|
|
5093
|
+
literal: [AST_NODE_TYPES20.TSLiteralType],
|
|
5094
|
+
date: [AST_NODE_TYPES20.TSTypeReference],
|
|
5095
|
+
array: [AST_NODE_TYPES20.TSArrayType, AST_NODE_TYPES20.TSTypeReference],
|
|
5096
|
+
tuple: [AST_NODE_TYPES20.TSTupleType],
|
|
5097
|
+
object: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5098
|
+
strictObject: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5099
|
+
looseObject: [AST_NODE_TYPES20.TSTypeLiteral, AST_NODE_TYPES20.TSTypeReference],
|
|
5100
|
+
record: [AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSTypeLiteral],
|
|
5101
|
+
map: [AST_NODE_TYPES20.TSTypeReference],
|
|
5102
|
+
set: [AST_NODE_TYPES20.TSTypeReference],
|
|
5103
|
+
promise: [AST_NODE_TYPES20.TSTypeReference],
|
|
5104
|
+
enum: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSLiteralType],
|
|
5105
|
+
nativeEnum: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference, AST_NODE_TYPES20.TSLiteralType],
|
|
5106
|
+
union: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference],
|
|
5107
|
+
discriminatedUnion: [AST_NODE_TYPES20.TSUnionType, AST_NODE_TYPES20.TSTypeReference],
|
|
5108
|
+
intersection: [AST_NODE_TYPES20.TSIntersectionType, AST_NODE_TYPES20.TSTypeReference]
|
|
5109
|
+
};
|
|
5110
|
+
function normalizeSchemaName(name) {
|
|
5111
|
+
return name.replace(/Schema$/i, "").replace(/^Z(?=[A-Z])/, "").toLowerCase();
|
|
5112
|
+
}
|
|
5113
|
+
function normalizeTypeName(name) {
|
|
5114
|
+
return name.replace(/Type$/, "").toLowerCase();
|
|
5115
|
+
}
|
|
5116
|
+
function unwrapNullish(annotation) {
|
|
5117
|
+
if (annotation.type !== AST_NODE_TYPES20.TSUnionType) {
|
|
5118
|
+
return {
|
|
5119
|
+
core: annotation,
|
|
5120
|
+
nullable: annotation.type === AST_NODE_TYPES20.TSNullKeyword
|
|
5121
|
+
};
|
|
5122
|
+
}
|
|
5123
|
+
const rest = [];
|
|
5124
|
+
let nullable = false;
|
|
5125
|
+
for (const member of annotation.types) {
|
|
5126
|
+
if (member.type === AST_NODE_TYPES20.TSNullKeyword) {
|
|
5127
|
+
nullable = true;
|
|
4796
5128
|
continue;
|
|
4797
5129
|
}
|
|
4798
|
-
if (
|
|
4799
|
-
out[i] = " ";
|
|
4800
|
-
out[i + 1] = " ";
|
|
4801
|
-
i += 2;
|
|
4802
|
-
while (i < n && !(text[i] === "*" && text[i + 1] === "/")) {
|
|
4803
|
-
if (text[i] !== "\n") {
|
|
4804
|
-
out[i] = " ";
|
|
4805
|
-
}
|
|
4806
|
-
i += 1;
|
|
4807
|
-
}
|
|
4808
|
-
if (i < n) {
|
|
4809
|
-
out[i] = " ";
|
|
4810
|
-
out[i + 1] = " ";
|
|
4811
|
-
i += 2;
|
|
4812
|
-
}
|
|
5130
|
+
if (member.type === AST_NODE_TYPES20.TSUndefinedKeyword) {
|
|
4813
5131
|
continue;
|
|
4814
5132
|
}
|
|
4815
|
-
|
|
5133
|
+
rest.push(member);
|
|
4816
5134
|
}
|
|
4817
|
-
|
|
5135
|
+
if (rest.length === 1) {
|
|
5136
|
+
return { core: rest[0] ?? null, nullable };
|
|
5137
|
+
}
|
|
5138
|
+
return { core: rest.length === 0 ? null : annotation, nullable };
|
|
4818
5139
|
}
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
5140
|
+
function leafAgrees(leaf, annotation) {
|
|
5141
|
+
if (leaf === null || annotation === null) {
|
|
5142
|
+
return null;
|
|
5143
|
+
}
|
|
5144
|
+
const expected = LEAF_NODE_TYPES[leaf];
|
|
5145
|
+
if (expected === void 0) {
|
|
5146
|
+
return null;
|
|
5147
|
+
}
|
|
5148
|
+
const { core } = unwrapNullish(annotation);
|
|
5149
|
+
if (core === null) {
|
|
5150
|
+
return null;
|
|
5151
|
+
}
|
|
5152
|
+
return expected.includes(core.type);
|
|
5153
|
+
}
|
|
5154
|
+
var prefer_zod_infer_default = ESLintUtils27.RuleCreator(
|
|
5155
|
+
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
5156
|
+
)({
|
|
5157
|
+
name: "prefer-zod-infer",
|
|
5158
|
+
meta: {
|
|
5159
|
+
type: "problem",
|
|
5160
|
+
docs: {
|
|
5161
|
+
description: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it."
|
|
5162
|
+
},
|
|
5163
|
+
schema: [
|
|
5164
|
+
{
|
|
5165
|
+
type: "object",
|
|
5166
|
+
additionalProperties: false,
|
|
5167
|
+
properties: {
|
|
5168
|
+
ignoreTypeNames: {
|
|
5169
|
+
type: "array",
|
|
5170
|
+
items: { type: "string" }
|
|
5171
|
+
},
|
|
5172
|
+
requireIdenticalShape: { type: "boolean" }
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
],
|
|
5176
|
+
messages: {
|
|
5177
|
+
handWrittenTwin: "`{{typeName}}` restates the shape of the Zod schema `{{schemaName}}` declared in this module. Derive it instead \u2014 `type {{typeName}} = z.infer<typeof {{schemaName}}>` \u2014 so a field added to the schema cannot silently leave the type behind."
|
|
5178
|
+
}
|
|
5179
|
+
},
|
|
5180
|
+
defaultOptions: [{}],
|
|
5181
|
+
create(context, [optionsArg]) {
|
|
5182
|
+
const ignorePatterns = (optionsArg?.ignoreTypeNames ?? []).map(
|
|
5183
|
+
(source) => new RegExp(source, "u")
|
|
5184
|
+
);
|
|
5185
|
+
const requireIdenticalShape = optionsArg?.requireIdenticalShape ?? true;
|
|
5186
|
+
if (isTestFile(context.filename) || isStoryFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
5187
|
+
return {};
|
|
5188
|
+
}
|
|
5189
|
+
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
5190
|
+
const schemas = [];
|
|
5191
|
+
const typeDeclarations = [];
|
|
5192
|
+
const constrainedTypeNames = /* @__PURE__ */ new Set();
|
|
5193
|
+
const reshapedSchemaNames = /* @__PURE__ */ new Set();
|
|
5194
|
+
function zodCallChain(node) {
|
|
5195
|
+
const chain = [];
|
|
5196
|
+
let current = node;
|
|
5197
|
+
while (current.type === AST_NODE_TYPES20.CallExpression) {
|
|
5198
|
+
const callee = current.callee;
|
|
5199
|
+
if (callee.type !== AST_NODE_TYPES20.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES20.Identifier) {
|
|
5200
|
+
return null;
|
|
5201
|
+
}
|
|
5202
|
+
chain.push(current);
|
|
5203
|
+
const receiver = callee.object;
|
|
5204
|
+
if (receiver.type === AST_NODE_TYPES20.Identifier) {
|
|
5205
|
+
return zodNamespaces.has(receiver.name) ? chain.reverse() : null;
|
|
5206
|
+
}
|
|
5207
|
+
current = receiver;
|
|
5208
|
+
}
|
|
5209
|
+
return null;
|
|
5210
|
+
}
|
|
5211
|
+
function methodName(call) {
|
|
5212
|
+
const callee = call.callee;
|
|
5213
|
+
return callee.type === AST_NODE_TYPES20.MemberExpression && callee.property.type === AST_NODE_TYPES20.Identifier ? callee.property.name : "";
|
|
5214
|
+
}
|
|
5215
|
+
function schemaField(node) {
|
|
5216
|
+
const modifiers = [];
|
|
5217
|
+
let current = node;
|
|
5218
|
+
let leaf = null;
|
|
5219
|
+
while (current.type === AST_NODE_TYPES20.CallExpression) {
|
|
5220
|
+
const callee = current.callee;
|
|
5221
|
+
if (callee.type !== AST_NODE_TYPES20.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES20.Identifier) {
|
|
5222
|
+
break;
|
|
5223
|
+
}
|
|
5224
|
+
const receiver = callee.object;
|
|
5225
|
+
if (receiver.type === AST_NODE_TYPES20.Identifier && zodNamespaces.has(receiver.name)) {
|
|
5226
|
+
leaf = callee.property.name;
|
|
5227
|
+
break;
|
|
5228
|
+
}
|
|
5229
|
+
modifiers.push(callee.property.name);
|
|
5230
|
+
current = receiver;
|
|
5231
|
+
}
|
|
5232
|
+
return {
|
|
5233
|
+
leaf,
|
|
5234
|
+
optional: modifiers.some((name) => OPTIONAL_MODIFIERS.has(name)),
|
|
5235
|
+
nullable: modifiers.some((name) => NULLABLE_MODIFIERS.has(name)),
|
|
5236
|
+
reshaped: modifiers.some((name) => RESHAPING_MODIFIERS.has(name))
|
|
5237
|
+
};
|
|
5238
|
+
}
|
|
5239
|
+
function schemaFields(init) {
|
|
5240
|
+
const chain = zodCallChain(init);
|
|
5241
|
+
if (chain === null || chain.length === 0) {
|
|
5242
|
+
return null;
|
|
5243
|
+
}
|
|
5244
|
+
const [base, ...rest] = chain;
|
|
5245
|
+
if (base === void 0) {
|
|
5246
|
+
return null;
|
|
5247
|
+
}
|
|
5248
|
+
const baseMethod = methodName(base);
|
|
5249
|
+
if (baseMethod !== "object" && baseMethod !== "strictObject") {
|
|
5250
|
+
return null;
|
|
5251
|
+
}
|
|
5252
|
+
if (rest.some((call) => !SHAPE_PRESERVING_METHODS.has(methodName(call)))) {
|
|
5253
|
+
return null;
|
|
5254
|
+
}
|
|
5255
|
+
const shape = base.arguments[0];
|
|
5256
|
+
if (shape === void 0 || shape.type !== AST_NODE_TYPES20.ObjectExpression) {
|
|
5257
|
+
return null;
|
|
5258
|
+
}
|
|
5259
|
+
const fields = /* @__PURE__ */ new Map();
|
|
5260
|
+
for (const property of shape.properties) {
|
|
5261
|
+
if (property.type !== AST_NODE_TYPES20.Property || property.computed) {
|
|
5262
|
+
return null;
|
|
5263
|
+
}
|
|
5264
|
+
const { key } = property;
|
|
5265
|
+
const name = key.type === AST_NODE_TYPES20.Identifier ? key.name : key.type === AST_NODE_TYPES20.Literal && typeof key.value === "string" ? key.value : null;
|
|
5266
|
+
if (name === null) {
|
|
5267
|
+
return null;
|
|
5268
|
+
}
|
|
5269
|
+
fields.set(name, schemaField(property.value));
|
|
5270
|
+
}
|
|
5271
|
+
return fields.size === 0 ? null : fields;
|
|
5272
|
+
}
|
|
5273
|
+
function typeMembers(members) {
|
|
5274
|
+
const result = /* @__PURE__ */ new Map();
|
|
5275
|
+
for (const member of members) {
|
|
5276
|
+
if (member.type !== AST_NODE_TYPES20.TSPropertySignature || member.computed) {
|
|
5277
|
+
return null;
|
|
5278
|
+
}
|
|
5279
|
+
const { key } = member;
|
|
5280
|
+
const name = key.type === AST_NODE_TYPES20.Identifier ? key.name : key.type === AST_NODE_TYPES20.Literal && typeof key.value === "string" ? key.value : null;
|
|
5281
|
+
if (name === null) {
|
|
5282
|
+
return null;
|
|
5283
|
+
}
|
|
5284
|
+
const annotation = member.typeAnnotation?.typeAnnotation ?? null;
|
|
5285
|
+
result.set(name, {
|
|
5286
|
+
optional: member.optional === true,
|
|
5287
|
+
nullable: annotation !== null && unwrapNullish(annotation).nullable,
|
|
5288
|
+
annotation
|
|
5289
|
+
});
|
|
5290
|
+
}
|
|
5291
|
+
return result.size === 0 ? null : result;
|
|
5292
|
+
}
|
|
5293
|
+
function collectConstrainedNames(node) {
|
|
5294
|
+
if (node.type === AST_NODE_TYPES20.TSTypeReference) {
|
|
5295
|
+
if (node.typeName.type === AST_NODE_TYPES20.Identifier) {
|
|
5296
|
+
constrainedTypeNames.add(node.typeName.name);
|
|
5297
|
+
}
|
|
5298
|
+
for (const argument of node.typeArguments?.params ?? []) {
|
|
5299
|
+
collectConstrainedNames(argument);
|
|
5300
|
+
}
|
|
5301
|
+
return;
|
|
5302
|
+
}
|
|
5303
|
+
if (node.type === AST_NODE_TYPES20.TSArrayType) {
|
|
5304
|
+
collectConstrainedNames(node.elementType);
|
|
5305
|
+
return;
|
|
5306
|
+
}
|
|
5307
|
+
if (node.type === AST_NODE_TYPES20.TSUnionType || node.type === AST_NODE_TYPES20.TSIntersectionType) {
|
|
5308
|
+
for (const member of node.types) {
|
|
5309
|
+
collectConstrainedNames(member);
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
function isTwin(fields, members) {
|
|
5314
|
+
if (!requireIdenticalShape) {
|
|
5315
|
+
return true;
|
|
5316
|
+
}
|
|
5317
|
+
if (fields.size !== members.size) {
|
|
5318
|
+
return false;
|
|
5319
|
+
}
|
|
5320
|
+
let agreements = 0;
|
|
5321
|
+
for (const [name, field] of fields) {
|
|
5322
|
+
const member = members.get(name);
|
|
5323
|
+
if (member === void 0) {
|
|
5324
|
+
return false;
|
|
5325
|
+
}
|
|
5326
|
+
if (field.reshaped) {
|
|
5327
|
+
return false;
|
|
5328
|
+
}
|
|
5329
|
+
if (field.optional !== member.optional) {
|
|
5330
|
+
return false;
|
|
5331
|
+
}
|
|
5332
|
+
if (field.nullable !== member.nullable) {
|
|
5333
|
+
return false;
|
|
5334
|
+
}
|
|
5335
|
+
const agrees = leafAgrees(field.leaf, member.annotation);
|
|
5336
|
+
if (agrees === false) {
|
|
5337
|
+
return false;
|
|
5338
|
+
}
|
|
5339
|
+
if (agrees === true) {
|
|
5340
|
+
agreements += 1;
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
return agreements > 0;
|
|
5344
|
+
}
|
|
5345
|
+
return {
|
|
5346
|
+
ImportDeclaration(node) {
|
|
5347
|
+
if (!isZodModule(node.source.value)) {
|
|
5348
|
+
return;
|
|
5349
|
+
}
|
|
5350
|
+
for (const specifier of node.specifiers) {
|
|
5351
|
+
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") {
|
|
5352
|
+
zodNamespaces.add(specifier.local.name);
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
},
|
|
5356
|
+
VariableDeclarator(node) {
|
|
5357
|
+
if (node.id.type !== AST_NODE_TYPES20.Identifier || node.init == null) {
|
|
5358
|
+
return;
|
|
5359
|
+
}
|
|
5360
|
+
const fields = schemaFields(node.init);
|
|
5361
|
+
if (fields !== null) {
|
|
5362
|
+
schemas.push({ name: node.id.name, fields });
|
|
5363
|
+
}
|
|
5364
|
+
},
|
|
5365
|
+
/** Guard (f): `XSchema.transform(...)` anywhere in the module. */
|
|
5366
|
+
"MemberExpression[computed=false]"(node) {
|
|
5367
|
+
if (node.object.type === AST_NODE_TYPES20.Identifier && node.property.type === AST_NODE_TYPES20.Identifier && MODULE_LEVEL_RESHAPERS.has(node.property.name)) {
|
|
5368
|
+
reshapedSchemaNames.add(node.object.name);
|
|
5369
|
+
}
|
|
5370
|
+
},
|
|
5371
|
+
/** Guard (c): `z.ZodType<T>` and every other type argument it carries. */
|
|
5372
|
+
TSTypeReference(node) {
|
|
5373
|
+
const { typeName } = node;
|
|
5374
|
+
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;
|
|
5375
|
+
if (referenced === null || !ZOD_TYPE_CONSTRAINTS.has(referenced)) {
|
|
5376
|
+
return;
|
|
5377
|
+
}
|
|
5378
|
+
for (const argument of node.typeArguments?.params ?? []) {
|
|
5379
|
+
collectConstrainedNames(argument);
|
|
5380
|
+
}
|
|
5381
|
+
},
|
|
5382
|
+
TSInterfaceDeclaration(node) {
|
|
5383
|
+
if (node.typeParameters !== void 0 || (node.extends?.length ?? 0) > 0) {
|
|
5384
|
+
return;
|
|
5385
|
+
}
|
|
5386
|
+
const members = typeMembers(node.body.body);
|
|
5387
|
+
if (members !== null) {
|
|
5388
|
+
typeDeclarations.push({ name: node.id.name, node: node.id, members });
|
|
5389
|
+
}
|
|
5390
|
+
},
|
|
5391
|
+
TSTypeAliasDeclaration(node) {
|
|
5392
|
+
if (node.typeParameters !== void 0 || node.typeAnnotation.type !== AST_NODE_TYPES20.TSTypeLiteral) {
|
|
5393
|
+
return;
|
|
5394
|
+
}
|
|
5395
|
+
const members = typeMembers(node.typeAnnotation.members);
|
|
5396
|
+
if (members !== null) {
|
|
5397
|
+
typeDeclarations.push({ name: node.id.name, node: node.id, members });
|
|
5398
|
+
}
|
|
5399
|
+
},
|
|
5400
|
+
"Program:exit"() {
|
|
5401
|
+
if (schemas.length === 0 || typeDeclarations.length === 0) {
|
|
5402
|
+
return;
|
|
5403
|
+
}
|
|
5404
|
+
const byName = /* @__PURE__ */ new Map();
|
|
5405
|
+
for (const schema of schemas) {
|
|
5406
|
+
const key = normalizeSchemaName(schema.name);
|
|
5407
|
+
if (key !== "" && !byName.has(key)) {
|
|
5408
|
+
byName.set(key, schema);
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
for (const declaration of typeDeclarations) {
|
|
5412
|
+
if (constrainedTypeNames.has(declaration.name)) {
|
|
5413
|
+
continue;
|
|
5414
|
+
}
|
|
5415
|
+
if (ignorePatterns.some((pattern) => pattern.test(declaration.name))) {
|
|
5416
|
+
continue;
|
|
5417
|
+
}
|
|
5418
|
+
const schema = byName.get(normalizeTypeName(declaration.name));
|
|
5419
|
+
if (schema === void 0 || reshapedSchemaNames.has(schema.name)) {
|
|
5420
|
+
continue;
|
|
5421
|
+
}
|
|
5422
|
+
if (!isTwin(schema.fields, declaration.members)) {
|
|
5423
|
+
continue;
|
|
5424
|
+
}
|
|
5425
|
+
context.report({
|
|
5426
|
+
node: declaration.node,
|
|
5427
|
+
messageId: "handWrittenTwin",
|
|
5428
|
+
data: { typeName: declaration.name, schemaName: schema.name }
|
|
5429
|
+
});
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
};
|
|
5433
|
+
}
|
|
5434
|
+
});
|
|
5435
|
+
|
|
5436
|
+
// src/rules/no-offset-pagination.ts
|
|
5437
|
+
import { ESLintUtils as ESLintUtils28 } from "@typescript-eslint/utils";
|
|
5438
|
+
|
|
5439
|
+
// src/rules/_sql.ts
|
|
5440
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
|
|
5441
|
+
function stripSqlNoise(text) {
|
|
5442
|
+
const out = [...text];
|
|
5443
|
+
const n = text.length;
|
|
5444
|
+
let i = 0;
|
|
5445
|
+
while (i < n) {
|
|
5446
|
+
const ch = text[i];
|
|
5447
|
+
if (ch === "'" || ch === '"') {
|
|
5448
|
+
out[i] = " ";
|
|
5449
|
+
i += 1;
|
|
5450
|
+
while (i < n) {
|
|
5451
|
+
const c = text[i];
|
|
5452
|
+
if (c === ch) {
|
|
5453
|
+
if (i + 1 < n && text[i + 1] === ch) {
|
|
5454
|
+
out[i] = " ";
|
|
5455
|
+
out[i + 1] = " ";
|
|
5456
|
+
i += 2;
|
|
5457
|
+
continue;
|
|
5458
|
+
}
|
|
5459
|
+
out[i] = " ";
|
|
5460
|
+
i += 1;
|
|
5461
|
+
break;
|
|
5462
|
+
}
|
|
5463
|
+
if (c !== "\n") {
|
|
5464
|
+
out[i] = " ";
|
|
5465
|
+
}
|
|
5466
|
+
i += 1;
|
|
5467
|
+
}
|
|
5468
|
+
continue;
|
|
5469
|
+
}
|
|
5470
|
+
if (ch === "-" && text[i + 1] === "-") {
|
|
5471
|
+
while (i < n && text[i] !== "\n") {
|
|
5472
|
+
out[i] = " ";
|
|
5473
|
+
i += 1;
|
|
5474
|
+
}
|
|
5475
|
+
continue;
|
|
5476
|
+
}
|
|
5477
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
5478
|
+
out[i] = " ";
|
|
5479
|
+
out[i + 1] = " ";
|
|
5480
|
+
i += 2;
|
|
5481
|
+
while (i < n && !(text[i] === "*" && text[i + 1] === "/")) {
|
|
5482
|
+
if (text[i] !== "\n") {
|
|
5483
|
+
out[i] = " ";
|
|
5484
|
+
}
|
|
5485
|
+
i += 1;
|
|
5486
|
+
}
|
|
5487
|
+
if (i < n) {
|
|
5488
|
+
out[i] = " ";
|
|
5489
|
+
out[i + 1] = " ";
|
|
5490
|
+
i += 2;
|
|
5491
|
+
}
|
|
5492
|
+
continue;
|
|
5493
|
+
}
|
|
5494
|
+
i += 1;
|
|
5495
|
+
}
|
|
5496
|
+
return out.join("");
|
|
5497
|
+
}
|
|
5498
|
+
var SUBSTITUTION_MARKER = "?";
|
|
5499
|
+
function sqlTextOf(node) {
|
|
5500
|
+
switch (node.type) {
|
|
5501
|
+
case AST_NODE_TYPES21.Literal:
|
|
5502
|
+
return typeof node.value === "string" ? node.value : null;
|
|
5503
|
+
case AST_NODE_TYPES21.TemplateLiteral:
|
|
5504
|
+
return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
|
|
5505
|
+
case AST_NODE_TYPES21.TaggedTemplateExpression:
|
|
5506
|
+
return sqlTextOf(node.quasi);
|
|
5507
|
+
case AST_NODE_TYPES21.BinaryExpression: {
|
|
5508
|
+
if (node.operator !== "+") {
|
|
5509
|
+
return null;
|
|
5510
|
+
}
|
|
5511
|
+
const left = sqlTextOf(node.left);
|
|
5512
|
+
const right = sqlTextOf(node.right);
|
|
5513
|
+
return left !== null && right !== null ? left + right : null;
|
|
5514
|
+
}
|
|
5515
|
+
case AST_NODE_TYPES21.ArrayExpression: {
|
|
5516
|
+
const parts = [];
|
|
5517
|
+
for (const element of node.elements) {
|
|
5518
|
+
if (element === null) {
|
|
5519
|
+
return null;
|
|
5520
|
+
}
|
|
4842
5521
|
const part = sqlTextOf(element);
|
|
4843
5522
|
if (part === null) {
|
|
4844
5523
|
return null;
|
|
@@ -4853,7 +5532,7 @@ function sqlTextOf(node) {
|
|
|
4853
5532
|
}
|
|
4854
5533
|
function isJoinedFragmentArray(node) {
|
|
4855
5534
|
const parent = node.parent;
|
|
4856
|
-
return parent?.type ===
|
|
5535
|
+
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;
|
|
4857
5536
|
}
|
|
4858
5537
|
function markConsumed(node, consumed) {
|
|
4859
5538
|
consumed.add(node);
|
|
@@ -4932,15 +5611,15 @@ var no_offset_pagination_default = ESLintUtils28.RuleCreator(
|
|
|
4932
5611
|
});
|
|
4933
5612
|
|
|
4934
5613
|
// src/rules/no-positional-tuple-return.ts
|
|
4935
|
-
import { AST_NODE_TYPES as
|
|
5614
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES22, ESLintUtils as ESLintUtils29 } from "@typescript-eslint/utils";
|
|
4936
5615
|
var MIN_ELEMENTS = 2;
|
|
4937
5616
|
var ACCESSOR_PAIR_LENGTH = 2;
|
|
4938
5617
|
var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
|
|
4939
5618
|
function tupleReturnType(node) {
|
|
4940
|
-
if (node.type ===
|
|
5619
|
+
if (node.type === AST_NODE_TYPES22.TSTupleType) {
|
|
4941
5620
|
return node;
|
|
4942
5621
|
}
|
|
4943
|
-
if (node.type ===
|
|
5622
|
+
if (node.type === AST_NODE_TYPES22.TSTypeReference && node.typeName.type === AST_NODE_TYPES22.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
|
|
4944
5623
|
const argument = node.typeArguments?.params[0];
|
|
4945
5624
|
return argument === void 0 ? null : tupleReturnType(argument);
|
|
4946
5625
|
}
|
|
@@ -4954,30 +5633,30 @@ function isPermittedTuple(tuple, sourceCode) {
|
|
|
4954
5633
|
if (elements.length < MIN_ELEMENTS) {
|
|
4955
5634
|
return true;
|
|
4956
5635
|
}
|
|
4957
|
-
if (elements.some((element) => element.type ===
|
|
5636
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES22.TSRestType)) {
|
|
4958
5637
|
return true;
|
|
4959
5638
|
}
|
|
4960
|
-
if (elements.some((element) => element.type ===
|
|
5639
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES22.TSNamedTupleMember)) {
|
|
4961
5640
|
return true;
|
|
4962
5641
|
}
|
|
4963
|
-
if (elements[0]?.type ===
|
|
5642
|
+
if (elements[0]?.type === AST_NODE_TYPES22.TSLiteralType) {
|
|
4964
5643
|
return true;
|
|
4965
5644
|
}
|
|
4966
|
-
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type ===
|
|
5645
|
+
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === AST_NODE_TYPES22.TSFunctionType)) {
|
|
4967
5646
|
return true;
|
|
4968
5647
|
}
|
|
4969
5648
|
const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
|
|
4970
5649
|
return texts.size === 1;
|
|
4971
5650
|
}
|
|
4972
5651
|
function functionName(node) {
|
|
4973
|
-
if (node.type ===
|
|
5652
|
+
if (node.type === AST_NODE_TYPES22.FunctionDeclaration) {
|
|
4974
5653
|
return node.id?.name ?? null;
|
|
4975
5654
|
}
|
|
4976
5655
|
const parent = node.parent;
|
|
4977
|
-
if (parent?.type ===
|
|
5656
|
+
if (parent?.type === AST_NODE_TYPES22.VariableDeclarator && parent.id.type === AST_NODE_TYPES22.Identifier) {
|
|
4978
5657
|
return parent.id.name;
|
|
4979
5658
|
}
|
|
4980
|
-
if ((parent?.type ===
|
|
5659
|
+
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) {
|
|
4981
5660
|
return parent.key.name;
|
|
4982
5661
|
}
|
|
4983
5662
|
return null;
|
|
@@ -4985,7 +5664,7 @@ function functionName(node) {
|
|
|
4985
5664
|
function isInlineExported(node) {
|
|
4986
5665
|
for (let current = node; current != null; current = current.parent) {
|
|
4987
5666
|
const parent = current.parent;
|
|
4988
|
-
if (parent?.type ===
|
|
5667
|
+
if (parent?.type === AST_NODE_TYPES22.ExportNamedDeclaration || parent?.type === AST_NODE_TYPES22.ExportDefaultDeclaration) {
|
|
4989
5668
|
return true;
|
|
4990
5669
|
}
|
|
4991
5670
|
}
|
|
@@ -4994,18 +5673,18 @@ function isInlineExported(node) {
|
|
|
4994
5673
|
function moduleScopeBindingName(node) {
|
|
4995
5674
|
let current = node;
|
|
4996
5675
|
let child = node;
|
|
4997
|
-
while (current.parent != null && current.parent.type !==
|
|
5676
|
+
while (current.parent != null && current.parent.type !== AST_NODE_TYPES22.Program) {
|
|
4998
5677
|
child = current;
|
|
4999
5678
|
current = current.parent;
|
|
5000
5679
|
}
|
|
5001
|
-
if (current.parent?.type !==
|
|
5680
|
+
if (current.parent?.type !== AST_NODE_TYPES22.Program) {
|
|
5002
5681
|
return null;
|
|
5003
5682
|
}
|
|
5004
|
-
if (current.type ===
|
|
5683
|
+
if (current.type === AST_NODE_TYPES22.FunctionDeclaration || current.type === AST_NODE_TYPES22.ClassDeclaration) {
|
|
5005
5684
|
return current.id?.name ?? null;
|
|
5006
5685
|
}
|
|
5007
|
-
if (current.type ===
|
|
5008
|
-
if (child.type !==
|
|
5686
|
+
if (current.type === AST_NODE_TYPES22.VariableDeclaration) {
|
|
5687
|
+
if (child.type !== AST_NODE_TYPES22.VariableDeclarator || child.id.type !== AST_NODE_TYPES22.Identifier) {
|
|
5009
5688
|
return null;
|
|
5010
5689
|
}
|
|
5011
5690
|
return child.id.name;
|
|
@@ -5015,19 +5694,19 @@ function moduleScopeBindingName(node) {
|
|
|
5015
5694
|
function specifierExportedNames(program) {
|
|
5016
5695
|
const names = /* @__PURE__ */ new Set();
|
|
5017
5696
|
for (const statement of program.body) {
|
|
5018
|
-
if (statement.type ===
|
|
5697
|
+
if (statement.type === AST_NODE_TYPES22.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
|
|
5019
5698
|
for (const specifier of statement.specifiers) {
|
|
5020
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
5699
|
+
if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES22.Identifier) {
|
|
5021
5700
|
names.add(specifier.local.name);
|
|
5022
5701
|
}
|
|
5023
5702
|
}
|
|
5024
5703
|
continue;
|
|
5025
5704
|
}
|
|
5026
|
-
if (statement.type ===
|
|
5705
|
+
if (statement.type === AST_NODE_TYPES22.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES22.Identifier) {
|
|
5027
5706
|
names.add(statement.declaration.name);
|
|
5028
5707
|
continue;
|
|
5029
5708
|
}
|
|
5030
|
-
if (statement.type ===
|
|
5709
|
+
if (statement.type === AST_NODE_TYPES22.TSExportAssignment && statement.expression.type === AST_NODE_TYPES22.Identifier) {
|
|
5031
5710
|
names.add(statement.expression.name);
|
|
5032
5711
|
}
|
|
5033
5712
|
}
|
|
@@ -5091,16 +5770,16 @@ var no_positional_tuple_return_default = ESLintUtils29.RuleCreator(
|
|
|
5091
5770
|
});
|
|
5092
5771
|
|
|
5093
5772
|
// src/rules/no-repeated-string-literal.ts
|
|
5094
|
-
import { AST_NODE_TYPES as
|
|
5773
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23, ESLintUtils as ESLintUtils30 } from "@typescript-eslint/utils";
|
|
5095
5774
|
var MIN_LENGTH = 40;
|
|
5096
5775
|
var MIN_DISTINCT_SCOPES = 2;
|
|
5097
5776
|
var PREVIEW_LENGTH = 40;
|
|
5098
5777
|
var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
|
|
5099
5778
|
var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
|
|
5100
|
-
var
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5779
|
+
var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
|
|
5780
|
+
AST_NODE_TYPES23.FunctionDeclaration,
|
|
5781
|
+
AST_NODE_TYPES23.FunctionExpression,
|
|
5782
|
+
AST_NODE_TYPES23.ArrowFunctionExpression
|
|
5104
5783
|
]);
|
|
5105
5784
|
function isStructured(value) {
|
|
5106
5785
|
return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
|
|
@@ -5111,7 +5790,7 @@ function preview(value) {
|
|
|
5111
5790
|
}
|
|
5112
5791
|
function enclosingFunction(node) {
|
|
5113
5792
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5114
|
-
if (
|
|
5793
|
+
if (FUNCTION_TYPES2.has(current.type)) {
|
|
5115
5794
|
return current;
|
|
5116
5795
|
}
|
|
5117
5796
|
}
|
|
@@ -5122,7 +5801,7 @@ function isScaffolding(node) {
|
|
|
5122
5801
|
if (parent === void 0) {
|
|
5123
5802
|
return true;
|
|
5124
5803
|
}
|
|
5125
|
-
return parent.type ===
|
|
5804
|
+
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;
|
|
5126
5805
|
}
|
|
5127
5806
|
var no_repeated_string_literal_default = ESLintUtils30.RuleCreator(
|
|
5128
5807
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
@@ -5164,7 +5843,7 @@ var no_repeated_string_literal_default = ESLintUtils30.RuleCreator(
|
|
|
5164
5843
|
}
|
|
5165
5844
|
},
|
|
5166
5845
|
TemplateLiteral(node) {
|
|
5167
|
-
if (node.parent.type ===
|
|
5846
|
+
if (node.parent.type === AST_NODE_TYPES23.TaggedTemplateExpression) {
|
|
5168
5847
|
return;
|
|
5169
5848
|
}
|
|
5170
5849
|
const [only] = node.quasis;
|
|
@@ -5267,7 +5946,7 @@ var no_select_star_default = ESLintUtils31.RuleCreator(
|
|
|
5267
5946
|
});
|
|
5268
5947
|
|
|
5269
5948
|
// src/rules/no-sleep-in-test-body.ts
|
|
5270
|
-
import { AST_NODE_TYPES as
|
|
5949
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ESLintUtils as ESLintUtils32 } from "@typescript-eslint/utils";
|
|
5271
5950
|
var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
|
|
5272
5951
|
var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
5273
5952
|
"it",
|
|
@@ -5275,43 +5954,43 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
|
5275
5954
|
"beforeEach",
|
|
5276
5955
|
"afterEach"
|
|
5277
5956
|
]);
|
|
5278
|
-
var
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5957
|
+
var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
|
|
5958
|
+
AST_NODE_TYPES24.FunctionDeclaration,
|
|
5959
|
+
AST_NODE_TYPES24.FunctionExpression,
|
|
5960
|
+
AST_NODE_TYPES24.ArrowFunctionExpression
|
|
5282
5961
|
]);
|
|
5283
5962
|
function isNonzeroNumericLiteral(node) {
|
|
5284
|
-
return node?.type ===
|
|
5963
|
+
return node?.type === AST_NODE_TYPES24.Literal && typeof node.value === "number" && node.value !== 0;
|
|
5285
5964
|
}
|
|
5286
5965
|
function isTimedSetTimeout(node) {
|
|
5287
|
-
return node.type ===
|
|
5966
|
+
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]);
|
|
5288
5967
|
}
|
|
5289
5968
|
function isPromiseSleep(node) {
|
|
5290
|
-
if (node.callee.type !==
|
|
5969
|
+
if (node.callee.type !== AST_NODE_TYPES24.Identifier || node.callee.name !== "Promise") {
|
|
5291
5970
|
return false;
|
|
5292
5971
|
}
|
|
5293
5972
|
const executor = node.arguments[0];
|
|
5294
|
-
if (executor?.type !==
|
|
5973
|
+
if (executor?.type !== AST_NODE_TYPES24.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES24.FunctionExpression) {
|
|
5295
5974
|
return false;
|
|
5296
5975
|
}
|
|
5297
5976
|
const body = executor.body;
|
|
5298
|
-
if (body.type !==
|
|
5977
|
+
if (body.type !== AST_NODE_TYPES24.BlockStatement) {
|
|
5299
5978
|
return isTimedSetTimeout(body);
|
|
5300
5979
|
}
|
|
5301
5980
|
return body.body.some(
|
|
5302
|
-
(stmt) => stmt.type ===
|
|
5981
|
+
(stmt) => stmt.type === AST_NODE_TYPES24.ExpressionStatement && isTimedSetTimeout(stmt.expression)
|
|
5303
5982
|
);
|
|
5304
5983
|
}
|
|
5305
5984
|
function isHelperSleep(node) {
|
|
5306
|
-
return node.callee.type ===
|
|
5985
|
+
return node.callee.type === AST_NODE_TYPES24.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
|
|
5307
5986
|
}
|
|
5308
5987
|
function nearestEnclosingFunction(node) {
|
|
5309
5988
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5310
|
-
if (!
|
|
5989
|
+
if (!FUNCTION_TYPES3.has(current.type)) {
|
|
5311
5990
|
continue;
|
|
5312
5991
|
}
|
|
5313
5992
|
const grandparent = current.parent;
|
|
5314
|
-
const isPromiseExecutor = grandparent?.type ===
|
|
5993
|
+
const isPromiseExecutor = grandparent?.type === AST_NODE_TYPES24.NewExpression && isPromiseSleep(grandparent);
|
|
5315
5994
|
if (!isPromiseExecutor) {
|
|
5316
5995
|
return current;
|
|
5317
5996
|
}
|
|
@@ -5319,23 +5998,23 @@ function nearestEnclosingFunction(node) {
|
|
|
5319
5998
|
return null;
|
|
5320
5999
|
}
|
|
5321
6000
|
function testCallerName(callee) {
|
|
5322
|
-
if (callee.type ===
|
|
6001
|
+
if (callee.type === AST_NODE_TYPES24.Identifier) {
|
|
5323
6002
|
return callee.name;
|
|
5324
6003
|
}
|
|
5325
|
-
if (callee.type ===
|
|
6004
|
+
if (callee.type === AST_NODE_TYPES24.MemberExpression) {
|
|
5326
6005
|
return testCallerName(callee.object);
|
|
5327
6006
|
}
|
|
5328
|
-
if (callee.type ===
|
|
6007
|
+
if (callee.type === AST_NODE_TYPES24.CallExpression) {
|
|
5329
6008
|
return testCallerName(callee.callee);
|
|
5330
6009
|
}
|
|
5331
|
-
if (callee.type ===
|
|
6010
|
+
if (callee.type === AST_NODE_TYPES24.TaggedTemplateExpression) {
|
|
5332
6011
|
return testCallerName(callee.tag);
|
|
5333
6012
|
}
|
|
5334
6013
|
return null;
|
|
5335
6014
|
}
|
|
5336
6015
|
function isTestBody(fn) {
|
|
5337
6016
|
const call = fn.parent;
|
|
5338
|
-
if (call?.type !==
|
|
6017
|
+
if (call?.type !== AST_NODE_TYPES24.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5339
6018
|
return false;
|
|
5340
6019
|
}
|
|
5341
6020
|
const name = testCallerName(call.callee);
|
|
@@ -5383,44 +6062,214 @@ var no_sleep_in_test_body_default = ESLintUtils32.RuleCreator(
|
|
|
5383
6062
|
});
|
|
5384
6063
|
|
|
5385
6064
|
// src/rules/no-conditional-in-test.ts
|
|
5386
|
-
import { AST_NODE_TYPES as
|
|
6065
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ESLintUtils as ESLintUtils33 } from "@typescript-eslint/utils";
|
|
5387
6066
|
var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
5388
|
-
var
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
6067
|
+
var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
6068
|
+
AST_NODE_TYPES25.FunctionDeclaration,
|
|
6069
|
+
AST_NODE_TYPES25.FunctionExpression,
|
|
6070
|
+
AST_NODE_TYPES25.ArrowFunctionExpression
|
|
6071
|
+
]);
|
|
6072
|
+
var ASSERTION_ROOTS = /* @__PURE__ */ new Set([
|
|
6073
|
+
"expect",
|
|
6074
|
+
"expectTypeOf",
|
|
6075
|
+
"assert",
|
|
6076
|
+
"assertType"
|
|
6077
|
+
]);
|
|
6078
|
+
var TYPE_ASSERTION_ROOTS = /* @__PURE__ */ new Set([
|
|
6079
|
+
"expectTypeOf",
|
|
6080
|
+
"assertType"
|
|
5392
6081
|
]);
|
|
5393
6082
|
function nearestEnclosingFunction2(node) {
|
|
5394
6083
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
5395
|
-
if (
|
|
6084
|
+
if (FUNCTION_TYPES4.has(current.type)) {
|
|
5396
6085
|
return current;
|
|
5397
6086
|
}
|
|
5398
6087
|
}
|
|
5399
6088
|
return null;
|
|
5400
6089
|
}
|
|
5401
6090
|
function testCallerName2(callee) {
|
|
5402
|
-
if (callee.type ===
|
|
6091
|
+
if (callee.type === AST_NODE_TYPES25.Identifier) {
|
|
5403
6092
|
return callee.name;
|
|
5404
6093
|
}
|
|
5405
|
-
if (callee.type ===
|
|
6094
|
+
if (callee.type === AST_NODE_TYPES25.MemberExpression) {
|
|
5406
6095
|
return testCallerName2(callee.object);
|
|
5407
6096
|
}
|
|
5408
|
-
if (callee.type ===
|
|
6097
|
+
if (callee.type === AST_NODE_TYPES25.CallExpression) {
|
|
5409
6098
|
return testCallerName2(callee.callee);
|
|
5410
6099
|
}
|
|
5411
|
-
if (callee.type ===
|
|
6100
|
+
if (callee.type === AST_NODE_TYPES25.TaggedTemplateExpression) {
|
|
5412
6101
|
return testCallerName2(callee.tag);
|
|
5413
6102
|
}
|
|
5414
6103
|
return null;
|
|
5415
6104
|
}
|
|
5416
6105
|
function isTestBody2(fn) {
|
|
5417
6106
|
const call = fn.parent;
|
|
5418
|
-
if (call?.type !==
|
|
6107
|
+
if (call?.type !== AST_NODE_TYPES25.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5419
6108
|
return false;
|
|
5420
6109
|
}
|
|
5421
6110
|
const name = testCallerName2(call.callee);
|
|
5422
6111
|
return name !== null && TEST_CALLERS2.has(name);
|
|
5423
6112
|
}
|
|
6113
|
+
function subtreeMatches2(node, predicate, descendIntoFunctions = true) {
|
|
6114
|
+
let found = false;
|
|
6115
|
+
const visit = (current) => {
|
|
6116
|
+
if (found) {
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
if (predicate(current)) {
|
|
6120
|
+
found = true;
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
for (const key of Object.keys(current)) {
|
|
6124
|
+
if (key === "parent") {
|
|
6125
|
+
continue;
|
|
6126
|
+
}
|
|
6127
|
+
if (!descendIntoFunctions && FUNCTION_TYPES4.has(current.type) && key === "body") {
|
|
6128
|
+
continue;
|
|
6129
|
+
}
|
|
6130
|
+
const value = current[key];
|
|
6131
|
+
if (Array.isArray(value)) {
|
|
6132
|
+
for (const child of value) {
|
|
6133
|
+
if (typeof child === "object" && child !== null && typeof child.type === "string") {
|
|
6134
|
+
visit(child);
|
|
6135
|
+
}
|
|
6136
|
+
}
|
|
6137
|
+
} else if (typeof value === "object" && value !== null && typeof value.type === "string") {
|
|
6138
|
+
visit(value);
|
|
6139
|
+
}
|
|
6140
|
+
if (found) {
|
|
6141
|
+
return;
|
|
6142
|
+
}
|
|
6143
|
+
}
|
|
6144
|
+
};
|
|
6145
|
+
visit(node);
|
|
6146
|
+
return found;
|
|
6147
|
+
}
|
|
6148
|
+
function rootIdentifier(node) {
|
|
6149
|
+
switch (node.type) {
|
|
6150
|
+
case AST_NODE_TYPES25.Identifier:
|
|
6151
|
+
return node.name;
|
|
6152
|
+
case AST_NODE_TYPES25.MemberExpression:
|
|
6153
|
+
return rootIdentifier(node.object);
|
|
6154
|
+
case AST_NODE_TYPES25.UnaryExpression:
|
|
6155
|
+
return rootIdentifier(node.argument);
|
|
6156
|
+
case AST_NODE_TYPES25.AwaitExpression:
|
|
6157
|
+
return rootIdentifier(node.argument);
|
|
6158
|
+
case AST_NODE_TYPES25.ChainExpression:
|
|
6159
|
+
case AST_NODE_TYPES25.TSNonNullExpression:
|
|
6160
|
+
case AST_NODE_TYPES25.TSAsExpression:
|
|
6161
|
+
return rootIdentifier(node.expression);
|
|
6162
|
+
case AST_NODE_TYPES25.BinaryExpression:
|
|
6163
|
+
case AST_NODE_TYPES25.LogicalExpression:
|
|
6164
|
+
return rootIdentifier(node.left);
|
|
6165
|
+
case AST_NODE_TYPES25.CallExpression:
|
|
6166
|
+
return rootIdentifier(node.callee);
|
|
6167
|
+
default:
|
|
6168
|
+
return null;
|
|
6169
|
+
}
|
|
6170
|
+
}
|
|
6171
|
+
function calleeRootName(call) {
|
|
6172
|
+
let current = call.callee;
|
|
6173
|
+
for (; ; ) {
|
|
6174
|
+
if (current.type === AST_NODE_TYPES25.Identifier) {
|
|
6175
|
+
return current.name;
|
|
6176
|
+
}
|
|
6177
|
+
if (current.type === AST_NODE_TYPES25.MemberExpression) {
|
|
6178
|
+
current = current.object;
|
|
6179
|
+
continue;
|
|
6180
|
+
}
|
|
6181
|
+
if (current.type === AST_NODE_TYPES25.CallExpression) {
|
|
6182
|
+
current = current.callee;
|
|
6183
|
+
continue;
|
|
6184
|
+
}
|
|
6185
|
+
if (current.type === AST_NODE_TYPES25.ChainExpression || current.type === AST_NODE_TYPES25.TSNonNullExpression) {
|
|
6186
|
+
current = current.expression;
|
|
6187
|
+
continue;
|
|
6188
|
+
}
|
|
6189
|
+
return null;
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6192
|
+
var isAssertionCall = (node) => node.type === AST_NODE_TYPES25.CallExpression && ASSERTION_ROOTS.has(calleeRootName(node) ?? "");
|
|
6193
|
+
var isTypeAssertionCall = (node) => node.type === AST_NODE_TYPES25.CallExpression && TYPE_ASSERTION_ROOTS.has(calleeRootName(node) ?? "");
|
|
6194
|
+
var containsAssertion = (node) => subtreeMatches2(node, isAssertionCall);
|
|
6195
|
+
var containsSkipCall = (node) => subtreeMatches2(
|
|
6196
|
+
node,
|
|
6197
|
+
(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"
|
|
6198
|
+
);
|
|
6199
|
+
var containsEscape = (node) => subtreeMatches2(
|
|
6200
|
+
node,
|
|
6201
|
+
(current) => current.type === AST_NODE_TYPES25.ReturnStatement || current.type === AST_NODE_TYPES25.ContinueStatement || current.type === AST_NODE_TYPES25.BreakStatement,
|
|
6202
|
+
false
|
|
6203
|
+
);
|
|
6204
|
+
function branchStatements(branch) {
|
|
6205
|
+
return branch.type === AST_NODE_TYPES25.BlockStatement ? branch.body : [branch];
|
|
6206
|
+
}
|
|
6207
|
+
function previousSibling(node) {
|
|
6208
|
+
const parent = node.parent;
|
|
6209
|
+
let siblings = null;
|
|
6210
|
+
if (parent.type === AST_NODE_TYPES25.BlockStatement || parent.type === AST_NODE_TYPES25.Program || parent.type === AST_NODE_TYPES25.StaticBlock) {
|
|
6211
|
+
siblings = parent.body;
|
|
6212
|
+
} else if (parent.type === AST_NODE_TYPES25.SwitchCase) {
|
|
6213
|
+
siblings = parent.consequent;
|
|
6214
|
+
}
|
|
6215
|
+
if (siblings === null) {
|
|
6216
|
+
return null;
|
|
6217
|
+
}
|
|
6218
|
+
const index = siblings.indexOf(node);
|
|
6219
|
+
return index > 0 ? siblings[index - 1] ?? null : null;
|
|
6220
|
+
}
|
|
6221
|
+
function isPinnedNarrowingGuard(node) {
|
|
6222
|
+
const testRoot = rootIdentifier(node.test);
|
|
6223
|
+
if (testRoot === null) {
|
|
6224
|
+
return false;
|
|
6225
|
+
}
|
|
6226
|
+
const previous = previousSibling(node);
|
|
6227
|
+
if (previous === null || previous.type !== AST_NODE_TYPES25.ExpressionStatement) {
|
|
6228
|
+
return false;
|
|
6229
|
+
}
|
|
6230
|
+
let matched = false;
|
|
6231
|
+
subtreeMatches2(previous, (current) => {
|
|
6232
|
+
if (current.type !== AST_NODE_TYPES25.CallExpression || current.callee.type !== AST_NODE_TYPES25.Identifier || current.callee.name !== "expect") {
|
|
6233
|
+
return false;
|
|
6234
|
+
}
|
|
6235
|
+
const subject = current.arguments[0];
|
|
6236
|
+
if (subject === void 0) {
|
|
6237
|
+
return false;
|
|
6238
|
+
}
|
|
6239
|
+
if (rootIdentifier(subject) === testRoot) {
|
|
6240
|
+
matched = true;
|
|
6241
|
+
return true;
|
|
6242
|
+
}
|
|
6243
|
+
return false;
|
|
6244
|
+
});
|
|
6245
|
+
return matched;
|
|
6246
|
+
}
|
|
6247
|
+
function isThrowingGuard(node) {
|
|
6248
|
+
if (node.alternate !== null) {
|
|
6249
|
+
return false;
|
|
6250
|
+
}
|
|
6251
|
+
const statements = branchStatements(node.consequent);
|
|
6252
|
+
return statements.length === 1 && statements[0]?.type === AST_NODE_TYPES25.ThrowStatement;
|
|
6253
|
+
}
|
|
6254
|
+
function isTypeAssertionBranch(branch) {
|
|
6255
|
+
const statements = branchStatements(branch);
|
|
6256
|
+
return statements.length > 0 && statements.every(
|
|
6257
|
+
(statement) => statement.type === AST_NODE_TYPES25.ExpressionStatement && isTypeAssertionCall(statement.expression)
|
|
6258
|
+
);
|
|
6259
|
+
}
|
|
6260
|
+
function isTypeLevelNarrowing(node) {
|
|
6261
|
+
return isTypeAssertionBranch(node.consequent) && (node.alternate === null || isTypeAssertionBranch(node.alternate));
|
|
6262
|
+
}
|
|
6263
|
+
var isInertBranch = (branch) => !containsAssertion(branch) && !containsEscape(branch) && !containsSkipCall(branch);
|
|
6264
|
+
function isInertNormalization(node) {
|
|
6265
|
+
return isInertBranch(node.consequent) && (node.alternate === null || isInertBranch(node.alternate));
|
|
6266
|
+
}
|
|
6267
|
+
function isExemptIfStatement(node) {
|
|
6268
|
+
return isPinnedNarrowingGuard(node) || isThrowingGuard(node) || isTypeLevelNarrowing(node) || isInertNormalization(node);
|
|
6269
|
+
}
|
|
6270
|
+
function isShortCircuitedAssertion(node) {
|
|
6271
|
+
return node.operator !== "??" && node.parent.type === AST_NODE_TYPES25.ExpressionStatement && containsAssertion(node.right);
|
|
6272
|
+
}
|
|
5424
6273
|
var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
5425
6274
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5426
6275
|
)({
|
|
@@ -5449,6 +6298,9 @@ var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
|
5449
6298
|
};
|
|
5450
6299
|
return {
|
|
5451
6300
|
IfStatement(node) {
|
|
6301
|
+
if (isExemptIfStatement(node)) {
|
|
6302
|
+
return;
|
|
6303
|
+
}
|
|
5452
6304
|
report(node);
|
|
5453
6305
|
},
|
|
5454
6306
|
SwitchStatement(node) {
|
|
@@ -5458,6 +6310,9 @@ var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
|
5458
6310
|
report(node);
|
|
5459
6311
|
},
|
|
5460
6312
|
LogicalExpression(node) {
|
|
6313
|
+
if (!isShortCircuitedAssertion(node)) {
|
|
6314
|
+
return;
|
|
6315
|
+
}
|
|
5461
6316
|
report(node);
|
|
5462
6317
|
}
|
|
5463
6318
|
};
|
|
@@ -5465,7 +6320,7 @@ var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
|
5465
6320
|
});
|
|
5466
6321
|
|
|
5467
6322
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
5468
|
-
import { AST_NODE_TYPES as
|
|
6323
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ESLintUtils as ESLintUtils34 } from "@typescript-eslint/utils";
|
|
5469
6324
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
5470
6325
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5471
6326
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
@@ -5478,36 +6333,36 @@ function isConstantReference(identifier) {
|
|
|
5478
6333
|
}
|
|
5479
6334
|
function isExcludedOperand(node) {
|
|
5480
6335
|
switch (node.type) {
|
|
5481
|
-
case
|
|
6336
|
+
case AST_NODE_TYPES26.Literal:
|
|
5482
6337
|
return true;
|
|
5483
|
-
case
|
|
6338
|
+
case AST_NODE_TYPES26.TemplateLiteral:
|
|
5484
6339
|
return node.expressions.length === 0;
|
|
5485
|
-
case
|
|
6340
|
+
case AST_NODE_TYPES26.Identifier:
|
|
5486
6341
|
return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
|
|
5487
|
-
case
|
|
5488
|
-
return !node.computed && node.property.type ===
|
|
6342
|
+
case AST_NODE_TYPES26.MemberExpression:
|
|
6343
|
+
return !node.computed && node.property.type === AST_NODE_TYPES26.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
|
|
5489
6344
|
default:
|
|
5490
6345
|
return false;
|
|
5491
6346
|
}
|
|
5492
6347
|
}
|
|
5493
6348
|
function operandName(node) {
|
|
5494
|
-
if (node.type ===
|
|
6349
|
+
if (node.type === AST_NODE_TYPES26.Identifier) {
|
|
5495
6350
|
return node.name;
|
|
5496
6351
|
}
|
|
5497
|
-
if (node.type ===
|
|
6352
|
+
if (node.type === AST_NODE_TYPES26.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES26.Identifier) {
|
|
5498
6353
|
return node.property.name;
|
|
5499
6354
|
}
|
|
5500
6355
|
return null;
|
|
5501
6356
|
}
|
|
5502
6357
|
function isSecretOperand(node) {
|
|
5503
|
-
if (node.type ===
|
|
6358
|
+
if (node.type === AST_NODE_TYPES26.TemplateLiteral) {
|
|
5504
6359
|
return node.expressions.some((expression) => isSecretOperand(expression));
|
|
5505
6360
|
}
|
|
5506
6361
|
const name = operandName(node);
|
|
5507
6362
|
return name !== null && isAuthSecretName(name);
|
|
5508
6363
|
}
|
|
5509
6364
|
function secretNameOf(node) {
|
|
5510
|
-
if (node.type ===
|
|
6365
|
+
if (node.type === AST_NODE_TYPES26.TemplateLiteral) {
|
|
5511
6366
|
for (const expression of node.expressions) {
|
|
5512
6367
|
const nested = secretNameOf(expression);
|
|
5513
6368
|
if (nested !== null) {
|
|
@@ -5594,17 +6449,17 @@ var store_insert_requires_on_conflict_default = ESLintUtils35.RuleCreator(
|
|
|
5594
6449
|
});
|
|
5595
6450
|
|
|
5596
6451
|
// src/rules/no-dynamic-sql.ts
|
|
5597
|
-
import { AST_NODE_TYPES as
|
|
6452
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES27, ESLintUtils as ESLintUtils36 } from "@typescript-eslint/utils";
|
|
5598
6453
|
var DEFAULT_METHODS = ["prepare", "exec", "query"];
|
|
5599
6454
|
var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
5600
6455
|
function isStaticFragment(expression) {
|
|
5601
|
-
if (expression.type ===
|
|
6456
|
+
if (expression.type === AST_NODE_TYPES27.Identifier) {
|
|
5602
6457
|
return CONSTANT_CASE_RE.test(expression.name);
|
|
5603
6458
|
}
|
|
5604
|
-
if (expression.type ===
|
|
6459
|
+
if (expression.type === AST_NODE_TYPES27.MemberExpression && !expression.computed && expression.property.type === AST_NODE_TYPES27.Identifier) {
|
|
5605
6460
|
return CONSTANT_CASE_RE.test(expression.property.name);
|
|
5606
6461
|
}
|
|
5607
|
-
if (expression.type ===
|
|
6462
|
+
if (expression.type === AST_NODE_TYPES27.Literal) {
|
|
5608
6463
|
return typeof expression.value === "string";
|
|
5609
6464
|
}
|
|
5610
6465
|
return false;
|
|
@@ -5615,36 +6470,36 @@ function runtimeInterpolations(template) {
|
|
|
5615
6470
|
);
|
|
5616
6471
|
}
|
|
5617
6472
|
function concatOperands(node) {
|
|
5618
|
-
if (node.type ===
|
|
6473
|
+
if (node.type === AST_NODE_TYPES27.BinaryExpression && node.operator === "+") {
|
|
5619
6474
|
return [...concatOperands(node.left), ...concatOperands(node.right)];
|
|
5620
6475
|
}
|
|
5621
6476
|
return [node];
|
|
5622
6477
|
}
|
|
5623
6478
|
function runtimeConcatOperands(node) {
|
|
5624
|
-
if (node.type !==
|
|
6479
|
+
if (node.type !== AST_NODE_TYPES27.BinaryExpression || node.operator !== "+") {
|
|
5625
6480
|
return [];
|
|
5626
6481
|
}
|
|
5627
6482
|
const operands = concatOperands(node);
|
|
5628
6483
|
const hasStringLiteral = operands.some(
|
|
5629
|
-
(operand) => operand.type ===
|
|
6484
|
+
(operand) => operand.type === AST_NODE_TYPES27.Literal && typeof operand.value === "string"
|
|
5630
6485
|
);
|
|
5631
6486
|
if (!hasStringLiteral) {
|
|
5632
6487
|
return [];
|
|
5633
6488
|
}
|
|
5634
6489
|
return operands.filter(
|
|
5635
|
-
(operand) => operand.type !==
|
|
6490
|
+
(operand) => operand.type !== AST_NODE_TYPES27.Literal && !isStaticFragment(operand)
|
|
5636
6491
|
);
|
|
5637
6492
|
}
|
|
5638
6493
|
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;
|
|
5639
6494
|
var RUNTIME_MARKER = " ? ";
|
|
5640
6495
|
function staticStatementText(node) {
|
|
5641
|
-
if (node.type ===
|
|
6496
|
+
if (node.type === AST_NODE_TYPES27.TemplateLiteral) {
|
|
5642
6497
|
return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
|
|
5643
6498
|
}
|
|
5644
|
-
if (node.type ===
|
|
6499
|
+
if (node.type === AST_NODE_TYPES27.Literal) {
|
|
5645
6500
|
return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
|
|
5646
6501
|
}
|
|
5647
|
-
if (node.type ===
|
|
6502
|
+
if (node.type === AST_NODE_TYPES27.BinaryExpression && node.operator === "+") {
|
|
5648
6503
|
return staticStatementText(node.left) + staticStatementText(node.right);
|
|
5649
6504
|
}
|
|
5650
6505
|
return RUNTIME_MARKER;
|
|
@@ -5654,7 +6509,7 @@ function looksLikeSql(node) {
|
|
|
5654
6509
|
}
|
|
5655
6510
|
function statementMethodName(node, methods) {
|
|
5656
6511
|
const callee = node.callee;
|
|
5657
|
-
if (callee.type !==
|
|
6512
|
+
if (callee.type !== AST_NODE_TYPES27.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES27.Identifier) {
|
|
5658
6513
|
return null;
|
|
5659
6514
|
}
|
|
5660
6515
|
const name = callee.property.name;
|
|
@@ -5699,7 +6554,7 @@ var no_dynamic_sql_default = ESLintUtils36.RuleCreator(
|
|
|
5699
6554
|
if (statement === void 0 || !looksLikeSql(statement)) {
|
|
5700
6555
|
return;
|
|
5701
6556
|
}
|
|
5702
|
-
const offenders = statement.type ===
|
|
6557
|
+
const offenders = statement.type === AST_NODE_TYPES27.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
|
|
5703
6558
|
for (const offender of offenders) {
|
|
5704
6559
|
context.report({
|
|
5705
6560
|
node: offender,
|
|
@@ -5713,7 +6568,7 @@ var no_dynamic_sql_default = ESLintUtils36.RuleCreator(
|
|
|
5713
6568
|
});
|
|
5714
6569
|
|
|
5715
6570
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
5716
|
-
import { ESLintUtils as ESLintUtils37 } from "@typescript-eslint/utils";
|
|
6571
|
+
import { ESLintUtils as ESLintUtils37, AST_NODE_TYPES as AST_NODE_TYPES28 } from "@typescript-eslint/utils";
|
|
5717
6572
|
var DEFAULT_ALLOW = [
|
|
5718
6573
|
"[\\\\/]clients?[\\\\/]",
|
|
5719
6574
|
"-client\\.[cm]?[jt]sx?$",
|
|
@@ -5723,17 +6578,15 @@ var DEFAULT_ALLOW = [
|
|
|
5723
6578
|
"[\\\\/]api[\\\\/]",
|
|
5724
6579
|
"[\\\\/]api\\.[cm]?[jt]sx?$",
|
|
5725
6580
|
"[-.]api\\.[cm]?[jt]sx?$",
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
"
|
|
5730
|
-
"
|
|
5731
|
-
"[
|
|
5732
|
-
"[
|
|
5733
|
-
"[\\\\/]tests?[\\\\/]",
|
|
5734
|
-
// jscodeshift input/output fixtures — text a codemod transforms, not code.
|
|
5735
|
-
"[\\\\/]__testfixtures__[\\\\/]"
|
|
6581
|
+
// Vendor wrapper conventions: a module that exists to own one third-party
|
|
6582
|
+
// origin's HTTP. See the SECOND SWEEP note in the file header.
|
|
6583
|
+
"[\\\\/]services?[\\\\/]",
|
|
6584
|
+
"[\\\\/](connectors|providers|integrations|adapters|fetchers)[\\\\/]",
|
|
6585
|
+
"[\\\\/]notifications[\\\\/]",
|
|
6586
|
+
"[Ss]ervice\\.[cm]?[jt]sx?$",
|
|
6587
|
+
"-(service|connector|adapter|sdk|fetcher)\\.[cm]?[jt]sx?$"
|
|
5736
6588
|
];
|
|
6589
|
+
var NON_PRODUCTION_TREE_RE = /[\\/](playwright|cypress|__testfixtures__)[\\/]/;
|
|
5737
6590
|
var GLOBAL_RECEIVERS = /* @__PURE__ */ new Set([
|
|
5738
6591
|
"globalThis",
|
|
5739
6592
|
"window",
|
|
@@ -5759,6 +6612,10 @@ function identifierLikeName(node) {
|
|
|
5759
6612
|
}
|
|
5760
6613
|
return null;
|
|
5761
6614
|
}
|
|
6615
|
+
function isConstructedArgumentHandoff(node) {
|
|
6616
|
+
const [first] = node.arguments;
|
|
6617
|
+
return node.arguments.length === 1 && first !== void 0 && first.type === AST_NODE_TYPES28.NewExpression;
|
|
6618
|
+
}
|
|
5762
6619
|
function isPresignedUrlTransfer(node) {
|
|
5763
6620
|
const first = node.arguments[0];
|
|
5764
6621
|
if (first === void 0) {
|
|
@@ -5805,15 +6662,18 @@ var no_raw_fetch_outside_clients_default = ESLintUtils37.RuleCreator(
|
|
|
5805
6662
|
},
|
|
5806
6663
|
defaultOptions: [{}],
|
|
5807
6664
|
create(context, [options]) {
|
|
6665
|
+
const filename = context.filename;
|
|
6666
|
+
if (isTestFile(filename) || NON_PRODUCTION_TREE_RE.test(filename)) {
|
|
6667
|
+
return {};
|
|
6668
|
+
}
|
|
5808
6669
|
const patterns = options?.allow ?? DEFAULT_ALLOW;
|
|
5809
6670
|
const allowed = compile(patterns);
|
|
5810
|
-
const filename = context.filename;
|
|
5811
6671
|
if (allowed.some((re) => re.test(filename))) {
|
|
5812
6672
|
return {};
|
|
5813
6673
|
}
|
|
5814
6674
|
return {
|
|
5815
6675
|
CallExpression(node) {
|
|
5816
|
-
if (isPresignedUrlTransfer(node)) {
|
|
6676
|
+
if (isPresignedUrlTransfer(node) || isConstructedArgumentHandoff(node)) {
|
|
5817
6677
|
return;
|
|
5818
6678
|
}
|
|
5819
6679
|
if (isGlobalFetchCall(node)) {
|
|
@@ -5825,7 +6685,7 @@ var no_raw_fetch_outside_clients_default = ESLintUtils37.RuleCreator(
|
|
|
5825
6685
|
});
|
|
5826
6686
|
|
|
5827
6687
|
// src/rules/no-storage-in-stateless-modules.ts
|
|
5828
|
-
import { AST_NODE_TYPES as
|
|
6688
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29, ESLintUtils as ESLintUtils38 } from "@typescript-eslint/utils";
|
|
5829
6689
|
var DEFAULT_METHODS2 = [
|
|
5830
6690
|
"prepare",
|
|
5831
6691
|
"put",
|
|
@@ -5844,7 +6704,7 @@ function compile2(patterns) {
|
|
|
5844
6704
|
}
|
|
5845
6705
|
function storageMethodName(node, methods) {
|
|
5846
6706
|
const callee = node.callee;
|
|
5847
|
-
if (callee.type !==
|
|
6707
|
+
if (callee.type !== AST_NODE_TYPES29.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES29.Identifier) {
|
|
5848
6708
|
return null;
|
|
5849
6709
|
}
|
|
5850
6710
|
const name = callee.property.name;
|
|
@@ -5916,7 +6776,7 @@ var no_storage_in_stateless_modules_default = ESLintUtils38.RuleCreator(
|
|
|
5916
6776
|
// src/rules/no-zod-native-enum.ts
|
|
5917
6777
|
import {
|
|
5918
6778
|
ESLintUtils as ESLintUtils39,
|
|
5919
|
-
AST_NODE_TYPES as
|
|
6779
|
+
AST_NODE_TYPES as AST_NODE_TYPES30
|
|
5920
6780
|
} from "@typescript-eslint/utils";
|
|
5921
6781
|
import * as ts2 from "typescript";
|
|
5922
6782
|
var IGNORE_PATTERNS2 = [
|
|
@@ -5935,7 +6795,7 @@ function isZodModule2(source) {
|
|
|
5935
6795
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
5936
6796
|
}
|
|
5937
6797
|
function unwrap3(node) {
|
|
5938
|
-
if (node.type ===
|
|
6798
|
+
if (node.type === AST_NODE_TYPES30.TSAsExpression || node.type === AST_NODE_TYPES30.TSSatisfiesExpression) {
|
|
5939
6799
|
return unwrap3(node.expression);
|
|
5940
6800
|
}
|
|
5941
6801
|
return node;
|
|
@@ -5943,14 +6803,14 @@ function unwrap3(node) {
|
|
|
5943
6803
|
function stringValueTexts(node, sourceCode) {
|
|
5944
6804
|
const texts = [];
|
|
5945
6805
|
for (const prop of node.properties) {
|
|
5946
|
-
if (prop.type !==
|
|
6806
|
+
if (prop.type !== AST_NODE_TYPES30.Property) {
|
|
5947
6807
|
return null;
|
|
5948
6808
|
}
|
|
5949
6809
|
if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
|
|
5950
6810
|
return null;
|
|
5951
6811
|
}
|
|
5952
6812
|
const value = prop.value;
|
|
5953
|
-
if (value.type !==
|
|
6813
|
+
if (value.type !== AST_NODE_TYPES30.Literal || typeof value.value !== "string") {
|
|
5954
6814
|
return null;
|
|
5955
6815
|
}
|
|
5956
6816
|
const text = sourceCode.getText(value);
|
|
@@ -5966,7 +6826,7 @@ function resolvesToLocalEnum(node, scope) {
|
|
|
5966
6826
|
const variable = current.variables.find((v) => v.name === node.name);
|
|
5967
6827
|
if (variable !== void 0) {
|
|
5968
6828
|
return variable.defs.some(
|
|
5969
|
-
(def) => def.node.type ===
|
|
6829
|
+
(def) => def.node.type === AST_NODE_TYPES30.TSEnumDeclaration
|
|
5970
6830
|
);
|
|
5971
6831
|
}
|
|
5972
6832
|
current = current.upper;
|
|
@@ -6020,25 +6880,25 @@ var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
|
6020
6880
|
const zodImportedNames = /* @__PURE__ */ new Map();
|
|
6021
6881
|
function isZodMemberCall(node, api) {
|
|
6022
6882
|
const callee = node.callee;
|
|
6023
|
-
if (callee.type ===
|
|
6883
|
+
if (callee.type === AST_NODE_TYPES30.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES30.Identifier) {
|
|
6024
6884
|
return callee.property.name === api;
|
|
6025
6885
|
}
|
|
6026
|
-
if (callee.type ===
|
|
6886
|
+
if (callee.type === AST_NODE_TYPES30.Identifier) {
|
|
6027
6887
|
return zodImportedNames.get(callee.name) === api;
|
|
6028
6888
|
}
|
|
6029
6889
|
return false;
|
|
6030
6890
|
}
|
|
6031
6891
|
function buildFix(node) {
|
|
6032
6892
|
const callee = node.callee;
|
|
6033
|
-
if (callee.type !==
|
|
6893
|
+
if (callee.type !== AST_NODE_TYPES30.MemberExpression || callee.property.type !== AST_NODE_TYPES30.Identifier) {
|
|
6034
6894
|
return null;
|
|
6035
6895
|
}
|
|
6036
6896
|
const arg = node.arguments[0];
|
|
6037
|
-
if (arg === void 0 || node.arguments.length !== 1 || arg.type ===
|
|
6897
|
+
if (arg === void 0 || node.arguments.length !== 1 || arg.type === AST_NODE_TYPES30.SpreadElement) {
|
|
6038
6898
|
return null;
|
|
6039
6899
|
}
|
|
6040
6900
|
const inner = unwrap3(arg);
|
|
6041
|
-
if (inner.type !==
|
|
6901
|
+
if (inner.type !== AST_NODE_TYPES30.ObjectExpression) {
|
|
6042
6902
|
return null;
|
|
6043
6903
|
}
|
|
6044
6904
|
const values = stringValueTexts(inner, sourceCode);
|
|
@@ -6058,7 +6918,7 @@ var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
|
6058
6918
|
return;
|
|
6059
6919
|
}
|
|
6060
6920
|
for (const spec of node.specifiers) {
|
|
6061
|
-
if (spec.type ===
|
|
6921
|
+
if (spec.type === AST_NODE_TYPES30.ImportSpecifier && spec.imported.type === AST_NODE_TYPES30.Identifier) {
|
|
6062
6922
|
zodImportedNames.set(spec.local.name, spec.imported.name);
|
|
6063
6923
|
}
|
|
6064
6924
|
}
|
|
@@ -6077,7 +6937,7 @@ var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
|
6077
6937
|
return;
|
|
6078
6938
|
}
|
|
6079
6939
|
const arg = node.arguments[0];
|
|
6080
|
-
if (arg === void 0 || arg.type !==
|
|
6940
|
+
if (arg === void 0 || arg.type !== AST_NODE_TYPES30.Identifier) {
|
|
6081
6941
|
return;
|
|
6082
6942
|
}
|
|
6083
6943
|
const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
|
|
@@ -6096,7 +6956,7 @@ var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
|
6096
6956
|
// src/rules/prefer-module-level-constant.ts
|
|
6097
6957
|
import {
|
|
6098
6958
|
ESLintUtils as ESLintUtils40,
|
|
6099
|
-
AST_NODE_TYPES as
|
|
6959
|
+
AST_NODE_TYPES as AST_NODE_TYPES31
|
|
6100
6960
|
} from "@typescript-eslint/utils";
|
|
6101
6961
|
var DEFAULT_MIN_ELEMENTS = 3;
|
|
6102
6962
|
var MAX_LITERAL_DEPTH = 4;
|
|
@@ -6106,13 +6966,6 @@ var IGNORE_PATTERNS3 = [
|
|
|
6106
6966
|
/\.generated\.tsx?$/,
|
|
6107
6967
|
/\.d\.ts$/
|
|
6108
6968
|
];
|
|
6109
|
-
var TEST_FILE_PATTERNS = [
|
|
6110
|
-
/\.(?:test|spec)\.[cm]?[jt]sx?$/,
|
|
6111
|
-
/[\\/]__tests__[\\/]/,
|
|
6112
|
-
/[\\/]__mocks__[\\/]/,
|
|
6113
|
-
/[\\/]tests?[\\/]/,
|
|
6114
|
-
/\.stories\.[cm]?[jt]sx?$/
|
|
6115
|
-
];
|
|
6116
6969
|
var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
6117
6970
|
// Array
|
|
6118
6971
|
"push",
|
|
@@ -6132,10 +6985,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
6132
6985
|
// Object-ish escape hatches
|
|
6133
6986
|
"assign"
|
|
6134
6987
|
]);
|
|
6135
|
-
var
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6988
|
+
var FUNCTION_TYPES5 = /* @__PURE__ */ new Set([
|
|
6989
|
+
AST_NODE_TYPES31.FunctionDeclaration,
|
|
6990
|
+
AST_NODE_TYPES31.FunctionExpression,
|
|
6991
|
+
AST_NODE_TYPES31.ArrowFunctionExpression
|
|
6139
6992
|
]);
|
|
6140
6993
|
var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
|
|
6141
6994
|
function isIgnoredFile3(filename, sourceText) {
|
|
@@ -6144,17 +6997,18 @@ function isIgnoredFile3(filename, sourceText) {
|
|
|
6144
6997
|
}
|
|
6145
6998
|
return /@generated\b/.test(sourceText.slice(0, 1024));
|
|
6146
6999
|
}
|
|
6147
|
-
function
|
|
6148
|
-
return
|
|
7000
|
+
function isLocalFixtureFile(filename) {
|
|
7001
|
+
return isTestFile(filename) || isStoryFile(filename);
|
|
6149
7002
|
}
|
|
6150
7003
|
function unwrap4(node) {
|
|
6151
|
-
if (node.type ===
|
|
7004
|
+
if (node.type === AST_NODE_TYPES31.TSAsExpression || node.type === AST_NODE_TYPES31.TSSatisfiesExpression || node.type === AST_NODE_TYPES31.TSNonNullExpression) {
|
|
6152
7005
|
return unwrap4(node.expression);
|
|
6153
7006
|
}
|
|
6154
7007
|
return node;
|
|
6155
7008
|
}
|
|
7009
|
+
var HAS_STATEFUL_FLAG_RE = /[gy]/;
|
|
6156
7010
|
function isRegexLiteral(node) {
|
|
6157
|
-
return node.type ===
|
|
7011
|
+
return node.type === AST_NODE_TYPES31.Literal && "regex" in node && node.regex !== void 0;
|
|
6158
7012
|
}
|
|
6159
7013
|
function isLiteralOnly(node, depth) {
|
|
6160
7014
|
if (depth > MAX_LITERAL_DEPTH) {
|
|
@@ -6162,29 +7016,29 @@ function isLiteralOnly(node, depth) {
|
|
|
6162
7016
|
}
|
|
6163
7017
|
const inner = unwrap4(node);
|
|
6164
7018
|
switch (inner.type) {
|
|
6165
|
-
case
|
|
6166
|
-
return
|
|
7019
|
+
case AST_NODE_TYPES31.Literal: {
|
|
7020
|
+
return !(isRegexLiteral(inner) && HAS_STATEFUL_FLAG_RE.test(inner.regex.flags));
|
|
6167
7021
|
}
|
|
6168
|
-
case
|
|
7022
|
+
case AST_NODE_TYPES31.TemplateLiteral: {
|
|
6169
7023
|
return inner.expressions.length === 0;
|
|
6170
7024
|
}
|
|
6171
|
-
case
|
|
6172
|
-
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type ===
|
|
7025
|
+
case AST_NODE_TYPES31.UnaryExpression: {
|
|
7026
|
+
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === AST_NODE_TYPES31.Literal && typeof inner.argument.value === "number";
|
|
6173
7027
|
}
|
|
6174
|
-
case
|
|
7028
|
+
case AST_NODE_TYPES31.ArrayExpression: {
|
|
6175
7029
|
return inner.elements.every(
|
|
6176
|
-
(el) => el !== null && el.type !==
|
|
7030
|
+
(el) => el !== null && el.type !== AST_NODE_TYPES31.SpreadElement && isLiteralOnly(el, depth + 1)
|
|
6177
7031
|
);
|
|
6178
7032
|
}
|
|
6179
|
-
case
|
|
7033
|
+
case AST_NODE_TYPES31.ObjectExpression: {
|
|
6180
7034
|
return inner.properties.every((prop) => {
|
|
6181
|
-
if (prop.type !==
|
|
7035
|
+
if (prop.type !== AST_NODE_TYPES31.Property) {
|
|
6182
7036
|
return false;
|
|
6183
7037
|
}
|
|
6184
7038
|
if (prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6185
7039
|
return false;
|
|
6186
7040
|
}
|
|
6187
|
-
if (prop.computed && prop.key.type !==
|
|
7041
|
+
if (prop.computed && prop.key.type !== AST_NODE_TYPES31.Literal) {
|
|
6188
7042
|
return false;
|
|
6189
7043
|
}
|
|
6190
7044
|
return isLiteralOnly(prop.value, depth + 1);
|
|
@@ -6197,7 +7051,7 @@ function isLiteralOnly(node, depth) {
|
|
|
6197
7051
|
}
|
|
6198
7052
|
function unwrapObjectFreeze(node) {
|
|
6199
7053
|
const inner = unwrap4(node);
|
|
6200
|
-
if (inner.type ===
|
|
7054
|
+
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) {
|
|
6201
7055
|
return unwrap4(inner.arguments[0]);
|
|
6202
7056
|
}
|
|
6203
7057
|
return inner;
|
|
@@ -6208,24 +7062,24 @@ function classify(init, checkRegex) {
|
|
|
6208
7062
|
if (!checkRegex) {
|
|
6209
7063
|
return null;
|
|
6210
7064
|
}
|
|
6211
|
-
if (
|
|
7065
|
+
if (HAS_STATEFUL_FLAG_RE.test(node.regex.flags)) {
|
|
6212
7066
|
return null;
|
|
6213
7067
|
}
|
|
6214
7068
|
return { kind: "regex", size: 1 };
|
|
6215
7069
|
}
|
|
6216
|
-
if (node.type ===
|
|
7070
|
+
if (node.type === AST_NODE_TYPES31.ArrayExpression) {
|
|
6217
7071
|
return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
|
|
6218
7072
|
}
|
|
6219
|
-
if (node.type ===
|
|
7073
|
+
if (node.type === AST_NODE_TYPES31.ObjectExpression) {
|
|
6220
7074
|
return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
|
|
6221
7075
|
}
|
|
6222
|
-
if (node.type ===
|
|
7076
|
+
if (node.type === AST_NODE_TYPES31.NewExpression && node.callee.type === AST_NODE_TYPES31.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
|
|
6223
7077
|
const arg = node.arguments[0];
|
|
6224
|
-
if (node.arguments.length !== 1 || arg === void 0 || arg.type ===
|
|
7078
|
+
if (node.arguments.length !== 1 || arg === void 0 || arg.type === AST_NODE_TYPES31.SpreadElement) {
|
|
6225
7079
|
return null;
|
|
6226
7080
|
}
|
|
6227
7081
|
const entries = unwrap4(arg);
|
|
6228
|
-
if (entries.type !==
|
|
7082
|
+
if (entries.type !== AST_NODE_TYPES31.ArrayExpression) {
|
|
6229
7083
|
return null;
|
|
6230
7084
|
}
|
|
6231
7085
|
return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
|
|
@@ -6235,7 +7089,7 @@ function classify(init, checkRegex) {
|
|
|
6235
7089
|
function enclosingFunction2(node) {
|
|
6236
7090
|
let current = node.parent;
|
|
6237
7091
|
while (current !== void 0 && current !== null) {
|
|
6238
|
-
if (
|
|
7092
|
+
if (FUNCTION_TYPES5.has(current.type)) {
|
|
6239
7093
|
return current;
|
|
6240
7094
|
}
|
|
6241
7095
|
current = current.parent;
|
|
@@ -6254,10 +7108,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
|
|
|
6254
7108
|
);
|
|
6255
7109
|
function isNonRetainingBuiltinCall(node, argument) {
|
|
6256
7110
|
const callee = node.callee;
|
|
6257
|
-
if (callee.type ===
|
|
7111
|
+
if (callee.type === AST_NODE_TYPES31.Identifier && callee.name === "structuredClone") {
|
|
6258
7112
|
return true;
|
|
6259
7113
|
}
|
|
6260
|
-
if (callee.type !==
|
|
7114
|
+
if (callee.type !== AST_NODE_TYPES31.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES31.Identifier || callee.property.type !== AST_NODE_TYPES31.Identifier) {
|
|
6261
7115
|
return false;
|
|
6262
7116
|
}
|
|
6263
7117
|
const members = NON_RETAINING_BUILTINS.get(callee.object.name);
|
|
@@ -6271,38 +7125,38 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
6271
7125
|
}
|
|
6272
7126
|
function isSafeRead(identifier) {
|
|
6273
7127
|
const parent = identifier.parent;
|
|
6274
|
-
if (parent.type ===
|
|
7128
|
+
if (parent.type === AST_NODE_TYPES31.MemberExpression) {
|
|
6275
7129
|
if (parent.object !== identifier) {
|
|
6276
7130
|
return true;
|
|
6277
7131
|
}
|
|
6278
7132
|
const grandparent = parent.parent;
|
|
6279
|
-
if (grandparent.type ===
|
|
7133
|
+
if (grandparent.type === AST_NODE_TYPES31.AssignmentExpression && grandparent.left === parent) {
|
|
6280
7134
|
return false;
|
|
6281
7135
|
}
|
|
6282
|
-
if (grandparent.type ===
|
|
7136
|
+
if (grandparent.type === AST_NODE_TYPES31.UpdateExpression) {
|
|
6283
7137
|
return false;
|
|
6284
7138
|
}
|
|
6285
|
-
if (grandparent.type ===
|
|
7139
|
+
if (grandparent.type === AST_NODE_TYPES31.UnaryExpression && grandparent.operator === "delete") {
|
|
6286
7140
|
return false;
|
|
6287
7141
|
}
|
|
6288
|
-
if (!parent.computed && parent.property.type ===
|
|
7142
|
+
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) {
|
|
6289
7143
|
return false;
|
|
6290
7144
|
}
|
|
6291
7145
|
return true;
|
|
6292
7146
|
}
|
|
6293
|
-
if (parent.type ===
|
|
7147
|
+
if (parent.type === AST_NODE_TYPES31.ForOfStatement && parent.right === identifier) {
|
|
6294
7148
|
return true;
|
|
6295
7149
|
}
|
|
6296
|
-
if (parent.type ===
|
|
7150
|
+
if (parent.type === AST_NODE_TYPES31.SpreadElement) {
|
|
6297
7151
|
return true;
|
|
6298
7152
|
}
|
|
6299
|
-
if (parent.type ===
|
|
7153
|
+
if (parent.type === AST_NODE_TYPES31.BinaryExpression) {
|
|
6300
7154
|
return true;
|
|
6301
7155
|
}
|
|
6302
|
-
if (parent.type ===
|
|
7156
|
+
if (parent.type === AST_NODE_TYPES31.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
|
|
6303
7157
|
return true;
|
|
6304
7158
|
}
|
|
6305
|
-
if (parent.type ===
|
|
7159
|
+
if (parent.type === AST_NODE_TYPES31.UnaryExpression && parent.operator !== "delete") {
|
|
6306
7160
|
return true;
|
|
6307
7161
|
}
|
|
6308
7162
|
return false;
|
|
@@ -6343,7 +7197,7 @@ var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
|
6343
7197
|
if (isIgnoredFile3(filename, sourceCode.getText())) {
|
|
6344
7198
|
return {};
|
|
6345
7199
|
}
|
|
6346
|
-
if (ignoreTestFiles &&
|
|
7200
|
+
if (ignoreTestFiles && isLocalFixtureFile(filename)) {
|
|
6347
7201
|
return {};
|
|
6348
7202
|
}
|
|
6349
7203
|
function allReferencesAreSafeReads(declarator) {
|
|
@@ -6359,7 +7213,7 @@ var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
|
6359
7213
|
if (reference.isWrite()) {
|
|
6360
7214
|
return false;
|
|
6361
7215
|
}
|
|
6362
|
-
if (reference.identifier.type !==
|
|
7216
|
+
if (reference.identifier.type !== AST_NODE_TYPES31.Identifier) {
|
|
6363
7217
|
return false;
|
|
6364
7218
|
}
|
|
6365
7219
|
if (!isSafeRead(reference.identifier)) {
|
|
@@ -6371,10 +7225,10 @@ var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
|
6371
7225
|
return {
|
|
6372
7226
|
VariableDeclarator(node) {
|
|
6373
7227
|
const declaration = node.parent;
|
|
6374
|
-
if (declaration.type !==
|
|
7228
|
+
if (declaration.type !== AST_NODE_TYPES31.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
|
|
6375
7229
|
return;
|
|
6376
7230
|
}
|
|
6377
|
-
if (node.id.type !==
|
|
7231
|
+
if (node.id.type !== AST_NODE_TYPES31.Identifier || node.init === null) {
|
|
6378
7232
|
return;
|
|
6379
7233
|
}
|
|
6380
7234
|
if (enclosingFunction2(node) === null) {
|
|
@@ -6401,7 +7255,7 @@ var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
|
6401
7255
|
});
|
|
6402
7256
|
|
|
6403
7257
|
// src/rules/jsdoc-restates-signature.ts
|
|
6404
|
-
import { AST_NODE_TYPES as
|
|
7258
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES32, ESLintUtils as ESLintUtils41 } from "@typescript-eslint/utils";
|
|
6405
7259
|
var VALUE_TAGS = /* @__PURE__ */ new Set([
|
|
6406
7260
|
"alpha",
|
|
6407
7261
|
"author",
|
|
@@ -6484,30 +7338,30 @@ function declarationNames(node) {
|
|
|
6484
7338
|
switch (node.type) {
|
|
6485
7339
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
6486
7340
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
6487
|
-
case
|
|
6488
|
-
case
|
|
7341
|
+
case AST_NODE_TYPES32.ExportNamedDeclaration:
|
|
7342
|
+
case AST_NODE_TYPES32.ExportDefaultDeclaration:
|
|
6489
7343
|
return node.declaration == null ? null : declarationNames(node.declaration);
|
|
6490
|
-
case
|
|
6491
|
-
case
|
|
7344
|
+
case AST_NODE_TYPES32.FunctionDeclaration:
|
|
7345
|
+
case AST_NODE_TYPES32.TSDeclareFunction:
|
|
6492
7346
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
6493
|
-
case
|
|
6494
|
-
case
|
|
6495
|
-
case
|
|
6496
|
-
case
|
|
7347
|
+
case AST_NODE_TYPES32.ClassDeclaration:
|
|
7348
|
+
case AST_NODE_TYPES32.TSInterfaceDeclaration:
|
|
7349
|
+
case AST_NODE_TYPES32.TSTypeAliasDeclaration:
|
|
7350
|
+
case AST_NODE_TYPES32.TSEnumDeclaration:
|
|
6497
7351
|
return node.id === null ? null : { name: node.id.name, params: [] };
|
|
6498
|
-
case
|
|
7352
|
+
case AST_NODE_TYPES32.VariableDeclaration: {
|
|
6499
7353
|
const declarator = node.declarations[0];
|
|
6500
|
-
if (declarator === void 0 || declarator.id.type !==
|
|
7354
|
+
if (declarator === void 0 || declarator.id.type !== AST_NODE_TYPES32.Identifier) return null;
|
|
6501
7355
|
const init = declarator.init;
|
|
6502
|
-
const params = init != null && (init.type ===
|
|
7356
|
+
const params = init != null && (init.type === AST_NODE_TYPES32.ArrowFunctionExpression || init.type === AST_NODE_TYPES32.FunctionExpression) ? paramNames(init.params) : [];
|
|
6503
7357
|
return { name: declarator.id.name, params };
|
|
6504
7358
|
}
|
|
6505
|
-
case
|
|
6506
|
-
case
|
|
6507
|
-
case
|
|
6508
|
-
case
|
|
6509
|
-
if (node.key.type !==
|
|
6510
|
-
const params = node.type ===
|
|
7359
|
+
case AST_NODE_TYPES32.MethodDefinition:
|
|
7360
|
+
case AST_NODE_TYPES32.PropertyDefinition:
|
|
7361
|
+
case AST_NODE_TYPES32.TSMethodSignature:
|
|
7362
|
+
case AST_NODE_TYPES32.TSPropertySignature: {
|
|
7363
|
+
if (node.key.type !== AST_NODE_TYPES32.Identifier) return null;
|
|
7364
|
+
const params = node.type === AST_NODE_TYPES32.MethodDefinition ? paramNames(node.value.params) : node.type === AST_NODE_TYPES32.TSMethodSignature ? paramNames(node.params) : [];
|
|
6511
7365
|
return { name: node.key.name, params };
|
|
6512
7366
|
}
|
|
6513
7367
|
default:
|
|
@@ -6517,9 +7371,9 @@ function declarationNames(node) {
|
|
|
6517
7371
|
function paramNames(params) {
|
|
6518
7372
|
const names = [];
|
|
6519
7373
|
for (const param of params) {
|
|
6520
|
-
const target = param.type ===
|
|
6521
|
-
if (target.type ===
|
|
6522
|
-
else if (target.type ===
|
|
7374
|
+
const target = param.type === AST_NODE_TYPES32.AssignmentPattern ? param.left : param;
|
|
7375
|
+
if (target.type === AST_NODE_TYPES32.Identifier) names.push(target.name);
|
|
7376
|
+
else if (target.type === AST_NODE_TYPES32.TSParameterProperty) continue;
|
|
6523
7377
|
}
|
|
6524
7378
|
return names;
|
|
6525
7379
|
}
|
|
@@ -6564,7 +7418,7 @@ var jsdoc_restates_signature_default = ESLintUtils41.RuleCreator(
|
|
|
6564
7418
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
|
|
6565
7419
|
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
|
6566
7420
|
let declaration = null;
|
|
6567
|
-
while (node != null && node.type !==
|
|
7421
|
+
while (node != null && node.type !== AST_NODE_TYPES32.Program) {
|
|
6568
7422
|
declaration = declarationNames(node);
|
|
6569
7423
|
if (declaration !== null) break;
|
|
6570
7424
|
node = node.parent ?? null;
|
|
@@ -6619,7 +7473,7 @@ var jsdoc_restates_signature_default = ESLintUtils41.RuleCreator(
|
|
|
6619
7473
|
});
|
|
6620
7474
|
|
|
6621
7475
|
// src/rules/no-restated-comment.ts
|
|
6622
|
-
import { AST_NODE_TYPES as
|
|
7476
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES33, ESLintUtils as ESLintUtils42 } from "@typescript-eslint/utils";
|
|
6623
7477
|
var MAX_WORDS = 8;
|
|
6624
7478
|
var MIN_CONTENT_TOKENS = 2;
|
|
6625
7479
|
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;
|
|
@@ -6671,7 +7525,7 @@ var no_restated_comment_default = ESLintUtils42.RuleCreator(
|
|
|
6671
7525
|
function labelsASiblingRun(comment) {
|
|
6672
7526
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
6673
7527
|
if (token === null) return false;
|
|
6674
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
7528
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES33.Program; node = node.parent) {
|
|
6675
7529
|
if (headsSiblingRun(node)) return true;
|
|
6676
7530
|
}
|
|
6677
7531
|
return false;
|
|
@@ -6836,7 +7690,7 @@ var trailing_value_narration_default = ESLintUtils43.RuleCreator(
|
|
|
6836
7690
|
});
|
|
6837
7691
|
|
|
6838
7692
|
// src/rules/no-tautological-expect.ts
|
|
6839
|
-
import { AST_NODE_TYPES as
|
|
7693
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES34, ESLintUtils as ESLintUtils44 } from "@typescript-eslint/utils";
|
|
6840
7694
|
var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
6841
7695
|
var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
|
|
6842
7696
|
"toBeDefined",
|
|
@@ -6850,17 +7704,17 @@ var OPERAND_PREVIEW_CHARS = 40;
|
|
|
6850
7704
|
var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
|
|
6851
7705
|
function isLiteral(node) {
|
|
6852
7706
|
switch (node.type) {
|
|
6853
|
-
case
|
|
7707
|
+
case AST_NODE_TYPES34.Literal:
|
|
6854
7708
|
return true;
|
|
6855
|
-
case
|
|
7709
|
+
case AST_NODE_TYPES34.TemplateLiteral:
|
|
6856
7710
|
return node.expressions.length === 0;
|
|
6857
|
-
case
|
|
7711
|
+
case AST_NODE_TYPES34.UnaryExpression:
|
|
6858
7712
|
return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
|
|
6859
|
-
case
|
|
7713
|
+
case AST_NODE_TYPES34.ArrayExpression:
|
|
6860
7714
|
return node.elements.every((element) => element !== null && isLiteral(element));
|
|
6861
|
-
case
|
|
7715
|
+
case AST_NODE_TYPES34.ObjectExpression:
|
|
6862
7716
|
return node.properties.every(
|
|
6863
|
-
(property) => property.type ===
|
|
7717
|
+
(property) => property.type === AST_NODE_TYPES34.Property && !property.computed && isLiteral(property.value)
|
|
6864
7718
|
);
|
|
6865
7719
|
default:
|
|
6866
7720
|
return false;
|
|
@@ -6868,7 +7722,7 @@ function isLiteral(node) {
|
|
|
6868
7722
|
}
|
|
6869
7723
|
function expectOperand(callee) {
|
|
6870
7724
|
const receiver = callee.object;
|
|
6871
|
-
if (receiver.type !==
|
|
7725
|
+
if (receiver.type !== AST_NODE_TYPES34.CallExpression || receiver.callee.type !== AST_NODE_TYPES34.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
|
|
6872
7726
|
return null;
|
|
6873
7727
|
}
|
|
6874
7728
|
return receiver.arguments[0] ?? null;
|
|
@@ -6900,10 +7754,10 @@ var no_tautological_expect_default = ESLintUtils44.RuleCreator(
|
|
|
6900
7754
|
return {
|
|
6901
7755
|
CallExpression(node) {
|
|
6902
7756
|
const callee = node.callee;
|
|
6903
|
-
if (callee.type !==
|
|
7757
|
+
if (callee.type !== AST_NODE_TYPES34.MemberExpression || callee.computed) {
|
|
6904
7758
|
return;
|
|
6905
7759
|
}
|
|
6906
|
-
if (callee.property.type !==
|
|
7760
|
+
if (callee.property.type !== AST_NODE_TYPES34.Identifier) {
|
|
6907
7761
|
return;
|
|
6908
7762
|
}
|
|
6909
7763
|
const matcher = callee.property.name;
|
|
@@ -6937,26 +7791,26 @@ var no_tautological_expect_default = ESLintUtils44.RuleCreator(
|
|
|
6937
7791
|
});
|
|
6938
7792
|
|
|
6939
7793
|
// src/rules/require-interface-for-injected-service.ts
|
|
6940
|
-
import { AST_NODE_TYPES as
|
|
7794
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES35, ESLintUtils as ESLintUtils45 } from "@typescript-eslint/utils";
|
|
6941
7795
|
var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
|
|
6942
7796
|
var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
|
|
6943
7797
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
6944
7798
|
var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
|
|
6945
7799
|
var ROUTER_FACTORY_NAME = "Router";
|
|
6946
7800
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
6947
|
-
var isExportedClass = (node) => node.parent.type ===
|
|
6948
|
-
var qualifiedName = (name) => name.type ===
|
|
7801
|
+
var isExportedClass = (node) => node.parent.type === AST_NODE_TYPES35.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES35.ExportDefaultDeclaration;
|
|
7802
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES35.Identifier ? name.name : name.type === AST_NODE_TYPES35.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
6949
7803
|
var typeReferenceName = (annotated) => {
|
|
6950
7804
|
let target = annotated;
|
|
6951
|
-
if (target.type ===
|
|
6952
|
-
if (target.type ===
|
|
6953
|
-
if (target.type !==
|
|
7805
|
+
if (target.type === AST_NODE_TYPES35.TSParameterProperty) target = target.parameter;
|
|
7806
|
+
if (target.type === AST_NODE_TYPES35.AssignmentPattern) target = target.left;
|
|
7807
|
+
if (target.type !== AST_NODE_TYPES35.Identifier) return null;
|
|
6954
7808
|
const annotation = target.typeAnnotation?.typeAnnotation;
|
|
6955
|
-
if (annotation === void 0 || annotation.type !==
|
|
7809
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES35.TSTypeReference) {
|
|
6956
7810
|
return null;
|
|
6957
7811
|
}
|
|
6958
7812
|
const { typeName } = annotation;
|
|
6959
|
-
const rightmost = typeName.type ===
|
|
7813
|
+
const rightmost = typeName.type === AST_NODE_TYPES35.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES35.TSQualifiedName ? typeName.right.name : null;
|
|
6960
7814
|
if (rightmost === null) return null;
|
|
6961
7815
|
return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
|
|
6962
7816
|
};
|
|
@@ -6966,17 +7820,17 @@ var readConstructor = (ctor) => {
|
|
|
6966
7820
|
let constructedFields = 0;
|
|
6967
7821
|
if (body !== null && body !== void 0) {
|
|
6968
7822
|
for (const statement of body.body) {
|
|
6969
|
-
if (statement.type !==
|
|
7823
|
+
if (statement.type !== AST_NODE_TYPES35.ExpressionStatement) continue;
|
|
6970
7824
|
const expression = statement.expression;
|
|
6971
|
-
if (expression.type !==
|
|
7825
|
+
if (expression.type !== AST_NODE_TYPES35.AssignmentExpression || expression.operator !== "=" || expression.left.type !== AST_NODE_TYPES35.MemberExpression || expression.left.object.type !== AST_NODE_TYPES35.ThisExpression) {
|
|
6972
7826
|
continue;
|
|
6973
7827
|
}
|
|
6974
7828
|
const source = expression.right;
|
|
6975
|
-
if (source.type ===
|
|
7829
|
+
if (source.type === AST_NODE_TYPES35.NewExpression) {
|
|
6976
7830
|
constructedFields += 1;
|
|
6977
|
-
} else if (source.type ===
|
|
7831
|
+
} else if (source.type === AST_NODE_TYPES35.Identifier) {
|
|
6978
7832
|
storedFrom.add(source.name);
|
|
6979
|
-
} else if (source.type ===
|
|
7833
|
+
} else if (source.type === AST_NODE_TYPES35.MemberExpression && source.object.type === AST_NODE_TYPES35.Identifier) {
|
|
6980
7834
|
storedFrom.add(source.object.name);
|
|
6981
7835
|
}
|
|
6982
7836
|
}
|
|
@@ -6985,7 +7839,7 @@ var readConstructor = (ctor) => {
|
|
|
6985
7839
|
for (const parameter of ctor.value.params) {
|
|
6986
7840
|
const reference = typeReferenceName(parameter);
|
|
6987
7841
|
if (reference === null) continue;
|
|
6988
|
-
const stored = parameter.type ===
|
|
7842
|
+
const stored = parameter.type === AST_NODE_TYPES35.TSParameterProperty || storedFrom.has(reference.name);
|
|
6989
7843
|
if (!stored) continue;
|
|
6990
7844
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
6991
7845
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -7015,19 +7869,19 @@ var subtreeHas = (root, found) => {
|
|
|
7015
7869
|
return hit;
|
|
7016
7870
|
};
|
|
7017
7871
|
var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
|
|
7018
|
-
if (node.type ===
|
|
7872
|
+
if (node.type === AST_NODE_TYPES35.CallExpression) {
|
|
7019
7873
|
const { callee } = node;
|
|
7020
|
-
if (callee.type ===
|
|
7021
|
-
return callee.type ===
|
|
7874
|
+
if (callee.type === AST_NODE_TYPES35.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
7875
|
+
return callee.type === AST_NODE_TYPES35.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES35.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
7022
7876
|
}
|
|
7023
|
-
return node.type ===
|
|
7877
|
+
return node.type === AST_NODE_TYPES35.TSTypeReference && node.typeName.type === AST_NODE_TYPES35.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
7024
7878
|
});
|
|
7025
7879
|
var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
|
|
7026
7880
|
var fileInterfaceNames = (program) => {
|
|
7027
7881
|
const names = [];
|
|
7028
7882
|
for (const statement of program.body) {
|
|
7029
|
-
const declaration = statement.type ===
|
|
7030
|
-
if (declaration?.type ===
|
|
7883
|
+
const declaration = statement.type === AST_NODE_TYPES35.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7884
|
+
if (declaration?.type === AST_NODE_TYPES35.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
7031
7885
|
}
|
|
7032
7886
|
return names;
|
|
7033
7887
|
};
|
|
@@ -7045,11 +7899,11 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
7045
7899
|
var publicMethodNames = (body) => {
|
|
7046
7900
|
const names = [];
|
|
7047
7901
|
for (const member of body.body) {
|
|
7048
|
-
if (member.type !==
|
|
7902
|
+
if (member.type !== AST_NODE_TYPES35.MethodDefinition) continue;
|
|
7049
7903
|
if (member.kind !== "method" || member.static) continue;
|
|
7050
7904
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
7051
|
-
if (member.key.type ===
|
|
7052
|
-
if (member.key.type ===
|
|
7905
|
+
if (member.key.type === AST_NODE_TYPES35.PrivateIdentifier) continue;
|
|
7906
|
+
if (member.key.type === AST_NODE_TYPES35.Identifier) names.push(member.key.name);
|
|
7053
7907
|
else names.push("\u2026");
|
|
7054
7908
|
}
|
|
7055
7909
|
return names;
|
|
@@ -7082,7 +7936,7 @@ var require_interface_for_injected_service_default = ESLintUtils45.RuleCreator(
|
|
|
7082
7936
|
if (node.implements.length > 0) return;
|
|
7083
7937
|
if (node.decorators.length > 0) return;
|
|
7084
7938
|
const ctor = node.body.body.find(
|
|
7085
|
-
(member) => member.type ===
|
|
7939
|
+
(member) => member.type === AST_NODE_TYPES35.MethodDefinition && member.kind === "constructor"
|
|
7086
7940
|
);
|
|
7087
7941
|
if (ctor === void 0) return;
|
|
7088
7942
|
const { collaborators, constructedFields } = readConstructor(ctor);
|
|
@@ -7107,20 +7961,20 @@ var require_interface_for_injected_service_default = ESLintUtils45.RuleCreator(
|
|
|
7107
7961
|
});
|
|
7108
7962
|
|
|
7109
7963
|
// src/rules/prefer-non-nullable-collection.ts
|
|
7110
|
-
import { AST_NODE_TYPES as
|
|
7964
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES36, ESLintUtils as ESLintUtils46 } from "@typescript-eslint/utils";
|
|
7111
7965
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
7112
7966
|
function propertyName(node) {
|
|
7113
7967
|
const key = node.key;
|
|
7114
|
-
if (key.type ===
|
|
7115
|
-
if (key.type ===
|
|
7968
|
+
if (key.type === AST_NODE_TYPES36.Identifier) return key.name;
|
|
7969
|
+
if (key.type === AST_NODE_TYPES36.Literal) return String(key.value);
|
|
7116
7970
|
return "collection";
|
|
7117
7971
|
}
|
|
7118
7972
|
function isArrayType(node) {
|
|
7119
|
-
if (node.type ===
|
|
7120
|
-
return node.type ===
|
|
7973
|
+
if (node.type === AST_NODE_TYPES36.TSArrayType) return true;
|
|
7974
|
+
return node.type === AST_NODE_TYPES36.TSTypeReference && node.typeName.type === AST_NODE_TYPES36.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
7121
7975
|
}
|
|
7122
7976
|
function isNullishType(node) {
|
|
7123
|
-
return node.type ===
|
|
7977
|
+
return node.type === AST_NODE_TYPES36.TSNullKeyword || node.type === AST_NODE_TYPES36.TSUndefinedKeyword;
|
|
7124
7978
|
}
|
|
7125
7979
|
function isNullableArrayOnly(node) {
|
|
7126
7980
|
const values = node.types.filter((member) => !isNullishType(member));
|
|
@@ -7149,7 +8003,7 @@ var prefer_non_nullable_collection_default = ESLintUtils46.RuleCreator(
|
|
|
7149
8003
|
function checkOptionalProperty(node) {
|
|
7150
8004
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
7151
8005
|
if (annotation === void 0) return;
|
|
7152
|
-
if (annotation.type !==
|
|
8006
|
+
if (annotation.type !== AST_NODE_TYPES36.TSUnionType || !isNullableArrayOnly(annotation)) {
|
|
7153
8007
|
return;
|
|
7154
8008
|
}
|
|
7155
8009
|
context.report({
|
|
@@ -7162,7 +8016,7 @@ var prefer_non_nullable_collection_default = ESLintUtils46.RuleCreator(
|
|
|
7162
8016
|
TSPropertySignature: checkOptionalProperty,
|
|
7163
8017
|
PropertyDefinition: checkOptionalProperty,
|
|
7164
8018
|
TSTypeAliasDeclaration(node) {
|
|
7165
|
-
if (node.typeAnnotation.type !==
|
|
8019
|
+
if (node.typeAnnotation.type !== AST_NODE_TYPES36.TSUnionType) return;
|
|
7166
8020
|
if (!isNullableArrayOnly(node.typeAnnotation)) return;
|
|
7167
8021
|
context.report({
|
|
7168
8022
|
node,
|
|
@@ -7174,174 +8028,217 @@ var prefer_non_nullable_collection_default = ESLintUtils46.RuleCreator(
|
|
|
7174
8028
|
}
|
|
7175
8029
|
});
|
|
7176
8030
|
|
|
7177
|
-
// src/rules/
|
|
7178
|
-
import { AST_NODE_TYPES as
|
|
7179
|
-
var
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
if (node.type === AST_NODE_TYPES34.Identifier) {
|
|
7195
|
-
return node.name;
|
|
8031
|
+
// src/rules/strict-test-assertions.ts
|
|
8032
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES37, ESLintUtils as ESLintUtils47 } from "@typescript-eslint/utils";
|
|
8033
|
+
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
8034
|
+
var ARRAY_MATCHERS = /* @__PURE__ */ new Set(["toEqual", "toStrictEqual"]);
|
|
8035
|
+
var COLLECTION_PROPERTIES = /* @__PURE__ */ new Set(["length", "size"]);
|
|
8036
|
+
var NUMERIC_SIGNS2 = /* @__PURE__ */ new Set(["-", "+"]);
|
|
8037
|
+
var MIN_RUN_LENGTH = 2;
|
|
8038
|
+
function literalText(node, getText) {
|
|
8039
|
+
switch (node.type) {
|
|
8040
|
+
case AST_NODE_TYPES37.Literal:
|
|
8041
|
+
return "regex" in node ? null : getText(node);
|
|
8042
|
+
case AST_NODE_TYPES37.TemplateLiteral:
|
|
8043
|
+
return node.expressions.length === 0 ? getText(node) : null;
|
|
8044
|
+
case AST_NODE_TYPES37.UnaryExpression:
|
|
8045
|
+
return NUMERIC_SIGNS2.has(node.operator) && literalText(node.argument, getText) !== null ? getText(node) : null;
|
|
8046
|
+
default:
|
|
8047
|
+
return null;
|
|
7196
8048
|
}
|
|
7197
|
-
|
|
7198
|
-
|
|
8049
|
+
}
|
|
8050
|
+
function isPureReceiver(node) {
|
|
8051
|
+
switch (node.type) {
|
|
8052
|
+
case AST_NODE_TYPES37.Identifier:
|
|
8053
|
+
case AST_NODE_TYPES37.ThisExpression:
|
|
8054
|
+
return true;
|
|
8055
|
+
case AST_NODE_TYPES37.MemberExpression:
|
|
8056
|
+
if (node.optional) {
|
|
8057
|
+
return false;
|
|
8058
|
+
}
|
|
8059
|
+
if (node.computed) {
|
|
8060
|
+
return node.property.type === AST_NODE_TYPES37.Literal && isPureReceiver(node.object);
|
|
8061
|
+
}
|
|
8062
|
+
return isPureReceiver(node.object);
|
|
8063
|
+
default:
|
|
8064
|
+
return false;
|
|
7199
8065
|
}
|
|
7200
|
-
return null;
|
|
7201
8066
|
}
|
|
7202
|
-
|
|
8067
|
+
function literalIndex(node) {
|
|
8068
|
+
if (node.type !== AST_NODE_TYPES37.Literal || typeof node.value !== "number") {
|
|
8069
|
+
return null;
|
|
8070
|
+
}
|
|
8071
|
+
return Number.isInteger(node.value) && node.value >= 0 ? node.value : null;
|
|
8072
|
+
}
|
|
8073
|
+
var strict_test_assertions_default = ESLintUtils47.RuleCreator(
|
|
7203
8074
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7204
8075
|
)({
|
|
7205
|
-
name: "
|
|
7206
|
-
meta: {
|
|
7207
|
-
type: "problem",
|
|
7208
|
-
docs: {
|
|
7209
|
-
description: "Disallow imperative dictionary access with string literals; use declarative Zod schemas."
|
|
7210
|
-
},
|
|
7211
|
-
schema: [],
|
|
7212
|
-
messages: {
|
|
7213
|
-
noImplicitAttributeAccess: "Imperative lookup for '{{key}}' \u2014 if the key is known, parse the object declaratively with a Zod schema instead."
|
|
7214
|
-
}
|
|
7215
|
-
},
|
|
7216
|
-
defaultOptions: [],
|
|
7217
|
-
create(context) {
|
|
7218
|
-
return {
|
|
7219
|
-
MemberExpression(node) {
|
|
7220
|
-
if (!node.computed) {
|
|
7221
|
-
return;
|
|
7222
|
-
}
|
|
7223
|
-
if (node.property.type === AST_NODE_TYPES34.Literal && typeof node.property.value === "string") {
|
|
7224
|
-
const baseName = getBaseName(node.object);
|
|
7225
|
-
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7226
|
-
context.report({
|
|
7227
|
-
node,
|
|
7228
|
-
messageId: "noImplicitAttributeAccess",
|
|
7229
|
-
data: { key: node.property.value }
|
|
7230
|
-
});
|
|
7231
|
-
}
|
|
7232
|
-
}
|
|
7233
|
-
},
|
|
7234
|
-
CallExpression(node) {
|
|
7235
|
-
const callee = node.callee;
|
|
7236
|
-
if (callee.type === AST_NODE_TYPES34.MemberExpression) {
|
|
7237
|
-
const method = callee.property.type === AST_NODE_TYPES34.Identifier ? callee.property.name : null;
|
|
7238
|
-
if (method === "get") {
|
|
7239
|
-
const arg = node.arguments[0];
|
|
7240
|
-
if (arg && arg.type === AST_NODE_TYPES34.Literal && typeof arg.value === "string") {
|
|
7241
|
-
const baseName = getBaseName(callee.object);
|
|
7242
|
-
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7243
|
-
context.report({
|
|
7244
|
-
node,
|
|
7245
|
-
messageId: "noImplicitAttributeAccess",
|
|
7246
|
-
data: { key: arg.value }
|
|
7247
|
-
});
|
|
7248
|
-
}
|
|
7249
|
-
}
|
|
7250
|
-
}
|
|
7251
|
-
}
|
|
7252
|
-
}
|
|
7253
|
-
};
|
|
7254
|
-
}
|
|
7255
|
-
});
|
|
7256
|
-
|
|
7257
|
-
// src/rules/strict-test-assertions.ts
|
|
7258
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES35, ESLintUtils as ESLintUtils48 } from "@typescript-eslint/utils";
|
|
7259
|
-
var strict_test_assertions_default = ESLintUtils48.RuleCreator.withoutDocs({
|
|
8076
|
+
name: "strict-test-assertions",
|
|
7260
8077
|
meta: {
|
|
7261
8078
|
type: "suggestion",
|
|
7262
8079
|
docs: {
|
|
7263
|
-
description: "
|
|
8080
|
+
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."
|
|
7264
8081
|
},
|
|
7265
8082
|
fixable: "code",
|
|
7266
8083
|
messages: {
|
|
7267
|
-
combineAssertions: "
|
|
8084
|
+
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 })`.",
|
|
8085
|
+
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 ])`."
|
|
7268
8086
|
},
|
|
7269
8087
|
schema: []
|
|
7270
8088
|
},
|
|
7271
8089
|
defaultOptions: [],
|
|
7272
8090
|
create(context) {
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
8091
|
+
if (!isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
8092
|
+
return {};
|
|
8093
|
+
}
|
|
8094
|
+
const { sourceCode } = context;
|
|
8095
|
+
function parseAssertion(statement) {
|
|
8096
|
+
if (statement.type !== AST_NODE_TYPES37.ExpressionStatement) {
|
|
8097
|
+
return null;
|
|
8098
|
+
}
|
|
8099
|
+
const call = statement.expression;
|
|
8100
|
+
if (call.type !== AST_NODE_TYPES37.CallExpression) {
|
|
8101
|
+
return null;
|
|
8102
|
+
}
|
|
8103
|
+
const callee = call.callee;
|
|
8104
|
+
if (callee.type !== AST_NODE_TYPES37.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES37.Identifier) {
|
|
8105
|
+
return null;
|
|
8106
|
+
}
|
|
8107
|
+
const matcher = callee.property.name;
|
|
8108
|
+
const expectCall = callee.object;
|
|
8109
|
+
if (expectCall.type !== AST_NODE_TYPES37.CallExpression || expectCall.callee.type !== AST_NODE_TYPES37.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
|
|
8110
|
+
return null;
|
|
8111
|
+
}
|
|
8112
|
+
const actual = expectCall.arguments[0];
|
|
8113
|
+
if (actual === void 0 || actual.type !== AST_NODE_TYPES37.MemberExpression || actual.optional) {
|
|
8114
|
+
return null;
|
|
8115
|
+
}
|
|
8116
|
+
if (!isPureReceiver(actual.object)) {
|
|
8117
|
+
return null;
|
|
8118
|
+
}
|
|
8119
|
+
let key;
|
|
8120
|
+
if (actual.computed) {
|
|
8121
|
+
const index = literalIndex(actual.property);
|
|
8122
|
+
if (index === null) {
|
|
8123
|
+
return null;
|
|
8124
|
+
}
|
|
8125
|
+
key = { kind: "index", index };
|
|
8126
|
+
} else {
|
|
8127
|
+
if (actual.property.type !== AST_NODE_TYPES37.Identifier || COLLECTION_PROPERTIES.has(actual.property.name)) {
|
|
8128
|
+
return null;
|
|
7282
8129
|
}
|
|
8130
|
+
key = { kind: "property", name: actual.property.name };
|
|
8131
|
+
}
|
|
8132
|
+
if (matcher === "toBeNull" && call.arguments.length === 0) {
|
|
8133
|
+
return { statement, receiver: actual.object, key, matcher, expectedText: "null", expectedIsLiteral: true };
|
|
8134
|
+
}
|
|
8135
|
+
if (!MERGEABLE_MATCHERS.has(matcher)) {
|
|
7283
8136
|
return null;
|
|
7284
8137
|
}
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
fixer.replaceText(first, replacement),
|
|
7311
|
-
...sequence.slice(1).map((stmt) => fixer.remove(stmt))
|
|
7312
|
-
];
|
|
7313
|
-
}
|
|
7314
|
-
});
|
|
8138
|
+
const expected = call.arguments[0];
|
|
8139
|
+
if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES37.SpreadElement) {
|
|
8140
|
+
return null;
|
|
8141
|
+
}
|
|
8142
|
+
const literal = literalText(expected, (node) => sourceCode.getText(node));
|
|
8143
|
+
return {
|
|
8144
|
+
statement,
|
|
8145
|
+
receiver: actual.object,
|
|
8146
|
+
key,
|
|
8147
|
+
matcher,
|
|
8148
|
+
expectedText: literal ?? sourceCode.getText(expected),
|
|
8149
|
+
expectedIsLiteral: literal !== null
|
|
8150
|
+
};
|
|
8151
|
+
}
|
|
8152
|
+
function reportPropertyRun(run) {
|
|
8153
|
+
const names = /* @__PURE__ */ new Set();
|
|
8154
|
+
for (const assertion of run) {
|
|
8155
|
+
if (assertion.key.kind !== "property" || !assertion.expectedIsLiteral) {
|
|
8156
|
+
return;
|
|
8157
|
+
}
|
|
8158
|
+
if (!MERGEABLE_MATCHERS.has(assertion.matcher) && assertion.matcher !== "toBeNull") {
|
|
8159
|
+
return;
|
|
8160
|
+
}
|
|
8161
|
+
if (names.has(assertion.key.name)) {
|
|
8162
|
+
return;
|
|
7315
8163
|
}
|
|
8164
|
+
names.add(assertion.key.name);
|
|
7316
8165
|
}
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
8166
|
+
const first = run[0];
|
|
8167
|
+
if (first === void 0) {
|
|
8168
|
+
return;
|
|
8169
|
+
}
|
|
8170
|
+
const receiverText = sourceCode.getText(first.receiver);
|
|
8171
|
+
const properties = run.map(
|
|
8172
|
+
(assertion) => assertion.key.kind === "property" ? `${assertion.key.name}: ${assertion.expectedText}` : ""
|
|
8173
|
+
).join(", ");
|
|
8174
|
+
context.report({
|
|
8175
|
+
node: first.statement,
|
|
8176
|
+
messageId: "combineAssertions",
|
|
8177
|
+
data: { count: String(run.length), receiver: receiverText },
|
|
8178
|
+
fix: (fixer) => [
|
|
8179
|
+
fixer.replaceText(first.statement, `expect(${receiverText}).toMatchObject({ ${properties} });`),
|
|
8180
|
+
...run.slice(1).map((assertion) => fixer.remove(assertion.statement))
|
|
8181
|
+
]
|
|
8182
|
+
});
|
|
8183
|
+
}
|
|
8184
|
+
function reportIndexRun(run) {
|
|
8185
|
+
const first = run[0];
|
|
8186
|
+
if (first === void 0 || !ARRAY_MATCHERS.has(first.matcher)) {
|
|
8187
|
+
return;
|
|
8188
|
+
}
|
|
8189
|
+
const indices = /* @__PURE__ */ new Set();
|
|
8190
|
+
for (const assertion of run) {
|
|
8191
|
+
if (assertion.key.kind !== "index" || assertion.matcher !== first.matcher) {
|
|
8192
|
+
return;
|
|
8193
|
+
}
|
|
8194
|
+
indices.add(assertion.key.index);
|
|
8195
|
+
}
|
|
8196
|
+
if (indices.size !== run.length || Math.max(...indices) !== run.length - 1) {
|
|
8197
|
+
return;
|
|
8198
|
+
}
|
|
8199
|
+
context.report({
|
|
8200
|
+
node: first.statement,
|
|
8201
|
+
messageId: "assertArrayOnce",
|
|
8202
|
+
data: {
|
|
8203
|
+
count: String(run.length),
|
|
8204
|
+
receiver: sourceCode.getText(first.receiver),
|
|
8205
|
+
last: String(run.length - 1),
|
|
8206
|
+
matcher: first.matcher
|
|
8207
|
+
}
|
|
8208
|
+
});
|
|
8209
|
+
}
|
|
8210
|
+
function checkBody(body) {
|
|
8211
|
+
let run = [];
|
|
8212
|
+
const flush = () => {
|
|
8213
|
+
const first = run[0];
|
|
8214
|
+
if (first !== void 0 && run.length >= MIN_RUN_LENGTH) {
|
|
8215
|
+
if (first.key.kind === "property") {
|
|
8216
|
+
reportPropertyRun(run);
|
|
7322
8217
|
} else {
|
|
7323
|
-
|
|
7324
|
-
if (obj) {
|
|
7325
|
-
currentObject = obj;
|
|
7326
|
-
sequence = [statement];
|
|
7327
|
-
} else {
|
|
7328
|
-
currentObject = null;
|
|
7329
|
-
sequence = [];
|
|
7330
|
-
}
|
|
8218
|
+
reportIndexRun(run);
|
|
7331
8219
|
}
|
|
7332
|
-
}
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
8220
|
+
}
|
|
8221
|
+
run = [];
|
|
8222
|
+
};
|
|
8223
|
+
for (const statement of body) {
|
|
8224
|
+
const assertion = parseAssertion(statement);
|
|
8225
|
+
const previous = run.at(-1);
|
|
8226
|
+
if (assertion !== null && previous !== void 0 && previous.key.kind === assertion.key.kind && sourceCode.getText(previous.receiver) === sourceCode.getText(assertion.receiver)) {
|
|
8227
|
+
run.push(assertion);
|
|
8228
|
+
continue;
|
|
8229
|
+
}
|
|
8230
|
+
flush();
|
|
8231
|
+
if (assertion !== null) {
|
|
8232
|
+
run = [assertion];
|
|
7336
8233
|
}
|
|
7337
8234
|
}
|
|
7338
|
-
|
|
8235
|
+
flush();
|
|
7339
8236
|
}
|
|
7340
8237
|
return {
|
|
7341
|
-
BlockStatement(node) {
|
|
8238
|
+
BlockStatement: (node) => {
|
|
7342
8239
|
checkBody(node.body);
|
|
7343
8240
|
},
|
|
7344
|
-
Program(node) {
|
|
8241
|
+
Program: (node) => {
|
|
7345
8242
|
checkBody(node.body);
|
|
7346
8243
|
}
|
|
7347
8244
|
};
|
|
@@ -7349,8 +8246,8 @@ var strict_test_assertions_default = ESLintUtils48.RuleCreator.withoutDocs({
|
|
|
7349
8246
|
});
|
|
7350
8247
|
|
|
7351
8248
|
// src/rules/no-async-callback-in-waitfor.ts
|
|
7352
|
-
import { AST_NODE_TYPES as
|
|
7353
|
-
var no_async_callback_in_waitfor_default =
|
|
8249
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES38, ESLintUtils as ESLintUtils48 } from "@typescript-eslint/utils";
|
|
8250
|
+
var no_async_callback_in_waitfor_default = ESLintUtils48.RuleCreator(
|
|
7354
8251
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7355
8252
|
)({
|
|
7356
8253
|
name: "no-async-callback-in-waitfor",
|
|
@@ -7371,9 +8268,9 @@ var no_async_callback_in_waitfor_default = ESLintUtils49.RuleCreator(
|
|
|
7371
8268
|
}
|
|
7372
8269
|
return {
|
|
7373
8270
|
CallExpression(node) {
|
|
7374
|
-
if (node.callee.type ===
|
|
8271
|
+
if (node.callee.type === AST_NODE_TYPES38.Identifier && node.callee.name === "waitFor") {
|
|
7375
8272
|
const callback = node.arguments[0];
|
|
7376
|
-
if (callback && (callback.type ===
|
|
8273
|
+
if (callback && (callback.type === AST_NODE_TYPES38.ArrowFunctionExpression || callback.type === AST_NODE_TYPES38.FunctionExpression) && callback.async) {
|
|
7377
8274
|
context.report({
|
|
7378
8275
|
node: callback,
|
|
7379
8276
|
messageId: "noAsyncCallbackInWaitFor"
|
|
@@ -7386,7 +8283,7 @@ var no_async_callback_in_waitfor_default = ESLintUtils49.RuleCreator(
|
|
|
7386
8283
|
});
|
|
7387
8284
|
|
|
7388
8285
|
// src/rules/no-hand-rolled-sleep.ts
|
|
7389
|
-
import { AST_NODE_TYPES as
|
|
8286
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES39, ESLintUtils as ESLintUtils49 } from "@typescript-eslint/utils";
|
|
7390
8287
|
var GLOBAL_OBJECTS2 = /* @__PURE__ */ new Set([
|
|
7391
8288
|
"globalThis",
|
|
7392
8289
|
"window",
|
|
@@ -7405,66 +8302,66 @@ function matchesAnyPattern3(filename, patterns) {
|
|
|
7405
8302
|
return false;
|
|
7406
8303
|
}
|
|
7407
8304
|
function isSetTimeoutCallee(callee) {
|
|
7408
|
-
if (callee.type ===
|
|
8305
|
+
if (callee.type === AST_NODE_TYPES39.Identifier) {
|
|
7409
8306
|
return callee.name === "setTimeout";
|
|
7410
8307
|
}
|
|
7411
|
-
return callee.type ===
|
|
8308
|
+
return callee.type === AST_NODE_TYPES39.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES39.Identifier && callee.property.name === "setTimeout" && callee.object.type === AST_NODE_TYPES39.Identifier && GLOBAL_OBJECTS2.has(callee.object.name);
|
|
7412
8309
|
}
|
|
7413
8310
|
function soleCall(fn) {
|
|
7414
|
-
if (fn.body.type !==
|
|
7415
|
-
return fn.body.type ===
|
|
8311
|
+
if (fn.body.type !== AST_NODE_TYPES39.BlockStatement) {
|
|
8312
|
+
return fn.body.type === AST_NODE_TYPES39.CallExpression ? fn.body : null;
|
|
7416
8313
|
}
|
|
7417
8314
|
if (fn.body.body.length !== 1) {
|
|
7418
8315
|
return null;
|
|
7419
8316
|
}
|
|
7420
8317
|
const [only] = fn.body.body;
|
|
7421
|
-
if (only?.type !==
|
|
8318
|
+
if (only?.type !== AST_NODE_TYPES39.ExpressionStatement) {
|
|
7422
8319
|
return null;
|
|
7423
8320
|
}
|
|
7424
|
-
return only.expression.type ===
|
|
8321
|
+
return only.expression.type === AST_NODE_TYPES39.CallExpression ? only.expression : null;
|
|
7425
8322
|
}
|
|
7426
8323
|
function isTimedDelay(delay) {
|
|
7427
8324
|
if (delay === void 0) {
|
|
7428
8325
|
return false;
|
|
7429
8326
|
}
|
|
7430
|
-
if (delay.type ===
|
|
8327
|
+
if (delay.type === AST_NODE_TYPES39.Literal && typeof delay.value === "number") {
|
|
7431
8328
|
return delay.value !== 0;
|
|
7432
8329
|
}
|
|
7433
8330
|
return true;
|
|
7434
8331
|
}
|
|
7435
8332
|
function settlesWithoutValue(callback, name) {
|
|
7436
|
-
if (callback.type ===
|
|
8333
|
+
if (callback.type === AST_NODE_TYPES39.Identifier) {
|
|
7437
8334
|
return callback.name === name;
|
|
7438
8335
|
}
|
|
7439
|
-
if (callback.type !==
|
|
8336
|
+
if (callback.type !== AST_NODE_TYPES39.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES39.FunctionExpression) {
|
|
7440
8337
|
return false;
|
|
7441
8338
|
}
|
|
7442
8339
|
const call = soleCall(callback);
|
|
7443
|
-
return call !== null && call.arguments.length === 0 && call.callee.type ===
|
|
8340
|
+
return call !== null && call.arguments.length === 0 && call.callee.type === AST_NODE_TYPES39.Identifier && call.callee.name === name;
|
|
7444
8341
|
}
|
|
7445
8342
|
function rejectsInCallback(callback, name) {
|
|
7446
|
-
if (callback.type ===
|
|
8343
|
+
if (callback.type === AST_NODE_TYPES39.Identifier) {
|
|
7447
8344
|
return callback.name === name;
|
|
7448
8345
|
}
|
|
7449
|
-
if (callback.type !==
|
|
8346
|
+
if (callback.type !== AST_NODE_TYPES39.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES39.FunctionExpression) {
|
|
7450
8347
|
return false;
|
|
7451
8348
|
}
|
|
7452
8349
|
const call = soleCall(callback);
|
|
7453
|
-
return call !== null && call.callee.type ===
|
|
8350
|
+
return call !== null && call.callee.type === AST_NODE_TYPES39.Identifier && call.callee.name === name;
|
|
7454
8351
|
}
|
|
7455
8352
|
function parameterName(fn, index) {
|
|
7456
8353
|
const parameter = fn.params[index];
|
|
7457
|
-
return parameter?.type ===
|
|
8354
|
+
return parameter?.type === AST_NODE_TYPES39.Identifier ? parameter.name : null;
|
|
7458
8355
|
}
|
|
7459
8356
|
function isRaceArm(node) {
|
|
7460
8357
|
const array = node.parent;
|
|
7461
|
-
if (array?.type !==
|
|
8358
|
+
if (array?.type !== AST_NODE_TYPES39.ArrayExpression) {
|
|
7462
8359
|
return false;
|
|
7463
8360
|
}
|
|
7464
8361
|
const call = array.parent;
|
|
7465
|
-
return call?.type ===
|
|
8362
|
+
return call?.type === AST_NODE_TYPES39.CallExpression && call.arguments[0] === array && call.callee.type === AST_NODE_TYPES39.MemberExpression && !call.callee.computed && call.callee.object.type === AST_NODE_TYPES39.Identifier && call.callee.object.name === "Promise" && call.callee.property.type === AST_NODE_TYPES39.Identifier && RACE_METHODS.has(call.callee.property.name);
|
|
7466
8363
|
}
|
|
7467
|
-
var no_hand_rolled_sleep_default =
|
|
8364
|
+
var no_hand_rolled_sleep_default = ESLintUtils49.RuleCreator(
|
|
7468
8365
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7469
8366
|
)({
|
|
7470
8367
|
name: "no-hand-rolled-sleep",
|
|
@@ -7512,10 +8409,10 @@ var no_hand_rolled_sleep_default = ESLintUtils50.RuleCreator(
|
|
|
7512
8409
|
}
|
|
7513
8410
|
const program = sourceCode.ast;
|
|
7514
8411
|
for (const statement of program.body) {
|
|
7515
|
-
if (statement.type ===
|
|
8412
|
+
if (statement.type === AST_NODE_TYPES39.ExpressionStatement && statement.expression.type === AST_NODE_TYPES39.Literal && statement.expression.value === "use client") {
|
|
7516
8413
|
return true;
|
|
7517
8414
|
}
|
|
7518
|
-
if (statement.type ===
|
|
8415
|
+
if (statement.type === AST_NODE_TYPES39.ImportDeclaration && typeof statement.source.value === "string" && CLIENT_ONLY_MODULES.test(statement.source.value)) {
|
|
7519
8416
|
return true;
|
|
7520
8417
|
}
|
|
7521
8418
|
}
|
|
@@ -7531,11 +8428,11 @@ var no_hand_rolled_sleep_default = ESLintUtils50.RuleCreator(
|
|
|
7531
8428
|
};
|
|
7532
8429
|
return {
|
|
7533
8430
|
NewExpression(node) {
|
|
7534
|
-
if (node.callee.type !==
|
|
8431
|
+
if (node.callee.type !== AST_NODE_TYPES39.Identifier || node.callee.name !== "Promise") {
|
|
7535
8432
|
return;
|
|
7536
8433
|
}
|
|
7537
8434
|
const executor = node.arguments[0];
|
|
7538
|
-
if (executor?.type !==
|
|
8435
|
+
if (executor?.type !== AST_NODE_TYPES39.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES39.FunctionExpression) {
|
|
7539
8436
|
return;
|
|
7540
8437
|
}
|
|
7541
8438
|
const call = soleCall(executor);
|
|
@@ -7562,43 +8459,8 @@ var no_hand_rolled_sleep_default = ESLintUtils50.RuleCreator(
|
|
|
7562
8459
|
}
|
|
7563
8460
|
});
|
|
7564
8461
|
|
|
7565
|
-
// src/rules/prefer-setup-file-mocks.ts
|
|
7566
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES38, ESLintUtils as ESLintUtils51 } from "@typescript-eslint/utils";
|
|
7567
|
-
var prefer_setup_file_mocks_default = ESLintUtils51.RuleCreator(
|
|
7568
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7569
|
-
)({
|
|
7570
|
-
name: "prefer-setup-file-mocks",
|
|
7571
|
-
meta: {
|
|
7572
|
-
type: "suggestion",
|
|
7573
|
-
docs: {
|
|
7574
|
-
description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
|
|
7575
|
-
},
|
|
7576
|
-
schema: [],
|
|
7577
|
-
messages: {
|
|
7578
|
-
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."
|
|
7579
|
-
}
|
|
7580
|
-
},
|
|
7581
|
-
defaultOptions: [],
|
|
7582
|
-
create(context) {
|
|
7583
|
-
if (!isTestFile(context.filename)) {
|
|
7584
|
-
return {};
|
|
7585
|
-
}
|
|
7586
|
-
return {
|
|
7587
|
-
CallExpression(node) {
|
|
7588
|
-
if (node.callee.type === AST_NODE_TYPES38.MemberExpression && node.callee.object.type === AST_NODE_TYPES38.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === AST_NODE_TYPES38.Identifier && node.callee.property.name === "mock") {
|
|
7589
|
-
context.report({
|
|
7590
|
-
node,
|
|
7591
|
-
messageId: "preferSetupFileMocks"
|
|
7592
|
-
});
|
|
7593
|
-
}
|
|
7594
|
-
}
|
|
7595
|
-
};
|
|
7596
|
-
}
|
|
7597
|
-
});
|
|
7598
|
-
|
|
7599
8462
|
// src/index.ts
|
|
7600
8463
|
var rules = {
|
|
7601
|
-
"ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
|
|
7602
8464
|
"enforce-file-structure": enforce_file_structure_default,
|
|
7603
8465
|
"no-client-side-data-fetching": no_client_side_data_fetching_default,
|
|
7604
8466
|
"no-comment-cruft": no_comment_cruft_default,
|
|
@@ -7623,6 +8485,7 @@ var rules = {
|
|
|
7623
8485
|
"no-unsafe-mock-casting": no_unsafe_mock_casting_default,
|
|
7624
8486
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
7625
8487
|
"prefer-zod-enum": prefer_zod_enum_default,
|
|
8488
|
+
"prefer-zod-infer": prefer_zod_infer_default,
|
|
7626
8489
|
"no-silent-promise-catch": no_silent_promise_catch_default,
|
|
7627
8490
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
7628
8491
|
"no-offset-pagination": no_offset_pagination_default,
|
|
@@ -7646,14 +8509,12 @@ var rules = {
|
|
|
7646
8509
|
"require-interface-for-injected-service": require_interface_for_injected_service_default,
|
|
7647
8510
|
"strict-test-assertions": strict_test_assertions_default,
|
|
7648
8511
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
7649
|
-
"no-
|
|
7650
|
-
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
|
|
7651
|
-
"prefer-setup-file-mocks": prefer_setup_file_mocks_default
|
|
8512
|
+
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default
|
|
7652
8513
|
};
|
|
7653
8514
|
var plugin = {
|
|
7654
8515
|
meta: {
|
|
7655
8516
|
name: "@sarj/eslint-plugin",
|
|
7656
|
-
version: "
|
|
8517
|
+
version: "5.0.0"
|
|
7657
8518
|
},
|
|
7658
8519
|
rules,
|
|
7659
8520
|
configs: {
|
|
@@ -7663,7 +8524,6 @@ var plugin = {
|
|
|
7663
8524
|
"@sarj/zod-naming-convention": "warn",
|
|
7664
8525
|
"@sarj/require-assert-never": "error",
|
|
7665
8526
|
"@sarj/require-zod-form-validation": "error",
|
|
7666
|
-
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7667
8527
|
"@sarj/enforce-file-structure": "warn",
|
|
7668
8528
|
"@sarj/no-client-side-data-fetching": "warn",
|
|
7669
8529
|
"@sarj/prefer-server-actions": "warn",
|
|
@@ -7689,6 +8549,11 @@ var plugin = {
|
|
|
7689
8549
|
"@sarj/no-unsafe-mock-casting": "warn",
|
|
7690
8550
|
"@sarj/prefer-string-literal-union": "warn",
|
|
7691
8551
|
"@sarj/prefer-zod-enum": "warn",
|
|
8552
|
+
// A type hand-written beside the Zod schema it restates drifts the
|
|
8553
|
+
// moment the schema gains a field. 30,759-file, 17-repo sweep
|
|
8554
|
+
// (2026-07): 5 reports, 5 true positives, all in public repos.
|
|
8555
|
+
// `requireIdenticalShape: false` widens it to 8 reports, 1 of them noise.
|
|
8556
|
+
"@sarj/prefer-zod-infer": "warn",
|
|
7692
8557
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7693
8558
|
"@sarj/require-fetch-timeout": "warn",
|
|
7694
8559
|
"@sarj/no-silent-promise-catch": "warn",
|
|
@@ -7743,9 +8608,7 @@ var plugin = {
|
|
|
7743
8608
|
// port, 29 fire, 28 of them true positives.
|
|
7744
8609
|
"@sarj/require-interface-for-injected-service": "warn",
|
|
7745
8610
|
"@sarj/prefer-non-nullable-collection": "warn",
|
|
7746
|
-
"@sarj/no-
|
|
7747
|
-
"@sarj/no-async-callback-in-waitfor": "warn",
|
|
7748
|
-
"@sarj/prefer-setup-file-mocks": "warn"
|
|
8611
|
+
"@sarj/no-async-callback-in-waitfor": "warn"
|
|
7749
8612
|
}
|
|
7750
8613
|
},
|
|
7751
8614
|
strict: {
|
|
@@ -7754,7 +8617,6 @@ var plugin = {
|
|
|
7754
8617
|
"@sarj/zod-naming-convention": "error",
|
|
7755
8618
|
"@sarj/require-assert-never": "error",
|
|
7756
8619
|
"@sarj/require-zod-form-validation": "error",
|
|
7757
|
-
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7758
8620
|
"@sarj/enforce-file-structure": "error",
|
|
7759
8621
|
"@sarj/no-raw-env": "error",
|
|
7760
8622
|
"@sarj/no-enum": "error",
|
|
@@ -7784,6 +8646,8 @@ var plugin = {
|
|
|
7784
8646
|
// Promoted to error 2026-07-25 — strict means strict (user directive).
|
|
7785
8647
|
"@sarj/prefer-string-literal-union": "error",
|
|
7786
8648
|
"@sarj/prefer-zod-enum": "error",
|
|
8649
|
+
// See the `recommended` block for the measured counts.
|
|
8650
|
+
"@sarj/prefer-zod-infer": "error",
|
|
7787
8651
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7788
8652
|
"@sarj/require-fetch-timeout": "error",
|
|
7789
8653
|
"@sarj/no-silent-promise-catch": "error",
|
|
@@ -7827,9 +8691,7 @@ var plugin = {
|
|
|
7827
8691
|
// corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
|
|
7828
8692
|
"@sarj/require-interface-for-injected-service": "error",
|
|
7829
8693
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
7830
|
-
"@sarj/no-
|
|
7831
|
-
"@sarj/no-async-callback-in-waitfor": "error",
|
|
7832
|
-
"@sarj/prefer-setup-file-mocks": "error"
|
|
8694
|
+
"@sarj/no-async-callback-in-waitfor": "error"
|
|
7833
8695
|
}
|
|
7834
8696
|
}
|
|
7835
8697
|
}
|