@sarj/eslint-plugin 2.15.0 → 2.17.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 +1 -0
- package/dist/index.cjs +1191 -526
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -2
- package/dist/index.d.ts +68 -2
- package/dist/index.js +977 -309
- 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
|
|
1
|
+
// src/rules/ban-loose-type-guards-in-tests.ts
|
|
2
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
3
3
|
|
|
4
4
|
// src/rules/_paths.ts
|
|
5
5
|
var SCRIPT_FILE_RE = /([\\/]scripts[\\/])|(\.mjs$)/;
|
|
@@ -24,7 +24,43 @@ 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
|
+
|
|
27
62
|
// src/rules/enforce-file-structure.ts
|
|
63
|
+
import { ESLintUtils as ESLintUtils2, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
28
64
|
var classifyStatement = (statement) => {
|
|
29
65
|
switch (statement.type) {
|
|
30
66
|
case AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -44,7 +80,7 @@ var isUseServerDirective = (statement) => {
|
|
|
44
80
|
if (expr.type !== AST_NODE_TYPES.Literal) return false;
|
|
45
81
|
return expr.value === "use server";
|
|
46
82
|
};
|
|
47
|
-
var enforce_file_structure_default =
|
|
83
|
+
var enforce_file_structure_default = ESLintUtils2.RuleCreator(
|
|
48
84
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
49
85
|
)({
|
|
50
86
|
name: "enforce-file-structure",
|
|
@@ -106,7 +142,7 @@ var enforce_file_structure_default = ESLintUtils.RuleCreator(
|
|
|
106
142
|
// src/rules/no-client-side-data-fetching.ts
|
|
107
143
|
import {
|
|
108
144
|
AST_NODE_TYPES as AST_NODE_TYPES2,
|
|
109
|
-
ESLintUtils as
|
|
145
|
+
ESLintUtils as ESLintUtils3
|
|
110
146
|
} from "@typescript-eslint/utils";
|
|
111
147
|
var FETCH_LIBS = /* @__PURE__ */ new Set(["axios", "ky", "superagent"]);
|
|
112
148
|
var HTTP_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -204,7 +240,7 @@ function isAnalyticsCall(node) {
|
|
|
204
240
|
if (url === "") return false;
|
|
205
241
|
return url.split(/[/.]/).some((segment) => ANALYTICS_SEGMENTS.has(segment));
|
|
206
242
|
}
|
|
207
|
-
var no_client_side_data_fetching_default =
|
|
243
|
+
var no_client_side_data_fetching_default = ESLintUtils3.RuleCreator(
|
|
208
244
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
209
245
|
)({
|
|
210
246
|
name: "no-client-side-data-fetching",
|
|
@@ -242,7 +278,7 @@ var no_client_side_data_fetching_default = ESLintUtils2.RuleCreator(
|
|
|
242
278
|
});
|
|
243
279
|
|
|
244
280
|
// src/rules/no-comment-cruft.ts
|
|
245
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as
|
|
281
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
246
282
|
|
|
247
283
|
// src/rules/_comments.ts
|
|
248
284
|
import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
|
|
@@ -433,9 +469,9 @@ function restatesStatementHead(body, statement) {
|
|
|
433
469
|
|
|
434
470
|
// src/rules/no-comment-cruft.ts
|
|
435
471
|
var LEADING_PREAMBLE_MIN = 4;
|
|
436
|
-
var STEP_NARRATION_RE = /^(?:first(?:ly)?|second(?:ly)?|third(?:ly)?|then|next|after(?:wards| that)?|finally|lastly|now)\s*[,:]\s*\S
|
|
472
|
+
var STEP_NARRATION_RE = /^(?:first(?:ly)?|second(?:ly)?|third(?:ly)?|then|next|after(?:wards| that)?|finally|lastly|now)\s*[,:]\s*\S/i;
|
|
437
473
|
var META_COMMENTARY_RE = /\b(?:for now|keeping (?:it|this) simple|could be (?:refactored|improved|cleaned up|simplified)|refactor(?:ed|ing)? (?:later|this)|not sure (?:if|whether|why|how)|quick[- ](?:and[- ]dirty|fix)|(?:a |bit of a )?hacky|is a hack|temporary (?:solution|workaround|fix|hack)|revisit (?:this|later|below)|clean (?:this|it) up|not ideal|placeholder for now)\b/i;
|
|
438
|
-
var DIRECTIVE_RE = /^(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|
|
|
474
|
+
var DIRECTIVE_RE = /^(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|hack\b|xxx\b)/i;
|
|
439
475
|
var LICENSE_RE = /copyright|licen[cs]ed?|spdx|permission is hereby granted|all rights reserved/i;
|
|
440
476
|
var ENUMERATED_ITEM_RE = /^(?:\d+[.):]|[-*•])\s+\S/;
|
|
441
477
|
var ENUMERATED_ITEM_MIN_WORDS = 3;
|
|
@@ -501,7 +537,8 @@ function isSectionLabel(text) {
|
|
|
501
537
|
}
|
|
502
538
|
var HELPER_OPENER_RE = /^(?:a\s+)?helper\s+(?:function|method|component|hook|class|type|util(?:ity)?)\b/i;
|
|
503
539
|
var LETS_RE = /^let'?s\s+(?:not\s+|just\s+|now\s+|first\s+)?(?:add|append|assign|await|build|calculate|call|check|clear|close|compute|convert|copy|count|create|declare|decrement|define|delete|extract|fetch|filter|find|format|generate|get|handle|increment|init|initialise|initialize|insert|iterate|join|load|log|loop|map|merge|open|parse|print|process|push|read|remove|render|reset|return|save|send|set|setup|sort|split|start|stop|store|update|validate|wrap|write)(?:s|es|ed|ing)?\b/i;
|
|
504
|
-
var ENUMERATION_RE = /^(?:\d+[.)]\s+\S|phase\s+\d+\b)/i;
|
|
540
|
+
var ENUMERATION_RE = /^(?:\d+[.)]\s+\S|(?:phase|step)\s+\d+\b)/i;
|
|
541
|
+
var DUMMY_TRANSLATION_RE = /^(?:increment|return|returns|get|gets|set\b(?! up\b)|sets\b(?! up\b)|function to|method to)\b/i;
|
|
505
542
|
var DIAGRAM_ARROW_RE = /[-=~]{2,}>|<[-=~]{2,}/;
|
|
506
543
|
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\.)/;
|
|
507
544
|
var CODE_TAIL_RE = /[;{}()]\s*$|=>\s*$|,\s*$/;
|
|
@@ -549,6 +586,14 @@ function isRedundantNarration(body, statementBelow, standalone, isolatedEnumerat
|
|
|
549
586
|
if (STEP_NARRATION_RE.test(t)) return true;
|
|
550
587
|
if (META_COMMENTARY_RE.test(t) && !JUSTIFICATION_RE.test(t)) return true;
|
|
551
588
|
if (HELPER_OPENER_RE.test(t) || LETS_RE.test(t)) return true;
|
|
589
|
+
const words = t.split(/\s+/);
|
|
590
|
+
if (words.length <= 4 && DUMMY_TRANSLATION_RE.test(t) && !/[():=]/.test(t)) {
|
|
591
|
+
const lowerT = t.toLowerCase();
|
|
592
|
+
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
|
+
if (words.length > 1) return true;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
552
597
|
if (!nested && isSectionLabel(t)) return true;
|
|
553
598
|
if (isolatedEnumeration && ENUMERATION_RE.test(t)) return true;
|
|
554
599
|
}
|
|
@@ -602,7 +647,7 @@ function hasCommentedOutCode(texts, precedingProse) {
|
|
|
602
647
|
}
|
|
603
648
|
return false;
|
|
604
649
|
}
|
|
605
|
-
var no_comment_cruft_default =
|
|
650
|
+
var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
606
651
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
607
652
|
)({
|
|
608
653
|
name: "no-comment-cruft",
|
|
@@ -616,7 +661,8 @@ var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
|
616
661
|
commentedOutCode: "Commented-out code \u2014 delete it; git history remembers.",
|
|
617
662
|
sectionBanner: "Section-banner / region comment \u2014 structure code with functions, not ASCII rules.",
|
|
618
663
|
fileHeaderPreamble: "File-header comment preamble \u2014 use a brief doc comment for the why, not a block of `//` lines.",
|
|
619
|
-
redundantNarration: "Comment narrates the code \u2014 delete it or say *why*, not *what*. Code is self-documenting."
|
|
664
|
+
redundantNarration: "Comment narrates the code \u2014 delete it or say *why*, not *what*. Code is self-documenting.",
|
|
665
|
+
untrackedTodo: "Untracked TODO/FIXME marker \u2014 add an issue ticket or context link."
|
|
620
666
|
}
|
|
621
667
|
},
|
|
622
668
|
defaultOptions: [],
|
|
@@ -670,6 +716,16 @@ var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
|
670
716
|
if (isJsDoc(comment) || !isStandalone(comment)) continue;
|
|
671
717
|
if (LICENSE_RE.test(comment.value)) continue;
|
|
672
718
|
const texts = comment.value.split("\n").map(stripCommentMarker).filter((l) => l.length > 0 && !isDirective(l));
|
|
719
|
+
const firstText = texts[0];
|
|
720
|
+
if (firstText !== void 0 && /^(?:todo|fixme)\b/i.test(firstText)) {
|
|
721
|
+
if (!runCitesAReference(comments, i)) {
|
|
722
|
+
context.report({
|
|
723
|
+
node: comment,
|
|
724
|
+
messageId: "untrackedTodo"
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
673
729
|
if (texts.some(isBanner)) {
|
|
674
730
|
context.report({ node: comment, messageId: "sectionBanner" });
|
|
675
731
|
continue;
|
|
@@ -698,7 +754,7 @@ var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
|
698
754
|
});
|
|
699
755
|
|
|
700
756
|
// src/rules/no-enum.ts
|
|
701
|
-
import { ESLintUtils as
|
|
757
|
+
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
702
758
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
703
759
|
/[\\/]generated[\\/]/,
|
|
704
760
|
/[\\/]openapi-gen[\\/]/,
|
|
@@ -718,7 +774,7 @@ function hasGeneratedMarker(sourceText) {
|
|
|
718
774
|
const head = sourceText.slice(0, 1024);
|
|
719
775
|
return /@generated\b/.test(head);
|
|
720
776
|
}
|
|
721
|
-
var no_enum_default =
|
|
777
|
+
var no_enum_default = ESLintUtils5.RuleCreator(
|
|
722
778
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
723
779
|
)({
|
|
724
780
|
name: "no-enum",
|
|
@@ -769,7 +825,7 @@ var no_enum_default = ESLintUtils4.RuleCreator(
|
|
|
769
825
|
});
|
|
770
826
|
|
|
771
827
|
// src/rules/no-insecure-random-id.ts
|
|
772
|
-
import { ESLintUtils as
|
|
828
|
+
import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
|
|
773
829
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
774
830
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
775
831
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -910,7 +966,7 @@ function isConcatenatedIntoPathOrDomId(node) {
|
|
|
910
966
|
collectStaticStringParts(top, parts);
|
|
911
967
|
return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
|
|
912
968
|
}
|
|
913
|
-
var no_insecure_random_id_default =
|
|
969
|
+
var no_insecure_random_id_default = ESLintUtils6.RuleCreator(
|
|
914
970
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
915
971
|
)({
|
|
916
972
|
name: "no-insecure-random-id",
|
|
@@ -954,7 +1010,7 @@ var no_insecure_random_id_default = ESLintUtils5.RuleCreator(
|
|
|
954
1010
|
});
|
|
955
1011
|
|
|
956
1012
|
// src/rules/no-json-stringify-error.ts
|
|
957
|
-
import { ESLintUtils as
|
|
1013
|
+
import { ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
|
|
958
1014
|
var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
|
|
959
1015
|
var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
|
|
960
1016
|
var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
|
|
@@ -1088,7 +1144,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
1088
1144
|
function isJsonStringify(callee) {
|
|
1089
1145
|
return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
|
|
1090
1146
|
}
|
|
1091
|
-
var no_json_stringify_error_default =
|
|
1147
|
+
var no_json_stringify_error_default = ESLintUtils7.RuleCreator(
|
|
1092
1148
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1093
1149
|
)({
|
|
1094
1150
|
name: "no-json-stringify-error",
|
|
@@ -1138,7 +1194,7 @@ var no_json_stringify_error_default = ESLintUtils6.RuleCreator(
|
|
|
1138
1194
|
});
|
|
1139
1195
|
|
|
1140
1196
|
// src/rules/no-log-only-catch.ts
|
|
1141
|
-
import { ESLintUtils as
|
|
1197
|
+
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
1142
1198
|
|
|
1143
1199
|
// src/rules/_logging.ts
|
|
1144
1200
|
import "@typescript-eslint/utils";
|
|
@@ -1248,7 +1304,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
|
|
|
1248
1304
|
/\.spec\./,
|
|
1249
1305
|
/[\\/]__tests__[\\/]/
|
|
1250
1306
|
];
|
|
1251
|
-
var no_log_only_catch_default =
|
|
1307
|
+
var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
1252
1308
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1253
1309
|
)({
|
|
1254
1310
|
name: "no-log-only-catch",
|
|
@@ -1311,7 +1367,7 @@ var no_log_only_catch_default = ESLintUtils7.RuleCreator(
|
|
|
1311
1367
|
});
|
|
1312
1368
|
|
|
1313
1369
|
// src/rules/no-raw-env.ts
|
|
1314
|
-
import { ESLintUtils as
|
|
1370
|
+
import { ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
|
|
1315
1371
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1316
1372
|
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1317
1373
|
function isValidatedEnvBoundary(filename, sourceText) {
|
|
@@ -1349,7 +1405,7 @@ function isWholeEnvSpread(node) {
|
|
|
1349
1405
|
const parent = node.parent;
|
|
1350
1406
|
return parent.type === "SpreadElement" && parent.argument === node;
|
|
1351
1407
|
}
|
|
1352
|
-
var no_raw_env_default =
|
|
1408
|
+
var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
1353
1409
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1354
1410
|
)({
|
|
1355
1411
|
name: "no-raw-env",
|
|
@@ -1384,7 +1440,7 @@ var no_raw_env_default = ESLintUtils8.RuleCreator(
|
|
|
1384
1440
|
|
|
1385
1441
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
1386
1442
|
import {
|
|
1387
|
-
ESLintUtils as
|
|
1443
|
+
ESLintUtils as ESLintUtils10,
|
|
1388
1444
|
AST_NODE_TYPES as AST_NODE_TYPES5
|
|
1389
1445
|
} from "@typescript-eslint/utils";
|
|
1390
1446
|
function sentinelKind(arg) {
|
|
@@ -1689,7 +1745,7 @@ function isWithin(node, ancestor) {
|
|
|
1689
1745
|
}
|
|
1690
1746
|
return false;
|
|
1691
1747
|
}
|
|
1692
|
-
var no_sentinel_return_on_catch_default =
|
|
1748
|
+
var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
1693
1749
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1694
1750
|
)({
|
|
1695
1751
|
name: "no-sentinel-return-on-catch",
|
|
@@ -1770,7 +1826,7 @@ var no_sentinel_return_on_catch_default = ESLintUtils9.RuleCreator(
|
|
|
1770
1826
|
});
|
|
1771
1827
|
|
|
1772
1828
|
// src/rules/no-sequential-await.ts
|
|
1773
|
-
import { ESLintUtils as
|
|
1829
|
+
import { ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
1774
1830
|
var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
|
|
1775
1831
|
var SEQUENTIAL_ITERABLE_HINT = /sort|reverse|ordered|sequence|hook|middleware|pipeline|preset|plugin|extension|\bstage|\bstep|\bphase|migration|chain|buffer|stream|teleport|chunk|\bqueue|drain/i;
|
|
1776
1832
|
var BENCH_FILE_RE = /(^|[\\/])bench(marks?)?[\\/]|\.bench\.[cm]?[jt]sx?$/i;
|
|
@@ -1924,7 +1980,7 @@ function shouldReport(awaits, earlyExit, iterableText, asserts = false) {
|
|
|
1924
1980
|
(node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
|
|
1925
1981
|
);
|
|
1926
1982
|
}
|
|
1927
|
-
var no_sequential_await_default =
|
|
1983
|
+
var no_sequential_await_default = ESLintUtils11.RuleCreator(
|
|
1928
1984
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1929
1985
|
)({
|
|
1930
1986
|
name: "no-sequential-await",
|
|
@@ -2019,7 +2075,7 @@ var no_sequential_await_default = ESLintUtils10.RuleCreator(
|
|
|
2019
2075
|
});
|
|
2020
2076
|
|
|
2021
2077
|
// src/rules/no-string-concat-in-loop.ts
|
|
2022
|
-
import { ESLintUtils as
|
|
2078
|
+
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
2023
2079
|
var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
2024
2080
|
"ForStatement",
|
|
2025
2081
|
"ForOfStatement",
|
|
@@ -2104,7 +2160,7 @@ function enclosingLoop(node) {
|
|
|
2104
2160
|
}
|
|
2105
2161
|
return null;
|
|
2106
2162
|
}
|
|
2107
|
-
var no_string_concat_in_loop_default =
|
|
2163
|
+
var no_string_concat_in_loop_default = ESLintUtils12.RuleCreator(
|
|
2108
2164
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2109
2165
|
)({
|
|
2110
2166
|
name: "no-string-concat-in-loop",
|
|
@@ -2169,7 +2225,7 @@ var no_string_concat_in_loop_default = ESLintUtils11.RuleCreator(
|
|
|
2169
2225
|
// src/rules/no-unnecessary-use-client.ts
|
|
2170
2226
|
import {
|
|
2171
2227
|
AST_NODE_TYPES as AST_NODE_TYPES6,
|
|
2172
|
-
ESLintUtils as
|
|
2228
|
+
ESLintUtils as ESLintUtils13
|
|
2173
2229
|
} from "@typescript-eslint/utils";
|
|
2174
2230
|
var HOOK_REGEX = /^use([A-Z]|$)/;
|
|
2175
2231
|
var EVENT_PROP_REGEX = /^on[A-Z]/;
|
|
@@ -2243,7 +2299,7 @@ var isGlobalReference = (node, context) => {
|
|
|
2243
2299
|
}
|
|
2244
2300
|
return true;
|
|
2245
2301
|
};
|
|
2246
|
-
var no_unnecessary_use_client_default =
|
|
2302
|
+
var no_unnecessary_use_client_default = ESLintUtils13.RuleCreator(
|
|
2247
2303
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2248
2304
|
)({
|
|
2249
2305
|
name: "no-unnecessary-use-client",
|
|
@@ -2364,7 +2420,7 @@ var no_unnecessary_use_client_default = ESLintUtils12.RuleCreator(
|
|
|
2364
2420
|
});
|
|
2365
2421
|
|
|
2366
2422
|
// src/rules/prefer-discriminated-union.ts
|
|
2367
|
-
import { ESLintUtils as
|
|
2423
|
+
import { ESLintUtils as ESLintUtils14 } from "@typescript-eslint/utils";
|
|
2368
2424
|
import { AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
2369
2425
|
var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
2370
2426
|
"success",
|
|
@@ -2411,7 +2467,7 @@ function looksLikeMutuallyExclusiveState(typeLiteral) {
|
|
|
2411
2467
|
}
|
|
2412
2468
|
return hasStatusBoolean && optionalCount >= MIN_OPTIONAL_MEMBERS && optionalPayloadCount >= 1;
|
|
2413
2469
|
}
|
|
2414
|
-
var prefer_discriminated_union_default =
|
|
2470
|
+
var prefer_discriminated_union_default = ESLintUtils14.RuleCreator(
|
|
2415
2471
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2416
2472
|
)({
|
|
2417
2473
|
name: "prefer-discriminated-union",
|
|
@@ -2454,7 +2510,7 @@ var prefer_discriminated_union_default = ESLintUtils13.RuleCreator(
|
|
|
2454
2510
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
2455
2511
|
import {
|
|
2456
2512
|
AST_NODE_TYPES as AST_NODE_TYPES8,
|
|
2457
|
-
ESLintUtils as
|
|
2513
|
+
ESLintUtils as ESLintUtils15
|
|
2458
2514
|
} from "@typescript-eslint/utils";
|
|
2459
2515
|
var unwrap = (node) => {
|
|
2460
2516
|
let current = node;
|
|
@@ -2577,7 +2633,7 @@ var isUnvalidatedVariableRef = (node, scope, tracked) => {
|
|
|
2577
2633
|
const variable = findVariable2(scope, unwrapped.name);
|
|
2578
2634
|
return variable !== null && tracked.has(variable);
|
|
2579
2635
|
};
|
|
2580
|
-
var prefer_schema_for_api_payload_default =
|
|
2636
|
+
var prefer_schema_for_api_payload_default = ESLintUtils15.RuleCreator(
|
|
2581
2637
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2582
2638
|
)({
|
|
2583
2639
|
name: "prefer-schema-for-api-payload",
|
|
@@ -2691,7 +2747,7 @@ var prefer_schema_for_api_payload_default = ESLintUtils14.RuleCreator(
|
|
|
2691
2747
|
});
|
|
2692
2748
|
|
|
2693
2749
|
// src/rules/prefer-semantic-colors.ts
|
|
2694
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as
|
|
2750
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as ESLintUtils16 } from "@typescript-eslint/utils";
|
|
2695
2751
|
import { existsSync, readFileSync } from "fs";
|
|
2696
2752
|
import { dirname, join, parse } from "path";
|
|
2697
2753
|
|
|
@@ -2828,7 +2884,7 @@ var propName = (key) => {
|
|
|
2828
2884
|
if (key.type === AST_NODE_TYPES9.Literal && typeof key.value === "string") return key.value;
|
|
2829
2885
|
return null;
|
|
2830
2886
|
};
|
|
2831
|
-
var prefer_semantic_colors_default =
|
|
2887
|
+
var prefer_semantic_colors_default = ESLintUtils16.RuleCreator(
|
|
2832
2888
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2833
2889
|
)({
|
|
2834
2890
|
name: "prefer-semantic-colors",
|
|
@@ -2950,7 +3006,7 @@ var prefer_semantic_colors_default = ESLintUtils15.RuleCreator(
|
|
|
2950
3006
|
});
|
|
2951
3007
|
|
|
2952
3008
|
// src/rules/prefer-server-actions.ts
|
|
2953
|
-
import { ESLintUtils as
|
|
3009
|
+
import { ESLintUtils as ESLintUtils17 } from "@typescript-eslint/utils";
|
|
2954
3010
|
var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
|
|
2955
3011
|
var AXIOS_MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "delete", "patch"]);
|
|
2956
3012
|
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\/)/;
|
|
@@ -3030,7 +3086,7 @@ function getPropertyNode(objNode, propName2) {
|
|
|
3030
3086
|
}
|
|
3031
3087
|
return null;
|
|
3032
3088
|
}
|
|
3033
|
-
var prefer_server_actions_default =
|
|
3089
|
+
var prefer_server_actions_default = ESLintUtils17.RuleCreator(
|
|
3034
3090
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3035
3091
|
)({
|
|
3036
3092
|
name: "prefer-server-actions",
|
|
@@ -3107,7 +3163,7 @@ var prefer_server_actions_default = ESLintUtils16.RuleCreator(
|
|
|
3107
3163
|
// src/rules/prefer-shadcn.ts
|
|
3108
3164
|
import {
|
|
3109
3165
|
AST_NODE_TYPES as AST_NODE_TYPES10,
|
|
3110
|
-
ESLintUtils as
|
|
3166
|
+
ESLintUtils as ESLintUtils18
|
|
3111
3167
|
} from "@typescript-eslint/utils";
|
|
3112
3168
|
var REPLACEMENTS = {
|
|
3113
3169
|
select: "Select",
|
|
@@ -3143,7 +3199,7 @@ var resolveInputReplacement = (node) => {
|
|
|
3143
3199
|
if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
|
|
3144
3200
|
return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
|
|
3145
3201
|
};
|
|
3146
|
-
var prefer_shadcn_default =
|
|
3202
|
+
var prefer_shadcn_default = ESLintUtils18.RuleCreator(
|
|
3147
3203
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3148
3204
|
)({
|
|
3149
3205
|
name: "prefer-shadcn",
|
|
@@ -3188,7 +3244,7 @@ var prefer_shadcn_default = ESLintUtils17.RuleCreator(
|
|
|
3188
3244
|
|
|
3189
3245
|
// src/rules/require-assert-never.ts
|
|
3190
3246
|
import {
|
|
3191
|
-
ESLintUtils as
|
|
3247
|
+
ESLintUtils as ESLintUtils19,
|
|
3192
3248
|
AST_NODE_TYPES as AST_NODE_TYPES11
|
|
3193
3249
|
} from "@typescript-eslint/utils";
|
|
3194
3250
|
var isAssertNeverCall = (expression) => {
|
|
@@ -3240,7 +3296,7 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
3240
3296
|
}
|
|
3241
3297
|
return false;
|
|
3242
3298
|
};
|
|
3243
|
-
var require_assert_never_default =
|
|
3299
|
+
var require_assert_never_default = ESLintUtils19.RuleCreator(
|
|
3244
3300
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3245
3301
|
)({
|
|
3246
3302
|
name: "require-assert-never",
|
|
@@ -3278,7 +3334,7 @@ var require_assert_never_default = ESLintUtils18.RuleCreator(
|
|
|
3278
3334
|
});
|
|
3279
3335
|
|
|
3280
3336
|
// src/rules/require-zod-form-validation.ts
|
|
3281
|
-
import { ESLintUtils as
|
|
3337
|
+
import { ESLintUtils as ESLintUtils20, AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
3282
3338
|
|
|
3283
3339
|
// src/rules/_zod.ts
|
|
3284
3340
|
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
@@ -3322,7 +3378,7 @@ var isFormDataMethodCall = (node) => {
|
|
|
3322
3378
|
const callee = current.callee;
|
|
3323
3379
|
return callee.type === AST_NODE_TYPES12.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES12.Identifier && callee.property.name === "formData";
|
|
3324
3380
|
};
|
|
3325
|
-
var require_zod_form_validation_default =
|
|
3381
|
+
var require_zod_form_validation_default = ESLintUtils20.RuleCreator(
|
|
3326
3382
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3327
3383
|
)({
|
|
3328
3384
|
name: "require-zod-form-validation",
|
|
@@ -3408,7 +3464,7 @@ var require_zod_form_validation_default = ESLintUtils19.RuleCreator(
|
|
|
3408
3464
|
});
|
|
3409
3465
|
|
|
3410
3466
|
// src/rules/zod-naming-convention.ts
|
|
3411
|
-
import { ESLintUtils as
|
|
3467
|
+
import { ESLintUtils as ESLintUtils21, AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
3412
3468
|
var CONVENTIONS = {
|
|
3413
3469
|
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
3414
3470
|
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
@@ -3448,7 +3504,7 @@ var calleeChainStartsWithZ = (node) => {
|
|
|
3448
3504
|
}
|
|
3449
3505
|
return false;
|
|
3450
3506
|
};
|
|
3451
|
-
var zod_naming_convention_default =
|
|
3507
|
+
var zod_naming_convention_default = ESLintUtils21.RuleCreator(
|
|
3452
3508
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3453
3509
|
)({
|
|
3454
3510
|
name: "zod-naming-convention",
|
|
@@ -3506,7 +3562,7 @@ var zod_naming_convention_default = ESLintUtils20.RuleCreator(
|
|
|
3506
3562
|
});
|
|
3507
3563
|
|
|
3508
3564
|
// src/rules/no-cors-wildcard-with-credentials.ts
|
|
3509
|
-
import { ESLintUtils as
|
|
3565
|
+
import { ESLintUtils as ESLintUtils22 } from "@typescript-eslint/utils";
|
|
3510
3566
|
var ACAO_HEADER = "access-control-allow-origin";
|
|
3511
3567
|
var ACAC_HEADER = "access-control-allow-credentials";
|
|
3512
3568
|
var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
|
|
@@ -3648,7 +3704,7 @@ function enclosingScope(node) {
|
|
|
3648
3704
|
}
|
|
3649
3705
|
return void 0;
|
|
3650
3706
|
}
|
|
3651
|
-
var no_cors_wildcard_with_credentials_default =
|
|
3707
|
+
var no_cors_wildcard_with_credentials_default = ESLintUtils22.RuleCreator(
|
|
3652
3708
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3653
3709
|
)({
|
|
3654
3710
|
name: "no-cors-wildcard-with-credentials",
|
|
@@ -3716,7 +3772,7 @@ var no_cors_wildcard_with_credentials_default = ESLintUtils21.RuleCreator(
|
|
|
3716
3772
|
});
|
|
3717
3773
|
|
|
3718
3774
|
// src/rules/no-silent-promise-catch.ts
|
|
3719
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES14, ESLintUtils as
|
|
3775
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES14, ESLintUtils as ESLintUtils23 } from "@typescript-eslint/utils";
|
|
3720
3776
|
function isBodyParseCall(node) {
|
|
3721
3777
|
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");
|
|
3722
3778
|
}
|
|
@@ -3769,7 +3825,7 @@ function isSilentHandler(handler) {
|
|
|
3769
3825
|
}
|
|
3770
3826
|
return false;
|
|
3771
3827
|
}
|
|
3772
|
-
var no_silent_promise_catch_default =
|
|
3828
|
+
var no_silent_promise_catch_default = ESLintUtils23.RuleCreator(
|
|
3773
3829
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3774
3830
|
)({
|
|
3775
3831
|
name: "no-silent-promise-catch",
|
|
@@ -3840,7 +3896,7 @@ var no_silent_promise_catch_default = ESLintUtils22.RuleCreator(
|
|
|
3840
3896
|
import {
|
|
3841
3897
|
AST_NODE_TYPES as AST_NODE_TYPES15,
|
|
3842
3898
|
ASTUtils,
|
|
3843
|
-
ESLintUtils as
|
|
3899
|
+
ESLintUtils as ESLintUtils24
|
|
3844
3900
|
} from "@typescript-eslint/utils";
|
|
3845
3901
|
var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
|
|
3846
3902
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
|
|
@@ -3877,7 +3933,7 @@ function initProvablyLacksSignal(init) {
|
|
|
3877
3933
|
function isStringish(node) {
|
|
3878
3934
|
return node.type === AST_NODE_TYPES15.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES15.TemplateLiteral;
|
|
3879
3935
|
}
|
|
3880
|
-
var require_fetch_timeout_default =
|
|
3936
|
+
var require_fetch_timeout_default = ESLintUtils24.RuleCreator(
|
|
3881
3937
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3882
3938
|
)({
|
|
3883
3939
|
name: "require-fetch-timeout",
|
|
@@ -3941,7 +3997,7 @@ var require_fetch_timeout_default = ESLintUtils23.RuleCreator(
|
|
|
3941
3997
|
});
|
|
3942
3998
|
|
|
3943
3999
|
// src/rules/require-schema-validate-search.ts
|
|
3944
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES16, ESLintUtils as
|
|
4000
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES16, ESLintUtils as ESLintUtils25 } from "@typescript-eslint/utils";
|
|
3945
4001
|
var VALIDATOR_METHODS = /* @__PURE__ */ new Set([
|
|
3946
4002
|
"parse",
|
|
3947
4003
|
"safeParse",
|
|
@@ -3990,7 +4046,7 @@ function findCastExpression(node, insideValidatorArg) {
|
|
|
3990
4046
|
}
|
|
3991
4047
|
return null;
|
|
3992
4048
|
}
|
|
3993
|
-
var require_schema_validate_search_default =
|
|
4049
|
+
var require_schema_validate_search_default = ESLintUtils25.RuleCreator(
|
|
3994
4050
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3995
4051
|
)({
|
|
3996
4052
|
name: "require-schema-validate-search",
|
|
@@ -4029,7 +4085,7 @@ var require_schema_validate_search_default = ESLintUtils24.RuleCreator(
|
|
|
4029
4085
|
|
|
4030
4086
|
// src/rules/no-fat-try-blocks.ts
|
|
4031
4087
|
import {
|
|
4032
|
-
ESLintUtils as
|
|
4088
|
+
ESLintUtils as ESLintUtils26,
|
|
4033
4089
|
AST_NODE_TYPES as AST_NODE_TYPES17
|
|
4034
4090
|
} from "@typescript-eslint/utils";
|
|
4035
4091
|
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
@@ -4222,7 +4278,7 @@ function handlerRethrows(handler) {
|
|
|
4222
4278
|
const last = body[body.length - 1];
|
|
4223
4279
|
return last !== void 0 && last.type === AST_NODE_TYPES17.ThrowStatement;
|
|
4224
4280
|
}
|
|
4225
|
-
var no_fat_try_blocks_default =
|
|
4281
|
+
var no_fat_try_blocks_default = ESLintUtils26.RuleCreator(
|
|
4226
4282
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4227
4283
|
)({
|
|
4228
4284
|
name: "no-fat-try-blocks",
|
|
@@ -4266,7 +4322,7 @@ var no_fat_try_blocks_default = ESLintUtils25.RuleCreator(
|
|
|
4266
4322
|
});
|
|
4267
4323
|
|
|
4268
4324
|
// src/rules/no-secret-in-log.ts
|
|
4269
|
-
import { ESLintUtils as
|
|
4325
|
+
import { ESLintUtils as ESLintUtils27 } from "@typescript-eslint/utils";
|
|
4270
4326
|
|
|
4271
4327
|
// src/rules/_secret_names.ts
|
|
4272
4328
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4528,7 +4584,7 @@ function propertyKeyName2(prop) {
|
|
|
4528
4584
|
}
|
|
4529
4585
|
return null;
|
|
4530
4586
|
}
|
|
4531
|
-
var no_secret_in_log_default =
|
|
4587
|
+
var no_secret_in_log_default = ESLintUtils27.RuleCreator(
|
|
4532
4588
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4533
4589
|
)({
|
|
4534
4590
|
name: "no-secret-in-log",
|
|
@@ -4605,7 +4661,7 @@ var no_secret_in_log_default = ESLintUtils26.RuleCreator(
|
|
|
4605
4661
|
});
|
|
4606
4662
|
|
|
4607
4663
|
// src/rules/no-unsafe-cast.ts
|
|
4608
|
-
import { ESLintUtils as
|
|
4664
|
+
import { ESLintUtils as ESLintUtils28 } from "@typescript-eslint/utils";
|
|
4609
4665
|
import { AST_NODE_TYPES as AST_NODE_TYPES18 } from "@typescript-eslint/utils";
|
|
4610
4666
|
function isAnyAnnotation(node) {
|
|
4611
4667
|
return node.type === AST_NODE_TYPES18.TSAnyKeyword;
|
|
@@ -4613,7 +4669,7 @@ function isAnyAnnotation(node) {
|
|
|
4613
4669
|
function isConstAssertion(typeAnnotation) {
|
|
4614
4670
|
return typeAnnotation.type === AST_NODE_TYPES18.TSTypeReference && typeAnnotation.typeName.type === AST_NODE_TYPES18.Identifier && typeAnnotation.typeName.name === "const";
|
|
4615
4671
|
}
|
|
4616
|
-
var no_unsafe_cast_default =
|
|
4672
|
+
var no_unsafe_cast_default = ESLintUtils28.RuleCreator(
|
|
4617
4673
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4618
4674
|
)({
|
|
4619
4675
|
name: "no-unsafe-cast",
|
|
@@ -4653,10 +4709,59 @@ var no_unsafe_cast_default = ESLintUtils27.RuleCreator(
|
|
|
4653
4709
|
}
|
|
4654
4710
|
});
|
|
4655
4711
|
|
|
4712
|
+
// src/rules/no-unsafe-mock-casting.ts
|
|
4713
|
+
import { ESLintUtils as ESLintUtils29 } from "@typescript-eslint/utils";
|
|
4714
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19 } from "@typescript-eslint/utils";
|
|
4715
|
+
function isMockTypeReference(node) {
|
|
4716
|
+
if (node.type !== AST_NODE_TYPES19.TSTypeReference) {
|
|
4717
|
+
return false;
|
|
4718
|
+
}
|
|
4719
|
+
const typeName = node.typeName;
|
|
4720
|
+
if (typeName.type === AST_NODE_TYPES19.Identifier) {
|
|
4721
|
+
const name = typeName.name;
|
|
4722
|
+
return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
|
|
4723
|
+
}
|
|
4724
|
+
if (typeName.type === AST_NODE_TYPES19.TSQualifiedName) {
|
|
4725
|
+
const rightName = typeName.right.name;
|
|
4726
|
+
return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
|
|
4727
|
+
}
|
|
4728
|
+
return false;
|
|
4729
|
+
}
|
|
4730
|
+
var no_unsafe_mock_casting_default = ESLintUtils29.RuleCreator(
|
|
4731
|
+
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4732
|
+
)({
|
|
4733
|
+
name: "no-unsafe-mock-casting",
|
|
4734
|
+
meta: {
|
|
4735
|
+
type: "problem",
|
|
4736
|
+
docs: {
|
|
4737
|
+
description: "Disallow casting to mock types like `jest.Mock` or `vi.Mock`. Use `vi.mocked()` or `jest.mocked()` instead."
|
|
4738
|
+
},
|
|
4739
|
+
schema: [],
|
|
4740
|
+
messages: {
|
|
4741
|
+
unsafeMockCast: "Do not cast to a Mock type. Use `vi.mocked(fn)` or `jest.mocked(fn)` instead to preserve type safety."
|
|
4742
|
+
}
|
|
4743
|
+
},
|
|
4744
|
+
defaultOptions: [],
|
|
4745
|
+
create(context) {
|
|
4746
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
4747
|
+
return {};
|
|
4748
|
+
}
|
|
4749
|
+
function checkAssertion(node) {
|
|
4750
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
4751
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
4752
|
+
}
|
|
4753
|
+
}
|
|
4754
|
+
return {
|
|
4755
|
+
TSAsExpression: checkAssertion,
|
|
4756
|
+
TSTypeAssertion: checkAssertion
|
|
4757
|
+
};
|
|
4758
|
+
}
|
|
4759
|
+
});
|
|
4760
|
+
|
|
4656
4761
|
// src/rules/prefer-string-literal-union.ts
|
|
4657
4762
|
import {
|
|
4658
|
-
ESLintUtils as
|
|
4659
|
-
AST_NODE_TYPES as
|
|
4763
|
+
ESLintUtils as ESLintUtils30,
|
|
4764
|
+
AST_NODE_TYPES as AST_NODE_TYPES20
|
|
4660
4765
|
} from "@typescript-eslint/utils";
|
|
4661
4766
|
import * as ts from "typescript";
|
|
4662
4767
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -4700,19 +4805,19 @@ function isChoiceLikeName(name) {
|
|
|
4700
4805
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
4701
4806
|
}
|
|
4702
4807
|
function keyName(key) {
|
|
4703
|
-
if (key.type ===
|
|
4808
|
+
if (key.type === AST_NODE_TYPES20.Identifier) {
|
|
4704
4809
|
return key.name;
|
|
4705
4810
|
}
|
|
4706
|
-
if (key.type ===
|
|
4811
|
+
if (key.type === AST_NODE_TYPES20.Literal && typeof key.value === "string") {
|
|
4707
4812
|
return key.value;
|
|
4708
4813
|
}
|
|
4709
4814
|
return null;
|
|
4710
4815
|
}
|
|
4711
4816
|
function isStringLiteralMember(t) {
|
|
4712
|
-
return t.type ===
|
|
4817
|
+
return t.type === AST_NODE_TYPES20.TSLiteralType && t.literal.type === AST_NODE_TYPES20.Literal && typeof t.literal.value === "string";
|
|
4713
4818
|
}
|
|
4714
4819
|
function isStringLiteralUnion(node) {
|
|
4715
|
-
if (node?.type !==
|
|
4820
|
+
if (node?.type !== AST_NODE_TYPES20.TSUnionType) {
|
|
4716
4821
|
return false;
|
|
4717
4822
|
}
|
|
4718
4823
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -4741,12 +4846,12 @@ function bindingSourceExpression(decl) {
|
|
|
4741
4846
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
4742
4847
|
}
|
|
4743
4848
|
function refKey(node) {
|
|
4744
|
-
if (node.type ===
|
|
4849
|
+
if (node.type === AST_NODE_TYPES20.Identifier) {
|
|
4745
4850
|
return node.name;
|
|
4746
4851
|
}
|
|
4747
|
-
if (node.type ===
|
|
4852
|
+
if (node.type === AST_NODE_TYPES20.MemberExpression && !node.computed) {
|
|
4748
4853
|
const inner = refKey(node.object);
|
|
4749
|
-
if (inner === null || node.property.type !==
|
|
4854
|
+
if (inner === null || node.property.type !== AST_NODE_TYPES20.Identifier) {
|
|
4750
4855
|
return null;
|
|
4751
4856
|
}
|
|
4752
4857
|
return `${inner}.${node.property.name}`;
|
|
@@ -4754,12 +4859,12 @@ function refKey(node) {
|
|
|
4754
4859
|
return null;
|
|
4755
4860
|
}
|
|
4756
4861
|
function strLiteral(node) {
|
|
4757
|
-
if (node.type ===
|
|
4862
|
+
if (node.type === AST_NODE_TYPES20.Literal && typeof node.value === "string") {
|
|
4758
4863
|
return node.value;
|
|
4759
4864
|
}
|
|
4760
4865
|
return null;
|
|
4761
4866
|
}
|
|
4762
|
-
var prefer_string_literal_union_default =
|
|
4867
|
+
var prefer_string_literal_union_default = ESLintUtils30.RuleCreator(
|
|
4763
4868
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4764
4869
|
)({
|
|
4765
4870
|
name: "prefer-string-literal-union",
|
|
@@ -4797,7 +4902,7 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
4797
4902
|
);
|
|
4798
4903
|
let services;
|
|
4799
4904
|
try {
|
|
4800
|
-
services =
|
|
4905
|
+
services = ESLintUtils30.getParserServices(context);
|
|
4801
4906
|
} catch {
|
|
4802
4907
|
services = null;
|
|
4803
4908
|
}
|
|
@@ -4909,7 +5014,7 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
4909
5014
|
containersWithUnion.add(container);
|
|
4910
5015
|
return;
|
|
4911
5016
|
}
|
|
4912
|
-
if (typeNode?.type !==
|
|
5017
|
+
if (typeNode?.type !== AST_NODE_TYPES20.TSStringKeyword) {
|
|
4913
5018
|
return;
|
|
4914
5019
|
}
|
|
4915
5020
|
const name = keyName(key);
|
|
@@ -4997,10 +5102,10 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
4997
5102
|
}
|
|
4998
5103
|
};
|
|
4999
5104
|
function refKeyText(node) {
|
|
5000
|
-
if (node.type ===
|
|
5105
|
+
if (node.type === AST_NODE_TYPES20.BinaryExpression) {
|
|
5001
5106
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
5002
5107
|
}
|
|
5003
|
-
if (node.type ===
|
|
5108
|
+
if (node.type === AST_NODE_TYPES20.SwitchStatement) {
|
|
5004
5109
|
return refKey(node.discriminant) ?? "value";
|
|
5005
5110
|
}
|
|
5006
5111
|
return "value";
|
|
@@ -5008,8 +5113,101 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
5008
5113
|
}
|
|
5009
5114
|
});
|
|
5010
5115
|
|
|
5116
|
+
// src/rules/prefer-zod-enum.ts
|
|
5117
|
+
import {
|
|
5118
|
+
AST_NODE_TYPES as AST_NODE_TYPES21,
|
|
5119
|
+
ESLintUtils as ESLintUtils31
|
|
5120
|
+
} from "@typescript-eslint/utils";
|
|
5121
|
+
function isZodModule(source) {
|
|
5122
|
+
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
5123
|
+
}
|
|
5124
|
+
var prefer_zod_enum_default = ESLintUtils31.RuleCreator(
|
|
5125
|
+
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
5126
|
+
)({
|
|
5127
|
+
name: "prefer-zod-enum",
|
|
5128
|
+
meta: {
|
|
5129
|
+
type: "suggestion",
|
|
5130
|
+
docs: {
|
|
5131
|
+
description: "Prefer z.enum([...]) over z.union([z.literal(...), ...]) for string choices"
|
|
5132
|
+
},
|
|
5133
|
+
fixable: "code",
|
|
5134
|
+
schema: [],
|
|
5135
|
+
messages: {
|
|
5136
|
+
preferEnum: "Use `z.enum([...])` instead of a union of string-literal schemas."
|
|
5137
|
+
}
|
|
5138
|
+
},
|
|
5139
|
+
defaultOptions: [],
|
|
5140
|
+
create(context) {
|
|
5141
|
+
const sourceCode = context.sourceCode;
|
|
5142
|
+
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
5143
|
+
function enumValues(node) {
|
|
5144
|
+
const callee = node.callee;
|
|
5145
|
+
if (callee.type !== AST_NODE_TYPES21.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES21.Identifier || !zodNamespaces.has(callee.object.name) || callee.property.type !== AST_NODE_TYPES21.Identifier || callee.property.name !== "union" || node.arguments.length !== 1) {
|
|
5146
|
+
return null;
|
|
5147
|
+
}
|
|
5148
|
+
const argument = node.arguments[0];
|
|
5149
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES21.ArrayExpression || argument.elements.length === 0) {
|
|
5150
|
+
return null;
|
|
5151
|
+
}
|
|
5152
|
+
const values = [];
|
|
5153
|
+
for (const element of argument.elements) {
|
|
5154
|
+
if (element === null || element.type !== AST_NODE_TYPES21.CallExpression || element.arguments.length !== 1 || element.callee.type !== AST_NODE_TYPES21.MemberExpression || element.callee.computed || element.callee.object.type !== AST_NODE_TYPES21.Identifier || !zodNamespaces.has(element.callee.object.name) || element.callee.property.type !== AST_NODE_TYPES21.Identifier || element.callee.property.name !== "literal") {
|
|
5155
|
+
return null;
|
|
5156
|
+
}
|
|
5157
|
+
const value = element.arguments[0];
|
|
5158
|
+
if (value === void 0 || value.type !== AST_NODE_TYPES21.Literal || typeof value.value !== "string") {
|
|
5159
|
+
return null;
|
|
5160
|
+
}
|
|
5161
|
+
values.push(value);
|
|
5162
|
+
}
|
|
5163
|
+
return values;
|
|
5164
|
+
}
|
|
5165
|
+
function buildFix(node, values) {
|
|
5166
|
+
const argument = node.arguments[0];
|
|
5167
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES21.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
|
|
5168
|
+
return void 0;
|
|
5169
|
+
}
|
|
5170
|
+
const callee = node.callee;
|
|
5171
|
+
if (callee.type !== AST_NODE_TYPES21.MemberExpression || callee.property.type !== AST_NODE_TYPES21.Identifier) {
|
|
5172
|
+
return void 0;
|
|
5173
|
+
}
|
|
5174
|
+
return (fixer) => [
|
|
5175
|
+
fixer.replaceText(callee.property, "enum"),
|
|
5176
|
+
fixer.replaceText(
|
|
5177
|
+
argument,
|
|
5178
|
+
`[${values.map((value) => sourceCode.getText(value)).join(", ")}]`
|
|
5179
|
+
)
|
|
5180
|
+
];
|
|
5181
|
+
}
|
|
5182
|
+
return {
|
|
5183
|
+
ImportDeclaration(node) {
|
|
5184
|
+
if (!isZodModule(node.source.value)) {
|
|
5185
|
+
return;
|
|
5186
|
+
}
|
|
5187
|
+
for (const specifier of node.specifiers) {
|
|
5188
|
+
if (specifier.type === AST_NODE_TYPES21.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES21.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES21.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES21.Identifier && specifier.imported.name === "z") {
|
|
5189
|
+
zodNamespaces.add(specifier.local.name);
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
},
|
|
5193
|
+
CallExpression(node) {
|
|
5194
|
+
const values = enumValues(node);
|
|
5195
|
+
if (values === null) {
|
|
5196
|
+
return;
|
|
5197
|
+
}
|
|
5198
|
+
const fix = buildFix(node, values);
|
|
5199
|
+
context.report({
|
|
5200
|
+
node,
|
|
5201
|
+
messageId: "preferEnum",
|
|
5202
|
+
...fix === void 0 ? {} : { fix }
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
});
|
|
5208
|
+
|
|
5011
5209
|
// src/rules/single-public-export.ts
|
|
5012
|
-
import { ESLintUtils as
|
|
5210
|
+
import { ESLintUtils as ESLintUtils32, AST_NODE_TYPES as AST_NODE_TYPES22 } from "@typescript-eslint/utils";
|
|
5013
5211
|
var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
|
|
5014
5212
|
"util",
|
|
5015
5213
|
"utils",
|
|
@@ -5043,12 +5241,12 @@ var kebabCase2 = (name) => {
|
|
|
5043
5241
|
}
|
|
5044
5242
|
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
5045
5243
|
};
|
|
5046
|
-
var isFunctionExpression = (node) => node !== null && (node.type ===
|
|
5244
|
+
var isFunctionExpression = (node) => node !== null && (node.type === AST_NODE_TYPES22.ArrowFunctionExpression || node.type === AST_NODE_TYPES22.FunctionExpression);
|
|
5047
5245
|
var functionConstName = (decl) => {
|
|
5048
5246
|
if (decl.declarations.length !== 1) return null;
|
|
5049
5247
|
const [declarator] = decl.declarations;
|
|
5050
5248
|
if (declarator === void 0) return null;
|
|
5051
|
-
if (declarator.id.type !==
|
|
5249
|
+
if (declarator.id.type !== AST_NODE_TYPES22.Identifier) return null;
|
|
5052
5250
|
if (!isFunctionExpression(declarator.init)) return null;
|
|
5053
5251
|
return declarator.id.name;
|
|
5054
5252
|
};
|
|
@@ -5062,20 +5260,20 @@ var summarizeExports = (body) => {
|
|
|
5062
5260
|
};
|
|
5063
5261
|
for (const statement of body) {
|
|
5064
5262
|
switch (statement.type) {
|
|
5065
|
-
case
|
|
5263
|
+
case AST_NODE_TYPES22.ExportAllDeclaration:
|
|
5066
5264
|
hasReExport = true;
|
|
5067
5265
|
break;
|
|
5068
|
-
case
|
|
5266
|
+
case AST_NODE_TYPES22.ExportDefaultDeclaration: {
|
|
5069
5267
|
names += 1;
|
|
5070
5268
|
const decl = statement.declaration;
|
|
5071
|
-
if (decl.type ===
|
|
5269
|
+
if (decl.type === AST_NODE_TYPES22.FunctionDeclaration && decl.id !== null) {
|
|
5072
5270
|
candidate = { name: decl.id.name, node: statement };
|
|
5073
|
-
} else if (decl.type ===
|
|
5271
|
+
} else if (decl.type === AST_NODE_TYPES22.ClassDeclaration && decl.id !== null) {
|
|
5074
5272
|
candidate = { name: decl.id.name, node: statement };
|
|
5075
5273
|
}
|
|
5076
5274
|
break;
|
|
5077
5275
|
}
|
|
5078
|
-
case
|
|
5276
|
+
case AST_NODE_TYPES22.ExportNamedDeclaration: {
|
|
5079
5277
|
if (statement.source !== null) {
|
|
5080
5278
|
hasReExport = true;
|
|
5081
5279
|
break;
|
|
@@ -5086,15 +5284,15 @@ var summarizeExports = (body) => {
|
|
|
5086
5284
|
break;
|
|
5087
5285
|
}
|
|
5088
5286
|
switch (decl.type) {
|
|
5089
|
-
case
|
|
5287
|
+
case AST_NODE_TYPES22.FunctionDeclaration:
|
|
5090
5288
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5091
5289
|
else names += 1;
|
|
5092
5290
|
break;
|
|
5093
|
-
case
|
|
5291
|
+
case AST_NODE_TYPES22.ClassDeclaration:
|
|
5094
5292
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5095
5293
|
else names += 1;
|
|
5096
5294
|
break;
|
|
5097
|
-
case
|
|
5295
|
+
case AST_NODE_TYPES22.VariableDeclaration: {
|
|
5098
5296
|
const fnName = functionConstName(decl);
|
|
5099
5297
|
if (fnName !== null && decl.declarations.length === 1) {
|
|
5100
5298
|
addCandidate(fnName, statement);
|
|
@@ -5114,7 +5312,7 @@ var summarizeExports = (body) => {
|
|
|
5114
5312
|
}
|
|
5115
5313
|
return { names, hasReExport, candidate };
|
|
5116
5314
|
};
|
|
5117
|
-
var single_public_export_default =
|
|
5315
|
+
var single_public_export_default = ESLintUtils32.RuleCreator(
|
|
5118
5316
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5119
5317
|
)({
|
|
5120
5318
|
name: "single-public-export",
|
|
@@ -5155,10 +5353,10 @@ var single_public_export_default = ESLintUtils29.RuleCreator(
|
|
|
5155
5353
|
});
|
|
5156
5354
|
|
|
5157
5355
|
// src/rules/no-offset-pagination.ts
|
|
5158
|
-
import { ESLintUtils as
|
|
5356
|
+
import { ESLintUtils as ESLintUtils33 } from "@typescript-eslint/utils";
|
|
5159
5357
|
|
|
5160
5358
|
// src/rules/_sql.ts
|
|
5161
|
-
import { AST_NODE_TYPES as
|
|
5359
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23 } from "@typescript-eslint/utils";
|
|
5162
5360
|
function stripSqlNoise(text) {
|
|
5163
5361
|
const out = [...text];
|
|
5164
5362
|
const n = text.length;
|
|
@@ -5219,13 +5417,13 @@ function stripSqlNoise(text) {
|
|
|
5219
5417
|
var SUBSTITUTION_MARKER = "?";
|
|
5220
5418
|
function sqlTextOf(node) {
|
|
5221
5419
|
switch (node.type) {
|
|
5222
|
-
case
|
|
5420
|
+
case AST_NODE_TYPES23.Literal:
|
|
5223
5421
|
return typeof node.value === "string" ? node.value : null;
|
|
5224
|
-
case
|
|
5422
|
+
case AST_NODE_TYPES23.TemplateLiteral:
|
|
5225
5423
|
return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
|
|
5226
|
-
case
|
|
5424
|
+
case AST_NODE_TYPES23.TaggedTemplateExpression:
|
|
5227
5425
|
return sqlTextOf(node.quasi);
|
|
5228
|
-
case
|
|
5426
|
+
case AST_NODE_TYPES23.BinaryExpression: {
|
|
5229
5427
|
if (node.operator !== "+") {
|
|
5230
5428
|
return null;
|
|
5231
5429
|
}
|
|
@@ -5233,7 +5431,7 @@ function sqlTextOf(node) {
|
|
|
5233
5431
|
const right = sqlTextOf(node.right);
|
|
5234
5432
|
return left !== null && right !== null ? left + right : null;
|
|
5235
5433
|
}
|
|
5236
|
-
case
|
|
5434
|
+
case AST_NODE_TYPES23.ArrayExpression: {
|
|
5237
5435
|
const parts = [];
|
|
5238
5436
|
for (const element of node.elements) {
|
|
5239
5437
|
if (element === null) {
|
|
@@ -5253,7 +5451,7 @@ function sqlTextOf(node) {
|
|
|
5253
5451
|
}
|
|
5254
5452
|
function isJoinedFragmentArray(node) {
|
|
5255
5453
|
const parent = node.parent;
|
|
5256
|
-
return parent?.type ===
|
|
5454
|
+
return parent?.type === AST_NODE_TYPES23.MemberExpression && parent.object === node && !parent.computed && parent.property.type === AST_NODE_TYPES23.Identifier && parent.property.name === "join" && parent.parent?.type === AST_NODE_TYPES23.CallExpression;
|
|
5257
5455
|
}
|
|
5258
5456
|
function markConsumed(node, consumed) {
|
|
5259
5457
|
consumed.add(node);
|
|
@@ -5303,7 +5501,7 @@ function createSqlListener(handler) {
|
|
|
5303
5501
|
// src/rules/no-offset-pagination.ts
|
|
5304
5502
|
var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
|
|
5305
5503
|
var OFFSET_GATE = /offset/i;
|
|
5306
|
-
var no_offset_pagination_default =
|
|
5504
|
+
var no_offset_pagination_default = ESLintUtils33.RuleCreator(
|
|
5307
5505
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5308
5506
|
)({
|
|
5309
5507
|
name: "no-offset-pagination",
|
|
@@ -5332,15 +5530,15 @@ var no_offset_pagination_default = ESLintUtils30.RuleCreator(
|
|
|
5332
5530
|
});
|
|
5333
5531
|
|
|
5334
5532
|
// src/rules/no-positional-tuple-return.ts
|
|
5335
|
-
import { AST_NODE_TYPES as
|
|
5533
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ESLintUtils as ESLintUtils34 } from "@typescript-eslint/utils";
|
|
5336
5534
|
var MIN_ELEMENTS = 2;
|
|
5337
5535
|
var ACCESSOR_PAIR_LENGTH = 2;
|
|
5338
5536
|
var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
|
|
5339
5537
|
function tupleReturnType(node) {
|
|
5340
|
-
if (node.type ===
|
|
5538
|
+
if (node.type === AST_NODE_TYPES24.TSTupleType) {
|
|
5341
5539
|
return node;
|
|
5342
5540
|
}
|
|
5343
|
-
if (node.type ===
|
|
5541
|
+
if (node.type === AST_NODE_TYPES24.TSTypeReference && node.typeName.type === AST_NODE_TYPES24.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
|
|
5344
5542
|
const argument = node.typeArguments?.params[0];
|
|
5345
5543
|
return argument === void 0 ? null : tupleReturnType(argument);
|
|
5346
5544
|
}
|
|
@@ -5354,30 +5552,30 @@ function isPermittedTuple(tuple, sourceCode) {
|
|
|
5354
5552
|
if (elements.length < MIN_ELEMENTS) {
|
|
5355
5553
|
return true;
|
|
5356
5554
|
}
|
|
5357
|
-
if (elements.some((element) => element.type ===
|
|
5555
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES24.TSRestType)) {
|
|
5358
5556
|
return true;
|
|
5359
5557
|
}
|
|
5360
|
-
if (elements.some((element) => element.type ===
|
|
5558
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES24.TSNamedTupleMember)) {
|
|
5361
5559
|
return true;
|
|
5362
5560
|
}
|
|
5363
|
-
if (elements[0]?.type ===
|
|
5561
|
+
if (elements[0]?.type === AST_NODE_TYPES24.TSLiteralType) {
|
|
5364
5562
|
return true;
|
|
5365
5563
|
}
|
|
5366
|
-
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type ===
|
|
5564
|
+
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === AST_NODE_TYPES24.TSFunctionType)) {
|
|
5367
5565
|
return true;
|
|
5368
5566
|
}
|
|
5369
5567
|
const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
|
|
5370
5568
|
return texts.size === 1;
|
|
5371
5569
|
}
|
|
5372
5570
|
function functionName(node) {
|
|
5373
|
-
if (node.type ===
|
|
5571
|
+
if (node.type === AST_NODE_TYPES24.FunctionDeclaration) {
|
|
5374
5572
|
return node.id?.name ?? null;
|
|
5375
5573
|
}
|
|
5376
5574
|
const parent = node.parent;
|
|
5377
|
-
if (parent?.type ===
|
|
5575
|
+
if (parent?.type === AST_NODE_TYPES24.VariableDeclarator && parent.id.type === AST_NODE_TYPES24.Identifier) {
|
|
5378
5576
|
return parent.id.name;
|
|
5379
5577
|
}
|
|
5380
|
-
if ((parent?.type ===
|
|
5578
|
+
if ((parent?.type === AST_NODE_TYPES24.MethodDefinition || parent?.type === AST_NODE_TYPES24.PropertyDefinition || parent?.type === AST_NODE_TYPES24.Property) && parent.key.type === AST_NODE_TYPES24.Identifier) {
|
|
5381
5579
|
return parent.key.name;
|
|
5382
5580
|
}
|
|
5383
5581
|
return null;
|
|
@@ -5385,7 +5583,7 @@ function functionName(node) {
|
|
|
5385
5583
|
function isInlineExported(node) {
|
|
5386
5584
|
for (let current = node; current != null; current = current.parent) {
|
|
5387
5585
|
const parent = current.parent;
|
|
5388
|
-
if (parent?.type ===
|
|
5586
|
+
if (parent?.type === AST_NODE_TYPES24.ExportNamedDeclaration || parent?.type === AST_NODE_TYPES24.ExportDefaultDeclaration) {
|
|
5389
5587
|
return true;
|
|
5390
5588
|
}
|
|
5391
5589
|
}
|
|
@@ -5394,18 +5592,18 @@ function isInlineExported(node) {
|
|
|
5394
5592
|
function moduleScopeBindingName(node) {
|
|
5395
5593
|
let current = node;
|
|
5396
5594
|
let child = node;
|
|
5397
|
-
while (current.parent != null && current.parent.type !==
|
|
5595
|
+
while (current.parent != null && current.parent.type !== AST_NODE_TYPES24.Program) {
|
|
5398
5596
|
child = current;
|
|
5399
5597
|
current = current.parent;
|
|
5400
5598
|
}
|
|
5401
|
-
if (current.parent?.type !==
|
|
5599
|
+
if (current.parent?.type !== AST_NODE_TYPES24.Program) {
|
|
5402
5600
|
return null;
|
|
5403
5601
|
}
|
|
5404
|
-
if (current.type ===
|
|
5602
|
+
if (current.type === AST_NODE_TYPES24.FunctionDeclaration || current.type === AST_NODE_TYPES24.ClassDeclaration) {
|
|
5405
5603
|
return current.id?.name ?? null;
|
|
5406
5604
|
}
|
|
5407
|
-
if (current.type ===
|
|
5408
|
-
if (child.type !==
|
|
5605
|
+
if (current.type === AST_NODE_TYPES24.VariableDeclaration) {
|
|
5606
|
+
if (child.type !== AST_NODE_TYPES24.VariableDeclarator || child.id.type !== AST_NODE_TYPES24.Identifier) {
|
|
5409
5607
|
return null;
|
|
5410
5608
|
}
|
|
5411
5609
|
return child.id.name;
|
|
@@ -5415,19 +5613,19 @@ function moduleScopeBindingName(node) {
|
|
|
5415
5613
|
function specifierExportedNames(program) {
|
|
5416
5614
|
const names = /* @__PURE__ */ new Set();
|
|
5417
5615
|
for (const statement of program.body) {
|
|
5418
|
-
if (statement.type ===
|
|
5616
|
+
if (statement.type === AST_NODE_TYPES24.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
|
|
5419
5617
|
for (const specifier of statement.specifiers) {
|
|
5420
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
5618
|
+
if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES24.Identifier) {
|
|
5421
5619
|
names.add(specifier.local.name);
|
|
5422
5620
|
}
|
|
5423
5621
|
}
|
|
5424
5622
|
continue;
|
|
5425
5623
|
}
|
|
5426
|
-
if (statement.type ===
|
|
5624
|
+
if (statement.type === AST_NODE_TYPES24.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES24.Identifier) {
|
|
5427
5625
|
names.add(statement.declaration.name);
|
|
5428
5626
|
continue;
|
|
5429
5627
|
}
|
|
5430
|
-
if (statement.type ===
|
|
5628
|
+
if (statement.type === AST_NODE_TYPES24.TSExportAssignment && statement.expression.type === AST_NODE_TYPES24.Identifier) {
|
|
5431
5629
|
names.add(statement.expression.name);
|
|
5432
5630
|
}
|
|
5433
5631
|
}
|
|
@@ -5443,7 +5641,7 @@ function isExported(node, specifierExports) {
|
|
|
5443
5641
|
const binding = moduleScopeBindingName(node);
|
|
5444
5642
|
return binding !== null && specifierExports.has(binding);
|
|
5445
5643
|
}
|
|
5446
|
-
var no_positional_tuple_return_default =
|
|
5644
|
+
var no_positional_tuple_return_default = ESLintUtils34.RuleCreator(
|
|
5447
5645
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5448
5646
|
)({
|
|
5449
5647
|
name: "no-positional-tuple-return",
|
|
@@ -5491,16 +5689,16 @@ var no_positional_tuple_return_default = ESLintUtils31.RuleCreator(
|
|
|
5491
5689
|
});
|
|
5492
5690
|
|
|
5493
5691
|
// src/rules/no-repeated-string-literal.ts
|
|
5494
|
-
import { AST_NODE_TYPES as
|
|
5692
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ESLintUtils as ESLintUtils35 } from "@typescript-eslint/utils";
|
|
5495
5693
|
var MIN_LENGTH = 40;
|
|
5496
5694
|
var MIN_DISTINCT_SCOPES = 2;
|
|
5497
5695
|
var PREVIEW_LENGTH = 40;
|
|
5498
5696
|
var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
|
|
5499
5697
|
var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
|
|
5500
5698
|
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5699
|
+
AST_NODE_TYPES25.FunctionDeclaration,
|
|
5700
|
+
AST_NODE_TYPES25.FunctionExpression,
|
|
5701
|
+
AST_NODE_TYPES25.ArrowFunctionExpression
|
|
5504
5702
|
]);
|
|
5505
5703
|
function isStructured(value) {
|
|
5506
5704
|
return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
|
|
@@ -5522,9 +5720,9 @@ function isScaffolding(node) {
|
|
|
5522
5720
|
if (parent === void 0) {
|
|
5523
5721
|
return true;
|
|
5524
5722
|
}
|
|
5525
|
-
return parent.type ===
|
|
5723
|
+
return parent.type === AST_NODE_TYPES25.ImportDeclaration || parent.type === AST_NODE_TYPES25.ExportNamedDeclaration || parent.type === AST_NODE_TYPES25.ExportAllDeclaration || parent.type === AST_NODE_TYPES25.TSImportType || parent.type === AST_NODE_TYPES25.JSXAttribute || parent.type === AST_NODE_TYPES25.TSLiteralType;
|
|
5526
5724
|
}
|
|
5527
|
-
var no_repeated_string_literal_default =
|
|
5725
|
+
var no_repeated_string_literal_default = ESLintUtils35.RuleCreator(
|
|
5528
5726
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5529
5727
|
)({
|
|
5530
5728
|
name: "no-repeated-string-literal",
|
|
@@ -5564,7 +5762,7 @@ var no_repeated_string_literal_default = ESLintUtils32.RuleCreator(
|
|
|
5564
5762
|
}
|
|
5565
5763
|
},
|
|
5566
5764
|
TemplateLiteral(node) {
|
|
5567
|
-
if (node.parent.type ===
|
|
5765
|
+
if (node.parent.type === AST_NODE_TYPES25.TaggedTemplateExpression) {
|
|
5568
5766
|
return;
|
|
5569
5767
|
}
|
|
5570
5768
|
const [only] = node.quasis;
|
|
@@ -5598,7 +5796,7 @@ var no_repeated_string_literal_default = ESLintUtils32.RuleCreator(
|
|
|
5598
5796
|
});
|
|
5599
5797
|
|
|
5600
5798
|
// src/rules/no-select-star.ts
|
|
5601
|
-
import { ESLintUtils as
|
|
5799
|
+
import { ESLintUtils as ESLintUtils36 } from "@typescript-eslint/utils";
|
|
5602
5800
|
var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
|
|
5603
5801
|
var SELECT_KEYWORD = /\bSELECT\b/gi;
|
|
5604
5802
|
var FROM_KEYWORD = /^FROM\b/i;
|
|
@@ -5638,7 +5836,7 @@ function hasRealSelectStar(sql) {
|
|
|
5638
5836
|
}
|
|
5639
5837
|
return false;
|
|
5640
5838
|
}
|
|
5641
|
-
var no_select_star_default =
|
|
5839
|
+
var no_select_star_default = ESLintUtils36.RuleCreator(
|
|
5642
5840
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5643
5841
|
)({
|
|
5644
5842
|
name: "no-select-star",
|
|
@@ -5667,7 +5865,7 @@ var no_select_star_default = ESLintUtils33.RuleCreator(
|
|
|
5667
5865
|
});
|
|
5668
5866
|
|
|
5669
5867
|
// src/rules/no-sleep-in-test-body.ts
|
|
5670
|
-
import { AST_NODE_TYPES as
|
|
5868
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ESLintUtils as ESLintUtils37 } from "@typescript-eslint/utils";
|
|
5671
5869
|
var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
|
|
5672
5870
|
var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
5673
5871
|
"it",
|
|
@@ -5676,34 +5874,34 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
|
5676
5874
|
"afterEach"
|
|
5677
5875
|
]);
|
|
5678
5876
|
var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5877
|
+
AST_NODE_TYPES26.FunctionDeclaration,
|
|
5878
|
+
AST_NODE_TYPES26.FunctionExpression,
|
|
5879
|
+
AST_NODE_TYPES26.ArrowFunctionExpression
|
|
5682
5880
|
]);
|
|
5683
5881
|
function isNonzeroNumericLiteral(node) {
|
|
5684
|
-
return node?.type ===
|
|
5882
|
+
return node?.type === AST_NODE_TYPES26.Literal && typeof node.value === "number" && node.value !== 0;
|
|
5685
5883
|
}
|
|
5686
5884
|
function isTimedSetTimeout(node) {
|
|
5687
|
-
return node.type ===
|
|
5885
|
+
return node.type === AST_NODE_TYPES26.CallExpression && node.callee.type === AST_NODE_TYPES26.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
|
|
5688
5886
|
}
|
|
5689
5887
|
function isPromiseSleep(node) {
|
|
5690
|
-
if (node.callee.type !==
|
|
5888
|
+
if (node.callee.type !== AST_NODE_TYPES26.Identifier || node.callee.name !== "Promise") {
|
|
5691
5889
|
return false;
|
|
5692
5890
|
}
|
|
5693
5891
|
const executor = node.arguments[0];
|
|
5694
|
-
if (executor?.type !==
|
|
5892
|
+
if (executor?.type !== AST_NODE_TYPES26.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES26.FunctionExpression) {
|
|
5695
5893
|
return false;
|
|
5696
5894
|
}
|
|
5697
5895
|
const body = executor.body;
|
|
5698
|
-
if (body.type !==
|
|
5896
|
+
if (body.type !== AST_NODE_TYPES26.BlockStatement) {
|
|
5699
5897
|
return isTimedSetTimeout(body);
|
|
5700
5898
|
}
|
|
5701
5899
|
return body.body.some(
|
|
5702
|
-
(stmt) => stmt.type ===
|
|
5900
|
+
(stmt) => stmt.type === AST_NODE_TYPES26.ExpressionStatement && isTimedSetTimeout(stmt.expression)
|
|
5703
5901
|
);
|
|
5704
5902
|
}
|
|
5705
5903
|
function isHelperSleep(node) {
|
|
5706
|
-
return node.callee.type ===
|
|
5904
|
+
return node.callee.type === AST_NODE_TYPES26.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
|
|
5707
5905
|
}
|
|
5708
5906
|
function nearestEnclosingFunction(node) {
|
|
5709
5907
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
@@ -5711,7 +5909,7 @@ function nearestEnclosingFunction(node) {
|
|
|
5711
5909
|
continue;
|
|
5712
5910
|
}
|
|
5713
5911
|
const grandparent = current.parent;
|
|
5714
|
-
const isPromiseExecutor = grandparent?.type ===
|
|
5912
|
+
const isPromiseExecutor = grandparent?.type === AST_NODE_TYPES26.NewExpression && isPromiseSleep(grandparent);
|
|
5715
5913
|
if (!isPromiseExecutor) {
|
|
5716
5914
|
return current;
|
|
5717
5915
|
}
|
|
@@ -5719,29 +5917,29 @@ function nearestEnclosingFunction(node) {
|
|
|
5719
5917
|
return null;
|
|
5720
5918
|
}
|
|
5721
5919
|
function testCallerName(callee) {
|
|
5722
|
-
if (callee.type ===
|
|
5920
|
+
if (callee.type === AST_NODE_TYPES26.Identifier) {
|
|
5723
5921
|
return callee.name;
|
|
5724
5922
|
}
|
|
5725
|
-
if (callee.type ===
|
|
5923
|
+
if (callee.type === AST_NODE_TYPES26.MemberExpression) {
|
|
5726
5924
|
return testCallerName(callee.object);
|
|
5727
5925
|
}
|
|
5728
|
-
if (callee.type ===
|
|
5926
|
+
if (callee.type === AST_NODE_TYPES26.CallExpression) {
|
|
5729
5927
|
return testCallerName(callee.callee);
|
|
5730
5928
|
}
|
|
5731
|
-
if (callee.type ===
|
|
5929
|
+
if (callee.type === AST_NODE_TYPES26.TaggedTemplateExpression) {
|
|
5732
5930
|
return testCallerName(callee.tag);
|
|
5733
5931
|
}
|
|
5734
5932
|
return null;
|
|
5735
5933
|
}
|
|
5736
5934
|
function isTestBody(fn) {
|
|
5737
5935
|
const call = fn.parent;
|
|
5738
|
-
if (call?.type !==
|
|
5936
|
+
if (call?.type !== AST_NODE_TYPES26.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5739
5937
|
return false;
|
|
5740
5938
|
}
|
|
5741
5939
|
const name = testCallerName(call.callee);
|
|
5742
5940
|
return name !== null && TEST_CALLERS.has(name);
|
|
5743
5941
|
}
|
|
5744
|
-
var no_sleep_in_test_body_default =
|
|
5942
|
+
var no_sleep_in_test_body_default = ESLintUtils37.RuleCreator(
|
|
5745
5943
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5746
5944
|
)({
|
|
5747
5945
|
name: "no-sleep-in-test-body",
|
|
@@ -5782,8 +5980,90 @@ var no_sleep_in_test_body_default = ESLintUtils34.RuleCreator(
|
|
|
5782
5980
|
}
|
|
5783
5981
|
});
|
|
5784
5982
|
|
|
5983
|
+
// src/rules/no-conditional-in-test.ts
|
|
5984
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES27, ESLintUtils as ESLintUtils38 } from "@typescript-eslint/utils";
|
|
5985
|
+
var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
5986
|
+
var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
|
|
5987
|
+
AST_NODE_TYPES27.FunctionDeclaration,
|
|
5988
|
+
AST_NODE_TYPES27.FunctionExpression,
|
|
5989
|
+
AST_NODE_TYPES27.ArrowFunctionExpression
|
|
5990
|
+
]);
|
|
5991
|
+
function nearestEnclosingFunction2(node) {
|
|
5992
|
+
for (let current = node.parent; current != null; current = current.parent) {
|
|
5993
|
+
if (FUNCTION_TYPES3.has(current.type)) {
|
|
5994
|
+
return current;
|
|
5995
|
+
}
|
|
5996
|
+
}
|
|
5997
|
+
return null;
|
|
5998
|
+
}
|
|
5999
|
+
function testCallerName2(callee) {
|
|
6000
|
+
if (callee.type === AST_NODE_TYPES27.Identifier) {
|
|
6001
|
+
return callee.name;
|
|
6002
|
+
}
|
|
6003
|
+
if (callee.type === AST_NODE_TYPES27.MemberExpression) {
|
|
6004
|
+
return testCallerName2(callee.object);
|
|
6005
|
+
}
|
|
6006
|
+
if (callee.type === AST_NODE_TYPES27.CallExpression) {
|
|
6007
|
+
return testCallerName2(callee.callee);
|
|
6008
|
+
}
|
|
6009
|
+
if (callee.type === AST_NODE_TYPES27.TaggedTemplateExpression) {
|
|
6010
|
+
return testCallerName2(callee.tag);
|
|
6011
|
+
}
|
|
6012
|
+
return null;
|
|
6013
|
+
}
|
|
6014
|
+
function isTestBody2(fn) {
|
|
6015
|
+
const call = fn.parent;
|
|
6016
|
+
if (call?.type !== AST_NODE_TYPES27.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
6017
|
+
return false;
|
|
6018
|
+
}
|
|
6019
|
+
const name = testCallerName2(call.callee);
|
|
6020
|
+
return name !== null && TEST_CALLERS2.has(name);
|
|
6021
|
+
}
|
|
6022
|
+
var no_conditional_in_test_default = ESLintUtils38.RuleCreator(
|
|
6023
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6024
|
+
)({
|
|
6025
|
+
name: "no-conditional-in-test",
|
|
6026
|
+
meta: {
|
|
6027
|
+
type: "problem",
|
|
6028
|
+
docs: {
|
|
6029
|
+
description: "Disallow conditional logic (if, switch, ternary) in test bodies, which can hide missing assertions or test multiple code paths."
|
|
6030
|
+
},
|
|
6031
|
+
schema: [],
|
|
6032
|
+
messages: {
|
|
6033
|
+
noConditionalInTest: "Avoid using conditional logic in tests. It can obscure intent and hide unexecuted assertions. Split the test instead."
|
|
6034
|
+
}
|
|
6035
|
+
},
|
|
6036
|
+
defaultOptions: [],
|
|
6037
|
+
create(context) {
|
|
6038
|
+
if (!isTestFile(context.filename)) {
|
|
6039
|
+
return {};
|
|
6040
|
+
}
|
|
6041
|
+
const report = (node) => {
|
|
6042
|
+
const enclosing = nearestEnclosingFunction2(node);
|
|
6043
|
+
if (enclosing === null || !isTestBody2(enclosing)) {
|
|
6044
|
+
return;
|
|
6045
|
+
}
|
|
6046
|
+
context.report({ node, messageId: "noConditionalInTest" });
|
|
6047
|
+
};
|
|
6048
|
+
return {
|
|
6049
|
+
IfStatement(node) {
|
|
6050
|
+
report(node);
|
|
6051
|
+
},
|
|
6052
|
+
SwitchStatement(node) {
|
|
6053
|
+
report(node);
|
|
6054
|
+
},
|
|
6055
|
+
ConditionalExpression(node) {
|
|
6056
|
+
report(node);
|
|
6057
|
+
},
|
|
6058
|
+
LogicalExpression(node) {
|
|
6059
|
+
report(node);
|
|
6060
|
+
}
|
|
6061
|
+
};
|
|
6062
|
+
}
|
|
6063
|
+
});
|
|
6064
|
+
|
|
5785
6065
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
5786
|
-
import { AST_NODE_TYPES as
|
|
6066
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES28, ESLintUtils as ESLintUtils39 } from "@typescript-eslint/utils";
|
|
5787
6067
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
5788
6068
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5789
6069
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
@@ -5796,36 +6076,36 @@ function isConstantReference(identifier) {
|
|
|
5796
6076
|
}
|
|
5797
6077
|
function isExcludedOperand(node) {
|
|
5798
6078
|
switch (node.type) {
|
|
5799
|
-
case
|
|
6079
|
+
case AST_NODE_TYPES28.Literal:
|
|
5800
6080
|
return true;
|
|
5801
|
-
case
|
|
6081
|
+
case AST_NODE_TYPES28.TemplateLiteral:
|
|
5802
6082
|
return node.expressions.length === 0;
|
|
5803
|
-
case
|
|
6083
|
+
case AST_NODE_TYPES28.Identifier:
|
|
5804
6084
|
return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
|
|
5805
|
-
case
|
|
5806
|
-
return !node.computed && node.property.type ===
|
|
6085
|
+
case AST_NODE_TYPES28.MemberExpression:
|
|
6086
|
+
return !node.computed && node.property.type === AST_NODE_TYPES28.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
|
|
5807
6087
|
default:
|
|
5808
6088
|
return false;
|
|
5809
6089
|
}
|
|
5810
6090
|
}
|
|
5811
6091
|
function operandName(node) {
|
|
5812
|
-
if (node.type ===
|
|
6092
|
+
if (node.type === AST_NODE_TYPES28.Identifier) {
|
|
5813
6093
|
return node.name;
|
|
5814
6094
|
}
|
|
5815
|
-
if (node.type ===
|
|
6095
|
+
if (node.type === AST_NODE_TYPES28.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES28.Identifier) {
|
|
5816
6096
|
return node.property.name;
|
|
5817
6097
|
}
|
|
5818
6098
|
return null;
|
|
5819
6099
|
}
|
|
5820
6100
|
function isSecretOperand(node) {
|
|
5821
|
-
if (node.type ===
|
|
6101
|
+
if (node.type === AST_NODE_TYPES28.TemplateLiteral) {
|
|
5822
6102
|
return node.expressions.some((expression) => isSecretOperand(expression));
|
|
5823
6103
|
}
|
|
5824
6104
|
const name = operandName(node);
|
|
5825
6105
|
return name !== null && isAuthSecretName(name);
|
|
5826
6106
|
}
|
|
5827
6107
|
function secretNameOf(node) {
|
|
5828
|
-
if (node.type ===
|
|
6108
|
+
if (node.type === AST_NODE_TYPES28.TemplateLiteral) {
|
|
5829
6109
|
for (const expression of node.expressions) {
|
|
5830
6110
|
const nested = secretNameOf(expression);
|
|
5831
6111
|
if (nested !== null) {
|
|
@@ -5836,7 +6116,7 @@ function secretNameOf(node) {
|
|
|
5836
6116
|
}
|
|
5837
6117
|
return operandName(node);
|
|
5838
6118
|
}
|
|
5839
|
-
var prefer_constant_time_secret_compare_default =
|
|
6119
|
+
var prefer_constant_time_secret_compare_default = ESLintUtils39.RuleCreator(
|
|
5840
6120
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5841
6121
|
)({
|
|
5842
6122
|
name: "prefer-constant-time-secret-compare",
|
|
@@ -5879,11 +6159,11 @@ var prefer_constant_time_secret_compare_default = ESLintUtils35.RuleCreator(
|
|
|
5879
6159
|
});
|
|
5880
6160
|
|
|
5881
6161
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
5882
|
-
import { ESLintUtils as
|
|
6162
|
+
import { ESLintUtils as ESLintUtils40 } from "@typescript-eslint/utils";
|
|
5883
6163
|
var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
|
|
5884
6164
|
var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
|
|
5885
6165
|
var INSERT_GATE = /insert/i;
|
|
5886
|
-
var store_insert_requires_on_conflict_default =
|
|
6166
|
+
var store_insert_requires_on_conflict_default = ESLintUtils40.RuleCreator(
|
|
5887
6167
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5888
6168
|
)({
|
|
5889
6169
|
name: "store-insert-requires-on-conflict",
|
|
@@ -5912,17 +6192,17 @@ var store_insert_requires_on_conflict_default = ESLintUtils36.RuleCreator(
|
|
|
5912
6192
|
});
|
|
5913
6193
|
|
|
5914
6194
|
// src/rules/no-dynamic-sql.ts
|
|
5915
|
-
import { AST_NODE_TYPES as
|
|
6195
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29, ESLintUtils as ESLintUtils41 } from "@typescript-eslint/utils";
|
|
5916
6196
|
var DEFAULT_METHODS = ["prepare", "exec", "query"];
|
|
5917
6197
|
var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
5918
6198
|
function isStaticFragment(expression) {
|
|
5919
|
-
if (expression.type ===
|
|
6199
|
+
if (expression.type === AST_NODE_TYPES29.Identifier) {
|
|
5920
6200
|
return CONSTANT_CASE_RE.test(expression.name);
|
|
5921
6201
|
}
|
|
5922
|
-
if (expression.type ===
|
|
6202
|
+
if (expression.type === AST_NODE_TYPES29.MemberExpression && !expression.computed && expression.property.type === AST_NODE_TYPES29.Identifier) {
|
|
5923
6203
|
return CONSTANT_CASE_RE.test(expression.property.name);
|
|
5924
6204
|
}
|
|
5925
|
-
if (expression.type ===
|
|
6205
|
+
if (expression.type === AST_NODE_TYPES29.Literal) {
|
|
5926
6206
|
return typeof expression.value === "string";
|
|
5927
6207
|
}
|
|
5928
6208
|
return false;
|
|
@@ -5933,36 +6213,36 @@ function runtimeInterpolations(template) {
|
|
|
5933
6213
|
);
|
|
5934
6214
|
}
|
|
5935
6215
|
function concatOperands(node) {
|
|
5936
|
-
if (node.type ===
|
|
6216
|
+
if (node.type === AST_NODE_TYPES29.BinaryExpression && node.operator === "+") {
|
|
5937
6217
|
return [...concatOperands(node.left), ...concatOperands(node.right)];
|
|
5938
6218
|
}
|
|
5939
6219
|
return [node];
|
|
5940
6220
|
}
|
|
5941
6221
|
function runtimeConcatOperands(node) {
|
|
5942
|
-
if (node.type !==
|
|
6222
|
+
if (node.type !== AST_NODE_TYPES29.BinaryExpression || node.operator !== "+") {
|
|
5943
6223
|
return [];
|
|
5944
6224
|
}
|
|
5945
6225
|
const operands = concatOperands(node);
|
|
5946
6226
|
const hasStringLiteral = operands.some(
|
|
5947
|
-
(operand) => operand.type ===
|
|
6227
|
+
(operand) => operand.type === AST_NODE_TYPES29.Literal && typeof operand.value === "string"
|
|
5948
6228
|
);
|
|
5949
6229
|
if (!hasStringLiteral) {
|
|
5950
6230
|
return [];
|
|
5951
6231
|
}
|
|
5952
6232
|
return operands.filter(
|
|
5953
|
-
(operand) => operand.type !==
|
|
6233
|
+
(operand) => operand.type !== AST_NODE_TYPES29.Literal && !isStaticFragment(operand)
|
|
5954
6234
|
);
|
|
5955
6235
|
}
|
|
5956
6236
|
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;
|
|
5957
6237
|
var RUNTIME_MARKER = " ? ";
|
|
5958
6238
|
function staticStatementText(node) {
|
|
5959
|
-
if (node.type ===
|
|
6239
|
+
if (node.type === AST_NODE_TYPES29.TemplateLiteral) {
|
|
5960
6240
|
return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
|
|
5961
6241
|
}
|
|
5962
|
-
if (node.type ===
|
|
6242
|
+
if (node.type === AST_NODE_TYPES29.Literal) {
|
|
5963
6243
|
return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
|
|
5964
6244
|
}
|
|
5965
|
-
if (node.type ===
|
|
6245
|
+
if (node.type === AST_NODE_TYPES29.BinaryExpression && node.operator === "+") {
|
|
5966
6246
|
return staticStatementText(node.left) + staticStatementText(node.right);
|
|
5967
6247
|
}
|
|
5968
6248
|
return RUNTIME_MARKER;
|
|
@@ -5972,13 +6252,13 @@ function looksLikeSql(node) {
|
|
|
5972
6252
|
}
|
|
5973
6253
|
function statementMethodName(node, methods) {
|
|
5974
6254
|
const callee = node.callee;
|
|
5975
|
-
if (callee.type !==
|
|
6255
|
+
if (callee.type !== AST_NODE_TYPES29.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES29.Identifier) {
|
|
5976
6256
|
return null;
|
|
5977
6257
|
}
|
|
5978
6258
|
const name = callee.property.name;
|
|
5979
6259
|
return methods.has(name) ? name : null;
|
|
5980
6260
|
}
|
|
5981
|
-
var no_dynamic_sql_default =
|
|
6261
|
+
var no_dynamic_sql_default = ESLintUtils41.RuleCreator(
|
|
5982
6262
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5983
6263
|
)({
|
|
5984
6264
|
name: "no-dynamic-sql",
|
|
@@ -6017,7 +6297,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6017
6297
|
if (statement === void 0 || !looksLikeSql(statement)) {
|
|
6018
6298
|
return;
|
|
6019
6299
|
}
|
|
6020
|
-
const offenders = statement.type ===
|
|
6300
|
+
const offenders = statement.type === AST_NODE_TYPES29.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
|
|
6021
6301
|
for (const offender of offenders) {
|
|
6022
6302
|
context.report({
|
|
6023
6303
|
node: offender,
|
|
@@ -6031,7 +6311,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6031
6311
|
});
|
|
6032
6312
|
|
|
6033
6313
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
6034
|
-
import { ESLintUtils as
|
|
6314
|
+
import { ESLintUtils as ESLintUtils42 } from "@typescript-eslint/utils";
|
|
6035
6315
|
var DEFAULT_ALLOW = [
|
|
6036
6316
|
"[\\\\/]clients?[\\\\/]",
|
|
6037
6317
|
"-client\\.[cm]?[jt]sx?$",
|
|
@@ -6095,7 +6375,7 @@ function compile(patterns) {
|
|
|
6095
6375
|
}
|
|
6096
6376
|
return compiled;
|
|
6097
6377
|
}
|
|
6098
|
-
var no_raw_fetch_outside_clients_default =
|
|
6378
|
+
var no_raw_fetch_outside_clients_default = ESLintUtils42.RuleCreator(
|
|
6099
6379
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6100
6380
|
)({
|
|
6101
6381
|
name: "no-raw-fetch-outside-clients",
|
|
@@ -6143,7 +6423,7 @@ var no_raw_fetch_outside_clients_default = ESLintUtils38.RuleCreator(
|
|
|
6143
6423
|
});
|
|
6144
6424
|
|
|
6145
6425
|
// src/rules/no-storage-in-stateless-modules.ts
|
|
6146
|
-
import { AST_NODE_TYPES as
|
|
6426
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES30, ESLintUtils as ESLintUtils43 } from "@typescript-eslint/utils";
|
|
6147
6427
|
var DEFAULT_METHODS2 = [
|
|
6148
6428
|
"prepare",
|
|
6149
6429
|
"put",
|
|
@@ -6162,7 +6442,7 @@ function compile2(patterns) {
|
|
|
6162
6442
|
}
|
|
6163
6443
|
function storageMethodName(node, methods) {
|
|
6164
6444
|
const callee = node.callee;
|
|
6165
|
-
if (callee.type !==
|
|
6445
|
+
if (callee.type !== AST_NODE_TYPES30.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES30.Identifier) {
|
|
6166
6446
|
return null;
|
|
6167
6447
|
}
|
|
6168
6448
|
const name = callee.property.name;
|
|
@@ -6174,7 +6454,7 @@ function storageMethodName(node, methods) {
|
|
|
6174
6454
|
}
|
|
6175
6455
|
return name;
|
|
6176
6456
|
}
|
|
6177
|
-
var no_storage_in_stateless_modules_default =
|
|
6457
|
+
var no_storage_in_stateless_modules_default = ESLintUtils43.RuleCreator(
|
|
6178
6458
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6179
6459
|
)({
|
|
6180
6460
|
name: "no-storage-in-stateless-modules",
|
|
@@ -6233,8 +6513,8 @@ var no_storage_in_stateless_modules_default = ESLintUtils39.RuleCreator(
|
|
|
6233
6513
|
|
|
6234
6514
|
// src/rules/no-zod-native-enum.ts
|
|
6235
6515
|
import {
|
|
6236
|
-
ESLintUtils as
|
|
6237
|
-
AST_NODE_TYPES as
|
|
6516
|
+
ESLintUtils as ESLintUtils44,
|
|
6517
|
+
AST_NODE_TYPES as AST_NODE_TYPES31
|
|
6238
6518
|
} from "@typescript-eslint/utils";
|
|
6239
6519
|
import * as ts2 from "typescript";
|
|
6240
6520
|
var IGNORE_PATTERNS2 = [
|
|
@@ -6249,11 +6529,11 @@ function isIgnoredFile2(filename, sourceText) {
|
|
|
6249
6529
|
}
|
|
6250
6530
|
return /@generated\b/.test(sourceText.slice(0, 1024));
|
|
6251
6531
|
}
|
|
6252
|
-
function
|
|
6532
|
+
function isZodModule2(source) {
|
|
6253
6533
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
6254
6534
|
}
|
|
6255
6535
|
function unwrap3(node) {
|
|
6256
|
-
if (node.type ===
|
|
6536
|
+
if (node.type === AST_NODE_TYPES31.TSAsExpression || node.type === AST_NODE_TYPES31.TSSatisfiesExpression) {
|
|
6257
6537
|
return unwrap3(node.expression);
|
|
6258
6538
|
}
|
|
6259
6539
|
return node;
|
|
@@ -6261,14 +6541,14 @@ function unwrap3(node) {
|
|
|
6261
6541
|
function stringValueTexts(node, sourceCode) {
|
|
6262
6542
|
const texts = [];
|
|
6263
6543
|
for (const prop of node.properties) {
|
|
6264
|
-
if (prop.type !==
|
|
6544
|
+
if (prop.type !== AST_NODE_TYPES31.Property) {
|
|
6265
6545
|
return null;
|
|
6266
6546
|
}
|
|
6267
6547
|
if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6268
6548
|
return null;
|
|
6269
6549
|
}
|
|
6270
6550
|
const value = prop.value;
|
|
6271
|
-
if (value.type !==
|
|
6551
|
+
if (value.type !== AST_NODE_TYPES31.Literal || typeof value.value !== "string") {
|
|
6272
6552
|
return null;
|
|
6273
6553
|
}
|
|
6274
6554
|
const text = sourceCode.getText(value);
|
|
@@ -6284,7 +6564,7 @@ function resolvesToLocalEnum(node, scope) {
|
|
|
6284
6564
|
const variable = current.variables.find((v) => v.name === node.name);
|
|
6285
6565
|
if (variable !== void 0) {
|
|
6286
6566
|
return variable.defs.some(
|
|
6287
|
-
(def) => def.node.type ===
|
|
6567
|
+
(def) => def.node.type === AST_NODE_TYPES31.TSEnumDeclaration
|
|
6288
6568
|
);
|
|
6289
6569
|
}
|
|
6290
6570
|
current = current.upper;
|
|
@@ -6304,7 +6584,7 @@ function resolvesToImportedEnum(node, services) {
|
|
|
6304
6584
|
}
|
|
6305
6585
|
return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
|
|
6306
6586
|
}
|
|
6307
|
-
var no_zod_native_enum_default =
|
|
6587
|
+
var no_zod_native_enum_default = ESLintUtils44.RuleCreator(
|
|
6308
6588
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6309
6589
|
)({
|
|
6310
6590
|
name: "no-zod-native-enum",
|
|
@@ -6331,32 +6611,32 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6331
6611
|
}
|
|
6332
6612
|
let services;
|
|
6333
6613
|
try {
|
|
6334
|
-
services =
|
|
6614
|
+
services = ESLintUtils44.getParserServices(context);
|
|
6335
6615
|
} catch {
|
|
6336
6616
|
services = null;
|
|
6337
6617
|
}
|
|
6338
6618
|
const zodImportedNames = /* @__PURE__ */ new Map();
|
|
6339
6619
|
function isZodMemberCall(node, api) {
|
|
6340
6620
|
const callee = node.callee;
|
|
6341
|
-
if (callee.type ===
|
|
6621
|
+
if (callee.type === AST_NODE_TYPES31.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES31.Identifier) {
|
|
6342
6622
|
return callee.property.name === api;
|
|
6343
6623
|
}
|
|
6344
|
-
if (callee.type ===
|
|
6624
|
+
if (callee.type === AST_NODE_TYPES31.Identifier) {
|
|
6345
6625
|
return zodImportedNames.get(callee.name) === api;
|
|
6346
6626
|
}
|
|
6347
6627
|
return false;
|
|
6348
6628
|
}
|
|
6349
6629
|
function buildFix(node) {
|
|
6350
6630
|
const callee = node.callee;
|
|
6351
|
-
if (callee.type !==
|
|
6631
|
+
if (callee.type !== AST_NODE_TYPES31.MemberExpression || callee.property.type !== AST_NODE_TYPES31.Identifier) {
|
|
6352
6632
|
return null;
|
|
6353
6633
|
}
|
|
6354
6634
|
const arg = node.arguments[0];
|
|
6355
|
-
if (arg === void 0 || node.arguments.length !== 1 || arg.type ===
|
|
6635
|
+
if (arg === void 0 || node.arguments.length !== 1 || arg.type === AST_NODE_TYPES31.SpreadElement) {
|
|
6356
6636
|
return null;
|
|
6357
6637
|
}
|
|
6358
6638
|
const inner = unwrap3(arg);
|
|
6359
|
-
if (inner.type !==
|
|
6639
|
+
if (inner.type !== AST_NODE_TYPES31.ObjectExpression) {
|
|
6360
6640
|
return null;
|
|
6361
6641
|
}
|
|
6362
6642
|
const values = stringValueTexts(inner, sourceCode);
|
|
@@ -6372,11 +6652,11 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6372
6652
|
}
|
|
6373
6653
|
return {
|
|
6374
6654
|
ImportDeclaration(node) {
|
|
6375
|
-
if (!
|
|
6655
|
+
if (!isZodModule2(node.source.value)) {
|
|
6376
6656
|
return;
|
|
6377
6657
|
}
|
|
6378
6658
|
for (const spec of node.specifiers) {
|
|
6379
|
-
if (spec.type ===
|
|
6659
|
+
if (spec.type === AST_NODE_TYPES31.ImportSpecifier && spec.imported.type === AST_NODE_TYPES31.Identifier) {
|
|
6380
6660
|
zodImportedNames.set(spec.local.name, spec.imported.name);
|
|
6381
6661
|
}
|
|
6382
6662
|
}
|
|
@@ -6395,7 +6675,7 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6395
6675
|
return;
|
|
6396
6676
|
}
|
|
6397
6677
|
const arg = node.arguments[0];
|
|
6398
|
-
if (arg === void 0 || arg.type !==
|
|
6678
|
+
if (arg === void 0 || arg.type !== AST_NODE_TYPES31.Identifier) {
|
|
6399
6679
|
return;
|
|
6400
6680
|
}
|
|
6401
6681
|
const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
|
|
@@ -6413,8 +6693,8 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6413
6693
|
|
|
6414
6694
|
// src/rules/prefer-module-level-constant.ts
|
|
6415
6695
|
import {
|
|
6416
|
-
ESLintUtils as
|
|
6417
|
-
AST_NODE_TYPES as
|
|
6696
|
+
ESLintUtils as ESLintUtils45,
|
|
6697
|
+
AST_NODE_TYPES as AST_NODE_TYPES32
|
|
6418
6698
|
} from "@typescript-eslint/utils";
|
|
6419
6699
|
var DEFAULT_MIN_ELEMENTS = 3;
|
|
6420
6700
|
var MAX_LITERAL_DEPTH = 4;
|
|
@@ -6450,10 +6730,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
6450
6730
|
// Object-ish escape hatches
|
|
6451
6731
|
"assign"
|
|
6452
6732
|
]);
|
|
6453
|
-
var
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6733
|
+
var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
6734
|
+
AST_NODE_TYPES32.FunctionDeclaration,
|
|
6735
|
+
AST_NODE_TYPES32.FunctionExpression,
|
|
6736
|
+
AST_NODE_TYPES32.ArrowFunctionExpression
|
|
6457
6737
|
]);
|
|
6458
6738
|
var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
|
|
6459
6739
|
function isIgnoredFile3(filename, sourceText) {
|
|
@@ -6466,13 +6746,13 @@ function isTestFile2(filename) {
|
|
|
6466
6746
|
return TEST_FILE_PATTERNS.some((re) => re.test(filename));
|
|
6467
6747
|
}
|
|
6468
6748
|
function unwrap4(node) {
|
|
6469
|
-
if (node.type ===
|
|
6749
|
+
if (node.type === AST_NODE_TYPES32.TSAsExpression || node.type === AST_NODE_TYPES32.TSSatisfiesExpression || node.type === AST_NODE_TYPES32.TSNonNullExpression) {
|
|
6470
6750
|
return unwrap4(node.expression);
|
|
6471
6751
|
}
|
|
6472
6752
|
return node;
|
|
6473
6753
|
}
|
|
6474
6754
|
function isRegexLiteral(node) {
|
|
6475
|
-
return node.type ===
|
|
6755
|
+
return node.type === AST_NODE_TYPES32.Literal && "regex" in node && node.regex !== void 0;
|
|
6476
6756
|
}
|
|
6477
6757
|
function isLiteralOnly(node, depth) {
|
|
6478
6758
|
if (depth > MAX_LITERAL_DEPTH) {
|
|
@@ -6480,29 +6760,29 @@ function isLiteralOnly(node, depth) {
|
|
|
6480
6760
|
}
|
|
6481
6761
|
const inner = unwrap4(node);
|
|
6482
6762
|
switch (inner.type) {
|
|
6483
|
-
case
|
|
6763
|
+
case AST_NODE_TYPES32.Literal: {
|
|
6484
6764
|
return true;
|
|
6485
6765
|
}
|
|
6486
|
-
case
|
|
6766
|
+
case AST_NODE_TYPES32.TemplateLiteral: {
|
|
6487
6767
|
return inner.expressions.length === 0;
|
|
6488
6768
|
}
|
|
6489
|
-
case
|
|
6490
|
-
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type ===
|
|
6769
|
+
case AST_NODE_TYPES32.UnaryExpression: {
|
|
6770
|
+
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === AST_NODE_TYPES32.Literal && typeof inner.argument.value === "number";
|
|
6491
6771
|
}
|
|
6492
|
-
case
|
|
6772
|
+
case AST_NODE_TYPES32.ArrayExpression: {
|
|
6493
6773
|
return inner.elements.every(
|
|
6494
|
-
(el) => el !== null && el.type !==
|
|
6774
|
+
(el) => el !== null && el.type !== AST_NODE_TYPES32.SpreadElement && isLiteralOnly(el, depth + 1)
|
|
6495
6775
|
);
|
|
6496
6776
|
}
|
|
6497
|
-
case
|
|
6777
|
+
case AST_NODE_TYPES32.ObjectExpression: {
|
|
6498
6778
|
return inner.properties.every((prop) => {
|
|
6499
|
-
if (prop.type !==
|
|
6779
|
+
if (prop.type !== AST_NODE_TYPES32.Property) {
|
|
6500
6780
|
return false;
|
|
6501
6781
|
}
|
|
6502
6782
|
if (prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6503
6783
|
return false;
|
|
6504
6784
|
}
|
|
6505
|
-
if (prop.computed && prop.key.type !==
|
|
6785
|
+
if (prop.computed && prop.key.type !== AST_NODE_TYPES32.Literal) {
|
|
6506
6786
|
return false;
|
|
6507
6787
|
}
|
|
6508
6788
|
return isLiteralOnly(prop.value, depth + 1);
|
|
@@ -6515,7 +6795,7 @@ function isLiteralOnly(node, depth) {
|
|
|
6515
6795
|
}
|
|
6516
6796
|
function unwrapObjectFreeze(node) {
|
|
6517
6797
|
const inner = unwrap4(node);
|
|
6518
|
-
if (inner.type ===
|
|
6798
|
+
if (inner.type === AST_NODE_TYPES32.CallExpression && inner.callee.type === AST_NODE_TYPES32.MemberExpression && !inner.callee.computed && inner.callee.object.type === AST_NODE_TYPES32.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === AST_NODE_TYPES32.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== AST_NODE_TYPES32.SpreadElement) {
|
|
6519
6799
|
return unwrap4(inner.arguments[0]);
|
|
6520
6800
|
}
|
|
6521
6801
|
return inner;
|
|
@@ -6531,19 +6811,19 @@ function classify(init, checkRegex) {
|
|
|
6531
6811
|
}
|
|
6532
6812
|
return { kind: "regex", size: 1 };
|
|
6533
6813
|
}
|
|
6534
|
-
if (node.type ===
|
|
6814
|
+
if (node.type === AST_NODE_TYPES32.ArrayExpression) {
|
|
6535
6815
|
return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
|
|
6536
6816
|
}
|
|
6537
|
-
if (node.type ===
|
|
6817
|
+
if (node.type === AST_NODE_TYPES32.ObjectExpression) {
|
|
6538
6818
|
return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
|
|
6539
6819
|
}
|
|
6540
|
-
if (node.type ===
|
|
6820
|
+
if (node.type === AST_NODE_TYPES32.NewExpression && node.callee.type === AST_NODE_TYPES32.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
|
|
6541
6821
|
const arg = node.arguments[0];
|
|
6542
|
-
if (node.arguments.length !== 1 || arg === void 0 || arg.type ===
|
|
6822
|
+
if (node.arguments.length !== 1 || arg === void 0 || arg.type === AST_NODE_TYPES32.SpreadElement) {
|
|
6543
6823
|
return null;
|
|
6544
6824
|
}
|
|
6545
6825
|
const entries = unwrap4(arg);
|
|
6546
|
-
if (entries.type !==
|
|
6826
|
+
if (entries.type !== AST_NODE_TYPES32.ArrayExpression) {
|
|
6547
6827
|
return null;
|
|
6548
6828
|
}
|
|
6549
6829
|
return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
|
|
@@ -6553,7 +6833,7 @@ function classify(init, checkRegex) {
|
|
|
6553
6833
|
function enclosingFunction2(node) {
|
|
6554
6834
|
let current = node.parent;
|
|
6555
6835
|
while (current !== void 0 && current !== null) {
|
|
6556
|
-
if (
|
|
6836
|
+
if (FUNCTION_TYPES4.has(current.type)) {
|
|
6557
6837
|
return current;
|
|
6558
6838
|
}
|
|
6559
6839
|
current = current.parent;
|
|
@@ -6572,10 +6852,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
|
|
|
6572
6852
|
);
|
|
6573
6853
|
function isNonRetainingBuiltinCall(node, argument) {
|
|
6574
6854
|
const callee = node.callee;
|
|
6575
|
-
if (callee.type ===
|
|
6855
|
+
if (callee.type === AST_NODE_TYPES32.Identifier && callee.name === "structuredClone") {
|
|
6576
6856
|
return true;
|
|
6577
6857
|
}
|
|
6578
|
-
if (callee.type !==
|
|
6858
|
+
if (callee.type !== AST_NODE_TYPES32.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES32.Identifier || callee.property.type !== AST_NODE_TYPES32.Identifier) {
|
|
6579
6859
|
return false;
|
|
6580
6860
|
}
|
|
6581
6861
|
const members = NON_RETAINING_BUILTINS.get(callee.object.name);
|
|
@@ -6589,43 +6869,43 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
6589
6869
|
}
|
|
6590
6870
|
function isSafeRead(identifier) {
|
|
6591
6871
|
const parent = identifier.parent;
|
|
6592
|
-
if (parent.type ===
|
|
6872
|
+
if (parent.type === AST_NODE_TYPES32.MemberExpression) {
|
|
6593
6873
|
if (parent.object !== identifier) {
|
|
6594
6874
|
return true;
|
|
6595
6875
|
}
|
|
6596
6876
|
const grandparent = parent.parent;
|
|
6597
|
-
if (grandparent.type ===
|
|
6877
|
+
if (grandparent.type === AST_NODE_TYPES32.AssignmentExpression && grandparent.left === parent) {
|
|
6598
6878
|
return false;
|
|
6599
6879
|
}
|
|
6600
|
-
if (grandparent.type ===
|
|
6880
|
+
if (grandparent.type === AST_NODE_TYPES32.UpdateExpression) {
|
|
6601
6881
|
return false;
|
|
6602
6882
|
}
|
|
6603
|
-
if (grandparent.type ===
|
|
6883
|
+
if (grandparent.type === AST_NODE_TYPES32.UnaryExpression && grandparent.operator === "delete") {
|
|
6604
6884
|
return false;
|
|
6605
6885
|
}
|
|
6606
|
-
if (!parent.computed && parent.property.type ===
|
|
6886
|
+
if (!parent.computed && parent.property.type === AST_NODE_TYPES32.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === AST_NODE_TYPES32.CallExpression && grandparent.callee === parent) {
|
|
6607
6887
|
return false;
|
|
6608
6888
|
}
|
|
6609
6889
|
return true;
|
|
6610
6890
|
}
|
|
6611
|
-
if (parent.type ===
|
|
6891
|
+
if (parent.type === AST_NODE_TYPES32.ForOfStatement && parent.right === identifier) {
|
|
6612
6892
|
return true;
|
|
6613
6893
|
}
|
|
6614
|
-
if (parent.type ===
|
|
6894
|
+
if (parent.type === AST_NODE_TYPES32.SpreadElement) {
|
|
6615
6895
|
return true;
|
|
6616
6896
|
}
|
|
6617
|
-
if (parent.type ===
|
|
6897
|
+
if (parent.type === AST_NODE_TYPES32.BinaryExpression) {
|
|
6618
6898
|
return true;
|
|
6619
6899
|
}
|
|
6620
|
-
if (parent.type ===
|
|
6900
|
+
if (parent.type === AST_NODE_TYPES32.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
|
|
6621
6901
|
return true;
|
|
6622
6902
|
}
|
|
6623
|
-
if (parent.type ===
|
|
6903
|
+
if (parent.type === AST_NODE_TYPES32.UnaryExpression && parent.operator !== "delete") {
|
|
6624
6904
|
return true;
|
|
6625
6905
|
}
|
|
6626
6906
|
return false;
|
|
6627
6907
|
}
|
|
6628
|
-
var prefer_module_level_constant_default =
|
|
6908
|
+
var prefer_module_level_constant_default = ESLintUtils45.RuleCreator(
|
|
6629
6909
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6630
6910
|
)({
|
|
6631
6911
|
name: "prefer-module-level-constant",
|
|
@@ -6677,7 +6957,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6677
6957
|
if (reference.isWrite()) {
|
|
6678
6958
|
return false;
|
|
6679
6959
|
}
|
|
6680
|
-
if (reference.identifier.type !==
|
|
6960
|
+
if (reference.identifier.type !== AST_NODE_TYPES32.Identifier) {
|
|
6681
6961
|
return false;
|
|
6682
6962
|
}
|
|
6683
6963
|
if (!isSafeRead(reference.identifier)) {
|
|
@@ -6689,10 +6969,10 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6689
6969
|
return {
|
|
6690
6970
|
VariableDeclarator(node) {
|
|
6691
6971
|
const declaration = node.parent;
|
|
6692
|
-
if (declaration.type !==
|
|
6972
|
+
if (declaration.type !== AST_NODE_TYPES32.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
|
|
6693
6973
|
return;
|
|
6694
6974
|
}
|
|
6695
|
-
if (node.id.type !==
|
|
6975
|
+
if (node.id.type !== AST_NODE_TYPES32.Identifier || node.init === null) {
|
|
6696
6976
|
return;
|
|
6697
6977
|
}
|
|
6698
6978
|
if (enclosingFunction2(node) === null) {
|
|
@@ -6719,7 +6999,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6719
6999
|
});
|
|
6720
7000
|
|
|
6721
7001
|
// src/rules/jsdoc-restates-signature.ts
|
|
6722
|
-
import { AST_NODE_TYPES as
|
|
7002
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES33, ESLintUtils as ESLintUtils46 } from "@typescript-eslint/utils";
|
|
6723
7003
|
var VALUE_TAGS = /* @__PURE__ */ new Set([
|
|
6724
7004
|
"alpha",
|
|
6725
7005
|
"author",
|
|
@@ -6802,30 +7082,30 @@ function declarationNames(node) {
|
|
|
6802
7082
|
switch (node.type) {
|
|
6803
7083
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
6804
7084
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
6805
|
-
case
|
|
6806
|
-
case
|
|
7085
|
+
case AST_NODE_TYPES33.ExportNamedDeclaration:
|
|
7086
|
+
case AST_NODE_TYPES33.ExportDefaultDeclaration:
|
|
6807
7087
|
return node.declaration == null ? null : declarationNames(node.declaration);
|
|
6808
|
-
case
|
|
6809
|
-
case
|
|
7088
|
+
case AST_NODE_TYPES33.FunctionDeclaration:
|
|
7089
|
+
case AST_NODE_TYPES33.TSDeclareFunction:
|
|
6810
7090
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
6811
|
-
case
|
|
6812
|
-
case
|
|
6813
|
-
case
|
|
6814
|
-
case
|
|
7091
|
+
case AST_NODE_TYPES33.ClassDeclaration:
|
|
7092
|
+
case AST_NODE_TYPES33.TSInterfaceDeclaration:
|
|
7093
|
+
case AST_NODE_TYPES33.TSTypeAliasDeclaration:
|
|
7094
|
+
case AST_NODE_TYPES33.TSEnumDeclaration:
|
|
6815
7095
|
return node.id === null ? null : { name: node.id.name, params: [] };
|
|
6816
|
-
case
|
|
7096
|
+
case AST_NODE_TYPES33.VariableDeclaration: {
|
|
6817
7097
|
const declarator = node.declarations[0];
|
|
6818
|
-
if (declarator === void 0 || declarator.id.type !==
|
|
7098
|
+
if (declarator === void 0 || declarator.id.type !== AST_NODE_TYPES33.Identifier) return null;
|
|
6819
7099
|
const init = declarator.init;
|
|
6820
|
-
const params = init != null && (init.type ===
|
|
7100
|
+
const params = init != null && (init.type === AST_NODE_TYPES33.ArrowFunctionExpression || init.type === AST_NODE_TYPES33.FunctionExpression) ? paramNames(init.params) : [];
|
|
6821
7101
|
return { name: declarator.id.name, params };
|
|
6822
7102
|
}
|
|
6823
|
-
case
|
|
6824
|
-
case
|
|
6825
|
-
case
|
|
6826
|
-
case
|
|
6827
|
-
if (node.key.type !==
|
|
6828
|
-
const params = node.type ===
|
|
7103
|
+
case AST_NODE_TYPES33.MethodDefinition:
|
|
7104
|
+
case AST_NODE_TYPES33.PropertyDefinition:
|
|
7105
|
+
case AST_NODE_TYPES33.TSMethodSignature:
|
|
7106
|
+
case AST_NODE_TYPES33.TSPropertySignature: {
|
|
7107
|
+
if (node.key.type !== AST_NODE_TYPES33.Identifier) return null;
|
|
7108
|
+
const params = node.type === AST_NODE_TYPES33.MethodDefinition ? paramNames(node.value.params) : node.type === AST_NODE_TYPES33.TSMethodSignature ? paramNames(node.params) : [];
|
|
6829
7109
|
return { name: node.key.name, params };
|
|
6830
7110
|
}
|
|
6831
7111
|
default:
|
|
@@ -6835,9 +7115,9 @@ function declarationNames(node) {
|
|
|
6835
7115
|
function paramNames(params) {
|
|
6836
7116
|
const names = [];
|
|
6837
7117
|
for (const param of params) {
|
|
6838
|
-
const target = param.type ===
|
|
6839
|
-
if (target.type ===
|
|
6840
|
-
else if (target.type ===
|
|
7118
|
+
const target = param.type === AST_NODE_TYPES33.AssignmentPattern ? param.left : param;
|
|
7119
|
+
if (target.type === AST_NODE_TYPES33.Identifier) names.push(target.name);
|
|
7120
|
+
else if (target.type === AST_NODE_TYPES33.TSParameterProperty) continue;
|
|
6841
7121
|
}
|
|
6842
7122
|
return names;
|
|
6843
7123
|
}
|
|
@@ -6846,7 +7126,7 @@ function tokensOf(names) {
|
|
|
6846
7126
|
for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
|
|
6847
7127
|
return tokens;
|
|
6848
7128
|
}
|
|
6849
|
-
var jsdoc_restates_signature_default =
|
|
7129
|
+
var jsdoc_restates_signature_default = ESLintUtils46.RuleCreator(
|
|
6850
7130
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6851
7131
|
)({
|
|
6852
7132
|
name: "jsdoc-restates-signature",
|
|
@@ -6882,7 +7162,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
6882
7162
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
|
|
6883
7163
|
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
|
6884
7164
|
let declaration = null;
|
|
6885
|
-
while (node != null && node.type !==
|
|
7165
|
+
while (node != null && node.type !== AST_NODE_TYPES33.Program) {
|
|
6886
7166
|
declaration = declarationNames(node);
|
|
6887
7167
|
if (declaration !== null) break;
|
|
6888
7168
|
node = node.parent ?? null;
|
|
@@ -6937,7 +7217,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
6937
7217
|
});
|
|
6938
7218
|
|
|
6939
7219
|
// src/rules/no-restated-comment.ts
|
|
6940
|
-
import { AST_NODE_TYPES as
|
|
7220
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES34, ESLintUtils as ESLintUtils47 } from "@typescript-eslint/utils";
|
|
6941
7221
|
var MAX_WORDS = 8;
|
|
6942
7222
|
var MIN_CONTENT_TOKENS = 2;
|
|
6943
7223
|
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;
|
|
@@ -6961,7 +7241,7 @@ function headsSiblingRun(node) {
|
|
|
6961
7241
|
const next = index >= 0 ? body[index + 1] : void 0;
|
|
6962
7242
|
return next !== void 0 && next.type === node.type;
|
|
6963
7243
|
}
|
|
6964
|
-
var no_restated_comment_default =
|
|
7244
|
+
var no_restated_comment_default = ESLintUtils47.RuleCreator(
|
|
6965
7245
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6966
7246
|
)({
|
|
6967
7247
|
name: "no-restated-comment",
|
|
@@ -6989,7 +7269,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
6989
7269
|
function labelsASiblingRun(comment) {
|
|
6990
7270
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
6991
7271
|
if (token === null) return false;
|
|
6992
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
7272
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES34.Program; node = node.parent) {
|
|
6993
7273
|
if (headsSiblingRun(node)) return true;
|
|
6994
7274
|
}
|
|
6995
7275
|
return false;
|
|
@@ -7029,7 +7309,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
7029
7309
|
});
|
|
7030
7310
|
|
|
7031
7311
|
// src/rules/trailing-value-narration.ts
|
|
7032
|
-
import { ESLintUtils as
|
|
7312
|
+
import { ESLintUtils as ESLintUtils48 } from "@typescript-eslint/utils";
|
|
7033
7313
|
var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
|
|
7034
7314
|
var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
|
|
7035
7315
|
var UNIT_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -7113,7 +7393,7 @@ function narratesValue(body, code) {
|
|
|
7113
7393
|
(word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
|
|
7114
7394
|
);
|
|
7115
7395
|
}
|
|
7116
|
-
var trailing_value_narration_default =
|
|
7396
|
+
var trailing_value_narration_default = ESLintUtils48.RuleCreator(
|
|
7117
7397
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7118
7398
|
)({
|
|
7119
7399
|
name: "trailing-value-narration",
|
|
@@ -7154,7 +7434,7 @@ var trailing_value_narration_default = ESLintUtils44.RuleCreator(
|
|
|
7154
7434
|
});
|
|
7155
7435
|
|
|
7156
7436
|
// src/rules/no-tautological-expect.ts
|
|
7157
|
-
import { AST_NODE_TYPES as
|
|
7437
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES35, ESLintUtils as ESLintUtils49 } from "@typescript-eslint/utils";
|
|
7158
7438
|
var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
7159
7439
|
var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
|
|
7160
7440
|
"toBeDefined",
|
|
@@ -7168,17 +7448,17 @@ var OPERAND_PREVIEW_CHARS = 40;
|
|
|
7168
7448
|
var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
|
|
7169
7449
|
function isLiteral(node) {
|
|
7170
7450
|
switch (node.type) {
|
|
7171
|
-
case
|
|
7451
|
+
case AST_NODE_TYPES35.Literal:
|
|
7172
7452
|
return true;
|
|
7173
|
-
case
|
|
7453
|
+
case AST_NODE_TYPES35.TemplateLiteral:
|
|
7174
7454
|
return node.expressions.length === 0;
|
|
7175
|
-
case
|
|
7455
|
+
case AST_NODE_TYPES35.UnaryExpression:
|
|
7176
7456
|
return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
|
|
7177
|
-
case
|
|
7457
|
+
case AST_NODE_TYPES35.ArrayExpression:
|
|
7178
7458
|
return node.elements.every((element) => element !== null && isLiteral(element));
|
|
7179
|
-
case
|
|
7459
|
+
case AST_NODE_TYPES35.ObjectExpression:
|
|
7180
7460
|
return node.properties.every(
|
|
7181
|
-
(property) => property.type ===
|
|
7461
|
+
(property) => property.type === AST_NODE_TYPES35.Property && !property.computed && isLiteral(property.value)
|
|
7182
7462
|
);
|
|
7183
7463
|
default:
|
|
7184
7464
|
return false;
|
|
@@ -7186,12 +7466,12 @@ function isLiteral(node) {
|
|
|
7186
7466
|
}
|
|
7187
7467
|
function expectOperand(callee) {
|
|
7188
7468
|
const receiver = callee.object;
|
|
7189
|
-
if (receiver.type !==
|
|
7469
|
+
if (receiver.type !== AST_NODE_TYPES35.CallExpression || receiver.callee.type !== AST_NODE_TYPES35.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
|
|
7190
7470
|
return null;
|
|
7191
7471
|
}
|
|
7192
7472
|
return receiver.arguments[0] ?? null;
|
|
7193
7473
|
}
|
|
7194
|
-
var no_tautological_expect_default =
|
|
7474
|
+
var no_tautological_expect_default = ESLintUtils49.RuleCreator(
|
|
7195
7475
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7196
7476
|
)({
|
|
7197
7477
|
name: "no-tautological-expect",
|
|
@@ -7218,10 +7498,10 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7218
7498
|
return {
|
|
7219
7499
|
CallExpression(node) {
|
|
7220
7500
|
const callee = node.callee;
|
|
7221
|
-
if (callee.type !==
|
|
7501
|
+
if (callee.type !== AST_NODE_TYPES35.MemberExpression || callee.computed) {
|
|
7222
7502
|
return;
|
|
7223
7503
|
}
|
|
7224
|
-
if (callee.property.type !==
|
|
7504
|
+
if (callee.property.type !== AST_NODE_TYPES35.Identifier) {
|
|
7225
7505
|
return;
|
|
7226
7506
|
}
|
|
7227
7507
|
const matcher = callee.property.name;
|
|
@@ -7255,26 +7535,26 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7255
7535
|
});
|
|
7256
7536
|
|
|
7257
7537
|
// src/rules/require-interface-for-injected-service.ts
|
|
7258
|
-
import { AST_NODE_TYPES as
|
|
7538
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES36, ESLintUtils as ESLintUtils50 } from "@typescript-eslint/utils";
|
|
7259
7539
|
var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
|
|
7260
7540
|
var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
|
|
7261
7541
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
7262
7542
|
var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
|
|
7263
7543
|
var ROUTER_FACTORY_NAME = "Router";
|
|
7264
7544
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
7265
|
-
var isExportedClass = (node) => node.parent.type ===
|
|
7266
|
-
var qualifiedName = (name) => name.type ===
|
|
7545
|
+
var isExportedClass = (node) => node.parent.type === AST_NODE_TYPES36.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES36.ExportDefaultDeclaration;
|
|
7546
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES36.Identifier ? name.name : name.type === AST_NODE_TYPES36.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
7267
7547
|
var typeReferenceName = (annotated) => {
|
|
7268
7548
|
let target = annotated;
|
|
7269
|
-
if (target.type ===
|
|
7270
|
-
if (target.type ===
|
|
7271
|
-
if (target.type !==
|
|
7549
|
+
if (target.type === AST_NODE_TYPES36.TSParameterProperty) target = target.parameter;
|
|
7550
|
+
if (target.type === AST_NODE_TYPES36.AssignmentPattern) target = target.left;
|
|
7551
|
+
if (target.type !== AST_NODE_TYPES36.Identifier) return null;
|
|
7272
7552
|
const annotation = target.typeAnnotation?.typeAnnotation;
|
|
7273
|
-
if (annotation === void 0 || annotation.type !==
|
|
7553
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES36.TSTypeReference) {
|
|
7274
7554
|
return null;
|
|
7275
7555
|
}
|
|
7276
7556
|
const { typeName } = annotation;
|
|
7277
|
-
const rightmost = typeName.type ===
|
|
7557
|
+
const rightmost = typeName.type === AST_NODE_TYPES36.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES36.TSQualifiedName ? typeName.right.name : null;
|
|
7278
7558
|
if (rightmost === null) return null;
|
|
7279
7559
|
return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
|
|
7280
7560
|
};
|
|
@@ -7284,17 +7564,17 @@ var readConstructor = (ctor) => {
|
|
|
7284
7564
|
let constructedFields = 0;
|
|
7285
7565
|
if (body !== null && body !== void 0) {
|
|
7286
7566
|
for (const statement of body.body) {
|
|
7287
|
-
if (statement.type !==
|
|
7567
|
+
if (statement.type !== AST_NODE_TYPES36.ExpressionStatement) continue;
|
|
7288
7568
|
const expression = statement.expression;
|
|
7289
|
-
if (expression.type !==
|
|
7569
|
+
if (expression.type !== AST_NODE_TYPES36.AssignmentExpression || expression.operator !== "=" || expression.left.type !== AST_NODE_TYPES36.MemberExpression || expression.left.object.type !== AST_NODE_TYPES36.ThisExpression) {
|
|
7290
7570
|
continue;
|
|
7291
7571
|
}
|
|
7292
7572
|
const source = expression.right;
|
|
7293
|
-
if (source.type ===
|
|
7573
|
+
if (source.type === AST_NODE_TYPES36.NewExpression) {
|
|
7294
7574
|
constructedFields += 1;
|
|
7295
|
-
} else if (source.type ===
|
|
7575
|
+
} else if (source.type === AST_NODE_TYPES36.Identifier) {
|
|
7296
7576
|
storedFrom.add(source.name);
|
|
7297
|
-
} else if (source.type ===
|
|
7577
|
+
} else if (source.type === AST_NODE_TYPES36.MemberExpression && source.object.type === AST_NODE_TYPES36.Identifier) {
|
|
7298
7578
|
storedFrom.add(source.object.name);
|
|
7299
7579
|
}
|
|
7300
7580
|
}
|
|
@@ -7303,7 +7583,7 @@ var readConstructor = (ctor) => {
|
|
|
7303
7583
|
for (const parameter of ctor.value.params) {
|
|
7304
7584
|
const reference = typeReferenceName(parameter);
|
|
7305
7585
|
if (reference === null) continue;
|
|
7306
|
-
const stored = parameter.type ===
|
|
7586
|
+
const stored = parameter.type === AST_NODE_TYPES36.TSParameterProperty || storedFrom.has(reference.name);
|
|
7307
7587
|
if (!stored) continue;
|
|
7308
7588
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
7309
7589
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -7333,19 +7613,19 @@ var subtreeHas = (root, found) => {
|
|
|
7333
7613
|
return hit;
|
|
7334
7614
|
};
|
|
7335
7615
|
var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
|
|
7336
|
-
if (node.type ===
|
|
7616
|
+
if (node.type === AST_NODE_TYPES36.CallExpression) {
|
|
7337
7617
|
const { callee } = node;
|
|
7338
|
-
if (callee.type ===
|
|
7339
|
-
return callee.type ===
|
|
7618
|
+
if (callee.type === AST_NODE_TYPES36.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
7619
|
+
return callee.type === AST_NODE_TYPES36.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES36.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
7340
7620
|
}
|
|
7341
|
-
return node.type ===
|
|
7621
|
+
return node.type === AST_NODE_TYPES36.TSTypeReference && node.typeName.type === AST_NODE_TYPES36.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
7342
7622
|
});
|
|
7343
7623
|
var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
|
|
7344
7624
|
var fileInterfaceNames = (program) => {
|
|
7345
7625
|
const names = [];
|
|
7346
7626
|
for (const statement of program.body) {
|
|
7347
|
-
const declaration = statement.type ===
|
|
7348
|
-
if (declaration?.type ===
|
|
7627
|
+
const declaration = statement.type === AST_NODE_TYPES36.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7628
|
+
if (declaration?.type === AST_NODE_TYPES36.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
7349
7629
|
}
|
|
7350
7630
|
return names;
|
|
7351
7631
|
};
|
|
@@ -7363,16 +7643,16 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
7363
7643
|
var publicMethodNames = (body) => {
|
|
7364
7644
|
const names = [];
|
|
7365
7645
|
for (const member of body.body) {
|
|
7366
|
-
if (member.type !==
|
|
7646
|
+
if (member.type !== AST_NODE_TYPES36.MethodDefinition) continue;
|
|
7367
7647
|
if (member.kind !== "method" || member.static) continue;
|
|
7368
7648
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
7369
|
-
if (member.key.type ===
|
|
7370
|
-
if (member.key.type ===
|
|
7649
|
+
if (member.key.type === AST_NODE_TYPES36.PrivateIdentifier) continue;
|
|
7650
|
+
if (member.key.type === AST_NODE_TYPES36.Identifier) names.push(member.key.name);
|
|
7371
7651
|
else names.push("\u2026");
|
|
7372
7652
|
}
|
|
7373
7653
|
return names;
|
|
7374
7654
|
};
|
|
7375
|
-
var require_interface_for_injected_service_default =
|
|
7655
|
+
var require_interface_for_injected_service_default = ESLintUtils50.RuleCreator(
|
|
7376
7656
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7377
7657
|
)({
|
|
7378
7658
|
name: "require-interface-for-injected-service",
|
|
@@ -7400,7 +7680,7 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7400
7680
|
if (node.implements.length > 0) return;
|
|
7401
7681
|
if (node.decorators.length > 0) return;
|
|
7402
7682
|
const ctor = node.body.body.find(
|
|
7403
|
-
(member) => member.type ===
|
|
7683
|
+
(member) => member.type === AST_NODE_TYPES36.MethodDefinition && member.kind === "constructor"
|
|
7404
7684
|
);
|
|
7405
7685
|
if (ctor === void 0) return;
|
|
7406
7686
|
const { collaborators, constructedFields } = readConstructor(ctor);
|
|
@@ -7425,26 +7705,26 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7425
7705
|
});
|
|
7426
7706
|
|
|
7427
7707
|
// src/rules/prefer-non-nullable-collection.ts
|
|
7428
|
-
import { AST_NODE_TYPES as
|
|
7708
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES37, ESLintUtils as ESLintUtils51 } from "@typescript-eslint/utils";
|
|
7429
7709
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
7430
7710
|
function propertyName(node) {
|
|
7431
7711
|
const key = node.key;
|
|
7432
|
-
if (key.type ===
|
|
7433
|
-
if (key.type ===
|
|
7712
|
+
if (key.type === AST_NODE_TYPES37.Identifier) return key.name;
|
|
7713
|
+
if (key.type === AST_NODE_TYPES37.Literal) return String(key.value);
|
|
7434
7714
|
return "collection";
|
|
7435
7715
|
}
|
|
7436
7716
|
function isArrayType(node) {
|
|
7437
|
-
if (node.type ===
|
|
7438
|
-
return node.type ===
|
|
7717
|
+
if (node.type === AST_NODE_TYPES37.TSArrayType) return true;
|
|
7718
|
+
return node.type === AST_NODE_TYPES37.TSTypeReference && node.typeName.type === AST_NODE_TYPES37.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
7439
7719
|
}
|
|
7440
7720
|
function isNullishType(node) {
|
|
7441
|
-
return node.type ===
|
|
7721
|
+
return node.type === AST_NODE_TYPES37.TSNullKeyword || node.type === AST_NODE_TYPES37.TSUndefinedKeyword;
|
|
7442
7722
|
}
|
|
7443
7723
|
function isNullableArrayOnly(node) {
|
|
7444
7724
|
const values = node.types.filter((member) => !isNullishType(member));
|
|
7445
7725
|
return values.length > 0 && values.length < node.types.length && values.every(isArrayType);
|
|
7446
7726
|
}
|
|
7447
|
-
var prefer_non_nullable_collection_default =
|
|
7727
|
+
var prefer_non_nullable_collection_default = ESLintUtils51.RuleCreator(
|
|
7448
7728
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
7449
7729
|
)({
|
|
7450
7730
|
name: "prefer-non-nullable-collection",
|
|
@@ -7467,7 +7747,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7467
7747
|
function checkOptionalProperty(node) {
|
|
7468
7748
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
7469
7749
|
if (annotation === void 0) return;
|
|
7470
|
-
if (annotation.type !==
|
|
7750
|
+
if (annotation.type !== AST_NODE_TYPES37.TSUnionType || !isNullableArrayOnly(annotation)) {
|
|
7471
7751
|
return;
|
|
7472
7752
|
}
|
|
7473
7753
|
context.report({
|
|
@@ -7480,7 +7760,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7480
7760
|
TSPropertySignature: checkOptionalProperty,
|
|
7481
7761
|
PropertyDefinition: checkOptionalProperty,
|
|
7482
7762
|
TSTypeAliasDeclaration(node) {
|
|
7483
|
-
if (node.typeAnnotation.type !==
|
|
7763
|
+
if (node.typeAnnotation.type !== AST_NODE_TYPES37.TSUnionType) return;
|
|
7484
7764
|
if (!isNullableArrayOnly(node.typeAnnotation)) return;
|
|
7485
7765
|
context.report({
|
|
7486
7766
|
node,
|
|
@@ -7492,8 +7772,372 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7492
7772
|
}
|
|
7493
7773
|
});
|
|
7494
7774
|
|
|
7775
|
+
// src/rules/primary-export-file-name.ts
|
|
7776
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES38, ESLintUtils as ESLintUtils52 } from "@typescript-eslint/utils";
|
|
7777
|
+
var CONVENTIONAL_BUCKET_EXPORTS2 = /* @__PURE__ */ new Set(["cn"]);
|
|
7778
|
+
var GENERIC_ENTRYPOINTS = /* @__PURE__ */ new Set(["main", "run", "cli", "setup", "teardown", "execute"]);
|
|
7779
|
+
var ACRONYM_OVERRIDES2 = [
|
|
7780
|
+
[/OAuth/g, "Oauth"],
|
|
7781
|
+
[/GraphQL/g, "Graphql"],
|
|
7782
|
+
[/gRPC/g, "Grpc"]
|
|
7783
|
+
];
|
|
7784
|
+
var CAMEL_BOUNDARY_RE2 = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
|
|
7785
|
+
var basename2 = (filename) => filename.split(/[/\\]/).pop() ?? filename;
|
|
7786
|
+
var stemOf2 = (base) => base.replace(/\.(test|spec|config|d|stories)\.[cm]?[jt]sx?$/i, "").replace(/\.[cm]?[jt]sx?$/i, "");
|
|
7787
|
+
var kebabCase3 = (name) => {
|
|
7788
|
+
let normalized = name;
|
|
7789
|
+
for (const [pattern, replacement] of ACRONYM_OVERRIDES2) {
|
|
7790
|
+
normalized = normalized.replace(pattern, replacement);
|
|
7791
|
+
}
|
|
7792
|
+
return normalized.replace(CAMEL_BOUNDARY_RE2, "-").toLowerCase();
|
|
7793
|
+
};
|
|
7794
|
+
var isFunctionOrClass = (node) => node.type === AST_NODE_TYPES38.ArrowFunctionExpression || node.type === AST_NODE_TYPES38.FunctionExpression;
|
|
7795
|
+
var findPrimaryExport = (body) => {
|
|
7796
|
+
let exportCount = 0;
|
|
7797
|
+
let primaryCandidate = null;
|
|
7798
|
+
for (const statement of body) {
|
|
7799
|
+
if (statement.type === AST_NODE_TYPES38.ExportAllDeclaration) {
|
|
7800
|
+
return null;
|
|
7801
|
+
}
|
|
7802
|
+
if (statement.type === AST_NODE_TYPES38.ExportDefaultDeclaration) {
|
|
7803
|
+
exportCount += 1;
|
|
7804
|
+
const decl = statement.declaration;
|
|
7805
|
+
if ((decl.type === AST_NODE_TYPES38.FunctionDeclaration || decl.type === AST_NODE_TYPES38.ClassDeclaration) && decl.id !== null) {
|
|
7806
|
+
primaryCandidate = { name: decl.id.name, node: statement, isDefault: true };
|
|
7807
|
+
} else if (decl.type === AST_NODE_TYPES38.Identifier) {
|
|
7808
|
+
primaryCandidate = { name: decl.name, node: statement, isDefault: true };
|
|
7809
|
+
}
|
|
7810
|
+
} else if (statement.type === AST_NODE_TYPES38.ExportNamedDeclaration) {
|
|
7811
|
+
if (statement.source !== null) {
|
|
7812
|
+
return null;
|
|
7813
|
+
}
|
|
7814
|
+
const decl = statement.declaration;
|
|
7815
|
+
if (decl === null) {
|
|
7816
|
+
exportCount += statement.specifiers.length;
|
|
7817
|
+
if (statement.specifiers.length === 1 && primaryCandidate === null) {
|
|
7818
|
+
const spec = statement.specifiers[0];
|
|
7819
|
+
if (spec && spec.exported.type === AST_NODE_TYPES38.Identifier) {
|
|
7820
|
+
primaryCandidate = { name: spec.exported.name, node: statement, isDefault: false };
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7823
|
+
} else if (decl.type === AST_NODE_TYPES38.FunctionDeclaration || decl.type === AST_NODE_TYPES38.ClassDeclaration) {
|
|
7824
|
+
if (decl.id !== null) {
|
|
7825
|
+
exportCount += 1;
|
|
7826
|
+
if (primaryCandidate === null) {
|
|
7827
|
+
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
7828
|
+
}
|
|
7829
|
+
}
|
|
7830
|
+
} else if (decl.type === AST_NODE_TYPES38.VariableDeclaration) {
|
|
7831
|
+
for (const declarator of decl.declarations) {
|
|
7832
|
+
if (declarator.id.type === AST_NODE_TYPES38.Identifier) {
|
|
7833
|
+
exportCount += 1;
|
|
7834
|
+
if (primaryCandidate === null && declarator.init && isFunctionOrClass(declarator.init)) {
|
|
7835
|
+
primaryCandidate = { name: declarator.id.name, node: statement, isDefault: false };
|
|
7836
|
+
}
|
|
7837
|
+
}
|
|
7838
|
+
}
|
|
7839
|
+
} else if (decl.type === AST_NODE_TYPES38.TSTypeAliasDeclaration || decl.type === AST_NODE_TYPES38.TSInterfaceDeclaration) {
|
|
7840
|
+
exportCount += 1;
|
|
7841
|
+
if (primaryCandidate === null) {
|
|
7842
|
+
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
}
|
|
7846
|
+
}
|
|
7847
|
+
if (primaryCandidate === null || exportCount > 2) {
|
|
7848
|
+
return null;
|
|
7849
|
+
}
|
|
7850
|
+
return { ...primaryCandidate, count: exportCount };
|
|
7851
|
+
};
|
|
7852
|
+
var primary_export_file_name_default = ESLintUtils52.RuleCreator(
|
|
7853
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7854
|
+
)({
|
|
7855
|
+
name: "primary-export-file-name",
|
|
7856
|
+
meta: {
|
|
7857
|
+
type: "suggestion",
|
|
7858
|
+
docs: {
|
|
7859
|
+
description: "Enforce semantic naming alignment: a file with a single primary export must be named after that export."
|
|
7860
|
+
},
|
|
7861
|
+
schema: [],
|
|
7862
|
+
messages: {
|
|
7863
|
+
primaryExportMismatch: "Module stem '{{stem}}' does not match its primary export '{{name}}' \u2014 rename the file to '{{expected}}{{ext}}' to describe its responsibility."
|
|
7864
|
+
}
|
|
7865
|
+
},
|
|
7866
|
+
defaultOptions: [],
|
|
7867
|
+
create(context) {
|
|
7868
|
+
const base = basename2(context.filename);
|
|
7869
|
+
if (base.endsWith(".d.ts") || base.startsWith("index.") || base.startsWith("_")) return {};
|
|
7870
|
+
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
7871
|
+
const stem3 = stemOf2(base);
|
|
7872
|
+
if (stem3 === "page" || stem3 === "layout" || stem3 === "loading" || stem3 === "error" || stem3 === "not-found" || stem3 === "route" || stem3 === "__root" || stem3 === "config" || stem3 === "constants" || stem3 === "types" || stem3.startsWith("$") || stem3.startsWith("[")) {
|
|
7873
|
+
return {};
|
|
7874
|
+
}
|
|
7875
|
+
return {
|
|
7876
|
+
Program(node) {
|
|
7877
|
+
const primary = findPrimaryExport(node.body);
|
|
7878
|
+
if (primary === null) return;
|
|
7879
|
+
if (CONVENTIONAL_BUCKET_EXPORTS2.has(primary.name) || GENERIC_ENTRYPOINTS.has(primary.name)) return;
|
|
7880
|
+
const expectedStem = kebabCase3(primary.name);
|
|
7881
|
+
if (stem3 === expectedStem) return;
|
|
7882
|
+
const ext = base.endsWith(".tsx") ? ".tsx" : ".ts";
|
|
7883
|
+
context.report({
|
|
7884
|
+
node: primary.node,
|
|
7885
|
+
messageId: "primaryExportMismatch",
|
|
7886
|
+
data: { stem: stem3, name: primary.name, expected: expectedStem, ext }
|
|
7887
|
+
});
|
|
7888
|
+
}
|
|
7889
|
+
};
|
|
7890
|
+
}
|
|
7891
|
+
});
|
|
7892
|
+
|
|
7893
|
+
// src/rules/no-implicit-attribute-access.ts
|
|
7894
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES39, ESLintUtils as ESLintUtils53 } from "@typescript-eslint/utils";
|
|
7895
|
+
var EXCLUDED_BASES = /* @__PURE__ */ new Set([
|
|
7896
|
+
"environ",
|
|
7897
|
+
"headers",
|
|
7898
|
+
"cookies",
|
|
7899
|
+
"session",
|
|
7900
|
+
"redis",
|
|
7901
|
+
"cache",
|
|
7902
|
+
"state",
|
|
7903
|
+
"config",
|
|
7904
|
+
"env",
|
|
7905
|
+
"process",
|
|
7906
|
+
"localStorage",
|
|
7907
|
+
"sessionStorage"
|
|
7908
|
+
]);
|
|
7909
|
+
function getBaseName(node) {
|
|
7910
|
+
if (node.type === AST_NODE_TYPES39.Identifier) {
|
|
7911
|
+
return node.name;
|
|
7912
|
+
}
|
|
7913
|
+
if (node.type === AST_NODE_TYPES39.MemberExpression && node.property.type === AST_NODE_TYPES39.Identifier) {
|
|
7914
|
+
return node.property.name;
|
|
7915
|
+
}
|
|
7916
|
+
return null;
|
|
7917
|
+
}
|
|
7918
|
+
var no_implicit_attribute_access_default = ESLintUtils53.RuleCreator(
|
|
7919
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7920
|
+
)({
|
|
7921
|
+
name: "no-implicit-attribute-access",
|
|
7922
|
+
meta: {
|
|
7923
|
+
type: "problem",
|
|
7924
|
+
docs: {
|
|
7925
|
+
description: "Disallow imperative dictionary access with string literals; use declarative Zod schemas."
|
|
7926
|
+
},
|
|
7927
|
+
schema: [],
|
|
7928
|
+
messages: {
|
|
7929
|
+
noImplicitAttributeAccess: "Imperative lookup for '{{key}}' \u2014 if the key is known, parse the object declaratively with a Zod schema instead."
|
|
7930
|
+
}
|
|
7931
|
+
},
|
|
7932
|
+
defaultOptions: [],
|
|
7933
|
+
create(context) {
|
|
7934
|
+
return {
|
|
7935
|
+
MemberExpression(node) {
|
|
7936
|
+
if (!node.computed) {
|
|
7937
|
+
return;
|
|
7938
|
+
}
|
|
7939
|
+
if (node.property.type === AST_NODE_TYPES39.Literal && typeof node.property.value === "string") {
|
|
7940
|
+
const baseName = getBaseName(node.object);
|
|
7941
|
+
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7942
|
+
context.report({
|
|
7943
|
+
node,
|
|
7944
|
+
messageId: "noImplicitAttributeAccess",
|
|
7945
|
+
data: { key: node.property.value }
|
|
7946
|
+
});
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
},
|
|
7950
|
+
CallExpression(node) {
|
|
7951
|
+
const callee = node.callee;
|
|
7952
|
+
if (callee.type === AST_NODE_TYPES39.MemberExpression) {
|
|
7953
|
+
const method = callee.property.type === AST_NODE_TYPES39.Identifier ? callee.property.name : null;
|
|
7954
|
+
if (method === "get") {
|
|
7955
|
+
const arg = node.arguments[0];
|
|
7956
|
+
if (arg && arg.type === AST_NODE_TYPES39.Literal && typeof arg.value === "string") {
|
|
7957
|
+
const baseName = getBaseName(callee.object);
|
|
7958
|
+
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7959
|
+
context.report({
|
|
7960
|
+
node,
|
|
7961
|
+
messageId: "noImplicitAttributeAccess",
|
|
7962
|
+
data: { key: arg.value }
|
|
7963
|
+
});
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
}
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
};
|
|
7970
|
+
}
|
|
7971
|
+
});
|
|
7972
|
+
|
|
7973
|
+
// src/rules/strict-test-assertions.ts
|
|
7974
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES40, ESLintUtils as ESLintUtils54 } from "@typescript-eslint/utils";
|
|
7975
|
+
var strict_test_assertions_default = ESLintUtils54.RuleCreator.withoutDocs({
|
|
7976
|
+
meta: {
|
|
7977
|
+
type: "suggestion",
|
|
7978
|
+
docs: {
|
|
7979
|
+
description: "Replace multiple sequential assertions with a single toMatchObject or toStrictEqual"
|
|
7980
|
+
},
|
|
7981
|
+
fixable: "code",
|
|
7982
|
+
messages: {
|
|
7983
|
+
combineAssertions: "Combine multiple sequential assertions on the same object into a single toMatchObject or toStrictEqual"
|
|
7984
|
+
},
|
|
7985
|
+
schema: []
|
|
7986
|
+
},
|
|
7987
|
+
defaultOptions: [],
|
|
7988
|
+
create(context) {
|
|
7989
|
+
function checkBody(body) {
|
|
7990
|
+
let currentObject = null;
|
|
7991
|
+
let sequence = [];
|
|
7992
|
+
function getExpectObject(expr) {
|
|
7993
|
+
if (expr.type === AST_NODE_TYPES40.CallExpression && expr.callee.type === AST_NODE_TYPES40.MemberExpression && expr.callee.object.type === AST_NODE_TYPES40.CallExpression && expr.callee.object.callee.type === AST_NODE_TYPES40.Identifier && expr.callee.object.callee.name === "expect" && expr.callee.object.arguments.length === 1) {
|
|
7994
|
+
const arg = expr.callee.object.arguments.at(0);
|
|
7995
|
+
if (arg?.type === AST_NODE_TYPES40.MemberExpression) {
|
|
7996
|
+
return arg.object;
|
|
7997
|
+
}
|
|
7998
|
+
}
|
|
7999
|
+
return null;
|
|
8000
|
+
}
|
|
8001
|
+
function reportSequence() {
|
|
8002
|
+
const first = sequence.at(0);
|
|
8003
|
+
if (sequence.length > 1 && first) {
|
|
8004
|
+
context.report({
|
|
8005
|
+
node: first,
|
|
8006
|
+
messageId: "combineAssertions",
|
|
8007
|
+
fix(fixer) {
|
|
8008
|
+
if (!currentObject) return null;
|
|
8009
|
+
const objectText = context.sourceCode.getText(currentObject);
|
|
8010
|
+
const props = sequence.map((stmt) => {
|
|
8011
|
+
if (stmt.expression.type !== AST_NODE_TYPES40.CallExpression || stmt.expression.callee.type !== AST_NODE_TYPES40.MemberExpression || stmt.expression.callee.object.type !== AST_NODE_TYPES40.CallExpression) {
|
|
8012
|
+
return null;
|
|
8013
|
+
}
|
|
8014
|
+
const actual = stmt.expression.callee.object.arguments.at(0);
|
|
8015
|
+
const expected = stmt.expression.arguments.at(0);
|
|
8016
|
+
if (actual?.type === AST_NODE_TYPES40.MemberExpression && actual.property.type === AST_NODE_TYPES40.Identifier && expected) {
|
|
8017
|
+
const propName2 = actual.property.name;
|
|
8018
|
+
const valText = context.sourceCode.getText(expected);
|
|
8019
|
+
return `${propName2}: ${valText}`;
|
|
8020
|
+
}
|
|
8021
|
+
return null;
|
|
8022
|
+
});
|
|
8023
|
+
if (props.some((p) => p === null)) return null;
|
|
8024
|
+
const replacement = `expect(${objectText}).toMatchObject({ ${props.join(", ")} });`;
|
|
8025
|
+
return [
|
|
8026
|
+
fixer.replaceText(first, replacement),
|
|
8027
|
+
...sequence.slice(1).map((stmt) => fixer.remove(stmt))
|
|
8028
|
+
];
|
|
8029
|
+
}
|
|
8030
|
+
});
|
|
8031
|
+
}
|
|
8032
|
+
}
|
|
8033
|
+
for (const statement of body) {
|
|
8034
|
+
if (statement.type === AST_NODE_TYPES40.ExpressionStatement) {
|
|
8035
|
+
const obj = getExpectObject(statement.expression);
|
|
8036
|
+
if (obj && currentObject && context.sourceCode.getText(obj) === context.sourceCode.getText(currentObject)) {
|
|
8037
|
+
sequence.push(statement);
|
|
8038
|
+
} else {
|
|
8039
|
+
reportSequence();
|
|
8040
|
+
if (obj) {
|
|
8041
|
+
currentObject = obj;
|
|
8042
|
+
sequence = [statement];
|
|
8043
|
+
} else {
|
|
8044
|
+
currentObject = null;
|
|
8045
|
+
sequence = [];
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
8048
|
+
} else {
|
|
8049
|
+
reportSequence();
|
|
8050
|
+
currentObject = null;
|
|
8051
|
+
sequence = [];
|
|
8052
|
+
}
|
|
8053
|
+
}
|
|
8054
|
+
reportSequence();
|
|
8055
|
+
}
|
|
8056
|
+
return {
|
|
8057
|
+
BlockStatement(node) {
|
|
8058
|
+
checkBody(node.body);
|
|
8059
|
+
},
|
|
8060
|
+
Program(node) {
|
|
8061
|
+
checkBody(node.body);
|
|
8062
|
+
}
|
|
8063
|
+
};
|
|
8064
|
+
}
|
|
8065
|
+
});
|
|
8066
|
+
|
|
8067
|
+
// src/rules/no-async-callback-in-waitfor.ts
|
|
8068
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES41, ESLintUtils as ESLintUtils55 } from "@typescript-eslint/utils";
|
|
8069
|
+
var no_async_callback_in_waitfor_default = ESLintUtils55.RuleCreator(
|
|
8070
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
8071
|
+
)({
|
|
8072
|
+
name: "no-async-callback-in-waitfor",
|
|
8073
|
+
meta: {
|
|
8074
|
+
type: "problem",
|
|
8075
|
+
docs: {
|
|
8076
|
+
description: "Disallow async callbacks in `waitFor` to prevent swallowed promise rejections."
|
|
8077
|
+
},
|
|
8078
|
+
schema: [],
|
|
8079
|
+
messages: {
|
|
8080
|
+
noAsyncCallbackInWaitFor: "The callback to `waitFor` should not be async. It expects synchronous assertions and runs the callback repeatedly."
|
|
8081
|
+
}
|
|
8082
|
+
},
|
|
8083
|
+
defaultOptions: [],
|
|
8084
|
+
create(context) {
|
|
8085
|
+
if (!isTestFile(context.filename)) {
|
|
8086
|
+
return {};
|
|
8087
|
+
}
|
|
8088
|
+
return {
|
|
8089
|
+
CallExpression(node) {
|
|
8090
|
+
if (node.callee.type === AST_NODE_TYPES41.Identifier && node.callee.name === "waitFor") {
|
|
8091
|
+
const callback = node.arguments[0];
|
|
8092
|
+
if (callback && (callback.type === AST_NODE_TYPES41.ArrowFunctionExpression || callback.type === AST_NODE_TYPES41.FunctionExpression) && callback.async) {
|
|
8093
|
+
context.report({
|
|
8094
|
+
node: callback,
|
|
8095
|
+
messageId: "noAsyncCallbackInWaitFor"
|
|
8096
|
+
});
|
|
8097
|
+
}
|
|
8098
|
+
}
|
|
8099
|
+
}
|
|
8100
|
+
};
|
|
8101
|
+
}
|
|
8102
|
+
});
|
|
8103
|
+
|
|
8104
|
+
// src/rules/prefer-setup-file-mocks.ts
|
|
8105
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES42, ESLintUtils as ESLintUtils56 } from "@typescript-eslint/utils";
|
|
8106
|
+
var prefer_setup_file_mocks_default = ESLintUtils56.RuleCreator(
|
|
8107
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
8108
|
+
)({
|
|
8109
|
+
name: "prefer-setup-file-mocks",
|
|
8110
|
+
meta: {
|
|
8111
|
+
type: "suggestion",
|
|
8112
|
+
docs: {
|
|
8113
|
+
description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
|
|
8114
|
+
},
|
|
8115
|
+
schema: [],
|
|
8116
|
+
messages: {
|
|
8117
|
+
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."
|
|
8118
|
+
}
|
|
8119
|
+
},
|
|
8120
|
+
defaultOptions: [],
|
|
8121
|
+
create(context) {
|
|
8122
|
+
if (!isTestFile(context.filename)) {
|
|
8123
|
+
return {};
|
|
8124
|
+
}
|
|
8125
|
+
return {
|
|
8126
|
+
CallExpression(node) {
|
|
8127
|
+
if (node.callee.type === AST_NODE_TYPES42.MemberExpression && node.callee.object.type === AST_NODE_TYPES42.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === AST_NODE_TYPES42.Identifier && node.callee.property.name === "mock") {
|
|
8128
|
+
context.report({
|
|
8129
|
+
node,
|
|
8130
|
+
messageId: "preferSetupFileMocks"
|
|
8131
|
+
});
|
|
8132
|
+
}
|
|
8133
|
+
}
|
|
8134
|
+
};
|
|
8135
|
+
}
|
|
8136
|
+
});
|
|
8137
|
+
|
|
7495
8138
|
// src/index.ts
|
|
7496
8139
|
var rules = {
|
|
8140
|
+
"ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
|
|
7497
8141
|
"enforce-file-structure": enforce_file_structure_default,
|
|
7498
8142
|
"no-client-side-data-fetching": no_client_side_data_fetching_default,
|
|
7499
8143
|
"no-comment-cruft": no_comment_cruft_default,
|
|
@@ -7518,8 +8162,11 @@ var rules = {
|
|
|
7518
8162
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
7519
8163
|
"no-secret-in-log": no_secret_in_log_default,
|
|
7520
8164
|
"no-unsafe-cast": no_unsafe_cast_default,
|
|
8165
|
+
"no-unsafe-mock-casting": no_unsafe_mock_casting_default,
|
|
7521
8166
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
8167
|
+
"prefer-zod-enum": prefer_zod_enum_default,
|
|
7522
8168
|
"single-public-export": single_public_export_default,
|
|
8169
|
+
"primary-export-file-name": primary_export_file_name_default,
|
|
7523
8170
|
"no-silent-promise-catch": no_silent_promise_catch_default,
|
|
7524
8171
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
7525
8172
|
"require-schema-validate-search": require_schema_validate_search_default,
|
|
@@ -7528,6 +8175,7 @@ var rules = {
|
|
|
7528
8175
|
"no-repeated-string-literal": no_repeated_string_literal_default,
|
|
7529
8176
|
"no-select-star": no_select_star_default,
|
|
7530
8177
|
"no-sleep-in-test-body": no_sleep_in_test_body_default,
|
|
8178
|
+
"no-conditional-in-test": no_conditional_in_test_default,
|
|
7531
8179
|
"prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
|
|
7532
8180
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
7533
8181
|
"no-dynamic-sql": no_dynamic_sql_default,
|
|
@@ -7540,12 +8188,16 @@ var rules = {
|
|
|
7540
8188
|
"trailing-value-narration": trailing_value_narration_default,
|
|
7541
8189
|
"no-tautological-expect": no_tautological_expect_default,
|
|
7542
8190
|
"require-interface-for-injected-service": require_interface_for_injected_service_default,
|
|
7543
|
-
"
|
|
8191
|
+
"strict-test-assertions": strict_test_assertions_default,
|
|
8192
|
+
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
8193
|
+
"no-implicit-attribute-access": no_implicit_attribute_access_default,
|
|
8194
|
+
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
|
|
8195
|
+
"prefer-setup-file-mocks": prefer_setup_file_mocks_default
|
|
7544
8196
|
};
|
|
7545
8197
|
var plugin = {
|
|
7546
8198
|
meta: {
|
|
7547
8199
|
name: "@sarj/eslint-plugin",
|
|
7548
|
-
version: "2.
|
|
8200
|
+
version: "2.17.0"
|
|
7549
8201
|
},
|
|
7550
8202
|
rules,
|
|
7551
8203
|
configs: {
|
|
@@ -7555,6 +8207,7 @@ var plugin = {
|
|
|
7555
8207
|
"@sarj/zod-naming-convention": "warn",
|
|
7556
8208
|
"@sarj/require-assert-never": "error",
|
|
7557
8209
|
"@sarj/require-zod-form-validation": "error",
|
|
8210
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7558
8211
|
"@sarj/enforce-file-structure": "warn",
|
|
7559
8212
|
"@sarj/no-client-side-data-fetching": "warn",
|
|
7560
8213
|
"@sarj/prefer-server-actions": "warn",
|
|
@@ -7579,8 +8232,11 @@ var plugin = {
|
|
|
7579
8232
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
7580
8233
|
"@sarj/no-secret-in-log": "warn",
|
|
7581
8234
|
"@sarj/no-unsafe-cast": "warn",
|
|
8235
|
+
"@sarj/no-unsafe-mock-casting": "warn",
|
|
7582
8236
|
"@sarj/single-public-export": "warn",
|
|
8237
|
+
"@sarj/primary-export-file-name": "warn",
|
|
7583
8238
|
"@sarj/prefer-string-literal-union": "warn",
|
|
8239
|
+
"@sarj/prefer-zod-enum": "warn",
|
|
7584
8240
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7585
8241
|
"@sarj/require-fetch-timeout": "warn",
|
|
7586
8242
|
"@sarj/no-silent-promise-catch": "warn",
|
|
@@ -7594,6 +8250,7 @@ var plugin = {
|
|
|
7594
8250
|
"@sarj/no-offset-pagination": "warn",
|
|
7595
8251
|
"@sarj/no-select-star": "warn",
|
|
7596
8252
|
"@sarj/no-sleep-in-test-body": "warn",
|
|
8253
|
+
"@sarj/no-conditional-in-test": "warn",
|
|
7597
8254
|
"@sarj/no-repeated-string-literal": "warn",
|
|
7598
8255
|
"@sarj/no-positional-tuple-return": "warn",
|
|
7599
8256
|
// Injection guard — low FP, applies to any repo touching SQL.
|
|
@@ -7629,7 +8286,10 @@ var plugin = {
|
|
|
7629
8286
|
// mocking. 11-repo sweep: 229 exported classes, 82% already carry a
|
|
7630
8287
|
// port, 29 fire, 28 of them true positives.
|
|
7631
8288
|
"@sarj/require-interface-for-injected-service": "warn",
|
|
7632
|
-
"@sarj/prefer-non-nullable-collection": "warn"
|
|
8289
|
+
"@sarj/prefer-non-nullable-collection": "warn",
|
|
8290
|
+
"@sarj/no-implicit-attribute-access": "warn",
|
|
8291
|
+
"@sarj/no-async-callback-in-waitfor": "warn",
|
|
8292
|
+
"@sarj/prefer-setup-file-mocks": "warn"
|
|
7633
8293
|
}
|
|
7634
8294
|
},
|
|
7635
8295
|
strict: {
|
|
@@ -7638,6 +8298,7 @@ var plugin = {
|
|
|
7638
8298
|
"@sarj/zod-naming-convention": "error",
|
|
7639
8299
|
"@sarj/require-assert-never": "error",
|
|
7640
8300
|
"@sarj/require-zod-form-validation": "error",
|
|
8301
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7641
8302
|
"@sarj/enforce-file-structure": "error",
|
|
7642
8303
|
"@sarj/no-raw-env": "error",
|
|
7643
8304
|
"@sarj/prefer-shadcn": "error",
|
|
@@ -7666,9 +8327,12 @@ var plugin = {
|
|
|
7666
8327
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
7667
8328
|
"@sarj/no-secret-in-log": "error",
|
|
7668
8329
|
"@sarj/no-unsafe-cast": "error",
|
|
8330
|
+
"@sarj/no-unsafe-mock-casting": "error",
|
|
7669
8331
|
"@sarj/single-public-export": "error",
|
|
8332
|
+
"@sarj/primary-export-file-name": "error",
|
|
7670
8333
|
// Promoted to error 2026-07-25 — strict means strict (user directive).
|
|
7671
8334
|
"@sarj/prefer-string-literal-union": "error",
|
|
8335
|
+
"@sarj/prefer-zod-enum": "error",
|
|
7672
8336
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7673
8337
|
"@sarj/require-fetch-timeout": "error",
|
|
7674
8338
|
"@sarj/no-silent-promise-catch": "error",
|
|
@@ -7679,6 +8343,7 @@ var plugin = {
|
|
|
7679
8343
|
"@sarj/no-offset-pagination": "error",
|
|
7680
8344
|
"@sarj/no-select-star": "error",
|
|
7681
8345
|
"@sarj/no-sleep-in-test-body": "error",
|
|
8346
|
+
"@sarj/no-conditional-in-test": "error",
|
|
7682
8347
|
"@sarj/no-repeated-string-literal": "error",
|
|
7683
8348
|
// API-shape advice rather than a runtime defect — a corpus sweep found its
|
|
7684
8349
|
// only hits are parser `[value, cursor]` returns, which are conventional.
|
|
@@ -7707,7 +8372,10 @@ var plugin = {
|
|
|
7707
8372
|
// / `prefer-library-fake` wave. The convention already exists in the
|
|
7708
8373
|
// corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
|
|
7709
8374
|
"@sarj/require-interface-for-injected-service": "error",
|
|
7710
|
-
"@sarj/prefer-non-nullable-collection": "error"
|
|
8375
|
+
"@sarj/prefer-non-nullable-collection": "error",
|
|
8376
|
+
"@sarj/no-implicit-attribute-access": "error",
|
|
8377
|
+
"@sarj/no-async-callback-in-waitfor": "error",
|
|
8378
|
+
"@sarj/prefer-setup-file-mocks": "error"
|
|
7711
8379
|
}
|
|
7712
8380
|
}
|
|
7713
8381
|
}
|