@sarj/eslint-plugin 2.16.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.cjs +872 -1040
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -31
- package/dist/index.d.ts +42 -31
- package/dist/index.js +811 -979
- 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";
|
|
@@ -611,7 +647,7 @@ function hasCommentedOutCode(texts, precedingProse) {
|
|
|
611
647
|
}
|
|
612
648
|
return false;
|
|
613
649
|
}
|
|
614
|
-
var no_comment_cruft_default =
|
|
650
|
+
var no_comment_cruft_default = ESLintUtils4.RuleCreator(
|
|
615
651
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
616
652
|
)({
|
|
617
653
|
name: "no-comment-cruft",
|
|
@@ -718,7 +754,7 @@ var no_comment_cruft_default = ESLintUtils3.RuleCreator(
|
|
|
718
754
|
});
|
|
719
755
|
|
|
720
756
|
// src/rules/no-enum.ts
|
|
721
|
-
import { ESLintUtils as
|
|
757
|
+
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
722
758
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
723
759
|
/[\\/]generated[\\/]/,
|
|
724
760
|
/[\\/]openapi-gen[\\/]/,
|
|
@@ -738,7 +774,7 @@ function hasGeneratedMarker(sourceText) {
|
|
|
738
774
|
const head = sourceText.slice(0, 1024);
|
|
739
775
|
return /@generated\b/.test(head);
|
|
740
776
|
}
|
|
741
|
-
var no_enum_default =
|
|
777
|
+
var no_enum_default = ESLintUtils5.RuleCreator(
|
|
742
778
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
743
779
|
)({
|
|
744
780
|
name: "no-enum",
|
|
@@ -789,7 +825,7 @@ var no_enum_default = ESLintUtils4.RuleCreator(
|
|
|
789
825
|
});
|
|
790
826
|
|
|
791
827
|
// src/rules/no-insecure-random-id.ts
|
|
792
|
-
import { ESLintUtils as
|
|
828
|
+
import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
|
|
793
829
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
794
830
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
795
831
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -930,7 +966,7 @@ function isConcatenatedIntoPathOrDomId(node) {
|
|
|
930
966
|
collectStaticStringParts(top, parts);
|
|
931
967
|
return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
|
|
932
968
|
}
|
|
933
|
-
var no_insecure_random_id_default =
|
|
969
|
+
var no_insecure_random_id_default = ESLintUtils6.RuleCreator(
|
|
934
970
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
935
971
|
)({
|
|
936
972
|
name: "no-insecure-random-id",
|
|
@@ -974,7 +1010,7 @@ var no_insecure_random_id_default = ESLintUtils5.RuleCreator(
|
|
|
974
1010
|
});
|
|
975
1011
|
|
|
976
1012
|
// src/rules/no-json-stringify-error.ts
|
|
977
|
-
import { ESLintUtils as
|
|
1013
|
+
import { ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
|
|
978
1014
|
var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
|
|
979
1015
|
var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
|
|
980
1016
|
var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
|
|
@@ -1108,7 +1144,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
1108
1144
|
function isJsonStringify(callee) {
|
|
1109
1145
|
return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
|
|
1110
1146
|
}
|
|
1111
|
-
var no_json_stringify_error_default =
|
|
1147
|
+
var no_json_stringify_error_default = ESLintUtils7.RuleCreator(
|
|
1112
1148
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1113
1149
|
)({
|
|
1114
1150
|
name: "no-json-stringify-error",
|
|
@@ -1158,7 +1194,7 @@ var no_json_stringify_error_default = ESLintUtils6.RuleCreator(
|
|
|
1158
1194
|
});
|
|
1159
1195
|
|
|
1160
1196
|
// src/rules/no-log-only-catch.ts
|
|
1161
|
-
import { ESLintUtils as
|
|
1197
|
+
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
1162
1198
|
|
|
1163
1199
|
// src/rules/_logging.ts
|
|
1164
1200
|
import "@typescript-eslint/utils";
|
|
@@ -1268,7 +1304,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
|
|
|
1268
1304
|
/\.spec\./,
|
|
1269
1305
|
/[\\/]__tests__[\\/]/
|
|
1270
1306
|
];
|
|
1271
|
-
var no_log_only_catch_default =
|
|
1307
|
+
var no_log_only_catch_default = ESLintUtils8.RuleCreator(
|
|
1272
1308
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1273
1309
|
)({
|
|
1274
1310
|
name: "no-log-only-catch",
|
|
@@ -1331,7 +1367,7 @@ var no_log_only_catch_default = ESLintUtils7.RuleCreator(
|
|
|
1331
1367
|
});
|
|
1332
1368
|
|
|
1333
1369
|
// src/rules/no-raw-env.ts
|
|
1334
|
-
import { ESLintUtils as
|
|
1370
|
+
import { ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
|
|
1335
1371
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1336
1372
|
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1337
1373
|
function isValidatedEnvBoundary(filename, sourceText) {
|
|
@@ -1369,7 +1405,7 @@ function isWholeEnvSpread(node) {
|
|
|
1369
1405
|
const parent = node.parent;
|
|
1370
1406
|
return parent.type === "SpreadElement" && parent.argument === node;
|
|
1371
1407
|
}
|
|
1372
|
-
var no_raw_env_default =
|
|
1408
|
+
var no_raw_env_default = ESLintUtils9.RuleCreator(
|
|
1373
1409
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1374
1410
|
)({
|
|
1375
1411
|
name: "no-raw-env",
|
|
@@ -1404,7 +1440,7 @@ var no_raw_env_default = ESLintUtils8.RuleCreator(
|
|
|
1404
1440
|
|
|
1405
1441
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
1406
1442
|
import {
|
|
1407
|
-
ESLintUtils as
|
|
1443
|
+
ESLintUtils as ESLintUtils10,
|
|
1408
1444
|
AST_NODE_TYPES as AST_NODE_TYPES5
|
|
1409
1445
|
} from "@typescript-eslint/utils";
|
|
1410
1446
|
function sentinelKind(arg) {
|
|
@@ -1709,7 +1745,7 @@ function isWithin(node, ancestor) {
|
|
|
1709
1745
|
}
|
|
1710
1746
|
return false;
|
|
1711
1747
|
}
|
|
1712
|
-
var no_sentinel_return_on_catch_default =
|
|
1748
|
+
var no_sentinel_return_on_catch_default = ESLintUtils10.RuleCreator(
|
|
1713
1749
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1714
1750
|
)({
|
|
1715
1751
|
name: "no-sentinel-return-on-catch",
|
|
@@ -1789,255 +1825,6 @@ var no_sentinel_return_on_catch_default = ESLintUtils9.RuleCreator(
|
|
|
1789
1825
|
}
|
|
1790
1826
|
});
|
|
1791
1827
|
|
|
1792
|
-
// src/rules/no-sequential-await.ts
|
|
1793
|
-
import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
1794
|
-
var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
|
|
1795
|
-
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;
|
|
1796
|
-
var BENCH_FILE_RE = /(^|[\\/])bench(marks?)?[\\/]|\.bench\.[cm]?[jt]sx?$/i;
|
|
1797
|
-
function isFunctionLike(node) {
|
|
1798
|
-
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
1799
|
-
}
|
|
1800
|
-
function isLoop(node) {
|
|
1801
|
-
return node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
|
|
1802
|
-
}
|
|
1803
|
-
function isNode2(value) {
|
|
1804
|
-
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
1805
|
-
}
|
|
1806
|
-
function visitScope(root, visit) {
|
|
1807
|
-
visit(root);
|
|
1808
|
-
for (const key of Object.keys(root)) {
|
|
1809
|
-
if (key === "parent") {
|
|
1810
|
-
continue;
|
|
1811
|
-
}
|
|
1812
|
-
const value = root[key];
|
|
1813
|
-
const children = Array.isArray(value) ? value : [value];
|
|
1814
|
-
for (const child of children) {
|
|
1815
|
-
if (isNode2(child) && !isFunctionLike(child) && !isLoop(child)) {
|
|
1816
|
-
visitScope(child, visit);
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
function collectAwaits(root) {
|
|
1822
|
-
const awaits = [];
|
|
1823
|
-
visitScope(root, (node) => {
|
|
1824
|
-
if (node.type === "AwaitExpression") {
|
|
1825
|
-
awaits.push(node);
|
|
1826
|
-
}
|
|
1827
|
-
});
|
|
1828
|
-
return awaits;
|
|
1829
|
-
}
|
|
1830
|
-
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
1831
|
-
function hasEarlyExit(root) {
|
|
1832
|
-
let found = false;
|
|
1833
|
-
visitScope(root, (node) => {
|
|
1834
|
-
if (node.type === "ReturnStatement" || node.type === "BreakStatement" || node.type === "ContinueStatement") {
|
|
1835
|
-
found = true;
|
|
1836
|
-
}
|
|
1837
|
-
});
|
|
1838
|
-
return found;
|
|
1839
|
-
}
|
|
1840
|
-
var TIMER_HELPER_RE = /^(sleep|timeout|delay|wait|pause|tick)$/i;
|
|
1841
|
-
function calleeName2(callee) {
|
|
1842
|
-
if (callee.type === "Identifier") return callee.name;
|
|
1843
|
-
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier") {
|
|
1844
|
-
return callee.property.name;
|
|
1845
|
-
}
|
|
1846
|
-
return null;
|
|
1847
|
-
}
|
|
1848
|
-
function isTimerYield(node) {
|
|
1849
|
-
const arg = node.argument;
|
|
1850
|
-
if (arg.type === "NewExpression" && arg.callee.type === "Identifier" && arg.callee.name === "Promise") {
|
|
1851
|
-
return true;
|
|
1852
|
-
}
|
|
1853
|
-
if (arg.type === "CallExpression") {
|
|
1854
|
-
if (arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.object.type === "Identifier" && arg.callee.object.name === "Promise" && arg.callee.property.type === "Identifier" && (arg.callee.property.name === "resolve" || arg.callee.property.name === "reject")) {
|
|
1855
|
-
return true;
|
|
1856
|
-
}
|
|
1857
|
-
const name = calleeName2(arg.callee);
|
|
1858
|
-
return name !== null && TIMER_HELPER_RE.test(name);
|
|
1859
|
-
}
|
|
1860
|
-
return false;
|
|
1861
|
-
}
|
|
1862
|
-
var QUEUE_DRAIN_METHODS = /^(shift|pop|dequeue|next|poll)$/;
|
|
1863
|
-
function isQueueDrain(node) {
|
|
1864
|
-
const arg = node.argument;
|
|
1865
|
-
return arg.type === "CallExpression" && arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.property.type === "Identifier" && QUEUE_DRAIN_METHODS.test(arg.callee.property.name);
|
|
1866
|
-
}
|
|
1867
|
-
function hasAssertion(root) {
|
|
1868
|
-
let found = false;
|
|
1869
|
-
visitScope(root, (node) => {
|
|
1870
|
-
if (node.type !== "CallExpression") {
|
|
1871
|
-
return;
|
|
1872
|
-
}
|
|
1873
|
-
let callee = node.callee;
|
|
1874
|
-
while (callee.type === "MemberExpression") {
|
|
1875
|
-
callee = callee.object;
|
|
1876
|
-
}
|
|
1877
|
-
if (callee.type === "CallExpression") {
|
|
1878
|
-
callee = callee.callee;
|
|
1879
|
-
}
|
|
1880
|
-
if (callee.type === "Identifier" && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
1881
|
-
found = true;
|
|
1882
|
-
}
|
|
1883
|
-
});
|
|
1884
|
-
return found;
|
|
1885
|
-
}
|
|
1886
|
-
function referencesName(root, name) {
|
|
1887
|
-
let found = false;
|
|
1888
|
-
visitScope(root, (node) => {
|
|
1889
|
-
if (node.type === "Identifier" && node.name === name) {
|
|
1890
|
-
found = true;
|
|
1891
|
-
}
|
|
1892
|
-
});
|
|
1893
|
-
return found;
|
|
1894
|
-
}
|
|
1895
|
-
function isThreadedAccumulator(node) {
|
|
1896
|
-
const parent = node.parent;
|
|
1897
|
-
let target = null;
|
|
1898
|
-
if (parent.type === "AssignmentExpression" && parent.operator === "=" && parent.right === node && parent.left.type === "Identifier") {
|
|
1899
|
-
target = parent.left.name;
|
|
1900
|
-
} else if (parent.type === "VariableDeclarator" && parent.init === node && parent.id.type === "Identifier") {
|
|
1901
|
-
target = parent.id.name;
|
|
1902
|
-
}
|
|
1903
|
-
if (target === null) {
|
|
1904
|
-
return false;
|
|
1905
|
-
}
|
|
1906
|
-
return referencesName(node.argument, target);
|
|
1907
|
-
}
|
|
1908
|
-
function namesReadBy(test) {
|
|
1909
|
-
const names = /* @__PURE__ */ new Set();
|
|
1910
|
-
visitScope(test, (node) => {
|
|
1911
|
-
if (node.type === "Identifier") {
|
|
1912
|
-
names.add(node.name);
|
|
1913
|
-
}
|
|
1914
|
-
});
|
|
1915
|
-
return names;
|
|
1916
|
-
}
|
|
1917
|
-
function testStateIsAssignedInBody(test, body) {
|
|
1918
|
-
const testNames = namesReadBy(test);
|
|
1919
|
-
if (testNames.size === 0) {
|
|
1920
|
-
return false;
|
|
1921
|
-
}
|
|
1922
|
-
let found = false;
|
|
1923
|
-
visitScope(body, (node) => {
|
|
1924
|
-
if (node.type === "AssignmentExpression" && node.operator === "=" && node.left.type === "Identifier" && testNames.has(node.left.name)) {
|
|
1925
|
-
found = true;
|
|
1926
|
-
}
|
|
1927
|
-
});
|
|
1928
|
-
return found;
|
|
1929
|
-
}
|
|
1930
|
-
function shouldReport(awaits, earlyExit, iterableText, asserts = false) {
|
|
1931
|
-
if (awaits.length === 0) {
|
|
1932
|
-
return false;
|
|
1933
|
-
}
|
|
1934
|
-
if (earlyExit) {
|
|
1935
|
-
return false;
|
|
1936
|
-
}
|
|
1937
|
-
if (asserts) {
|
|
1938
|
-
return false;
|
|
1939
|
-
}
|
|
1940
|
-
if (iterableText !== null && SEQUENTIAL_ITERABLE_HINT.test(iterableText)) {
|
|
1941
|
-
return false;
|
|
1942
|
-
}
|
|
1943
|
-
return awaits.some(
|
|
1944
|
-
(node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
|
|
1945
|
-
);
|
|
1946
|
-
}
|
|
1947
|
-
var no_sequential_await_default = ESLintUtils10.RuleCreator(
|
|
1948
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1949
|
-
)({
|
|
1950
|
-
name: "no-sequential-await",
|
|
1951
|
-
meta: {
|
|
1952
|
-
type: "problem",
|
|
1953
|
-
docs: {
|
|
1954
|
-
description: "Disallow serial `await` inside a loop; use `await Promise.all(...)` to run the operations concurrently."
|
|
1955
|
-
},
|
|
1956
|
-
schema: [],
|
|
1957
|
-
messages: {
|
|
1958
|
-
noSequentialAwait: "Avoid `await` inside a loop \u2014 it serializes I/O. Collect the promises and `await Promise.all(xs.map(async (x) => ...))` instead."
|
|
1959
|
-
}
|
|
1960
|
-
},
|
|
1961
|
-
defaultOptions: [],
|
|
1962
|
-
create(context) {
|
|
1963
|
-
if (isTestFile(context.filename) || BENCH_FILE_RE.test(context.filename)) {
|
|
1964
|
-
return {};
|
|
1965
|
-
}
|
|
1966
|
-
function loopParts(node) {
|
|
1967
|
-
if (node.type === "ForStatement") {
|
|
1968
|
-
return [node.body, node.test, node.update];
|
|
1969
|
-
}
|
|
1970
|
-
if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
|
|
1971
|
-
return [node.body];
|
|
1972
|
-
}
|
|
1973
|
-
return [node.body, node.test];
|
|
1974
|
-
}
|
|
1975
|
-
function iterableTextOf(node) {
|
|
1976
|
-
if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
|
|
1977
|
-
return context.sourceCode.getText(node.right);
|
|
1978
|
-
}
|
|
1979
|
-
return null;
|
|
1980
|
-
}
|
|
1981
|
-
function checkLoop(node) {
|
|
1982
|
-
if ((node.type === "WhileStatement" || node.type === "DoWhileStatement") && testStateIsAssignedInBody(node.test, node.body)) {
|
|
1983
|
-
return;
|
|
1984
|
-
}
|
|
1985
|
-
const awaits = [];
|
|
1986
|
-
let earlyExit = false;
|
|
1987
|
-
let asserts = false;
|
|
1988
|
-
for (const part of loopParts(node)) {
|
|
1989
|
-
if (part === null || isLoop(part)) {
|
|
1990
|
-
continue;
|
|
1991
|
-
}
|
|
1992
|
-
awaits.push(...collectAwaits(part));
|
|
1993
|
-
if (!earlyExit && hasEarlyExit(part)) {
|
|
1994
|
-
earlyExit = true;
|
|
1995
|
-
}
|
|
1996
|
-
if (!asserts && hasAssertion(part)) {
|
|
1997
|
-
asserts = true;
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
if (shouldReport(awaits, earlyExit, iterableTextOf(node), asserts)) {
|
|
2001
|
-
context.report({ node, messageId: "noSequentialAwait" });
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
return {
|
|
2005
|
-
ForStatement: checkLoop,
|
|
2006
|
-
ForInStatement: checkLoop,
|
|
2007
|
-
WhileStatement: checkLoop,
|
|
2008
|
-
DoWhileStatement: checkLoop,
|
|
2009
|
-
ForOfStatement(node) {
|
|
2010
|
-
if (node.await) {
|
|
2011
|
-
return;
|
|
2012
|
-
}
|
|
2013
|
-
checkLoop(node);
|
|
2014
|
-
},
|
|
2015
|
-
CallExpression(node) {
|
|
2016
|
-
const callee = node.callee;
|
|
2017
|
-
if (callee.type !== "MemberExpression" || callee.computed) {
|
|
2018
|
-
return;
|
|
2019
|
-
}
|
|
2020
|
-
if (callee.property.type !== "Identifier" || !ARRAY_ITERATION_METHODS.has(callee.property.name)) {
|
|
2021
|
-
return;
|
|
2022
|
-
}
|
|
2023
|
-
const callback = node.arguments[0];
|
|
2024
|
-
if (callback === void 0 || !isFunctionLike(callback) || !("async" in callback && callback.async)) {
|
|
2025
|
-
return;
|
|
2026
|
-
}
|
|
2027
|
-
if (callee.property.name !== "forEach" && node.parent.type !== "ExpressionStatement") {
|
|
2028
|
-
return;
|
|
2029
|
-
}
|
|
2030
|
-
const awaits = collectAwaits(callback.body);
|
|
2031
|
-
const earlyExit = hasEarlyExit(callback.body);
|
|
2032
|
-
const iterableText = context.sourceCode.getText(callee.object);
|
|
2033
|
-
if (shouldReport(awaits, earlyExit, iterableText, hasAssertion(callback.body))) {
|
|
2034
|
-
context.report({ node, messageId: "noSequentialAwait" });
|
|
2035
|
-
}
|
|
2036
|
-
}
|
|
2037
|
-
};
|
|
2038
|
-
}
|
|
2039
|
-
});
|
|
2040
|
-
|
|
2041
1828
|
// src/rules/no-string-concat-in-loop.ts
|
|
2042
1829
|
import { ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
2043
1830
|
var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2539,7 +2326,7 @@ var isLocalFileRead = (node) => {
|
|
|
2539
2326
|
visit(node);
|
|
2540
2327
|
return found;
|
|
2541
2328
|
};
|
|
2542
|
-
var
|
|
2329
|
+
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
2543
2330
|
var isInsideAssertion = (node) => {
|
|
2544
2331
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
2545
2332
|
if (current.type !== AST_NODE_TYPES8.CallExpression) continue;
|
|
@@ -2550,7 +2337,7 @@ var isInsideAssertion = (node) => {
|
|
|
2550
2337
|
if (callee.type === AST_NODE_TYPES8.CallExpression) {
|
|
2551
2338
|
callee = callee.callee;
|
|
2552
2339
|
}
|
|
2553
|
-
if (callee.type === AST_NODE_TYPES8.Identifier &&
|
|
2340
|
+
if (callee.type === AST_NODE_TYPES8.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
2554
2341
|
return true;
|
|
2555
2342
|
}
|
|
2556
2343
|
}
|
|
@@ -2764,6 +2551,7 @@ var DETECTION_FILES = [
|
|
|
2764
2551
|
"src/styles/globals.css",
|
|
2765
2552
|
"styles/globals.css"
|
|
2766
2553
|
];
|
|
2554
|
+
var MAX_UPWARD_DEPTH = 8;
|
|
2767
2555
|
var semanticTokenCache = /* @__PURE__ */ new Map();
|
|
2768
2556
|
var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
|
|
2769
2557
|
"mask",
|
|
@@ -2818,9 +2606,15 @@ var isInsideIconFactoryPath = (node) => {
|
|
|
2818
2606
|
var hasSemanticTokenSystem = (filename) => {
|
|
2819
2607
|
let dir = dirname(filename);
|
|
2820
2608
|
const root = parse(dir).root;
|
|
2821
|
-
|
|
2609
|
+
const visited = [];
|
|
2610
|
+
let answer;
|
|
2611
|
+
for (let depth = 0; depth < MAX_UPWARD_DEPTH; depth += 1) {
|
|
2822
2612
|
const cached = semanticTokenCache.get(dir);
|
|
2823
|
-
if (cached !== void 0)
|
|
2613
|
+
if (cached !== void 0) {
|
|
2614
|
+
answer = cached;
|
|
2615
|
+
break;
|
|
2616
|
+
}
|
|
2617
|
+
visited.push(dir);
|
|
2824
2618
|
let found = false;
|
|
2825
2619
|
for (const rel of DETECTION_FILES) {
|
|
2826
2620
|
const candidate = join(dir, rel);
|
|
@@ -2837,11 +2631,19 @@ var hasSemanticTokenSystem = (filename) => {
|
|
|
2837
2631
|
} catch {
|
|
2838
2632
|
}
|
|
2839
2633
|
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2634
|
+
if (found) {
|
|
2635
|
+
answer = true;
|
|
2636
|
+
break;
|
|
2637
|
+
}
|
|
2638
|
+
if (dir === root) {
|
|
2639
|
+
answer = false;
|
|
2640
|
+
break;
|
|
2641
|
+
}
|
|
2842
2642
|
dir = dirname(dir);
|
|
2843
2643
|
}
|
|
2844
|
-
return false;
|
|
2644
|
+
if (answer === void 0) return false;
|
|
2645
|
+
for (const seen of visited) semanticTokenCache.set(seen, answer);
|
|
2646
|
+
return answer;
|
|
2845
2647
|
};
|
|
2846
2648
|
var propName = (key) => {
|
|
2847
2649
|
if (key.type === AST_NODE_TYPES9.Identifier) return key.name;
|
|
@@ -3124,122 +2926,40 @@ var prefer_server_actions_default = ESLintUtils16.RuleCreator(
|
|
|
3124
2926
|
}
|
|
3125
2927
|
});
|
|
3126
2928
|
|
|
3127
|
-
// src/rules/prefer-shadcn.ts
|
|
3128
|
-
import {
|
|
3129
|
-
AST_NODE_TYPES as AST_NODE_TYPES10,
|
|
3130
|
-
ESLintUtils as ESLintUtils17
|
|
3131
|
-
} from "@typescript-eslint/utils";
|
|
3132
|
-
var REPLACEMENTS = {
|
|
3133
|
-
select: "Select",
|
|
3134
|
-
textarea: "Textarea",
|
|
3135
|
-
dialog: "Dialog"
|
|
3136
|
-
};
|
|
3137
|
-
var INPUT_TYPE_REPLACEMENTS = {
|
|
3138
|
-
checkbox: "Checkbox",
|
|
3139
|
-
radio: "RadioGroup",
|
|
3140
|
-
range: "Slider"
|
|
3141
|
-
};
|
|
3142
|
-
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
|
|
3143
|
-
var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
3144
|
-
var literalTypeAttr = (node) => {
|
|
3145
|
-
for (const attribute of node.attributes) {
|
|
3146
|
-
if (attribute.type !== AST_NODE_TYPES10.JSXAttribute || attribute.name.type !== AST_NODE_TYPES10.JSXIdentifier || attribute.name.name !== "type") {
|
|
3147
|
-
continue;
|
|
3148
|
-
}
|
|
3149
|
-
if (attribute.value?.type === AST_NODE_TYPES10.Literal && typeof attribute.value.value === "string") {
|
|
3150
|
-
return { kind: "literal", value: attribute.value.value.toLowerCase() };
|
|
3151
|
-
}
|
|
3152
|
-
return { kind: "dynamic" };
|
|
3153
|
-
}
|
|
3154
|
-
return null;
|
|
3155
|
-
};
|
|
3156
|
-
var hasFileAcceptAttr = (node) => node.attributes.some(
|
|
3157
|
-
(attribute) => attribute.type === AST_NODE_TYPES10.JSXAttribute && attribute.name.type === AST_NODE_TYPES10.JSXIdentifier && attribute.name.name === "accept"
|
|
3158
|
-
);
|
|
3159
|
-
var resolveInputReplacement = (node) => {
|
|
3160
|
-
const typeAttr = literalTypeAttr(node);
|
|
3161
|
-
if (hasFileAcceptAttr(node)) return null;
|
|
3162
|
-
if (typeAttr === null || typeAttr.kind === "dynamic") return "Input";
|
|
3163
|
-
if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
|
|
3164
|
-
return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
|
|
3165
|
-
};
|
|
3166
|
-
var prefer_shadcn_default = ESLintUtils17.RuleCreator(
|
|
3167
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3168
|
-
)({
|
|
3169
|
-
name: "prefer-shadcn",
|
|
3170
|
-
meta: {
|
|
3171
|
-
type: "suggestion",
|
|
3172
|
-
docs: {
|
|
3173
|
-
description: "Prefer shadcn/ui form primitives over native `<input>`, `<select>`, `<textarea>`, and `<dialog>` elements."
|
|
3174
|
-
},
|
|
3175
|
-
schema: [],
|
|
3176
|
-
messages: {
|
|
3177
|
-
preferShadcn: "Use the shadcn <{{replacement}}> component from @/components/ui/{{lowercase}} instead of native <{{element}}>."
|
|
3178
|
-
}
|
|
3179
|
-
},
|
|
3180
|
-
defaultOptions: [],
|
|
3181
|
-
create(context) {
|
|
3182
|
-
if (isTestFile(context.filename) || isStoryFile(context.filename)) {
|
|
3183
|
-
return {};
|
|
3184
|
-
}
|
|
3185
|
-
return {
|
|
3186
|
-
JSXOpeningElement(node) {
|
|
3187
|
-
if (node.name.type !== "JSXIdentifier") {
|
|
3188
|
-
return;
|
|
3189
|
-
}
|
|
3190
|
-
const elementName = node.name.name;
|
|
3191
|
-
const replacement = elementName === "input" ? resolveInputReplacement(node) : REPLACEMENTS[elementName];
|
|
3192
|
-
if (replacement === void 0 || replacement === null) {
|
|
3193
|
-
return;
|
|
3194
|
-
}
|
|
3195
|
-
context.report({
|
|
3196
|
-
node,
|
|
3197
|
-
messageId: "preferShadcn",
|
|
3198
|
-
data: {
|
|
3199
|
-
element: elementName,
|
|
3200
|
-
replacement,
|
|
3201
|
-
lowercase: kebabCase(replacement)
|
|
3202
|
-
}
|
|
3203
|
-
});
|
|
3204
|
-
}
|
|
3205
|
-
};
|
|
3206
|
-
}
|
|
3207
|
-
});
|
|
3208
|
-
|
|
3209
2929
|
// src/rules/require-assert-never.ts
|
|
3210
2930
|
import {
|
|
3211
|
-
ESLintUtils as
|
|
3212
|
-
AST_NODE_TYPES as
|
|
2931
|
+
ESLintUtils as ESLintUtils17,
|
|
2932
|
+
AST_NODE_TYPES as AST_NODE_TYPES10
|
|
3213
2933
|
} from "@typescript-eslint/utils";
|
|
3214
2934
|
var isAssertNeverCall = (expression) => {
|
|
3215
|
-
if (expression.type !==
|
|
2935
|
+
if (expression.type !== AST_NODE_TYPES10.CallExpression) return false;
|
|
3216
2936
|
const callee = expression.callee;
|
|
3217
|
-
if (callee.type ===
|
|
2937
|
+
if (callee.type === AST_NODE_TYPES10.Identifier) {
|
|
3218
2938
|
return callee.name === "assertNever";
|
|
3219
2939
|
}
|
|
3220
|
-
if (callee.type ===
|
|
2940
|
+
if (callee.type === AST_NODE_TYPES10.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES10.Identifier) {
|
|
3221
2941
|
return callee.property.name === "assertNever";
|
|
3222
2942
|
}
|
|
3223
2943
|
return false;
|
|
3224
2944
|
};
|
|
3225
2945
|
var statementContainsAssertNever = (statement) => {
|
|
3226
|
-
if (statement.type ===
|
|
2946
|
+
if (statement.type === AST_NODE_TYPES10.ExpressionStatement) {
|
|
3227
2947
|
return isAssertNeverCall(statement.expression);
|
|
3228
2948
|
}
|
|
3229
|
-
if (statement.type ===
|
|
2949
|
+
if (statement.type === AST_NODE_TYPES10.ThrowStatement) {
|
|
3230
2950
|
return isAssertNeverCall(statement.argument);
|
|
3231
2951
|
}
|
|
3232
|
-
if (statement.type ===
|
|
2952
|
+
if (statement.type === AST_NODE_TYPES10.ReturnStatement) {
|
|
3233
2953
|
return statement.argument !== null && isAssertNeverCall(statement.argument);
|
|
3234
2954
|
}
|
|
3235
|
-
if (statement.type ===
|
|
2955
|
+
if (statement.type === AST_NODE_TYPES10.BlockStatement) {
|
|
3236
2956
|
return statement.body.some(statementContainsAssertNever);
|
|
3237
2957
|
}
|
|
3238
2958
|
return false;
|
|
3239
2959
|
};
|
|
3240
2960
|
var isRuntimeHandlingStatement = (statement) => {
|
|
3241
|
-
if (statement.type ===
|
|
3242
|
-
if (statement.type ===
|
|
2961
|
+
if (statement.type === AST_NODE_TYPES10.EmptyStatement) return false;
|
|
2962
|
+
if (statement.type === AST_NODE_TYPES10.BlockStatement) {
|
|
3243
2963
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
3244
2964
|
}
|
|
3245
2965
|
return true;
|
|
@@ -3255,12 +2975,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
3255
2975
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
3256
2976
|
}
|
|
3257
2977
|
const only = defaultCase.consequent[0];
|
|
3258
|
-
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type ===
|
|
2978
|
+
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === AST_NODE_TYPES10.BlockStatement && only.body.length === 0) {
|
|
3259
2979
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
3260
2980
|
}
|
|
3261
2981
|
return false;
|
|
3262
2982
|
};
|
|
3263
|
-
var require_assert_never_default =
|
|
2983
|
+
var require_assert_never_default = ESLintUtils17.RuleCreator(
|
|
3264
2984
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3265
2985
|
)({
|
|
3266
2986
|
name: "require-assert-never",
|
|
@@ -3298,7 +3018,7 @@ var require_assert_never_default = ESLintUtils18.RuleCreator(
|
|
|
3298
3018
|
});
|
|
3299
3019
|
|
|
3300
3020
|
// src/rules/require-zod-form-validation.ts
|
|
3301
|
-
import { ESLintUtils as
|
|
3021
|
+
import { ESLintUtils as ESLintUtils18, AST_NODE_TYPES as AST_NODE_TYPES11 } from "@typescript-eslint/utils";
|
|
3302
3022
|
|
|
3303
3023
|
// src/rules/_zod.ts
|
|
3304
3024
|
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
@@ -3309,14 +3029,14 @@ var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
|
|
|
3309
3029
|
var looksLikeZodSchema = (node) => {
|
|
3310
3030
|
let current = node;
|
|
3311
3031
|
while (true) {
|
|
3312
|
-
if (current.type ===
|
|
3032
|
+
if (current.type === AST_NODE_TYPES11.Identifier) {
|
|
3313
3033
|
return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
|
|
3314
3034
|
}
|
|
3315
|
-
if (current.type ===
|
|
3035
|
+
if (current.type === AST_NODE_TYPES11.CallExpression) {
|
|
3316
3036
|
current = current.callee;
|
|
3317
3037
|
continue;
|
|
3318
3038
|
}
|
|
3319
|
-
if (current.type ===
|
|
3039
|
+
if (current.type === AST_NODE_TYPES11.MemberExpression) {
|
|
3320
3040
|
current = current.object;
|
|
3321
3041
|
continue;
|
|
3322
3042
|
}
|
|
@@ -3324,25 +3044,25 @@ var looksLikeZodSchema = (node) => {
|
|
|
3324
3044
|
}
|
|
3325
3045
|
};
|
|
3326
3046
|
var isZodParseCall = (node) => {
|
|
3327
|
-
if (node.type !==
|
|
3047
|
+
if (node.type !== AST_NODE_TYPES11.CallExpression) return false;
|
|
3328
3048
|
const callee = node.callee;
|
|
3329
|
-
if (callee.type !==
|
|
3049
|
+
if (callee.type !== AST_NODE_TYPES11.MemberExpression) return false;
|
|
3330
3050
|
if (callee.computed) return false;
|
|
3331
|
-
if (callee.property.type !==
|
|
3051
|
+
if (callee.property.type !== AST_NODE_TYPES11.Identifier) return false;
|
|
3332
3052
|
const method = callee.property.name;
|
|
3333
3053
|
if (method !== "parse" && method !== "safeParse") return false;
|
|
3334
3054
|
return looksLikeZodSchema(callee.object);
|
|
3335
3055
|
};
|
|
3336
3056
|
var isFormDataMethodCall = (node) => {
|
|
3337
3057
|
let current = node;
|
|
3338
|
-
if (current.type ===
|
|
3058
|
+
if (current.type === AST_NODE_TYPES11.AwaitExpression) {
|
|
3339
3059
|
current = current.argument;
|
|
3340
3060
|
}
|
|
3341
|
-
if (current.type !==
|
|
3061
|
+
if (current.type !== AST_NODE_TYPES11.CallExpression) return false;
|
|
3342
3062
|
const callee = current.callee;
|
|
3343
|
-
return callee.type ===
|
|
3063
|
+
return callee.type === AST_NODE_TYPES11.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES11.Identifier && callee.property.name === "formData";
|
|
3344
3064
|
};
|
|
3345
|
-
var require_zod_form_validation_default =
|
|
3065
|
+
var require_zod_form_validation_default = ESLintUtils18.RuleCreator(
|
|
3346
3066
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3347
3067
|
)({
|
|
3348
3068
|
name: "require-zod-form-validation",
|
|
@@ -3362,14 +3082,14 @@ var require_zod_form_validation_default = ESLintUtils19.RuleCreator(
|
|
|
3362
3082
|
return {};
|
|
3363
3083
|
}
|
|
3364
3084
|
const isFormSourceIdentifier = (node) => {
|
|
3365
|
-
if (node.type !==
|
|
3085
|
+
if (node.type !== AST_NODE_TYPES11.Identifier) return false;
|
|
3366
3086
|
if (/formdata/i.test(node.name)) return true;
|
|
3367
3087
|
let scope = context.sourceCode.getScope(node);
|
|
3368
3088
|
while (scope !== null) {
|
|
3369
3089
|
const variable = scope.set.get(node.name);
|
|
3370
3090
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
3371
3091
|
const def = variable.defs[0];
|
|
3372
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
3092
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES11.VariableDeclarator && def.node.init !== null) {
|
|
3373
3093
|
return isFormDataMethodCall(def.node.init);
|
|
3374
3094
|
}
|
|
3375
3095
|
return false;
|
|
@@ -3380,8 +3100,8 @@ var require_zod_form_validation_default = ESLintUtils19.RuleCreator(
|
|
|
3380
3100
|
};
|
|
3381
3101
|
const isFormDataGetCall = (node) => {
|
|
3382
3102
|
const callee = node.callee;
|
|
3383
|
-
if (callee.type !==
|
|
3384
|
-
if (callee.property.type !==
|
|
3103
|
+
if (callee.type !== AST_NODE_TYPES11.MemberExpression) return false;
|
|
3104
|
+
if (callee.property.type !== AST_NODE_TYPES11.Identifier || callee.property.name !== "get") {
|
|
3385
3105
|
return false;
|
|
3386
3106
|
}
|
|
3387
3107
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -3396,11 +3116,11 @@ var require_zod_form_validation_default = ESLintUtils19.RuleCreator(
|
|
|
3396
3116
|
};
|
|
3397
3117
|
const isInstanceofNarrowing = (node) => {
|
|
3398
3118
|
const parent = node.parent;
|
|
3399
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
3119
|
+
return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES11.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
|
|
3400
3120
|
};
|
|
3401
3121
|
const boundDeclarator = (node) => {
|
|
3402
3122
|
const parent = node.parent;
|
|
3403
|
-
if (parent.type ===
|
|
3123
|
+
if (parent.type === AST_NODE_TYPES11.VariableDeclarator && parent.init === node && parent.id.type === AST_NODE_TYPES11.Identifier) {
|
|
3404
3124
|
return parent;
|
|
3405
3125
|
}
|
|
3406
3126
|
return null;
|
|
@@ -3428,7 +3148,7 @@ var require_zod_form_validation_default = ESLintUtils19.RuleCreator(
|
|
|
3428
3148
|
});
|
|
3429
3149
|
|
|
3430
3150
|
// src/rules/zod-naming-convention.ts
|
|
3431
|
-
import { ESLintUtils as
|
|
3151
|
+
import { ESLintUtils as ESLintUtils19, AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
3432
3152
|
var CONVENTIONS = {
|
|
3433
3153
|
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
3434
3154
|
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
@@ -3452,15 +3172,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
|
3452
3172
|
"registry",
|
|
3453
3173
|
"implement"
|
|
3454
3174
|
]);
|
|
3455
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
3175
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES12.Identifier ? callee.property.name : null;
|
|
3456
3176
|
var calleeChainStartsWithZ = (node) => {
|
|
3457
3177
|
let current = node;
|
|
3458
|
-
while (current.type ===
|
|
3178
|
+
while (current.type === AST_NODE_TYPES12.MemberExpression) {
|
|
3459
3179
|
const receiver = current.object;
|
|
3460
|
-
if (receiver.type ===
|
|
3180
|
+
if (receiver.type === AST_NODE_TYPES12.Identifier && receiver.name === "z") {
|
|
3461
3181
|
return true;
|
|
3462
3182
|
}
|
|
3463
|
-
if (receiver.type ===
|
|
3183
|
+
if (receiver.type === AST_NODE_TYPES12.CallExpression) {
|
|
3464
3184
|
current = receiver.callee;
|
|
3465
3185
|
continue;
|
|
3466
3186
|
}
|
|
@@ -3468,7 +3188,7 @@ var calleeChainStartsWithZ = (node) => {
|
|
|
3468
3188
|
}
|
|
3469
3189
|
return false;
|
|
3470
3190
|
};
|
|
3471
|
-
var zod_naming_convention_default =
|
|
3191
|
+
var zod_naming_convention_default = ESLintUtils19.RuleCreator(
|
|
3472
3192
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3473
3193
|
)({
|
|
3474
3194
|
name: "zod-naming-convention",
|
|
@@ -3507,13 +3227,13 @@ var zod_naming_convention_default = ESLintUtils20.RuleCreator(
|
|
|
3507
3227
|
VariableDeclarator(node) {
|
|
3508
3228
|
const init = node.init;
|
|
3509
3229
|
if (init === null || init === void 0) return;
|
|
3510
|
-
if (init.type !==
|
|
3230
|
+
if (init.type !== AST_NODE_TYPES12.CallExpression) return;
|
|
3511
3231
|
const callee = init.callee;
|
|
3512
|
-
if (callee.type !==
|
|
3232
|
+
if (callee.type !== AST_NODE_TYPES12.MemberExpression) return;
|
|
3513
3233
|
if (!calleeChainStartsWithZ(callee)) return;
|
|
3514
3234
|
const terminal = terminalMethodName(callee);
|
|
3515
3235
|
if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
|
|
3516
|
-
if (node.id.type !==
|
|
3236
|
+
if (node.id.type !== AST_NODE_TYPES12.Identifier) return;
|
|
3517
3237
|
if (test.test(node.id.name)) return;
|
|
3518
3238
|
if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
|
|
3519
3239
|
context.report({
|
|
@@ -3526,7 +3246,7 @@ var zod_naming_convention_default = ESLintUtils20.RuleCreator(
|
|
|
3526
3246
|
});
|
|
3527
3247
|
|
|
3528
3248
|
// src/rules/no-cors-wildcard-with-credentials.ts
|
|
3529
|
-
import { ESLintUtils as
|
|
3249
|
+
import { ESLintUtils as ESLintUtils20 } from "@typescript-eslint/utils";
|
|
3530
3250
|
var ACAO_HEADER = "access-control-allow-origin";
|
|
3531
3251
|
var ACAC_HEADER = "access-control-allow-credentials";
|
|
3532
3252
|
var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
|
|
@@ -3558,17 +3278,17 @@ function subtreeContainsStarLiteral(node) {
|
|
|
3558
3278
|
const value = node[key];
|
|
3559
3279
|
if (Array.isArray(value)) {
|
|
3560
3280
|
for (const child of value) {
|
|
3561
|
-
if (
|
|
3281
|
+
if (isNode2(child) && subtreeContainsStarLiteral(child)) {
|
|
3562
3282
|
return true;
|
|
3563
3283
|
}
|
|
3564
3284
|
}
|
|
3565
|
-
} else if (
|
|
3285
|
+
} else if (isNode2(value) && subtreeContainsStarLiteral(value)) {
|
|
3566
3286
|
return true;
|
|
3567
3287
|
}
|
|
3568
3288
|
}
|
|
3569
3289
|
return false;
|
|
3570
3290
|
}
|
|
3571
|
-
function
|
|
3291
|
+
function isNode2(value) {
|
|
3572
3292
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
3573
3293
|
}
|
|
3574
3294
|
function propertyKeyName(prop) {
|
|
@@ -3584,7 +3304,7 @@ function propertyKeyName(prop) {
|
|
|
3584
3304
|
}
|
|
3585
3305
|
return void 0;
|
|
3586
3306
|
}
|
|
3587
|
-
function
|
|
3307
|
+
function calleeName2(node) {
|
|
3588
3308
|
const callee = node.callee;
|
|
3589
3309
|
if (callee.type === "Identifier") {
|
|
3590
3310
|
return callee.name;
|
|
@@ -3595,7 +3315,7 @@ function calleeName3(node) {
|
|
|
3595
3315
|
return void 0;
|
|
3596
3316
|
}
|
|
3597
3317
|
function isCorsWildcardCredentialsCall(node) {
|
|
3598
|
-
const name =
|
|
3318
|
+
const name = calleeName2(node);
|
|
3599
3319
|
if (name === void 0 || name.toLowerCase() !== "cors") {
|
|
3600
3320
|
return false;
|
|
3601
3321
|
}
|
|
@@ -3668,7 +3388,7 @@ function enclosingScope(node) {
|
|
|
3668
3388
|
}
|
|
3669
3389
|
return void 0;
|
|
3670
3390
|
}
|
|
3671
|
-
var no_cors_wildcard_with_credentials_default =
|
|
3391
|
+
var no_cors_wildcard_with_credentials_default = ESLintUtils20.RuleCreator(
|
|
3672
3392
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3673
3393
|
)({
|
|
3674
3394
|
name: "no-cors-wildcard-with-credentials",
|
|
@@ -3736,9 +3456,9 @@ var no_cors_wildcard_with_credentials_default = ESLintUtils21.RuleCreator(
|
|
|
3736
3456
|
});
|
|
3737
3457
|
|
|
3738
3458
|
// src/rules/no-silent-promise-catch.ts
|
|
3739
|
-
import { AST_NODE_TYPES as
|
|
3459
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES13, ESLintUtils as ESLintUtils21 } from "@typescript-eslint/utils";
|
|
3740
3460
|
function isBodyParseCall(node) {
|
|
3741
|
-
return node.type ===
|
|
3461
|
+
return node.type === AST_NODE_TYPES13.CallExpression && node.arguments.length === 0 && node.callee.type === AST_NODE_TYPES13.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES13.Identifier && (node.callee.property.name === "json" || node.callee.property.name === "text");
|
|
3742
3462
|
}
|
|
3743
3463
|
var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
3744
3464
|
"cancel",
|
|
@@ -3753,21 +3473,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
|
3753
3473
|
var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
|
|
3754
3474
|
var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
|
|
3755
3475
|
function isTeardownCall(node) {
|
|
3756
|
-
return node.type ===
|
|
3476
|
+
return node.type === AST_NODE_TYPES13.CallExpression && node.callee.type === AST_NODE_TYPES13.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES13.Identifier && TEARDOWN_METHODS.has(node.callee.property.name);
|
|
3757
3477
|
}
|
|
3758
3478
|
function isSilentExpression(node) {
|
|
3759
3479
|
switch (node.type) {
|
|
3760
|
-
case
|
|
3480
|
+
case AST_NODE_TYPES13.Literal:
|
|
3761
3481
|
return !("regex" in node);
|
|
3762
|
-
case
|
|
3482
|
+
case AST_NODE_TYPES13.Identifier:
|
|
3763
3483
|
return node.name === "undefined";
|
|
3764
|
-
case
|
|
3765
|
-
return node.operator === "void" && node.argument.type ===
|
|
3766
|
-
case
|
|
3484
|
+
case AST_NODE_TYPES13.UnaryExpression:
|
|
3485
|
+
return node.operator === "void" && node.argument.type === AST_NODE_TYPES13.Literal;
|
|
3486
|
+
case AST_NODE_TYPES13.ObjectExpression:
|
|
3767
3487
|
return node.properties.length === 0;
|
|
3768
|
-
case
|
|
3488
|
+
case AST_NODE_TYPES13.ArrayExpression:
|
|
3769
3489
|
return node.elements.length === 0;
|
|
3770
|
-
case
|
|
3490
|
+
case AST_NODE_TYPES13.TSAsExpression:
|
|
3771
3491
|
return isSilentExpression(node.expression);
|
|
3772
3492
|
default:
|
|
3773
3493
|
return false;
|
|
@@ -3775,7 +3495,7 @@ function isSilentExpression(node) {
|
|
|
3775
3495
|
}
|
|
3776
3496
|
function isSilentHandler(handler) {
|
|
3777
3497
|
const body = handler.body;
|
|
3778
|
-
if (body.type !==
|
|
3498
|
+
if (body.type !== AST_NODE_TYPES13.BlockStatement) {
|
|
3779
3499
|
return isSilentExpression(body);
|
|
3780
3500
|
}
|
|
3781
3501
|
if (body.body.length === 0) {
|
|
@@ -3783,13 +3503,13 @@ function isSilentHandler(handler) {
|
|
|
3783
3503
|
}
|
|
3784
3504
|
if (body.body.length === 1) {
|
|
3785
3505
|
const only = body.body[0];
|
|
3786
|
-
if (only !== void 0 && only.type ===
|
|
3506
|
+
if (only !== void 0 && only.type === AST_NODE_TYPES13.ReturnStatement) {
|
|
3787
3507
|
return only.argument === null || isSilentExpression(only.argument);
|
|
3788
3508
|
}
|
|
3789
3509
|
}
|
|
3790
3510
|
return false;
|
|
3791
3511
|
}
|
|
3792
|
-
var no_silent_promise_catch_default =
|
|
3512
|
+
var no_silent_promise_catch_default = ESLintUtils21.RuleCreator(
|
|
3793
3513
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3794
3514
|
)({
|
|
3795
3515
|
name: "no-silent-promise-catch",
|
|
@@ -3814,7 +3534,7 @@ var no_silent_promise_catch_default = ESLintUtils22.RuleCreator(
|
|
|
3814
3534
|
return true;
|
|
3815
3535
|
}
|
|
3816
3536
|
let statement = call;
|
|
3817
|
-
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !==
|
|
3537
|
+
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== AST_NODE_TYPES13.VariableDeclaration) {
|
|
3818
3538
|
statement = statement.parent;
|
|
3819
3539
|
}
|
|
3820
3540
|
if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
|
|
@@ -3826,7 +3546,7 @@ var no_silent_promise_catch_default = ESLintUtils22.RuleCreator(
|
|
|
3826
3546
|
};
|
|
3827
3547
|
return {
|
|
3828
3548
|
CallExpression(node) {
|
|
3829
|
-
if (node.callee.type !==
|
|
3549
|
+
if (node.callee.type !== AST_NODE_TYPES13.MemberExpression || node.callee.computed || node.callee.property.type !== AST_NODE_TYPES13.Identifier || node.callee.property.name !== "catch") {
|
|
3830
3550
|
return;
|
|
3831
3551
|
}
|
|
3832
3552
|
if (isBodyParseCall(node.callee.object)) {
|
|
@@ -3835,14 +3555,14 @@ var no_silent_promise_catch_default = ESLintUtils22.RuleCreator(
|
|
|
3835
3555
|
if (isTeardownCall(node.callee.object)) {
|
|
3836
3556
|
return;
|
|
3837
3557
|
}
|
|
3838
|
-
if (node.parent.type ===
|
|
3558
|
+
if (node.parent.type === AST_NODE_TYPES13.MemberExpression && node.parent.object === node) {
|
|
3839
3559
|
return;
|
|
3840
3560
|
}
|
|
3841
3561
|
if (node.arguments.length !== 1) {
|
|
3842
3562
|
return;
|
|
3843
3563
|
}
|
|
3844
3564
|
const handler = node.arguments[0];
|
|
3845
|
-
if (handler === void 0 || handler.type !==
|
|
3565
|
+
if (handler === void 0 || handler.type !== AST_NODE_TYPES13.ArrowFunctionExpression && handler.type !== AST_NODE_TYPES13.FunctionExpression) {
|
|
3846
3566
|
return;
|
|
3847
3567
|
}
|
|
3848
3568
|
if (hasExplanatoryComment(node, handler)) {
|
|
@@ -3858,9 +3578,9 @@ var no_silent_promise_catch_default = ESLintUtils22.RuleCreator(
|
|
|
3858
3578
|
|
|
3859
3579
|
// src/rules/require-fetch-timeout.ts
|
|
3860
3580
|
import {
|
|
3861
|
-
AST_NODE_TYPES as
|
|
3581
|
+
AST_NODE_TYPES as AST_NODE_TYPES14,
|
|
3862
3582
|
ASTUtils,
|
|
3863
|
-
ESLintUtils as
|
|
3583
|
+
ESLintUtils as ESLintUtils22
|
|
3864
3584
|
} from "@typescript-eslint/utils";
|
|
3865
3585
|
var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
|
|
3866
3586
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
|
|
@@ -3878,14 +3598,14 @@ function matchesAnyPattern2(filename, patterns) {
|
|
|
3878
3598
|
return false;
|
|
3879
3599
|
}
|
|
3880
3600
|
function initProvablyLacksSignal(init) {
|
|
3881
|
-
if (init.type !==
|
|
3601
|
+
if (init.type !== AST_NODE_TYPES14.ObjectExpression) {
|
|
3882
3602
|
return false;
|
|
3883
3603
|
}
|
|
3884
3604
|
for (const prop of init.properties) {
|
|
3885
|
-
if (prop.type ===
|
|
3605
|
+
if (prop.type === AST_NODE_TYPES14.SpreadElement) {
|
|
3886
3606
|
return false;
|
|
3887
3607
|
}
|
|
3888
|
-
if (prop.key.type ===
|
|
3608
|
+
if (prop.key.type === AST_NODE_TYPES14.Identifier && prop.key.name === "signal" || prop.key.type === AST_NODE_TYPES14.Literal && prop.key.value === "signal") {
|
|
3889
3609
|
return false;
|
|
3890
3610
|
}
|
|
3891
3611
|
if (prop.computed) {
|
|
@@ -3895,9 +3615,9 @@ function initProvablyLacksSignal(init) {
|
|
|
3895
3615
|
return true;
|
|
3896
3616
|
}
|
|
3897
3617
|
function isStringish(node) {
|
|
3898
|
-
return node.type ===
|
|
3618
|
+
return node.type === AST_NODE_TYPES14.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES14.TemplateLiteral;
|
|
3899
3619
|
}
|
|
3900
|
-
var require_fetch_timeout_default =
|
|
3620
|
+
var require_fetch_timeout_default = ESLintUtils22.RuleCreator(
|
|
3901
3621
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3902
3622
|
)({
|
|
3903
3623
|
name: "require-fetch-timeout",
|
|
@@ -3938,10 +3658,10 @@ var require_fetch_timeout_default = ESLintUtils23.RuleCreator(
|
|
|
3938
3658
|
return variable === null || variable.defs.length === 0;
|
|
3939
3659
|
}
|
|
3940
3660
|
function isGlobalFetchCall2(callee) {
|
|
3941
|
-
if (callee.type ===
|
|
3661
|
+
if (callee.type === AST_NODE_TYPES14.Identifier) {
|
|
3942
3662
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
3943
3663
|
}
|
|
3944
|
-
return callee.type ===
|
|
3664
|
+
return callee.type === AST_NODE_TYPES14.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES14.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES14.Identifier && GLOBAL_OBJECTS.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
3945
3665
|
}
|
|
3946
3666
|
return {
|
|
3947
3667
|
CallExpression(node) {
|
|
@@ -3960,103 +3680,16 @@ var require_fetch_timeout_default = ESLintUtils23.RuleCreator(
|
|
|
3960
3680
|
}
|
|
3961
3681
|
});
|
|
3962
3682
|
|
|
3963
|
-
// src/rules/
|
|
3964
|
-
import {
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
function isValidatorCall(node) {
|
|
3974
|
-
return node.callee.type === AST_NODE_TYPES16.MemberExpression && !node.callee.computed && node.callee.property.type === AST_NODE_TYPES16.Identifier && VALIDATOR_METHODS.has(node.callee.property.name);
|
|
3975
|
-
}
|
|
3976
|
-
function findCastExpression(node, insideValidatorArg) {
|
|
3977
|
-
if ((node.type === AST_NODE_TYPES16.TSAsExpression || node.type === AST_NODE_TYPES16.TSTypeAssertion) && !isConstTypeAnnotation(node.typeAnnotation) && !insideValidatorArg) {
|
|
3978
|
-
return node;
|
|
3979
|
-
}
|
|
3980
|
-
if (node.type === AST_NODE_TYPES16.CallExpression && isValidatorCall(node)) {
|
|
3981
|
-
const inCallee = findCastExpression(node.callee, insideValidatorArg);
|
|
3982
|
-
if (inCallee !== null) {
|
|
3983
|
-
return inCallee;
|
|
3984
|
-
}
|
|
3985
|
-
for (const arg of node.arguments) {
|
|
3986
|
-
const found = findCastExpression(arg, true);
|
|
3987
|
-
if (found !== null) {
|
|
3988
|
-
return found;
|
|
3989
|
-
}
|
|
3990
|
-
}
|
|
3991
|
-
return null;
|
|
3992
|
-
}
|
|
3993
|
-
for (const key of Object.keys(node)) {
|
|
3994
|
-
if (key === "parent") {
|
|
3995
|
-
continue;
|
|
3996
|
-
}
|
|
3997
|
-
const value = node[key];
|
|
3998
|
-
const children = Array.isArray(value) ? value : [value];
|
|
3999
|
-
for (const child of children) {
|
|
4000
|
-
if (child !== null && typeof child === "object" && "type" in child && typeof child.type === "string") {
|
|
4001
|
-
const found = findCastExpression(
|
|
4002
|
-
child,
|
|
4003
|
-
insideValidatorArg
|
|
4004
|
-
);
|
|
4005
|
-
if (found !== null) {
|
|
4006
|
-
return found;
|
|
4007
|
-
}
|
|
4008
|
-
}
|
|
4009
|
-
}
|
|
4010
|
-
}
|
|
4011
|
-
return null;
|
|
4012
|
-
}
|
|
4013
|
-
var require_schema_validate_search_default = ESLintUtils24.RuleCreator(
|
|
4014
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4015
|
-
)({
|
|
4016
|
-
name: "require-schema-validate-search",
|
|
4017
|
-
meta: {
|
|
4018
|
-
type: "problem",
|
|
4019
|
-
docs: {
|
|
4020
|
-
description: "Disallow `as` casts inside hand-rolled `validateSearch` functions; use a schema validator (e.g. zodValidator) so search params are validated at runtime."
|
|
4021
|
-
},
|
|
4022
|
-
schema: [],
|
|
4023
|
-
messages: {
|
|
4024
|
-
castInValidateSearch: "This `validateSearch` asserts the search-param shape with `as` instead of validating it \u2014 malformed query params flow through typed as clean data. Use a schema validator (e.g. `zodValidator(searchSchema)` or `searchSchema.parse`) instead of casting."
|
|
4025
|
-
}
|
|
4026
|
-
},
|
|
4027
|
-
defaultOptions: [],
|
|
4028
|
-
create(context) {
|
|
4029
|
-
if (isTestFile(context.filename)) {
|
|
4030
|
-
return {};
|
|
4031
|
-
}
|
|
4032
|
-
return {
|
|
4033
|
-
Property(node) {
|
|
4034
|
-
const isValidateSearchKey = !node.computed && node.key.type === AST_NODE_TYPES16.Identifier && node.key.name === "validateSearch" || node.key.type === AST_NODE_TYPES16.Literal && node.key.value === "validateSearch";
|
|
4035
|
-
if (!isValidateSearchKey) {
|
|
4036
|
-
return;
|
|
4037
|
-
}
|
|
4038
|
-
if (node.value.type !== AST_NODE_TYPES16.ArrowFunctionExpression && node.value.type !== AST_NODE_TYPES16.FunctionExpression) {
|
|
4039
|
-
return;
|
|
4040
|
-
}
|
|
4041
|
-
const cast = findCastExpression(node.value.body, false);
|
|
4042
|
-
if (cast !== null) {
|
|
4043
|
-
context.report({ node: cast, messageId: "castInValidateSearch" });
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
};
|
|
4047
|
-
}
|
|
4048
|
-
});
|
|
4049
|
-
|
|
4050
|
-
// src/rules/no-fat-try-blocks.ts
|
|
4051
|
-
import {
|
|
4052
|
-
ESLintUtils as ESLintUtils25,
|
|
4053
|
-
AST_NODE_TYPES as AST_NODE_TYPES17
|
|
4054
|
-
} from "@typescript-eslint/utils";
|
|
4055
|
-
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
4056
|
-
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
4057
|
-
AST_NODE_TYPES17.FunctionDeclaration,
|
|
4058
|
-
AST_NODE_TYPES17.FunctionExpression,
|
|
4059
|
-
AST_NODE_TYPES17.ArrowFunctionExpression
|
|
3683
|
+
// src/rules/no-fat-try-blocks.ts
|
|
3684
|
+
import {
|
|
3685
|
+
ESLintUtils as ESLintUtils23,
|
|
3686
|
+
AST_NODE_TYPES as AST_NODE_TYPES15
|
|
3687
|
+
} from "@typescript-eslint/utils";
|
|
3688
|
+
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
3689
|
+
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
3690
|
+
AST_NODE_TYPES15.FunctionDeclaration,
|
|
3691
|
+
AST_NODE_TYPES15.FunctionExpression,
|
|
3692
|
+
AST_NODE_TYPES15.ArrowFunctionExpression
|
|
4060
3693
|
]);
|
|
4061
3694
|
var PURE_METHODS = /* @__PURE__ */ new Set([
|
|
4062
3695
|
"map",
|
|
@@ -4149,25 +3782,25 @@ var PURE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
4149
3782
|
"Response",
|
|
4150
3783
|
"AbortController"
|
|
4151
3784
|
]);
|
|
4152
|
-
function
|
|
3785
|
+
function isNode3(value) {
|
|
4153
3786
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
4154
3787
|
}
|
|
4155
3788
|
function isPureCall(node) {
|
|
4156
3789
|
const callee = node.callee;
|
|
4157
|
-
if (callee.type !==
|
|
3790
|
+
if (callee.type !== AST_NODE_TYPES15.MemberExpression) {
|
|
4158
3791
|
return false;
|
|
4159
3792
|
}
|
|
4160
3793
|
const property = callee.property;
|
|
4161
|
-
if (property.type !==
|
|
3794
|
+
if (property.type !== AST_NODE_TYPES15.Identifier) {
|
|
4162
3795
|
return false;
|
|
4163
3796
|
}
|
|
4164
|
-
if (callee.object.type ===
|
|
3797
|
+
if (callee.object.type === AST_NODE_TYPES15.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
|
|
4165
3798
|
return true;
|
|
4166
3799
|
}
|
|
4167
3800
|
return PURE_METHODS.has(property.name);
|
|
4168
3801
|
}
|
|
4169
3802
|
function isPureNew(node) {
|
|
4170
|
-
return node.callee.type ===
|
|
3803
|
+
return node.callee.type === AST_NODE_TYPES15.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
|
|
4171
3804
|
}
|
|
4172
3805
|
function subtreeMatches(stmt, predicate) {
|
|
4173
3806
|
let found = false;
|
|
@@ -4189,11 +3822,11 @@ function subtreeMatches(stmt, predicate) {
|
|
|
4189
3822
|
const value = current[key];
|
|
4190
3823
|
if (Array.isArray(value)) {
|
|
4191
3824
|
for (const child of value) {
|
|
4192
|
-
if (
|
|
3825
|
+
if (isNode3(child)) {
|
|
4193
3826
|
visit(child);
|
|
4194
3827
|
}
|
|
4195
3828
|
}
|
|
4196
|
-
} else if (
|
|
3829
|
+
} else if (isNode3(value)) {
|
|
4197
3830
|
visit(value);
|
|
4198
3831
|
}
|
|
4199
3832
|
if (found) {
|
|
@@ -4204,20 +3837,20 @@ function subtreeMatches(stmt, predicate) {
|
|
|
4204
3837
|
visit(stmt);
|
|
4205
3838
|
return found;
|
|
4206
3839
|
}
|
|
4207
|
-
var hasAwait = (node) => subtreeMatches(node, (n) => n.type ===
|
|
3840
|
+
var hasAwait = (node) => subtreeMatches(node, (n) => n.type === AST_NODE_TYPES15.AwaitExpression);
|
|
4208
3841
|
var hasThrowingCallOrNew = (node) => subtreeMatches(
|
|
4209
3842
|
node,
|
|
4210
|
-
(n) => n.type ===
|
|
3843
|
+
(n) => n.type === AST_NODE_TYPES15.CallExpression && !isPureCall(n) || n.type === AST_NODE_TYPES15.NewExpression && !isPureNew(n)
|
|
4211
3844
|
);
|
|
4212
3845
|
function unwrap2(expr) {
|
|
4213
3846
|
let current = expr;
|
|
4214
|
-
while (current.type ===
|
|
3847
|
+
while (current.type === AST_NODE_TYPES15.ChainExpression || current.type === AST_NODE_TYPES15.TSNonNullExpression) {
|
|
4215
3848
|
current = current.expression;
|
|
4216
3849
|
}
|
|
4217
3850
|
return current;
|
|
4218
3851
|
}
|
|
4219
3852
|
function isBareCallStatement(stmt) {
|
|
4220
|
-
return stmt.type ===
|
|
3853
|
+
return stmt.type === AST_NODE_TYPES15.ExpressionStatement && unwrap2(stmt.expression).type === AST_NODE_TYPES15.CallExpression;
|
|
4221
3854
|
}
|
|
4222
3855
|
function canThrow(stmt) {
|
|
4223
3856
|
if (hasAwait(stmt)) {
|
|
@@ -4226,10 +3859,10 @@ function canThrow(stmt) {
|
|
|
4226
3859
|
if (isBareCallStatement(stmt)) {
|
|
4227
3860
|
return false;
|
|
4228
3861
|
}
|
|
4229
|
-
if (stmt.type ===
|
|
3862
|
+
if (stmt.type === AST_NODE_TYPES15.BlockStatement) {
|
|
4230
3863
|
return stmt.body.some(canThrow);
|
|
4231
3864
|
}
|
|
4232
|
-
if (stmt.type ===
|
|
3865
|
+
if (stmt.type === AST_NODE_TYPES15.IfStatement) {
|
|
4233
3866
|
return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
|
|
4234
3867
|
}
|
|
4235
3868
|
return hasThrowingCallOrNew(stmt);
|
|
@@ -4240,9 +3873,9 @@ function handlerRethrows(handler) {
|
|
|
4240
3873
|
}
|
|
4241
3874
|
const body = handler.body.body;
|
|
4242
3875
|
const last = body[body.length - 1];
|
|
4243
|
-
return last !== void 0 && last.type ===
|
|
3876
|
+
return last !== void 0 && last.type === AST_NODE_TYPES15.ThrowStatement;
|
|
4244
3877
|
}
|
|
4245
|
-
var no_fat_try_blocks_default =
|
|
3878
|
+
var no_fat_try_blocks_default = ESLintUtils23.RuleCreator(
|
|
4246
3879
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4247
3880
|
)({
|
|
4248
3881
|
name: "no-fat-try-blocks",
|
|
@@ -4286,7 +3919,7 @@ var no_fat_try_blocks_default = ESLintUtils25.RuleCreator(
|
|
|
4286
3919
|
});
|
|
4287
3920
|
|
|
4288
3921
|
// src/rules/no-secret-in-log.ts
|
|
4289
|
-
import { ESLintUtils as
|
|
3922
|
+
import { ESLintUtils as ESLintUtils24 } from "@typescript-eslint/utils";
|
|
4290
3923
|
|
|
4291
3924
|
// src/rules/_secret_names.ts
|
|
4292
3925
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4548,7 +4181,7 @@ function propertyKeyName2(prop) {
|
|
|
4548
4181
|
}
|
|
4549
4182
|
return null;
|
|
4550
4183
|
}
|
|
4551
|
-
var no_secret_in_log_default =
|
|
4184
|
+
var no_secret_in_log_default = ESLintUtils24.RuleCreator(
|
|
4552
4185
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4553
4186
|
)({
|
|
4554
4187
|
name: "no-secret-in-log",
|
|
@@ -4624,46 +4257,46 @@ var no_secret_in_log_default = ESLintUtils26.RuleCreator(
|
|
|
4624
4257
|
}
|
|
4625
4258
|
});
|
|
4626
4259
|
|
|
4627
|
-
// src/rules/no-unsafe-
|
|
4628
|
-
import { ESLintUtils as
|
|
4629
|
-
import { AST_NODE_TYPES as
|
|
4630
|
-
function
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4260
|
+
// src/rules/no-unsafe-mock-casting.ts
|
|
4261
|
+
import { ESLintUtils as ESLintUtils25 } from "@typescript-eslint/utils";
|
|
4262
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES16 } from "@typescript-eslint/utils";
|
|
4263
|
+
function isMockTypeReference(node) {
|
|
4264
|
+
if (node.type !== AST_NODE_TYPES16.TSTypeReference) {
|
|
4265
|
+
return false;
|
|
4266
|
+
}
|
|
4267
|
+
const typeName = node.typeName;
|
|
4268
|
+
if (typeName.type === AST_NODE_TYPES16.Identifier) {
|
|
4269
|
+
const name = typeName.name;
|
|
4270
|
+
return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
|
|
4271
|
+
}
|
|
4272
|
+
if (typeName.type === AST_NODE_TYPES16.TSQualifiedName) {
|
|
4273
|
+
const rightName = typeName.right.name;
|
|
4274
|
+
return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
|
|
4275
|
+
}
|
|
4276
|
+
return false;
|
|
4635
4277
|
}
|
|
4636
|
-
var
|
|
4278
|
+
var no_unsafe_mock_casting_default = ESLintUtils25.RuleCreator(
|
|
4637
4279
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4638
4280
|
)({
|
|
4639
|
-
name: "no-unsafe-
|
|
4281
|
+
name: "no-unsafe-mock-casting",
|
|
4640
4282
|
meta: {
|
|
4641
4283
|
type: "problem",
|
|
4642
4284
|
docs: {
|
|
4643
|
-
description: "Disallow
|
|
4285
|
+
description: "Disallow casting to mock types like `jest.Mock` or `vi.Mock`. Use `vi.mocked()` or `jest.mocked()` instead."
|
|
4644
4286
|
},
|
|
4645
4287
|
schema: [],
|
|
4646
4288
|
messages: {
|
|
4647
|
-
|
|
4648
|
-
doubleCast: "`as unknown as T` double-cast bypasses the compiler's structural check. Prefer a runtime validator (e.g. a zod schema) or an accurate type at the boundary."
|
|
4289
|
+
unsafeMockCast: "Do not cast to a Mock type. Use `vi.mocked(fn)` or `jest.mocked(fn)` instead to preserve type safety."
|
|
4649
4290
|
}
|
|
4650
4291
|
},
|
|
4651
4292
|
defaultOptions: [],
|
|
4652
4293
|
create(context) {
|
|
4653
|
-
if (
|
|
4294
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
4654
4295
|
return {};
|
|
4655
4296
|
}
|
|
4656
4297
|
function checkAssertion(node) {
|
|
4657
|
-
if (
|
|
4658
|
-
|
|
4659
|
-
}
|
|
4660
|
-
if (isAnyAnnotation(node.typeAnnotation)) {
|
|
4661
|
-
context.report({ node, messageId: "asAny" });
|
|
4662
|
-
return;
|
|
4663
|
-
}
|
|
4664
|
-
const inner = node.expression;
|
|
4665
|
-
if (inner.type === AST_NODE_TYPES18.TSAsExpression || inner.type === AST_NODE_TYPES18.TSTypeAssertion) {
|
|
4666
|
-
context.report({ node, messageId: "doubleCast" });
|
|
4298
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
4299
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
4667
4300
|
}
|
|
4668
4301
|
}
|
|
4669
4302
|
return {
|
|
@@ -4675,8 +4308,8 @@ var no_unsafe_cast_default = ESLintUtils27.RuleCreator(
|
|
|
4675
4308
|
|
|
4676
4309
|
// src/rules/prefer-string-literal-union.ts
|
|
4677
4310
|
import {
|
|
4678
|
-
ESLintUtils as
|
|
4679
|
-
AST_NODE_TYPES as
|
|
4311
|
+
ESLintUtils as ESLintUtils26,
|
|
4312
|
+
AST_NODE_TYPES as AST_NODE_TYPES17
|
|
4680
4313
|
} from "@typescript-eslint/utils";
|
|
4681
4314
|
import * as ts from "typescript";
|
|
4682
4315
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -4720,19 +4353,19 @@ function isChoiceLikeName(name) {
|
|
|
4720
4353
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
4721
4354
|
}
|
|
4722
4355
|
function keyName(key) {
|
|
4723
|
-
if (key.type ===
|
|
4356
|
+
if (key.type === AST_NODE_TYPES17.Identifier) {
|
|
4724
4357
|
return key.name;
|
|
4725
4358
|
}
|
|
4726
|
-
if (key.type ===
|
|
4359
|
+
if (key.type === AST_NODE_TYPES17.Literal && typeof key.value === "string") {
|
|
4727
4360
|
return key.value;
|
|
4728
4361
|
}
|
|
4729
4362
|
return null;
|
|
4730
4363
|
}
|
|
4731
4364
|
function isStringLiteralMember(t) {
|
|
4732
|
-
return t.type ===
|
|
4365
|
+
return t.type === AST_NODE_TYPES17.TSLiteralType && t.literal.type === AST_NODE_TYPES17.Literal && typeof t.literal.value === "string";
|
|
4733
4366
|
}
|
|
4734
4367
|
function isStringLiteralUnion(node) {
|
|
4735
|
-
if (node?.type !==
|
|
4368
|
+
if (node?.type !== AST_NODE_TYPES17.TSUnionType) {
|
|
4736
4369
|
return false;
|
|
4737
4370
|
}
|
|
4738
4371
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -4761,12 +4394,12 @@ function bindingSourceExpression(decl) {
|
|
|
4761
4394
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
4762
4395
|
}
|
|
4763
4396
|
function refKey(node) {
|
|
4764
|
-
if (node.type ===
|
|
4397
|
+
if (node.type === AST_NODE_TYPES17.Identifier) {
|
|
4765
4398
|
return node.name;
|
|
4766
4399
|
}
|
|
4767
|
-
if (node.type ===
|
|
4400
|
+
if (node.type === AST_NODE_TYPES17.MemberExpression && !node.computed) {
|
|
4768
4401
|
const inner = refKey(node.object);
|
|
4769
|
-
if (inner === null || node.property.type !==
|
|
4402
|
+
if (inner === null || node.property.type !== AST_NODE_TYPES17.Identifier) {
|
|
4770
4403
|
return null;
|
|
4771
4404
|
}
|
|
4772
4405
|
return `${inner}.${node.property.name}`;
|
|
@@ -4774,12 +4407,12 @@ function refKey(node) {
|
|
|
4774
4407
|
return null;
|
|
4775
4408
|
}
|
|
4776
4409
|
function strLiteral(node) {
|
|
4777
|
-
if (node.type ===
|
|
4410
|
+
if (node.type === AST_NODE_TYPES17.Literal && typeof node.value === "string") {
|
|
4778
4411
|
return node.value;
|
|
4779
4412
|
}
|
|
4780
4413
|
return null;
|
|
4781
4414
|
}
|
|
4782
|
-
var prefer_string_literal_union_default =
|
|
4415
|
+
var prefer_string_literal_union_default = ESLintUtils26.RuleCreator(
|
|
4783
4416
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4784
4417
|
)({
|
|
4785
4418
|
name: "prefer-string-literal-union",
|
|
@@ -4817,7 +4450,7 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
4817
4450
|
);
|
|
4818
4451
|
let services;
|
|
4819
4452
|
try {
|
|
4820
|
-
services =
|
|
4453
|
+
services = ESLintUtils26.getParserServices(context);
|
|
4821
4454
|
} catch {
|
|
4822
4455
|
services = null;
|
|
4823
4456
|
}
|
|
@@ -4929,7 +4562,7 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
4929
4562
|
containersWithUnion.add(container);
|
|
4930
4563
|
return;
|
|
4931
4564
|
}
|
|
4932
|
-
if (typeNode?.type !==
|
|
4565
|
+
if (typeNode?.type !== AST_NODE_TYPES17.TSStringKeyword) {
|
|
4933
4566
|
return;
|
|
4934
4567
|
}
|
|
4935
4568
|
const name = keyName(key);
|
|
@@ -5017,10 +4650,10 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
5017
4650
|
}
|
|
5018
4651
|
};
|
|
5019
4652
|
function refKeyText(node) {
|
|
5020
|
-
if (node.type ===
|
|
4653
|
+
if (node.type === AST_NODE_TYPES17.BinaryExpression) {
|
|
5021
4654
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
5022
4655
|
}
|
|
5023
|
-
if (node.type ===
|
|
4656
|
+
if (node.type === AST_NODE_TYPES17.SwitchStatement) {
|
|
5024
4657
|
return refKey(node.discriminant) ?? "value";
|
|
5025
4658
|
}
|
|
5026
4659
|
return "value";
|
|
@@ -5028,146 +4661,93 @@ var prefer_string_literal_union_default = ESLintUtils28.RuleCreator(
|
|
|
5028
4661
|
}
|
|
5029
4662
|
});
|
|
5030
4663
|
|
|
5031
|
-
// src/rules/
|
|
5032
|
-
import {
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
"type",
|
|
5042
|
-
"types",
|
|
5043
|
-
"model",
|
|
5044
|
-
"models",
|
|
5045
|
-
"shared",
|
|
5046
|
-
"misc"
|
|
5047
|
-
]);
|
|
5048
|
-
var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
|
|
5049
|
-
var ACRONYM_OVERRIDES = [
|
|
5050
|
-
[/OAuth/g, "Oauth"],
|
|
5051
|
-
[/GraphQL/g, "Graphql"],
|
|
5052
|
-
[/gRPC/g, "Grpc"]
|
|
5053
|
-
];
|
|
5054
|
-
var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
|
|
5055
|
-
var TEST_FILE_RE = /\.(test|spec)\.[cm]?[jt]sx?$/i;
|
|
5056
|
-
var SCRIPT_EXT_RE = /\.[cm]?[jt]sx?$/i;
|
|
5057
|
-
var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
|
|
5058
|
-
var stemOf = (base) => base.replace(SCRIPT_EXT_RE, "");
|
|
5059
|
-
var kebabCase2 = (name) => {
|
|
5060
|
-
let normalized = name;
|
|
5061
|
-
for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
|
|
5062
|
-
normalized = normalized.replace(pattern, replacement);
|
|
5063
|
-
}
|
|
5064
|
-
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
5065
|
-
};
|
|
5066
|
-
var isFunctionExpression = (node) => node !== null && (node.type === AST_NODE_TYPES20.ArrowFunctionExpression || node.type === AST_NODE_TYPES20.FunctionExpression);
|
|
5067
|
-
var functionConstName = (decl) => {
|
|
5068
|
-
if (decl.declarations.length !== 1) return null;
|
|
5069
|
-
const [declarator] = decl.declarations;
|
|
5070
|
-
if (declarator === void 0) return null;
|
|
5071
|
-
if (declarator.id.type !== AST_NODE_TYPES20.Identifier) return null;
|
|
5072
|
-
if (!isFunctionExpression(declarator.init)) return null;
|
|
5073
|
-
return declarator.id.name;
|
|
5074
|
-
};
|
|
5075
|
-
var summarizeExports = (body) => {
|
|
5076
|
-
let names = 0;
|
|
5077
|
-
let hasReExport = false;
|
|
5078
|
-
let candidate = null;
|
|
5079
|
-
const addCandidate = (name, node) => {
|
|
5080
|
-
names += 1;
|
|
5081
|
-
candidate = { name, node };
|
|
5082
|
-
};
|
|
5083
|
-
for (const statement of body) {
|
|
5084
|
-
switch (statement.type) {
|
|
5085
|
-
case AST_NODE_TYPES20.ExportAllDeclaration:
|
|
5086
|
-
hasReExport = true;
|
|
5087
|
-
break;
|
|
5088
|
-
case AST_NODE_TYPES20.ExportDefaultDeclaration: {
|
|
5089
|
-
names += 1;
|
|
5090
|
-
const decl = statement.declaration;
|
|
5091
|
-
if (decl.type === AST_NODE_TYPES20.FunctionDeclaration && decl.id !== null) {
|
|
5092
|
-
candidate = { name: decl.id.name, node: statement };
|
|
5093
|
-
} else if (decl.type === AST_NODE_TYPES20.ClassDeclaration && decl.id !== null) {
|
|
5094
|
-
candidate = { name: decl.id.name, node: statement };
|
|
5095
|
-
}
|
|
5096
|
-
break;
|
|
5097
|
-
}
|
|
5098
|
-
case AST_NODE_TYPES20.ExportNamedDeclaration: {
|
|
5099
|
-
if (statement.source !== null) {
|
|
5100
|
-
hasReExport = true;
|
|
5101
|
-
break;
|
|
5102
|
-
}
|
|
5103
|
-
const decl = statement.declaration;
|
|
5104
|
-
if (decl === null) {
|
|
5105
|
-
names += statement.specifiers.length;
|
|
5106
|
-
break;
|
|
5107
|
-
}
|
|
5108
|
-
switch (decl.type) {
|
|
5109
|
-
case AST_NODE_TYPES20.FunctionDeclaration:
|
|
5110
|
-
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5111
|
-
else names += 1;
|
|
5112
|
-
break;
|
|
5113
|
-
case AST_NODE_TYPES20.ClassDeclaration:
|
|
5114
|
-
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5115
|
-
else names += 1;
|
|
5116
|
-
break;
|
|
5117
|
-
case AST_NODE_TYPES20.VariableDeclaration: {
|
|
5118
|
-
const fnName = functionConstName(decl);
|
|
5119
|
-
if (fnName !== null && decl.declarations.length === 1) {
|
|
5120
|
-
addCandidate(fnName, statement);
|
|
5121
|
-
} else {
|
|
5122
|
-
names += decl.declarations.length;
|
|
5123
|
-
}
|
|
5124
|
-
break;
|
|
5125
|
-
}
|
|
5126
|
-
default:
|
|
5127
|
-
names += 1;
|
|
5128
|
-
}
|
|
5129
|
-
break;
|
|
5130
|
-
}
|
|
5131
|
-
default:
|
|
5132
|
-
break;
|
|
5133
|
-
}
|
|
5134
|
-
}
|
|
5135
|
-
return { names, hasReExport, candidate };
|
|
5136
|
-
};
|
|
5137
|
-
var single_public_export_default = ESLintUtils29.RuleCreator(
|
|
5138
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4664
|
+
// src/rules/prefer-zod-enum.ts
|
|
4665
|
+
import {
|
|
4666
|
+
AST_NODE_TYPES as AST_NODE_TYPES18,
|
|
4667
|
+
ESLintUtils as ESLintUtils27
|
|
4668
|
+
} from "@typescript-eslint/utils";
|
|
4669
|
+
function isZodModule(source) {
|
|
4670
|
+
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
4671
|
+
}
|
|
4672
|
+
var prefer_zod_enum_default = ESLintUtils27.RuleCreator(
|
|
4673
|
+
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
5139
4674
|
)({
|
|
5140
|
-
name: "
|
|
4675
|
+
name: "prefer-zod-enum",
|
|
5141
4676
|
meta: {
|
|
5142
4677
|
type: "suggestion",
|
|
5143
4678
|
docs: {
|
|
5144
|
-
description: "
|
|
4679
|
+
description: "Prefer z.enum([...]) over z.union([z.literal(...), ...]) for string choices"
|
|
5145
4680
|
},
|
|
4681
|
+
fixable: "code",
|
|
5146
4682
|
schema: [],
|
|
5147
4683
|
messages: {
|
|
5148
|
-
|
|
4684
|
+
preferEnum: "Use `z.enum([...])` instead of a union of string-literal schemas."
|
|
5149
4685
|
}
|
|
5150
4686
|
},
|
|
5151
4687
|
defaultOptions: [],
|
|
5152
4688
|
create(context) {
|
|
5153
|
-
const
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
4689
|
+
const sourceCode = context.sourceCode;
|
|
4690
|
+
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
4691
|
+
function enumValues(node) {
|
|
4692
|
+
const callee = node.callee;
|
|
4693
|
+
if (callee.type !== AST_NODE_TYPES18.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES18.Identifier || !zodNamespaces.has(callee.object.name) || callee.property.type !== AST_NODE_TYPES18.Identifier || callee.property.name !== "union" || node.arguments.length !== 1) {
|
|
4694
|
+
return null;
|
|
4695
|
+
}
|
|
4696
|
+
const argument = node.arguments[0];
|
|
4697
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES18.ArrayExpression || argument.elements.length === 0) {
|
|
4698
|
+
return null;
|
|
4699
|
+
}
|
|
4700
|
+
const values = [];
|
|
4701
|
+
for (const element of argument.elements) {
|
|
4702
|
+
if (element === null || element.type !== AST_NODE_TYPES18.CallExpression || element.arguments.length !== 1 || element.callee.type !== AST_NODE_TYPES18.MemberExpression || element.callee.computed || element.callee.object.type !== AST_NODE_TYPES18.Identifier || !zodNamespaces.has(element.callee.object.name) || element.callee.property.type !== AST_NODE_TYPES18.Identifier || element.callee.property.name !== "literal") {
|
|
4703
|
+
return null;
|
|
4704
|
+
}
|
|
4705
|
+
const value = element.arguments[0];
|
|
4706
|
+
if (value === void 0 || value.type !== AST_NODE_TYPES18.Literal || typeof value.value !== "string") {
|
|
4707
|
+
return null;
|
|
4708
|
+
}
|
|
4709
|
+
values.push(value);
|
|
4710
|
+
}
|
|
4711
|
+
return values;
|
|
4712
|
+
}
|
|
4713
|
+
function buildFix(node, values) {
|
|
4714
|
+
const argument = node.arguments[0];
|
|
4715
|
+
if (argument === void 0 || argument.type !== AST_NODE_TYPES18.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
|
|
4716
|
+
return void 0;
|
|
4717
|
+
}
|
|
4718
|
+
const callee = node.callee;
|
|
4719
|
+
if (callee.type !== AST_NODE_TYPES18.MemberExpression || callee.property.type !== AST_NODE_TYPES18.Identifier) {
|
|
4720
|
+
return void 0;
|
|
4721
|
+
}
|
|
4722
|
+
return (fixer) => [
|
|
4723
|
+
fixer.replaceText(callee.property, "enum"),
|
|
4724
|
+
fixer.replaceText(
|
|
4725
|
+
argument,
|
|
4726
|
+
`[${values.map((value) => sourceCode.getText(value)).join(", ")}]`
|
|
4727
|
+
)
|
|
4728
|
+
];
|
|
4729
|
+
}
|
|
5159
4730
|
return {
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
4731
|
+
ImportDeclaration(node) {
|
|
4732
|
+
if (!isZodModule(node.source.value)) {
|
|
4733
|
+
return;
|
|
4734
|
+
}
|
|
4735
|
+
for (const specifier of node.specifiers) {
|
|
4736
|
+
if (specifier.type === AST_NODE_TYPES18.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES18.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES18.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES18.Identifier && specifier.imported.name === "z") {
|
|
4737
|
+
zodNamespaces.add(specifier.local.name);
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4740
|
+
},
|
|
4741
|
+
CallExpression(node) {
|
|
4742
|
+
const values = enumValues(node);
|
|
4743
|
+
if (values === null) {
|
|
4744
|
+
return;
|
|
4745
|
+
}
|
|
4746
|
+
const fix = buildFix(node, values);
|
|
5167
4747
|
context.report({
|
|
5168
|
-
node
|
|
5169
|
-
messageId: "
|
|
5170
|
-
|
|
4748
|
+
node,
|
|
4749
|
+
messageId: "preferEnum",
|
|
4750
|
+
...fix === void 0 ? {} : { fix }
|
|
5171
4751
|
});
|
|
5172
4752
|
}
|
|
5173
4753
|
};
|
|
@@ -5175,10 +4755,10 @@ var single_public_export_default = ESLintUtils29.RuleCreator(
|
|
|
5175
4755
|
});
|
|
5176
4756
|
|
|
5177
4757
|
// src/rules/no-offset-pagination.ts
|
|
5178
|
-
import { ESLintUtils as
|
|
4758
|
+
import { ESLintUtils as ESLintUtils28 } from "@typescript-eslint/utils";
|
|
5179
4759
|
|
|
5180
4760
|
// src/rules/_sql.ts
|
|
5181
|
-
import { AST_NODE_TYPES as
|
|
4761
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19 } from "@typescript-eslint/utils";
|
|
5182
4762
|
function stripSqlNoise(text) {
|
|
5183
4763
|
const out = [...text];
|
|
5184
4764
|
const n = text.length;
|
|
@@ -5239,13 +4819,13 @@ function stripSqlNoise(text) {
|
|
|
5239
4819
|
var SUBSTITUTION_MARKER = "?";
|
|
5240
4820
|
function sqlTextOf(node) {
|
|
5241
4821
|
switch (node.type) {
|
|
5242
|
-
case
|
|
4822
|
+
case AST_NODE_TYPES19.Literal:
|
|
5243
4823
|
return typeof node.value === "string" ? node.value : null;
|
|
5244
|
-
case
|
|
4824
|
+
case AST_NODE_TYPES19.TemplateLiteral:
|
|
5245
4825
|
return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
|
|
5246
|
-
case
|
|
4826
|
+
case AST_NODE_TYPES19.TaggedTemplateExpression:
|
|
5247
4827
|
return sqlTextOf(node.quasi);
|
|
5248
|
-
case
|
|
4828
|
+
case AST_NODE_TYPES19.BinaryExpression: {
|
|
5249
4829
|
if (node.operator !== "+") {
|
|
5250
4830
|
return null;
|
|
5251
4831
|
}
|
|
@@ -5253,7 +4833,7 @@ function sqlTextOf(node) {
|
|
|
5253
4833
|
const right = sqlTextOf(node.right);
|
|
5254
4834
|
return left !== null && right !== null ? left + right : null;
|
|
5255
4835
|
}
|
|
5256
|
-
case
|
|
4836
|
+
case AST_NODE_TYPES19.ArrayExpression: {
|
|
5257
4837
|
const parts = [];
|
|
5258
4838
|
for (const element of node.elements) {
|
|
5259
4839
|
if (element === null) {
|
|
@@ -5273,7 +4853,7 @@ function sqlTextOf(node) {
|
|
|
5273
4853
|
}
|
|
5274
4854
|
function isJoinedFragmentArray(node) {
|
|
5275
4855
|
const parent = node.parent;
|
|
5276
|
-
return parent?.type ===
|
|
4856
|
+
return parent?.type === AST_NODE_TYPES19.MemberExpression && parent.object === node && !parent.computed && parent.property.type === AST_NODE_TYPES19.Identifier && parent.property.name === "join" && parent.parent?.type === AST_NODE_TYPES19.CallExpression;
|
|
5277
4857
|
}
|
|
5278
4858
|
function markConsumed(node, consumed) {
|
|
5279
4859
|
consumed.add(node);
|
|
@@ -5323,7 +4903,7 @@ function createSqlListener(handler) {
|
|
|
5323
4903
|
// src/rules/no-offset-pagination.ts
|
|
5324
4904
|
var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
|
|
5325
4905
|
var OFFSET_GATE = /offset/i;
|
|
5326
|
-
var no_offset_pagination_default =
|
|
4906
|
+
var no_offset_pagination_default = ESLintUtils28.RuleCreator(
|
|
5327
4907
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5328
4908
|
)({
|
|
5329
4909
|
name: "no-offset-pagination",
|
|
@@ -5352,15 +4932,15 @@ var no_offset_pagination_default = ESLintUtils30.RuleCreator(
|
|
|
5352
4932
|
});
|
|
5353
4933
|
|
|
5354
4934
|
// src/rules/no-positional-tuple-return.ts
|
|
5355
|
-
import { AST_NODE_TYPES as
|
|
4935
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES20, ESLintUtils as ESLintUtils29 } from "@typescript-eslint/utils";
|
|
5356
4936
|
var MIN_ELEMENTS = 2;
|
|
5357
4937
|
var ACCESSOR_PAIR_LENGTH = 2;
|
|
5358
4938
|
var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
|
|
5359
4939
|
function tupleReturnType(node) {
|
|
5360
|
-
if (node.type ===
|
|
4940
|
+
if (node.type === AST_NODE_TYPES20.TSTupleType) {
|
|
5361
4941
|
return node;
|
|
5362
4942
|
}
|
|
5363
|
-
if (node.type ===
|
|
4943
|
+
if (node.type === AST_NODE_TYPES20.TSTypeReference && node.typeName.type === AST_NODE_TYPES20.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
|
|
5364
4944
|
const argument = node.typeArguments?.params[0];
|
|
5365
4945
|
return argument === void 0 ? null : tupleReturnType(argument);
|
|
5366
4946
|
}
|
|
@@ -5374,30 +4954,30 @@ function isPermittedTuple(tuple, sourceCode) {
|
|
|
5374
4954
|
if (elements.length < MIN_ELEMENTS) {
|
|
5375
4955
|
return true;
|
|
5376
4956
|
}
|
|
5377
|
-
if (elements.some((element) => element.type ===
|
|
4957
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES20.TSRestType)) {
|
|
5378
4958
|
return true;
|
|
5379
4959
|
}
|
|
5380
|
-
if (elements.some((element) => element.type ===
|
|
4960
|
+
if (elements.some((element) => element.type === AST_NODE_TYPES20.TSNamedTupleMember)) {
|
|
5381
4961
|
return true;
|
|
5382
4962
|
}
|
|
5383
|
-
if (elements[0]?.type ===
|
|
4963
|
+
if (elements[0]?.type === AST_NODE_TYPES20.TSLiteralType) {
|
|
5384
4964
|
return true;
|
|
5385
4965
|
}
|
|
5386
|
-
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type ===
|
|
4966
|
+
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === AST_NODE_TYPES20.TSFunctionType)) {
|
|
5387
4967
|
return true;
|
|
5388
4968
|
}
|
|
5389
4969
|
const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
|
|
5390
4970
|
return texts.size === 1;
|
|
5391
4971
|
}
|
|
5392
4972
|
function functionName(node) {
|
|
5393
|
-
if (node.type ===
|
|
4973
|
+
if (node.type === AST_NODE_TYPES20.FunctionDeclaration) {
|
|
5394
4974
|
return node.id?.name ?? null;
|
|
5395
4975
|
}
|
|
5396
4976
|
const parent = node.parent;
|
|
5397
|
-
if (parent?.type ===
|
|
4977
|
+
if (parent?.type === AST_NODE_TYPES20.VariableDeclarator && parent.id.type === AST_NODE_TYPES20.Identifier) {
|
|
5398
4978
|
return parent.id.name;
|
|
5399
4979
|
}
|
|
5400
|
-
if ((parent?.type ===
|
|
4980
|
+
if ((parent?.type === AST_NODE_TYPES20.MethodDefinition || parent?.type === AST_NODE_TYPES20.PropertyDefinition || parent?.type === AST_NODE_TYPES20.Property) && parent.key.type === AST_NODE_TYPES20.Identifier) {
|
|
5401
4981
|
return parent.key.name;
|
|
5402
4982
|
}
|
|
5403
4983
|
return null;
|
|
@@ -5405,7 +4985,7 @@ function functionName(node) {
|
|
|
5405
4985
|
function isInlineExported(node) {
|
|
5406
4986
|
for (let current = node; current != null; current = current.parent) {
|
|
5407
4987
|
const parent = current.parent;
|
|
5408
|
-
if (parent?.type ===
|
|
4988
|
+
if (parent?.type === AST_NODE_TYPES20.ExportNamedDeclaration || parent?.type === AST_NODE_TYPES20.ExportDefaultDeclaration) {
|
|
5409
4989
|
return true;
|
|
5410
4990
|
}
|
|
5411
4991
|
}
|
|
@@ -5414,18 +4994,18 @@ function isInlineExported(node) {
|
|
|
5414
4994
|
function moduleScopeBindingName(node) {
|
|
5415
4995
|
let current = node;
|
|
5416
4996
|
let child = node;
|
|
5417
|
-
while (current.parent != null && current.parent.type !==
|
|
4997
|
+
while (current.parent != null && current.parent.type !== AST_NODE_TYPES20.Program) {
|
|
5418
4998
|
child = current;
|
|
5419
4999
|
current = current.parent;
|
|
5420
5000
|
}
|
|
5421
|
-
if (current.parent?.type !==
|
|
5001
|
+
if (current.parent?.type !== AST_NODE_TYPES20.Program) {
|
|
5422
5002
|
return null;
|
|
5423
5003
|
}
|
|
5424
|
-
if (current.type ===
|
|
5004
|
+
if (current.type === AST_NODE_TYPES20.FunctionDeclaration || current.type === AST_NODE_TYPES20.ClassDeclaration) {
|
|
5425
5005
|
return current.id?.name ?? null;
|
|
5426
5006
|
}
|
|
5427
|
-
if (current.type ===
|
|
5428
|
-
if (child.type !==
|
|
5007
|
+
if (current.type === AST_NODE_TYPES20.VariableDeclaration) {
|
|
5008
|
+
if (child.type !== AST_NODE_TYPES20.VariableDeclarator || child.id.type !== AST_NODE_TYPES20.Identifier) {
|
|
5429
5009
|
return null;
|
|
5430
5010
|
}
|
|
5431
5011
|
return child.id.name;
|
|
@@ -5435,19 +5015,19 @@ function moduleScopeBindingName(node) {
|
|
|
5435
5015
|
function specifierExportedNames(program) {
|
|
5436
5016
|
const names = /* @__PURE__ */ new Set();
|
|
5437
5017
|
for (const statement of program.body) {
|
|
5438
|
-
if (statement.type ===
|
|
5018
|
+
if (statement.type === AST_NODE_TYPES20.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
|
|
5439
5019
|
for (const specifier of statement.specifiers) {
|
|
5440
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
5020
|
+
if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES20.Identifier) {
|
|
5441
5021
|
names.add(specifier.local.name);
|
|
5442
5022
|
}
|
|
5443
5023
|
}
|
|
5444
5024
|
continue;
|
|
5445
5025
|
}
|
|
5446
|
-
if (statement.type ===
|
|
5026
|
+
if (statement.type === AST_NODE_TYPES20.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES20.Identifier) {
|
|
5447
5027
|
names.add(statement.declaration.name);
|
|
5448
5028
|
continue;
|
|
5449
5029
|
}
|
|
5450
|
-
if (statement.type ===
|
|
5030
|
+
if (statement.type === AST_NODE_TYPES20.TSExportAssignment && statement.expression.type === AST_NODE_TYPES20.Identifier) {
|
|
5451
5031
|
names.add(statement.expression.name);
|
|
5452
5032
|
}
|
|
5453
5033
|
}
|
|
@@ -5463,7 +5043,7 @@ function isExported(node, specifierExports) {
|
|
|
5463
5043
|
const binding = moduleScopeBindingName(node);
|
|
5464
5044
|
return binding !== null && specifierExports.has(binding);
|
|
5465
5045
|
}
|
|
5466
|
-
var no_positional_tuple_return_default =
|
|
5046
|
+
var no_positional_tuple_return_default = ESLintUtils29.RuleCreator(
|
|
5467
5047
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5468
5048
|
)({
|
|
5469
5049
|
name: "no-positional-tuple-return",
|
|
@@ -5511,16 +5091,16 @@ var no_positional_tuple_return_default = ESLintUtils31.RuleCreator(
|
|
|
5511
5091
|
});
|
|
5512
5092
|
|
|
5513
5093
|
// src/rules/no-repeated-string-literal.ts
|
|
5514
|
-
import { AST_NODE_TYPES as
|
|
5094
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES21, ESLintUtils as ESLintUtils30 } from "@typescript-eslint/utils";
|
|
5515
5095
|
var MIN_LENGTH = 40;
|
|
5516
5096
|
var MIN_DISTINCT_SCOPES = 2;
|
|
5517
5097
|
var PREVIEW_LENGTH = 40;
|
|
5518
5098
|
var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
|
|
5519
5099
|
var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
|
|
5520
5100
|
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5101
|
+
AST_NODE_TYPES21.FunctionDeclaration,
|
|
5102
|
+
AST_NODE_TYPES21.FunctionExpression,
|
|
5103
|
+
AST_NODE_TYPES21.ArrowFunctionExpression
|
|
5524
5104
|
]);
|
|
5525
5105
|
function isStructured(value) {
|
|
5526
5106
|
return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
|
|
@@ -5542,9 +5122,9 @@ function isScaffolding(node) {
|
|
|
5542
5122
|
if (parent === void 0) {
|
|
5543
5123
|
return true;
|
|
5544
5124
|
}
|
|
5545
|
-
return parent.type ===
|
|
5125
|
+
return parent.type === AST_NODE_TYPES21.ImportDeclaration || parent.type === AST_NODE_TYPES21.ExportNamedDeclaration || parent.type === AST_NODE_TYPES21.ExportAllDeclaration || parent.type === AST_NODE_TYPES21.TSImportType || parent.type === AST_NODE_TYPES21.JSXAttribute || parent.type === AST_NODE_TYPES21.TSLiteralType;
|
|
5546
5126
|
}
|
|
5547
|
-
var no_repeated_string_literal_default =
|
|
5127
|
+
var no_repeated_string_literal_default = ESLintUtils30.RuleCreator(
|
|
5548
5128
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5549
5129
|
)({
|
|
5550
5130
|
name: "no-repeated-string-literal",
|
|
@@ -5584,7 +5164,7 @@ var no_repeated_string_literal_default = ESLintUtils32.RuleCreator(
|
|
|
5584
5164
|
}
|
|
5585
5165
|
},
|
|
5586
5166
|
TemplateLiteral(node) {
|
|
5587
|
-
if (node.parent.type ===
|
|
5167
|
+
if (node.parent.type === AST_NODE_TYPES21.TaggedTemplateExpression) {
|
|
5588
5168
|
return;
|
|
5589
5169
|
}
|
|
5590
5170
|
const [only] = node.quasis;
|
|
@@ -5618,7 +5198,7 @@ var no_repeated_string_literal_default = ESLintUtils32.RuleCreator(
|
|
|
5618
5198
|
});
|
|
5619
5199
|
|
|
5620
5200
|
// src/rules/no-select-star.ts
|
|
5621
|
-
import { ESLintUtils as
|
|
5201
|
+
import { ESLintUtils as ESLintUtils31 } from "@typescript-eslint/utils";
|
|
5622
5202
|
var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
|
|
5623
5203
|
var SELECT_KEYWORD = /\bSELECT\b/gi;
|
|
5624
5204
|
var FROM_KEYWORD = /^FROM\b/i;
|
|
@@ -5658,7 +5238,7 @@ function hasRealSelectStar(sql) {
|
|
|
5658
5238
|
}
|
|
5659
5239
|
return false;
|
|
5660
5240
|
}
|
|
5661
|
-
var no_select_star_default =
|
|
5241
|
+
var no_select_star_default = ESLintUtils31.RuleCreator(
|
|
5662
5242
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5663
5243
|
)({
|
|
5664
5244
|
name: "no-select-star",
|
|
@@ -5687,7 +5267,7 @@ var no_select_star_default = ESLintUtils33.RuleCreator(
|
|
|
5687
5267
|
});
|
|
5688
5268
|
|
|
5689
5269
|
// src/rules/no-sleep-in-test-body.ts
|
|
5690
|
-
import { AST_NODE_TYPES as
|
|
5270
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES22, ESLintUtils as ESLintUtils32 } from "@typescript-eslint/utils";
|
|
5691
5271
|
var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
|
|
5692
5272
|
var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
5693
5273
|
"it",
|
|
@@ -5696,34 +5276,34 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
|
5696
5276
|
"afterEach"
|
|
5697
5277
|
]);
|
|
5698
5278
|
var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5279
|
+
AST_NODE_TYPES22.FunctionDeclaration,
|
|
5280
|
+
AST_NODE_TYPES22.FunctionExpression,
|
|
5281
|
+
AST_NODE_TYPES22.ArrowFunctionExpression
|
|
5702
5282
|
]);
|
|
5703
5283
|
function isNonzeroNumericLiteral(node) {
|
|
5704
|
-
return node?.type ===
|
|
5284
|
+
return node?.type === AST_NODE_TYPES22.Literal && typeof node.value === "number" && node.value !== 0;
|
|
5705
5285
|
}
|
|
5706
5286
|
function isTimedSetTimeout(node) {
|
|
5707
|
-
return node.type ===
|
|
5287
|
+
return node.type === AST_NODE_TYPES22.CallExpression && node.callee.type === AST_NODE_TYPES22.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
|
|
5708
5288
|
}
|
|
5709
5289
|
function isPromiseSleep(node) {
|
|
5710
|
-
if (node.callee.type !==
|
|
5290
|
+
if (node.callee.type !== AST_NODE_TYPES22.Identifier || node.callee.name !== "Promise") {
|
|
5711
5291
|
return false;
|
|
5712
5292
|
}
|
|
5713
5293
|
const executor = node.arguments[0];
|
|
5714
|
-
if (executor?.type !==
|
|
5294
|
+
if (executor?.type !== AST_NODE_TYPES22.ArrowFunctionExpression && executor?.type !== AST_NODE_TYPES22.FunctionExpression) {
|
|
5715
5295
|
return false;
|
|
5716
5296
|
}
|
|
5717
5297
|
const body = executor.body;
|
|
5718
|
-
if (body.type !==
|
|
5298
|
+
if (body.type !== AST_NODE_TYPES22.BlockStatement) {
|
|
5719
5299
|
return isTimedSetTimeout(body);
|
|
5720
5300
|
}
|
|
5721
5301
|
return body.body.some(
|
|
5722
|
-
(stmt) => stmt.type ===
|
|
5302
|
+
(stmt) => stmt.type === AST_NODE_TYPES22.ExpressionStatement && isTimedSetTimeout(stmt.expression)
|
|
5723
5303
|
);
|
|
5724
5304
|
}
|
|
5725
5305
|
function isHelperSleep(node) {
|
|
5726
|
-
return node.callee.type ===
|
|
5306
|
+
return node.callee.type === AST_NODE_TYPES22.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
|
|
5727
5307
|
}
|
|
5728
5308
|
function nearestEnclosingFunction(node) {
|
|
5729
5309
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
@@ -5731,7 +5311,7 @@ function nearestEnclosingFunction(node) {
|
|
|
5731
5311
|
continue;
|
|
5732
5312
|
}
|
|
5733
5313
|
const grandparent = current.parent;
|
|
5734
|
-
const isPromiseExecutor = grandparent?.type ===
|
|
5314
|
+
const isPromiseExecutor = grandparent?.type === AST_NODE_TYPES22.NewExpression && isPromiseSleep(grandparent);
|
|
5735
5315
|
if (!isPromiseExecutor) {
|
|
5736
5316
|
return current;
|
|
5737
5317
|
}
|
|
@@ -5739,29 +5319,29 @@ function nearestEnclosingFunction(node) {
|
|
|
5739
5319
|
return null;
|
|
5740
5320
|
}
|
|
5741
5321
|
function testCallerName(callee) {
|
|
5742
|
-
if (callee.type ===
|
|
5322
|
+
if (callee.type === AST_NODE_TYPES22.Identifier) {
|
|
5743
5323
|
return callee.name;
|
|
5744
5324
|
}
|
|
5745
|
-
if (callee.type ===
|
|
5325
|
+
if (callee.type === AST_NODE_TYPES22.MemberExpression) {
|
|
5746
5326
|
return testCallerName(callee.object);
|
|
5747
5327
|
}
|
|
5748
|
-
if (callee.type ===
|
|
5328
|
+
if (callee.type === AST_NODE_TYPES22.CallExpression) {
|
|
5749
5329
|
return testCallerName(callee.callee);
|
|
5750
5330
|
}
|
|
5751
|
-
if (callee.type ===
|
|
5331
|
+
if (callee.type === AST_NODE_TYPES22.TaggedTemplateExpression) {
|
|
5752
5332
|
return testCallerName(callee.tag);
|
|
5753
5333
|
}
|
|
5754
5334
|
return null;
|
|
5755
5335
|
}
|
|
5756
5336
|
function isTestBody(fn) {
|
|
5757
5337
|
const call = fn.parent;
|
|
5758
|
-
if (call?.type !==
|
|
5338
|
+
if (call?.type !== AST_NODE_TYPES22.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5759
5339
|
return false;
|
|
5760
5340
|
}
|
|
5761
5341
|
const name = testCallerName(call.callee);
|
|
5762
5342
|
return name !== null && TEST_CALLERS.has(name);
|
|
5763
5343
|
}
|
|
5764
|
-
var no_sleep_in_test_body_default =
|
|
5344
|
+
var no_sleep_in_test_body_default = ESLintUtils32.RuleCreator(
|
|
5765
5345
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5766
5346
|
)({
|
|
5767
5347
|
name: "no-sleep-in-test-body",
|
|
@@ -5802,8 +5382,90 @@ var no_sleep_in_test_body_default = ESLintUtils34.RuleCreator(
|
|
|
5802
5382
|
}
|
|
5803
5383
|
});
|
|
5804
5384
|
|
|
5385
|
+
// src/rules/no-conditional-in-test.ts
|
|
5386
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23, ESLintUtils as ESLintUtils33 } from "@typescript-eslint/utils";
|
|
5387
|
+
var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
5388
|
+
var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
|
|
5389
|
+
AST_NODE_TYPES23.FunctionDeclaration,
|
|
5390
|
+
AST_NODE_TYPES23.FunctionExpression,
|
|
5391
|
+
AST_NODE_TYPES23.ArrowFunctionExpression
|
|
5392
|
+
]);
|
|
5393
|
+
function nearestEnclosingFunction2(node) {
|
|
5394
|
+
for (let current = node.parent; current != null; current = current.parent) {
|
|
5395
|
+
if (FUNCTION_TYPES3.has(current.type)) {
|
|
5396
|
+
return current;
|
|
5397
|
+
}
|
|
5398
|
+
}
|
|
5399
|
+
return null;
|
|
5400
|
+
}
|
|
5401
|
+
function testCallerName2(callee) {
|
|
5402
|
+
if (callee.type === AST_NODE_TYPES23.Identifier) {
|
|
5403
|
+
return callee.name;
|
|
5404
|
+
}
|
|
5405
|
+
if (callee.type === AST_NODE_TYPES23.MemberExpression) {
|
|
5406
|
+
return testCallerName2(callee.object);
|
|
5407
|
+
}
|
|
5408
|
+
if (callee.type === AST_NODE_TYPES23.CallExpression) {
|
|
5409
|
+
return testCallerName2(callee.callee);
|
|
5410
|
+
}
|
|
5411
|
+
if (callee.type === AST_NODE_TYPES23.TaggedTemplateExpression) {
|
|
5412
|
+
return testCallerName2(callee.tag);
|
|
5413
|
+
}
|
|
5414
|
+
return null;
|
|
5415
|
+
}
|
|
5416
|
+
function isTestBody2(fn) {
|
|
5417
|
+
const call = fn.parent;
|
|
5418
|
+
if (call?.type !== AST_NODE_TYPES23.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5419
|
+
return false;
|
|
5420
|
+
}
|
|
5421
|
+
const name = testCallerName2(call.callee);
|
|
5422
|
+
return name !== null && TEST_CALLERS2.has(name);
|
|
5423
|
+
}
|
|
5424
|
+
var no_conditional_in_test_default = ESLintUtils33.RuleCreator(
|
|
5425
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5426
|
+
)({
|
|
5427
|
+
name: "no-conditional-in-test",
|
|
5428
|
+
meta: {
|
|
5429
|
+
type: "problem",
|
|
5430
|
+
docs: {
|
|
5431
|
+
description: "Disallow conditional logic (if, switch, ternary) in test bodies, which can hide missing assertions or test multiple code paths."
|
|
5432
|
+
},
|
|
5433
|
+
schema: [],
|
|
5434
|
+
messages: {
|
|
5435
|
+
noConditionalInTest: "Avoid using conditional logic in tests. It can obscure intent and hide unexecuted assertions. Split the test instead."
|
|
5436
|
+
}
|
|
5437
|
+
},
|
|
5438
|
+
defaultOptions: [],
|
|
5439
|
+
create(context) {
|
|
5440
|
+
if (!isTestFile(context.filename)) {
|
|
5441
|
+
return {};
|
|
5442
|
+
}
|
|
5443
|
+
const report = (node) => {
|
|
5444
|
+
const enclosing = nearestEnclosingFunction2(node);
|
|
5445
|
+
if (enclosing === null || !isTestBody2(enclosing)) {
|
|
5446
|
+
return;
|
|
5447
|
+
}
|
|
5448
|
+
context.report({ node, messageId: "noConditionalInTest" });
|
|
5449
|
+
};
|
|
5450
|
+
return {
|
|
5451
|
+
IfStatement(node) {
|
|
5452
|
+
report(node);
|
|
5453
|
+
},
|
|
5454
|
+
SwitchStatement(node) {
|
|
5455
|
+
report(node);
|
|
5456
|
+
},
|
|
5457
|
+
ConditionalExpression(node) {
|
|
5458
|
+
report(node);
|
|
5459
|
+
},
|
|
5460
|
+
LogicalExpression(node) {
|
|
5461
|
+
report(node);
|
|
5462
|
+
}
|
|
5463
|
+
};
|
|
5464
|
+
}
|
|
5465
|
+
});
|
|
5466
|
+
|
|
5805
5467
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
5806
|
-
import { AST_NODE_TYPES as
|
|
5468
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24, ESLintUtils as ESLintUtils34 } from "@typescript-eslint/utils";
|
|
5807
5469
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
5808
5470
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5809
5471
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
@@ -5816,36 +5478,36 @@ function isConstantReference(identifier) {
|
|
|
5816
5478
|
}
|
|
5817
5479
|
function isExcludedOperand(node) {
|
|
5818
5480
|
switch (node.type) {
|
|
5819
|
-
case
|
|
5481
|
+
case AST_NODE_TYPES24.Literal:
|
|
5820
5482
|
return true;
|
|
5821
|
-
case
|
|
5483
|
+
case AST_NODE_TYPES24.TemplateLiteral:
|
|
5822
5484
|
return node.expressions.length === 0;
|
|
5823
|
-
case
|
|
5485
|
+
case AST_NODE_TYPES24.Identifier:
|
|
5824
5486
|
return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
|
|
5825
|
-
case
|
|
5826
|
-
return !node.computed && node.property.type ===
|
|
5487
|
+
case AST_NODE_TYPES24.MemberExpression:
|
|
5488
|
+
return !node.computed && node.property.type === AST_NODE_TYPES24.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
|
|
5827
5489
|
default:
|
|
5828
5490
|
return false;
|
|
5829
5491
|
}
|
|
5830
5492
|
}
|
|
5831
5493
|
function operandName(node) {
|
|
5832
|
-
if (node.type ===
|
|
5494
|
+
if (node.type === AST_NODE_TYPES24.Identifier) {
|
|
5833
5495
|
return node.name;
|
|
5834
5496
|
}
|
|
5835
|
-
if (node.type ===
|
|
5497
|
+
if (node.type === AST_NODE_TYPES24.MemberExpression && !node.computed && node.property.type === AST_NODE_TYPES24.Identifier) {
|
|
5836
5498
|
return node.property.name;
|
|
5837
5499
|
}
|
|
5838
5500
|
return null;
|
|
5839
5501
|
}
|
|
5840
5502
|
function isSecretOperand(node) {
|
|
5841
|
-
if (node.type ===
|
|
5503
|
+
if (node.type === AST_NODE_TYPES24.TemplateLiteral) {
|
|
5842
5504
|
return node.expressions.some((expression) => isSecretOperand(expression));
|
|
5843
5505
|
}
|
|
5844
5506
|
const name = operandName(node);
|
|
5845
5507
|
return name !== null && isAuthSecretName(name);
|
|
5846
5508
|
}
|
|
5847
5509
|
function secretNameOf(node) {
|
|
5848
|
-
if (node.type ===
|
|
5510
|
+
if (node.type === AST_NODE_TYPES24.TemplateLiteral) {
|
|
5849
5511
|
for (const expression of node.expressions) {
|
|
5850
5512
|
const nested = secretNameOf(expression);
|
|
5851
5513
|
if (nested !== null) {
|
|
@@ -5856,7 +5518,7 @@ function secretNameOf(node) {
|
|
|
5856
5518
|
}
|
|
5857
5519
|
return operandName(node);
|
|
5858
5520
|
}
|
|
5859
|
-
var prefer_constant_time_secret_compare_default =
|
|
5521
|
+
var prefer_constant_time_secret_compare_default = ESLintUtils34.RuleCreator(
|
|
5860
5522
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5861
5523
|
)({
|
|
5862
5524
|
name: "prefer-constant-time-secret-compare",
|
|
@@ -5899,11 +5561,11 @@ var prefer_constant_time_secret_compare_default = ESLintUtils35.RuleCreator(
|
|
|
5899
5561
|
});
|
|
5900
5562
|
|
|
5901
5563
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
5902
|
-
import { ESLintUtils as
|
|
5564
|
+
import { ESLintUtils as ESLintUtils35 } from "@typescript-eslint/utils";
|
|
5903
5565
|
var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
|
|
5904
5566
|
var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
|
|
5905
5567
|
var INSERT_GATE = /insert/i;
|
|
5906
|
-
var store_insert_requires_on_conflict_default =
|
|
5568
|
+
var store_insert_requires_on_conflict_default = ESLintUtils35.RuleCreator(
|
|
5907
5569
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5908
5570
|
)({
|
|
5909
5571
|
name: "store-insert-requires-on-conflict",
|
|
@@ -5932,17 +5594,17 @@ var store_insert_requires_on_conflict_default = ESLintUtils36.RuleCreator(
|
|
|
5932
5594
|
});
|
|
5933
5595
|
|
|
5934
5596
|
// src/rules/no-dynamic-sql.ts
|
|
5935
|
-
import { AST_NODE_TYPES as
|
|
5597
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ESLintUtils as ESLintUtils36 } from "@typescript-eslint/utils";
|
|
5936
5598
|
var DEFAULT_METHODS = ["prepare", "exec", "query"];
|
|
5937
5599
|
var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
5938
5600
|
function isStaticFragment(expression) {
|
|
5939
|
-
if (expression.type ===
|
|
5601
|
+
if (expression.type === AST_NODE_TYPES25.Identifier) {
|
|
5940
5602
|
return CONSTANT_CASE_RE.test(expression.name);
|
|
5941
5603
|
}
|
|
5942
|
-
if (expression.type ===
|
|
5604
|
+
if (expression.type === AST_NODE_TYPES25.MemberExpression && !expression.computed && expression.property.type === AST_NODE_TYPES25.Identifier) {
|
|
5943
5605
|
return CONSTANT_CASE_RE.test(expression.property.name);
|
|
5944
5606
|
}
|
|
5945
|
-
if (expression.type ===
|
|
5607
|
+
if (expression.type === AST_NODE_TYPES25.Literal) {
|
|
5946
5608
|
return typeof expression.value === "string";
|
|
5947
5609
|
}
|
|
5948
5610
|
return false;
|
|
@@ -5953,36 +5615,36 @@ function runtimeInterpolations(template) {
|
|
|
5953
5615
|
);
|
|
5954
5616
|
}
|
|
5955
5617
|
function concatOperands(node) {
|
|
5956
|
-
if (node.type ===
|
|
5618
|
+
if (node.type === AST_NODE_TYPES25.BinaryExpression && node.operator === "+") {
|
|
5957
5619
|
return [...concatOperands(node.left), ...concatOperands(node.right)];
|
|
5958
5620
|
}
|
|
5959
5621
|
return [node];
|
|
5960
5622
|
}
|
|
5961
5623
|
function runtimeConcatOperands(node) {
|
|
5962
|
-
if (node.type !==
|
|
5624
|
+
if (node.type !== AST_NODE_TYPES25.BinaryExpression || node.operator !== "+") {
|
|
5963
5625
|
return [];
|
|
5964
5626
|
}
|
|
5965
5627
|
const operands = concatOperands(node);
|
|
5966
5628
|
const hasStringLiteral = operands.some(
|
|
5967
|
-
(operand) => operand.type ===
|
|
5629
|
+
(operand) => operand.type === AST_NODE_TYPES25.Literal && typeof operand.value === "string"
|
|
5968
5630
|
);
|
|
5969
5631
|
if (!hasStringLiteral) {
|
|
5970
5632
|
return [];
|
|
5971
5633
|
}
|
|
5972
5634
|
return operands.filter(
|
|
5973
|
-
(operand) => operand.type !==
|
|
5635
|
+
(operand) => operand.type !== AST_NODE_TYPES25.Literal && !isStaticFragment(operand)
|
|
5974
5636
|
);
|
|
5975
5637
|
}
|
|
5976
5638
|
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;
|
|
5977
5639
|
var RUNTIME_MARKER = " ? ";
|
|
5978
5640
|
function staticStatementText(node) {
|
|
5979
|
-
if (node.type ===
|
|
5641
|
+
if (node.type === AST_NODE_TYPES25.TemplateLiteral) {
|
|
5980
5642
|
return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
|
|
5981
5643
|
}
|
|
5982
|
-
if (node.type ===
|
|
5644
|
+
if (node.type === AST_NODE_TYPES25.Literal) {
|
|
5983
5645
|
return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
|
|
5984
5646
|
}
|
|
5985
|
-
if (node.type ===
|
|
5647
|
+
if (node.type === AST_NODE_TYPES25.BinaryExpression && node.operator === "+") {
|
|
5986
5648
|
return staticStatementText(node.left) + staticStatementText(node.right);
|
|
5987
5649
|
}
|
|
5988
5650
|
return RUNTIME_MARKER;
|
|
@@ -5992,13 +5654,13 @@ function looksLikeSql(node) {
|
|
|
5992
5654
|
}
|
|
5993
5655
|
function statementMethodName(node, methods) {
|
|
5994
5656
|
const callee = node.callee;
|
|
5995
|
-
if (callee.type !==
|
|
5657
|
+
if (callee.type !== AST_NODE_TYPES25.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES25.Identifier) {
|
|
5996
5658
|
return null;
|
|
5997
5659
|
}
|
|
5998
5660
|
const name = callee.property.name;
|
|
5999
5661
|
return methods.has(name) ? name : null;
|
|
6000
5662
|
}
|
|
6001
|
-
var no_dynamic_sql_default =
|
|
5663
|
+
var no_dynamic_sql_default = ESLintUtils36.RuleCreator(
|
|
6002
5664
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6003
5665
|
)({
|
|
6004
5666
|
name: "no-dynamic-sql",
|
|
@@ -6037,7 +5699,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6037
5699
|
if (statement === void 0 || !looksLikeSql(statement)) {
|
|
6038
5700
|
return;
|
|
6039
5701
|
}
|
|
6040
|
-
const offenders = statement.type ===
|
|
5702
|
+
const offenders = statement.type === AST_NODE_TYPES25.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
|
|
6041
5703
|
for (const offender of offenders) {
|
|
6042
5704
|
context.report({
|
|
6043
5705
|
node: offender,
|
|
@@ -6051,7 +5713,7 @@ var no_dynamic_sql_default = ESLintUtils37.RuleCreator(
|
|
|
6051
5713
|
});
|
|
6052
5714
|
|
|
6053
5715
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
6054
|
-
import { ESLintUtils as
|
|
5716
|
+
import { ESLintUtils as ESLintUtils37 } from "@typescript-eslint/utils";
|
|
6055
5717
|
var DEFAULT_ALLOW = [
|
|
6056
5718
|
"[\\\\/]clients?[\\\\/]",
|
|
6057
5719
|
"-client\\.[cm]?[jt]sx?$",
|
|
@@ -6115,7 +5777,7 @@ function compile(patterns) {
|
|
|
6115
5777
|
}
|
|
6116
5778
|
return compiled;
|
|
6117
5779
|
}
|
|
6118
|
-
var no_raw_fetch_outside_clients_default =
|
|
5780
|
+
var no_raw_fetch_outside_clients_default = ESLintUtils37.RuleCreator(
|
|
6119
5781
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6120
5782
|
)({
|
|
6121
5783
|
name: "no-raw-fetch-outside-clients",
|
|
@@ -6163,7 +5825,7 @@ var no_raw_fetch_outside_clients_default = ESLintUtils38.RuleCreator(
|
|
|
6163
5825
|
});
|
|
6164
5826
|
|
|
6165
5827
|
// src/rules/no-storage-in-stateless-modules.ts
|
|
6166
|
-
import { AST_NODE_TYPES as
|
|
5828
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ESLintUtils as ESLintUtils38 } from "@typescript-eslint/utils";
|
|
6167
5829
|
var DEFAULT_METHODS2 = [
|
|
6168
5830
|
"prepare",
|
|
6169
5831
|
"put",
|
|
@@ -6182,7 +5844,7 @@ function compile2(patterns) {
|
|
|
6182
5844
|
}
|
|
6183
5845
|
function storageMethodName(node, methods) {
|
|
6184
5846
|
const callee = node.callee;
|
|
6185
|
-
if (callee.type !==
|
|
5847
|
+
if (callee.type !== AST_NODE_TYPES26.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES26.Identifier) {
|
|
6186
5848
|
return null;
|
|
6187
5849
|
}
|
|
6188
5850
|
const name = callee.property.name;
|
|
@@ -6194,7 +5856,7 @@ function storageMethodName(node, methods) {
|
|
|
6194
5856
|
}
|
|
6195
5857
|
return name;
|
|
6196
5858
|
}
|
|
6197
|
-
var no_storage_in_stateless_modules_default =
|
|
5859
|
+
var no_storage_in_stateless_modules_default = ESLintUtils38.RuleCreator(
|
|
6198
5860
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6199
5861
|
)({
|
|
6200
5862
|
name: "no-storage-in-stateless-modules",
|
|
@@ -6253,8 +5915,8 @@ var no_storage_in_stateless_modules_default = ESLintUtils39.RuleCreator(
|
|
|
6253
5915
|
|
|
6254
5916
|
// src/rules/no-zod-native-enum.ts
|
|
6255
5917
|
import {
|
|
6256
|
-
ESLintUtils as
|
|
6257
|
-
AST_NODE_TYPES as
|
|
5918
|
+
ESLintUtils as ESLintUtils39,
|
|
5919
|
+
AST_NODE_TYPES as AST_NODE_TYPES27
|
|
6258
5920
|
} from "@typescript-eslint/utils";
|
|
6259
5921
|
import * as ts2 from "typescript";
|
|
6260
5922
|
var IGNORE_PATTERNS2 = [
|
|
@@ -6269,11 +5931,11 @@ function isIgnoredFile2(filename, sourceText) {
|
|
|
6269
5931
|
}
|
|
6270
5932
|
return /@generated\b/.test(sourceText.slice(0, 1024));
|
|
6271
5933
|
}
|
|
6272
|
-
function
|
|
5934
|
+
function isZodModule2(source) {
|
|
6273
5935
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
6274
5936
|
}
|
|
6275
5937
|
function unwrap3(node) {
|
|
6276
|
-
if (node.type ===
|
|
5938
|
+
if (node.type === AST_NODE_TYPES27.TSAsExpression || node.type === AST_NODE_TYPES27.TSSatisfiesExpression) {
|
|
6277
5939
|
return unwrap3(node.expression);
|
|
6278
5940
|
}
|
|
6279
5941
|
return node;
|
|
@@ -6281,14 +5943,14 @@ function unwrap3(node) {
|
|
|
6281
5943
|
function stringValueTexts(node, sourceCode) {
|
|
6282
5944
|
const texts = [];
|
|
6283
5945
|
for (const prop of node.properties) {
|
|
6284
|
-
if (prop.type !==
|
|
5946
|
+
if (prop.type !== AST_NODE_TYPES27.Property) {
|
|
6285
5947
|
return null;
|
|
6286
5948
|
}
|
|
6287
5949
|
if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6288
5950
|
return null;
|
|
6289
5951
|
}
|
|
6290
5952
|
const value = prop.value;
|
|
6291
|
-
if (value.type !==
|
|
5953
|
+
if (value.type !== AST_NODE_TYPES27.Literal || typeof value.value !== "string") {
|
|
6292
5954
|
return null;
|
|
6293
5955
|
}
|
|
6294
5956
|
const text = sourceCode.getText(value);
|
|
@@ -6304,7 +5966,7 @@ function resolvesToLocalEnum(node, scope) {
|
|
|
6304
5966
|
const variable = current.variables.find((v) => v.name === node.name);
|
|
6305
5967
|
if (variable !== void 0) {
|
|
6306
5968
|
return variable.defs.some(
|
|
6307
|
-
(def) => def.node.type ===
|
|
5969
|
+
(def) => def.node.type === AST_NODE_TYPES27.TSEnumDeclaration
|
|
6308
5970
|
);
|
|
6309
5971
|
}
|
|
6310
5972
|
current = current.upper;
|
|
@@ -6324,7 +5986,7 @@ function resolvesToImportedEnum(node, services) {
|
|
|
6324
5986
|
}
|
|
6325
5987
|
return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
|
|
6326
5988
|
}
|
|
6327
|
-
var no_zod_native_enum_default =
|
|
5989
|
+
var no_zod_native_enum_default = ESLintUtils39.RuleCreator(
|
|
6328
5990
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6329
5991
|
)({
|
|
6330
5992
|
name: "no-zod-native-enum",
|
|
@@ -6351,32 +6013,32 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6351
6013
|
}
|
|
6352
6014
|
let services;
|
|
6353
6015
|
try {
|
|
6354
|
-
services =
|
|
6016
|
+
services = ESLintUtils39.getParserServices(context);
|
|
6355
6017
|
} catch {
|
|
6356
6018
|
services = null;
|
|
6357
6019
|
}
|
|
6358
6020
|
const zodImportedNames = /* @__PURE__ */ new Map();
|
|
6359
6021
|
function isZodMemberCall(node, api) {
|
|
6360
6022
|
const callee = node.callee;
|
|
6361
|
-
if (callee.type ===
|
|
6023
|
+
if (callee.type === AST_NODE_TYPES27.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES27.Identifier) {
|
|
6362
6024
|
return callee.property.name === api;
|
|
6363
6025
|
}
|
|
6364
|
-
if (callee.type ===
|
|
6026
|
+
if (callee.type === AST_NODE_TYPES27.Identifier) {
|
|
6365
6027
|
return zodImportedNames.get(callee.name) === api;
|
|
6366
6028
|
}
|
|
6367
6029
|
return false;
|
|
6368
6030
|
}
|
|
6369
6031
|
function buildFix(node) {
|
|
6370
6032
|
const callee = node.callee;
|
|
6371
|
-
if (callee.type !==
|
|
6033
|
+
if (callee.type !== AST_NODE_TYPES27.MemberExpression || callee.property.type !== AST_NODE_TYPES27.Identifier) {
|
|
6372
6034
|
return null;
|
|
6373
6035
|
}
|
|
6374
6036
|
const arg = node.arguments[0];
|
|
6375
|
-
if (arg === void 0 || node.arguments.length !== 1 || arg.type ===
|
|
6037
|
+
if (arg === void 0 || node.arguments.length !== 1 || arg.type === AST_NODE_TYPES27.SpreadElement) {
|
|
6376
6038
|
return null;
|
|
6377
6039
|
}
|
|
6378
6040
|
const inner = unwrap3(arg);
|
|
6379
|
-
if (inner.type !==
|
|
6041
|
+
if (inner.type !== AST_NODE_TYPES27.ObjectExpression) {
|
|
6380
6042
|
return null;
|
|
6381
6043
|
}
|
|
6382
6044
|
const values = stringValueTexts(inner, sourceCode);
|
|
@@ -6392,11 +6054,11 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6392
6054
|
}
|
|
6393
6055
|
return {
|
|
6394
6056
|
ImportDeclaration(node) {
|
|
6395
|
-
if (!
|
|
6057
|
+
if (!isZodModule2(node.source.value)) {
|
|
6396
6058
|
return;
|
|
6397
6059
|
}
|
|
6398
6060
|
for (const spec of node.specifiers) {
|
|
6399
|
-
if (spec.type ===
|
|
6061
|
+
if (spec.type === AST_NODE_TYPES27.ImportSpecifier && spec.imported.type === AST_NODE_TYPES27.Identifier) {
|
|
6400
6062
|
zodImportedNames.set(spec.local.name, spec.imported.name);
|
|
6401
6063
|
}
|
|
6402
6064
|
}
|
|
@@ -6415,7 +6077,7 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6415
6077
|
return;
|
|
6416
6078
|
}
|
|
6417
6079
|
const arg = node.arguments[0];
|
|
6418
|
-
if (arg === void 0 || arg.type !==
|
|
6080
|
+
if (arg === void 0 || arg.type !== AST_NODE_TYPES27.Identifier) {
|
|
6419
6081
|
return;
|
|
6420
6082
|
}
|
|
6421
6083
|
const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
|
|
@@ -6433,8 +6095,8 @@ var no_zod_native_enum_default = ESLintUtils40.RuleCreator(
|
|
|
6433
6095
|
|
|
6434
6096
|
// src/rules/prefer-module-level-constant.ts
|
|
6435
6097
|
import {
|
|
6436
|
-
ESLintUtils as
|
|
6437
|
-
AST_NODE_TYPES as
|
|
6098
|
+
ESLintUtils as ESLintUtils40,
|
|
6099
|
+
AST_NODE_TYPES as AST_NODE_TYPES28
|
|
6438
6100
|
} from "@typescript-eslint/utils";
|
|
6439
6101
|
var DEFAULT_MIN_ELEMENTS = 3;
|
|
6440
6102
|
var MAX_LITERAL_DEPTH = 4;
|
|
@@ -6470,10 +6132,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
6470
6132
|
// Object-ish escape hatches
|
|
6471
6133
|
"assign"
|
|
6472
6134
|
]);
|
|
6473
|
-
var
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6135
|
+
var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
6136
|
+
AST_NODE_TYPES28.FunctionDeclaration,
|
|
6137
|
+
AST_NODE_TYPES28.FunctionExpression,
|
|
6138
|
+
AST_NODE_TYPES28.ArrowFunctionExpression
|
|
6477
6139
|
]);
|
|
6478
6140
|
var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
|
|
6479
6141
|
function isIgnoredFile3(filename, sourceText) {
|
|
@@ -6486,13 +6148,13 @@ function isTestFile2(filename) {
|
|
|
6486
6148
|
return TEST_FILE_PATTERNS.some((re) => re.test(filename));
|
|
6487
6149
|
}
|
|
6488
6150
|
function unwrap4(node) {
|
|
6489
|
-
if (node.type ===
|
|
6151
|
+
if (node.type === AST_NODE_TYPES28.TSAsExpression || node.type === AST_NODE_TYPES28.TSSatisfiesExpression || node.type === AST_NODE_TYPES28.TSNonNullExpression) {
|
|
6490
6152
|
return unwrap4(node.expression);
|
|
6491
6153
|
}
|
|
6492
6154
|
return node;
|
|
6493
6155
|
}
|
|
6494
6156
|
function isRegexLiteral(node) {
|
|
6495
|
-
return node.type ===
|
|
6157
|
+
return node.type === AST_NODE_TYPES28.Literal && "regex" in node && node.regex !== void 0;
|
|
6496
6158
|
}
|
|
6497
6159
|
function isLiteralOnly(node, depth) {
|
|
6498
6160
|
if (depth > MAX_LITERAL_DEPTH) {
|
|
@@ -6500,29 +6162,29 @@ function isLiteralOnly(node, depth) {
|
|
|
6500
6162
|
}
|
|
6501
6163
|
const inner = unwrap4(node);
|
|
6502
6164
|
switch (inner.type) {
|
|
6503
|
-
case
|
|
6165
|
+
case AST_NODE_TYPES28.Literal: {
|
|
6504
6166
|
return true;
|
|
6505
6167
|
}
|
|
6506
|
-
case
|
|
6168
|
+
case AST_NODE_TYPES28.TemplateLiteral: {
|
|
6507
6169
|
return inner.expressions.length === 0;
|
|
6508
6170
|
}
|
|
6509
|
-
case
|
|
6510
|
-
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type ===
|
|
6171
|
+
case AST_NODE_TYPES28.UnaryExpression: {
|
|
6172
|
+
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === AST_NODE_TYPES28.Literal && typeof inner.argument.value === "number";
|
|
6511
6173
|
}
|
|
6512
|
-
case
|
|
6174
|
+
case AST_NODE_TYPES28.ArrayExpression: {
|
|
6513
6175
|
return inner.elements.every(
|
|
6514
|
-
(el) => el !== null && el.type !==
|
|
6176
|
+
(el) => el !== null && el.type !== AST_NODE_TYPES28.SpreadElement && isLiteralOnly(el, depth + 1)
|
|
6515
6177
|
);
|
|
6516
6178
|
}
|
|
6517
|
-
case
|
|
6179
|
+
case AST_NODE_TYPES28.ObjectExpression: {
|
|
6518
6180
|
return inner.properties.every((prop) => {
|
|
6519
|
-
if (prop.type !==
|
|
6181
|
+
if (prop.type !== AST_NODE_TYPES28.Property) {
|
|
6520
6182
|
return false;
|
|
6521
6183
|
}
|
|
6522
6184
|
if (prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6523
6185
|
return false;
|
|
6524
6186
|
}
|
|
6525
|
-
if (prop.computed && prop.key.type !==
|
|
6187
|
+
if (prop.computed && prop.key.type !== AST_NODE_TYPES28.Literal) {
|
|
6526
6188
|
return false;
|
|
6527
6189
|
}
|
|
6528
6190
|
return isLiteralOnly(prop.value, depth + 1);
|
|
@@ -6535,7 +6197,7 @@ function isLiteralOnly(node, depth) {
|
|
|
6535
6197
|
}
|
|
6536
6198
|
function unwrapObjectFreeze(node) {
|
|
6537
6199
|
const inner = unwrap4(node);
|
|
6538
|
-
if (inner.type ===
|
|
6200
|
+
if (inner.type === AST_NODE_TYPES28.CallExpression && inner.callee.type === AST_NODE_TYPES28.MemberExpression && !inner.callee.computed && inner.callee.object.type === AST_NODE_TYPES28.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === AST_NODE_TYPES28.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== AST_NODE_TYPES28.SpreadElement) {
|
|
6539
6201
|
return unwrap4(inner.arguments[0]);
|
|
6540
6202
|
}
|
|
6541
6203
|
return inner;
|
|
@@ -6551,19 +6213,19 @@ function classify(init, checkRegex) {
|
|
|
6551
6213
|
}
|
|
6552
6214
|
return { kind: "regex", size: 1 };
|
|
6553
6215
|
}
|
|
6554
|
-
if (node.type ===
|
|
6216
|
+
if (node.type === AST_NODE_TYPES28.ArrayExpression) {
|
|
6555
6217
|
return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
|
|
6556
6218
|
}
|
|
6557
|
-
if (node.type ===
|
|
6219
|
+
if (node.type === AST_NODE_TYPES28.ObjectExpression) {
|
|
6558
6220
|
return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
|
|
6559
6221
|
}
|
|
6560
|
-
if (node.type ===
|
|
6222
|
+
if (node.type === AST_NODE_TYPES28.NewExpression && node.callee.type === AST_NODE_TYPES28.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
|
|
6561
6223
|
const arg = node.arguments[0];
|
|
6562
|
-
if (node.arguments.length !== 1 || arg === void 0 || arg.type ===
|
|
6224
|
+
if (node.arguments.length !== 1 || arg === void 0 || arg.type === AST_NODE_TYPES28.SpreadElement) {
|
|
6563
6225
|
return null;
|
|
6564
6226
|
}
|
|
6565
6227
|
const entries = unwrap4(arg);
|
|
6566
|
-
if (entries.type !==
|
|
6228
|
+
if (entries.type !== AST_NODE_TYPES28.ArrayExpression) {
|
|
6567
6229
|
return null;
|
|
6568
6230
|
}
|
|
6569
6231
|
return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
|
|
@@ -6573,7 +6235,7 @@ function classify(init, checkRegex) {
|
|
|
6573
6235
|
function enclosingFunction2(node) {
|
|
6574
6236
|
let current = node.parent;
|
|
6575
6237
|
while (current !== void 0 && current !== null) {
|
|
6576
|
-
if (
|
|
6238
|
+
if (FUNCTION_TYPES4.has(current.type)) {
|
|
6577
6239
|
return current;
|
|
6578
6240
|
}
|
|
6579
6241
|
current = current.parent;
|
|
@@ -6592,10 +6254,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
|
|
|
6592
6254
|
);
|
|
6593
6255
|
function isNonRetainingBuiltinCall(node, argument) {
|
|
6594
6256
|
const callee = node.callee;
|
|
6595
|
-
if (callee.type ===
|
|
6257
|
+
if (callee.type === AST_NODE_TYPES28.Identifier && callee.name === "structuredClone") {
|
|
6596
6258
|
return true;
|
|
6597
6259
|
}
|
|
6598
|
-
if (callee.type !==
|
|
6260
|
+
if (callee.type !== AST_NODE_TYPES28.MemberExpression || callee.computed || callee.object.type !== AST_NODE_TYPES28.Identifier || callee.property.type !== AST_NODE_TYPES28.Identifier) {
|
|
6599
6261
|
return false;
|
|
6600
6262
|
}
|
|
6601
6263
|
const members = NON_RETAINING_BUILTINS.get(callee.object.name);
|
|
@@ -6609,43 +6271,43 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
6609
6271
|
}
|
|
6610
6272
|
function isSafeRead(identifier) {
|
|
6611
6273
|
const parent = identifier.parent;
|
|
6612
|
-
if (parent.type ===
|
|
6274
|
+
if (parent.type === AST_NODE_TYPES28.MemberExpression) {
|
|
6613
6275
|
if (parent.object !== identifier) {
|
|
6614
6276
|
return true;
|
|
6615
6277
|
}
|
|
6616
6278
|
const grandparent = parent.parent;
|
|
6617
|
-
if (grandparent.type ===
|
|
6279
|
+
if (grandparent.type === AST_NODE_TYPES28.AssignmentExpression && grandparent.left === parent) {
|
|
6618
6280
|
return false;
|
|
6619
6281
|
}
|
|
6620
|
-
if (grandparent.type ===
|
|
6282
|
+
if (grandparent.type === AST_NODE_TYPES28.UpdateExpression) {
|
|
6621
6283
|
return false;
|
|
6622
6284
|
}
|
|
6623
|
-
if (grandparent.type ===
|
|
6285
|
+
if (grandparent.type === AST_NODE_TYPES28.UnaryExpression && grandparent.operator === "delete") {
|
|
6624
6286
|
return false;
|
|
6625
6287
|
}
|
|
6626
|
-
if (!parent.computed && parent.property.type ===
|
|
6288
|
+
if (!parent.computed && parent.property.type === AST_NODE_TYPES28.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === AST_NODE_TYPES28.CallExpression && grandparent.callee === parent) {
|
|
6627
6289
|
return false;
|
|
6628
6290
|
}
|
|
6629
6291
|
return true;
|
|
6630
6292
|
}
|
|
6631
|
-
if (parent.type ===
|
|
6293
|
+
if (parent.type === AST_NODE_TYPES28.ForOfStatement && parent.right === identifier) {
|
|
6632
6294
|
return true;
|
|
6633
6295
|
}
|
|
6634
|
-
if (parent.type ===
|
|
6296
|
+
if (parent.type === AST_NODE_TYPES28.SpreadElement) {
|
|
6635
6297
|
return true;
|
|
6636
6298
|
}
|
|
6637
|
-
if (parent.type ===
|
|
6299
|
+
if (parent.type === AST_NODE_TYPES28.BinaryExpression) {
|
|
6638
6300
|
return true;
|
|
6639
6301
|
}
|
|
6640
|
-
if (parent.type ===
|
|
6302
|
+
if (parent.type === AST_NODE_TYPES28.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
|
|
6641
6303
|
return true;
|
|
6642
6304
|
}
|
|
6643
|
-
if (parent.type ===
|
|
6305
|
+
if (parent.type === AST_NODE_TYPES28.UnaryExpression && parent.operator !== "delete") {
|
|
6644
6306
|
return true;
|
|
6645
6307
|
}
|
|
6646
6308
|
return false;
|
|
6647
6309
|
}
|
|
6648
|
-
var prefer_module_level_constant_default =
|
|
6310
|
+
var prefer_module_level_constant_default = ESLintUtils40.RuleCreator(
|
|
6649
6311
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6650
6312
|
)({
|
|
6651
6313
|
name: "prefer-module-level-constant",
|
|
@@ -6697,7 +6359,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6697
6359
|
if (reference.isWrite()) {
|
|
6698
6360
|
return false;
|
|
6699
6361
|
}
|
|
6700
|
-
if (reference.identifier.type !==
|
|
6362
|
+
if (reference.identifier.type !== AST_NODE_TYPES28.Identifier) {
|
|
6701
6363
|
return false;
|
|
6702
6364
|
}
|
|
6703
6365
|
if (!isSafeRead(reference.identifier)) {
|
|
@@ -6709,10 +6371,10 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6709
6371
|
return {
|
|
6710
6372
|
VariableDeclarator(node) {
|
|
6711
6373
|
const declaration = node.parent;
|
|
6712
|
-
if (declaration.type !==
|
|
6374
|
+
if (declaration.type !== AST_NODE_TYPES28.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
|
|
6713
6375
|
return;
|
|
6714
6376
|
}
|
|
6715
|
-
if (node.id.type !==
|
|
6377
|
+
if (node.id.type !== AST_NODE_TYPES28.Identifier || node.init === null) {
|
|
6716
6378
|
return;
|
|
6717
6379
|
}
|
|
6718
6380
|
if (enclosingFunction2(node) === null) {
|
|
@@ -6739,7 +6401,7 @@ var prefer_module_level_constant_default = ESLintUtils41.RuleCreator(
|
|
|
6739
6401
|
});
|
|
6740
6402
|
|
|
6741
6403
|
// src/rules/jsdoc-restates-signature.ts
|
|
6742
|
-
import { AST_NODE_TYPES as
|
|
6404
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29, ESLintUtils as ESLintUtils41 } from "@typescript-eslint/utils";
|
|
6743
6405
|
var VALUE_TAGS = /* @__PURE__ */ new Set([
|
|
6744
6406
|
"alpha",
|
|
6745
6407
|
"author",
|
|
@@ -6822,30 +6484,30 @@ function declarationNames(node) {
|
|
|
6822
6484
|
switch (node.type) {
|
|
6823
6485
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
6824
6486
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
6825
|
-
case
|
|
6826
|
-
case
|
|
6487
|
+
case AST_NODE_TYPES29.ExportNamedDeclaration:
|
|
6488
|
+
case AST_NODE_TYPES29.ExportDefaultDeclaration:
|
|
6827
6489
|
return node.declaration == null ? null : declarationNames(node.declaration);
|
|
6828
|
-
case
|
|
6829
|
-
case
|
|
6490
|
+
case AST_NODE_TYPES29.FunctionDeclaration:
|
|
6491
|
+
case AST_NODE_TYPES29.TSDeclareFunction:
|
|
6830
6492
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
6831
|
-
case
|
|
6832
|
-
case
|
|
6833
|
-
case
|
|
6834
|
-
case
|
|
6493
|
+
case AST_NODE_TYPES29.ClassDeclaration:
|
|
6494
|
+
case AST_NODE_TYPES29.TSInterfaceDeclaration:
|
|
6495
|
+
case AST_NODE_TYPES29.TSTypeAliasDeclaration:
|
|
6496
|
+
case AST_NODE_TYPES29.TSEnumDeclaration:
|
|
6835
6497
|
return node.id === null ? null : { name: node.id.name, params: [] };
|
|
6836
|
-
case
|
|
6498
|
+
case AST_NODE_TYPES29.VariableDeclaration: {
|
|
6837
6499
|
const declarator = node.declarations[0];
|
|
6838
|
-
if (declarator === void 0 || declarator.id.type !==
|
|
6500
|
+
if (declarator === void 0 || declarator.id.type !== AST_NODE_TYPES29.Identifier) return null;
|
|
6839
6501
|
const init = declarator.init;
|
|
6840
|
-
const params = init != null && (init.type ===
|
|
6502
|
+
const params = init != null && (init.type === AST_NODE_TYPES29.ArrowFunctionExpression || init.type === AST_NODE_TYPES29.FunctionExpression) ? paramNames(init.params) : [];
|
|
6841
6503
|
return { name: declarator.id.name, params };
|
|
6842
6504
|
}
|
|
6843
|
-
case
|
|
6844
|
-
case
|
|
6845
|
-
case
|
|
6846
|
-
case
|
|
6847
|
-
if (node.key.type !==
|
|
6848
|
-
const params = node.type ===
|
|
6505
|
+
case AST_NODE_TYPES29.MethodDefinition:
|
|
6506
|
+
case AST_NODE_TYPES29.PropertyDefinition:
|
|
6507
|
+
case AST_NODE_TYPES29.TSMethodSignature:
|
|
6508
|
+
case AST_NODE_TYPES29.TSPropertySignature: {
|
|
6509
|
+
if (node.key.type !== AST_NODE_TYPES29.Identifier) return null;
|
|
6510
|
+
const params = node.type === AST_NODE_TYPES29.MethodDefinition ? paramNames(node.value.params) : node.type === AST_NODE_TYPES29.TSMethodSignature ? paramNames(node.params) : [];
|
|
6849
6511
|
return { name: node.key.name, params };
|
|
6850
6512
|
}
|
|
6851
6513
|
default:
|
|
@@ -6855,9 +6517,9 @@ function declarationNames(node) {
|
|
|
6855
6517
|
function paramNames(params) {
|
|
6856
6518
|
const names = [];
|
|
6857
6519
|
for (const param of params) {
|
|
6858
|
-
const target = param.type ===
|
|
6859
|
-
if (target.type ===
|
|
6860
|
-
else if (target.type ===
|
|
6520
|
+
const target = param.type === AST_NODE_TYPES29.AssignmentPattern ? param.left : param;
|
|
6521
|
+
if (target.type === AST_NODE_TYPES29.Identifier) names.push(target.name);
|
|
6522
|
+
else if (target.type === AST_NODE_TYPES29.TSParameterProperty) continue;
|
|
6861
6523
|
}
|
|
6862
6524
|
return names;
|
|
6863
6525
|
}
|
|
@@ -6866,7 +6528,7 @@ function tokensOf(names) {
|
|
|
6866
6528
|
for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
|
|
6867
6529
|
return tokens;
|
|
6868
6530
|
}
|
|
6869
|
-
var jsdoc_restates_signature_default =
|
|
6531
|
+
var jsdoc_restates_signature_default = ESLintUtils41.RuleCreator(
|
|
6870
6532
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6871
6533
|
)({
|
|
6872
6534
|
name: "jsdoc-restates-signature",
|
|
@@ -6902,7 +6564,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
6902
6564
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
|
|
6903
6565
|
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
|
6904
6566
|
let declaration = null;
|
|
6905
|
-
while (node != null && node.type !==
|
|
6567
|
+
while (node != null && node.type !== AST_NODE_TYPES29.Program) {
|
|
6906
6568
|
declaration = declarationNames(node);
|
|
6907
6569
|
if (declaration !== null) break;
|
|
6908
6570
|
node = node.parent ?? null;
|
|
@@ -6957,7 +6619,7 @@ var jsdoc_restates_signature_default = ESLintUtils42.RuleCreator(
|
|
|
6957
6619
|
});
|
|
6958
6620
|
|
|
6959
6621
|
// src/rules/no-restated-comment.ts
|
|
6960
|
-
import { AST_NODE_TYPES as
|
|
6622
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES30, ESLintUtils as ESLintUtils42 } from "@typescript-eslint/utils";
|
|
6961
6623
|
var MAX_WORDS = 8;
|
|
6962
6624
|
var MIN_CONTENT_TOKENS = 2;
|
|
6963
6625
|
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;
|
|
@@ -6981,7 +6643,7 @@ function headsSiblingRun(node) {
|
|
|
6981
6643
|
const next = index >= 0 ? body[index + 1] : void 0;
|
|
6982
6644
|
return next !== void 0 && next.type === node.type;
|
|
6983
6645
|
}
|
|
6984
|
-
var no_restated_comment_default =
|
|
6646
|
+
var no_restated_comment_default = ESLintUtils42.RuleCreator(
|
|
6985
6647
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6986
6648
|
)({
|
|
6987
6649
|
name: "no-restated-comment",
|
|
@@ -7009,7 +6671,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
7009
6671
|
function labelsASiblingRun(comment) {
|
|
7010
6672
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
7011
6673
|
if (token === null) return false;
|
|
7012
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
6674
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES30.Program; node = node.parent) {
|
|
7013
6675
|
if (headsSiblingRun(node)) return true;
|
|
7014
6676
|
}
|
|
7015
6677
|
return false;
|
|
@@ -7049,7 +6711,7 @@ var no_restated_comment_default = ESLintUtils43.RuleCreator(
|
|
|
7049
6711
|
});
|
|
7050
6712
|
|
|
7051
6713
|
// src/rules/trailing-value-narration.ts
|
|
7052
|
-
import { ESLintUtils as
|
|
6714
|
+
import { ESLintUtils as ESLintUtils43 } from "@typescript-eslint/utils";
|
|
7053
6715
|
var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
|
|
7054
6716
|
var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
|
|
7055
6717
|
var UNIT_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -7133,7 +6795,7 @@ function narratesValue(body, code) {
|
|
|
7133
6795
|
(word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
|
|
7134
6796
|
);
|
|
7135
6797
|
}
|
|
7136
|
-
var trailing_value_narration_default =
|
|
6798
|
+
var trailing_value_narration_default = ESLintUtils43.RuleCreator(
|
|
7137
6799
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7138
6800
|
)({
|
|
7139
6801
|
name: "trailing-value-narration",
|
|
@@ -7174,7 +6836,7 @@ var trailing_value_narration_default = ESLintUtils44.RuleCreator(
|
|
|
7174
6836
|
});
|
|
7175
6837
|
|
|
7176
6838
|
// src/rules/no-tautological-expect.ts
|
|
7177
|
-
import { AST_NODE_TYPES as
|
|
6839
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES31, ESLintUtils as ESLintUtils44 } from "@typescript-eslint/utils";
|
|
7178
6840
|
var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
7179
6841
|
var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
|
|
7180
6842
|
"toBeDefined",
|
|
@@ -7188,17 +6850,17 @@ var OPERAND_PREVIEW_CHARS = 40;
|
|
|
7188
6850
|
var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
|
|
7189
6851
|
function isLiteral(node) {
|
|
7190
6852
|
switch (node.type) {
|
|
7191
|
-
case
|
|
6853
|
+
case AST_NODE_TYPES31.Literal:
|
|
7192
6854
|
return true;
|
|
7193
|
-
case
|
|
6855
|
+
case AST_NODE_TYPES31.TemplateLiteral:
|
|
7194
6856
|
return node.expressions.length === 0;
|
|
7195
|
-
case
|
|
6857
|
+
case AST_NODE_TYPES31.UnaryExpression:
|
|
7196
6858
|
return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
|
|
7197
|
-
case
|
|
6859
|
+
case AST_NODE_TYPES31.ArrayExpression:
|
|
7198
6860
|
return node.elements.every((element) => element !== null && isLiteral(element));
|
|
7199
|
-
case
|
|
6861
|
+
case AST_NODE_TYPES31.ObjectExpression:
|
|
7200
6862
|
return node.properties.every(
|
|
7201
|
-
(property) => property.type ===
|
|
6863
|
+
(property) => property.type === AST_NODE_TYPES31.Property && !property.computed && isLiteral(property.value)
|
|
7202
6864
|
);
|
|
7203
6865
|
default:
|
|
7204
6866
|
return false;
|
|
@@ -7206,12 +6868,12 @@ function isLiteral(node) {
|
|
|
7206
6868
|
}
|
|
7207
6869
|
function expectOperand(callee) {
|
|
7208
6870
|
const receiver = callee.object;
|
|
7209
|
-
if (receiver.type !==
|
|
6871
|
+
if (receiver.type !== AST_NODE_TYPES31.CallExpression || receiver.callee.type !== AST_NODE_TYPES31.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
|
|
7210
6872
|
return null;
|
|
7211
6873
|
}
|
|
7212
6874
|
return receiver.arguments[0] ?? null;
|
|
7213
6875
|
}
|
|
7214
|
-
var no_tautological_expect_default =
|
|
6876
|
+
var no_tautological_expect_default = ESLintUtils44.RuleCreator(
|
|
7215
6877
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7216
6878
|
)({
|
|
7217
6879
|
name: "no-tautological-expect",
|
|
@@ -7238,10 +6900,10 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7238
6900
|
return {
|
|
7239
6901
|
CallExpression(node) {
|
|
7240
6902
|
const callee = node.callee;
|
|
7241
|
-
if (callee.type !==
|
|
6903
|
+
if (callee.type !== AST_NODE_TYPES31.MemberExpression || callee.computed) {
|
|
7242
6904
|
return;
|
|
7243
6905
|
}
|
|
7244
|
-
if (callee.property.type !==
|
|
6906
|
+
if (callee.property.type !== AST_NODE_TYPES31.Identifier) {
|
|
7245
6907
|
return;
|
|
7246
6908
|
}
|
|
7247
6909
|
const matcher = callee.property.name;
|
|
@@ -7275,26 +6937,26 @@ var no_tautological_expect_default = ESLintUtils45.RuleCreator(
|
|
|
7275
6937
|
});
|
|
7276
6938
|
|
|
7277
6939
|
// src/rules/require-interface-for-injected-service.ts
|
|
7278
|
-
import { AST_NODE_TYPES as
|
|
6940
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES32, ESLintUtils as ESLintUtils45 } from "@typescript-eslint/utils";
|
|
7279
6941
|
var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
|
|
7280
6942
|
var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
|
|
7281
6943
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
7282
6944
|
var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
|
|
7283
6945
|
var ROUTER_FACTORY_NAME = "Router";
|
|
7284
6946
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
7285
|
-
var isExportedClass = (node) => node.parent.type ===
|
|
7286
|
-
var qualifiedName = (name) => name.type ===
|
|
6947
|
+
var isExportedClass = (node) => node.parent.type === AST_NODE_TYPES32.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES32.ExportDefaultDeclaration;
|
|
6948
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES32.Identifier ? name.name : name.type === AST_NODE_TYPES32.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
7287
6949
|
var typeReferenceName = (annotated) => {
|
|
7288
6950
|
let target = annotated;
|
|
7289
|
-
if (target.type ===
|
|
7290
|
-
if (target.type ===
|
|
7291
|
-
if (target.type !==
|
|
6951
|
+
if (target.type === AST_NODE_TYPES32.TSParameterProperty) target = target.parameter;
|
|
6952
|
+
if (target.type === AST_NODE_TYPES32.AssignmentPattern) target = target.left;
|
|
6953
|
+
if (target.type !== AST_NODE_TYPES32.Identifier) return null;
|
|
7292
6954
|
const annotation = target.typeAnnotation?.typeAnnotation;
|
|
7293
|
-
if (annotation === void 0 || annotation.type !==
|
|
6955
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES32.TSTypeReference) {
|
|
7294
6956
|
return null;
|
|
7295
6957
|
}
|
|
7296
6958
|
const { typeName } = annotation;
|
|
7297
|
-
const rightmost = typeName.type ===
|
|
6959
|
+
const rightmost = typeName.type === AST_NODE_TYPES32.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES32.TSQualifiedName ? typeName.right.name : null;
|
|
7298
6960
|
if (rightmost === null) return null;
|
|
7299
6961
|
return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
|
|
7300
6962
|
};
|
|
@@ -7304,17 +6966,17 @@ var readConstructor = (ctor) => {
|
|
|
7304
6966
|
let constructedFields = 0;
|
|
7305
6967
|
if (body !== null && body !== void 0) {
|
|
7306
6968
|
for (const statement of body.body) {
|
|
7307
|
-
if (statement.type !==
|
|
6969
|
+
if (statement.type !== AST_NODE_TYPES32.ExpressionStatement) continue;
|
|
7308
6970
|
const expression = statement.expression;
|
|
7309
|
-
if (expression.type !==
|
|
6971
|
+
if (expression.type !== AST_NODE_TYPES32.AssignmentExpression || expression.operator !== "=" || expression.left.type !== AST_NODE_TYPES32.MemberExpression || expression.left.object.type !== AST_NODE_TYPES32.ThisExpression) {
|
|
7310
6972
|
continue;
|
|
7311
6973
|
}
|
|
7312
6974
|
const source = expression.right;
|
|
7313
|
-
if (source.type ===
|
|
6975
|
+
if (source.type === AST_NODE_TYPES32.NewExpression) {
|
|
7314
6976
|
constructedFields += 1;
|
|
7315
|
-
} else if (source.type ===
|
|
6977
|
+
} else if (source.type === AST_NODE_TYPES32.Identifier) {
|
|
7316
6978
|
storedFrom.add(source.name);
|
|
7317
|
-
} else if (source.type ===
|
|
6979
|
+
} else if (source.type === AST_NODE_TYPES32.MemberExpression && source.object.type === AST_NODE_TYPES32.Identifier) {
|
|
7318
6980
|
storedFrom.add(source.object.name);
|
|
7319
6981
|
}
|
|
7320
6982
|
}
|
|
@@ -7323,7 +6985,7 @@ var readConstructor = (ctor) => {
|
|
|
7323
6985
|
for (const parameter of ctor.value.params) {
|
|
7324
6986
|
const reference = typeReferenceName(parameter);
|
|
7325
6987
|
if (reference === null) continue;
|
|
7326
|
-
const stored = parameter.type ===
|
|
6988
|
+
const stored = parameter.type === AST_NODE_TYPES32.TSParameterProperty || storedFrom.has(reference.name);
|
|
7327
6989
|
if (!stored) continue;
|
|
7328
6990
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
7329
6991
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -7353,19 +7015,19 @@ var subtreeHas = (root, found) => {
|
|
|
7353
7015
|
return hit;
|
|
7354
7016
|
};
|
|
7355
7017
|
var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
|
|
7356
|
-
if (node.type ===
|
|
7018
|
+
if (node.type === AST_NODE_TYPES32.CallExpression) {
|
|
7357
7019
|
const { callee } = node;
|
|
7358
|
-
if (callee.type ===
|
|
7359
|
-
return callee.type ===
|
|
7020
|
+
if (callee.type === AST_NODE_TYPES32.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
7021
|
+
return callee.type === AST_NODE_TYPES32.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES32.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
7360
7022
|
}
|
|
7361
|
-
return node.type ===
|
|
7023
|
+
return node.type === AST_NODE_TYPES32.TSTypeReference && node.typeName.type === AST_NODE_TYPES32.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
7362
7024
|
});
|
|
7363
7025
|
var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
|
|
7364
7026
|
var fileInterfaceNames = (program) => {
|
|
7365
7027
|
const names = [];
|
|
7366
7028
|
for (const statement of program.body) {
|
|
7367
|
-
const declaration = statement.type ===
|
|
7368
|
-
if (declaration?.type ===
|
|
7029
|
+
const declaration = statement.type === AST_NODE_TYPES32.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7030
|
+
if (declaration?.type === AST_NODE_TYPES32.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
7369
7031
|
}
|
|
7370
7032
|
return names;
|
|
7371
7033
|
};
|
|
@@ -7383,16 +7045,16 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
7383
7045
|
var publicMethodNames = (body) => {
|
|
7384
7046
|
const names = [];
|
|
7385
7047
|
for (const member of body.body) {
|
|
7386
|
-
if (member.type !==
|
|
7048
|
+
if (member.type !== AST_NODE_TYPES32.MethodDefinition) continue;
|
|
7387
7049
|
if (member.kind !== "method" || member.static) continue;
|
|
7388
7050
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
7389
|
-
if (member.key.type ===
|
|
7390
|
-
if (member.key.type ===
|
|
7051
|
+
if (member.key.type === AST_NODE_TYPES32.PrivateIdentifier) continue;
|
|
7052
|
+
if (member.key.type === AST_NODE_TYPES32.Identifier) names.push(member.key.name);
|
|
7391
7053
|
else names.push("\u2026");
|
|
7392
7054
|
}
|
|
7393
7055
|
return names;
|
|
7394
7056
|
};
|
|
7395
|
-
var require_interface_for_injected_service_default =
|
|
7057
|
+
var require_interface_for_injected_service_default = ESLintUtils45.RuleCreator(
|
|
7396
7058
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7397
7059
|
)({
|
|
7398
7060
|
name: "require-interface-for-injected-service",
|
|
@@ -7420,7 +7082,7 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7420
7082
|
if (node.implements.length > 0) return;
|
|
7421
7083
|
if (node.decorators.length > 0) return;
|
|
7422
7084
|
const ctor = node.body.body.find(
|
|
7423
|
-
(member) => member.type ===
|
|
7085
|
+
(member) => member.type === AST_NODE_TYPES32.MethodDefinition && member.kind === "constructor"
|
|
7424
7086
|
);
|
|
7425
7087
|
if (ctor === void 0) return;
|
|
7426
7088
|
const { collaborators, constructedFields } = readConstructor(ctor);
|
|
@@ -7445,26 +7107,26 @@ var require_interface_for_injected_service_default = ESLintUtils46.RuleCreator(
|
|
|
7445
7107
|
});
|
|
7446
7108
|
|
|
7447
7109
|
// src/rules/prefer-non-nullable-collection.ts
|
|
7448
|
-
import { AST_NODE_TYPES as
|
|
7110
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES33, ESLintUtils as ESLintUtils46 } from "@typescript-eslint/utils";
|
|
7449
7111
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
7450
7112
|
function propertyName(node) {
|
|
7451
7113
|
const key = node.key;
|
|
7452
|
-
if (key.type ===
|
|
7453
|
-
if (key.type ===
|
|
7114
|
+
if (key.type === AST_NODE_TYPES33.Identifier) return key.name;
|
|
7115
|
+
if (key.type === AST_NODE_TYPES33.Literal) return String(key.value);
|
|
7454
7116
|
return "collection";
|
|
7455
7117
|
}
|
|
7456
7118
|
function isArrayType(node) {
|
|
7457
|
-
if (node.type ===
|
|
7458
|
-
return node.type ===
|
|
7119
|
+
if (node.type === AST_NODE_TYPES33.TSArrayType) return true;
|
|
7120
|
+
return node.type === AST_NODE_TYPES33.TSTypeReference && node.typeName.type === AST_NODE_TYPES33.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
7459
7121
|
}
|
|
7460
7122
|
function isNullishType(node) {
|
|
7461
|
-
return node.type ===
|
|
7123
|
+
return node.type === AST_NODE_TYPES33.TSNullKeyword || node.type === AST_NODE_TYPES33.TSUndefinedKeyword;
|
|
7462
7124
|
}
|
|
7463
7125
|
function isNullableArrayOnly(node) {
|
|
7464
7126
|
const values = node.types.filter((member) => !isNullishType(member));
|
|
7465
7127
|
return values.length > 0 && values.length < node.types.length && values.every(isArrayType);
|
|
7466
7128
|
}
|
|
7467
|
-
var prefer_non_nullable_collection_default =
|
|
7129
|
+
var prefer_non_nullable_collection_default = ESLintUtils46.RuleCreator(
|
|
7468
7130
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
7469
7131
|
)({
|
|
7470
7132
|
name: "prefer-non-nullable-collection",
|
|
@@ -7487,7 +7149,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7487
7149
|
function checkOptionalProperty(node) {
|
|
7488
7150
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
7489
7151
|
if (annotation === void 0) return;
|
|
7490
|
-
if (annotation.type !==
|
|
7152
|
+
if (annotation.type !== AST_NODE_TYPES33.TSUnionType || !isNullableArrayOnly(annotation)) {
|
|
7491
7153
|
return;
|
|
7492
7154
|
}
|
|
7493
7155
|
context.report({
|
|
@@ -7500,7 +7162,7 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7500
7162
|
TSPropertySignature: checkOptionalProperty,
|
|
7501
7163
|
PropertyDefinition: checkOptionalProperty,
|
|
7502
7164
|
TSTypeAliasDeclaration(node) {
|
|
7503
|
-
if (node.typeAnnotation.type !==
|
|
7165
|
+
if (node.typeAnnotation.type !== AST_NODE_TYPES33.TSUnionType) return;
|
|
7504
7166
|
if (!isNullableArrayOnly(node.typeAnnotation)) return;
|
|
7505
7167
|
context.report({
|
|
7506
7168
|
node,
|
|
@@ -7513,41 +7175,41 @@ var prefer_non_nullable_collection_default = ESLintUtils47.RuleCreator(
|
|
|
7513
7175
|
});
|
|
7514
7176
|
|
|
7515
7177
|
// src/rules/primary-export-file-name.ts
|
|
7516
|
-
import { AST_NODE_TYPES as
|
|
7517
|
-
var
|
|
7178
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES34, ESLintUtils as ESLintUtils47 } from "@typescript-eslint/utils";
|
|
7179
|
+
var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
|
|
7518
7180
|
var GENERIC_ENTRYPOINTS = /* @__PURE__ */ new Set(["main", "run", "cli", "setup", "teardown", "execute"]);
|
|
7519
|
-
var
|
|
7181
|
+
var ACRONYM_OVERRIDES = [
|
|
7520
7182
|
[/OAuth/g, "Oauth"],
|
|
7521
7183
|
[/GraphQL/g, "Graphql"],
|
|
7522
7184
|
[/gRPC/g, "Grpc"]
|
|
7523
7185
|
];
|
|
7524
|
-
var
|
|
7525
|
-
var
|
|
7526
|
-
var
|
|
7527
|
-
var
|
|
7186
|
+
var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
|
|
7187
|
+
var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
|
|
7188
|
+
var stemOf = (base) => base.replace(/\.(test|spec|config|d|stories)\.[cm]?[jt]sx?$/i, "").replace(/\.[cm]?[jt]sx?$/i, "");
|
|
7189
|
+
var kebabCase = (name) => {
|
|
7528
7190
|
let normalized = name;
|
|
7529
|
-
for (const [pattern, replacement] of
|
|
7191
|
+
for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
|
|
7530
7192
|
normalized = normalized.replace(pattern, replacement);
|
|
7531
7193
|
}
|
|
7532
|
-
return normalized.replace(
|
|
7194
|
+
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
7533
7195
|
};
|
|
7534
|
-
var isFunctionOrClass = (node) => node.type ===
|
|
7196
|
+
var isFunctionOrClass = (node) => node.type === AST_NODE_TYPES34.ArrowFunctionExpression || node.type === AST_NODE_TYPES34.FunctionExpression;
|
|
7535
7197
|
var findPrimaryExport = (body) => {
|
|
7536
7198
|
let exportCount = 0;
|
|
7537
7199
|
let primaryCandidate = null;
|
|
7538
7200
|
for (const statement of body) {
|
|
7539
|
-
if (statement.type ===
|
|
7201
|
+
if (statement.type === AST_NODE_TYPES34.ExportAllDeclaration) {
|
|
7540
7202
|
return null;
|
|
7541
7203
|
}
|
|
7542
|
-
if (statement.type ===
|
|
7204
|
+
if (statement.type === AST_NODE_TYPES34.ExportDefaultDeclaration) {
|
|
7543
7205
|
exportCount += 1;
|
|
7544
7206
|
const decl = statement.declaration;
|
|
7545
|
-
if ((decl.type ===
|
|
7207
|
+
if ((decl.type === AST_NODE_TYPES34.FunctionDeclaration || decl.type === AST_NODE_TYPES34.ClassDeclaration) && decl.id !== null) {
|
|
7546
7208
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: true };
|
|
7547
|
-
} else if (decl.type ===
|
|
7209
|
+
} else if (decl.type === AST_NODE_TYPES34.Identifier) {
|
|
7548
7210
|
primaryCandidate = { name: decl.name, node: statement, isDefault: true };
|
|
7549
7211
|
}
|
|
7550
|
-
} else if (statement.type ===
|
|
7212
|
+
} else if (statement.type === AST_NODE_TYPES34.ExportNamedDeclaration) {
|
|
7551
7213
|
if (statement.source !== null) {
|
|
7552
7214
|
return null;
|
|
7553
7215
|
}
|
|
@@ -7556,27 +7218,27 @@ var findPrimaryExport = (body) => {
|
|
|
7556
7218
|
exportCount += statement.specifiers.length;
|
|
7557
7219
|
if (statement.specifiers.length === 1 && primaryCandidate === null) {
|
|
7558
7220
|
const spec = statement.specifiers[0];
|
|
7559
|
-
if (spec && spec.exported.type ===
|
|
7221
|
+
if (spec && spec.exported.type === AST_NODE_TYPES34.Identifier) {
|
|
7560
7222
|
primaryCandidate = { name: spec.exported.name, node: statement, isDefault: false };
|
|
7561
7223
|
}
|
|
7562
7224
|
}
|
|
7563
|
-
} else if (decl.type ===
|
|
7225
|
+
} else if (decl.type === AST_NODE_TYPES34.FunctionDeclaration || decl.type === AST_NODE_TYPES34.ClassDeclaration) {
|
|
7564
7226
|
if (decl.id !== null) {
|
|
7565
7227
|
exportCount += 1;
|
|
7566
7228
|
if (primaryCandidate === null) {
|
|
7567
7229
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
7568
7230
|
}
|
|
7569
7231
|
}
|
|
7570
|
-
} else if (decl.type ===
|
|
7232
|
+
} else if (decl.type === AST_NODE_TYPES34.VariableDeclaration) {
|
|
7571
7233
|
for (const declarator of decl.declarations) {
|
|
7572
|
-
if (declarator.id.type ===
|
|
7234
|
+
if (declarator.id.type === AST_NODE_TYPES34.Identifier) {
|
|
7573
7235
|
exportCount += 1;
|
|
7574
7236
|
if (primaryCandidate === null && declarator.init && isFunctionOrClass(declarator.init)) {
|
|
7575
7237
|
primaryCandidate = { name: declarator.id.name, node: statement, isDefault: false };
|
|
7576
7238
|
}
|
|
7577
7239
|
}
|
|
7578
7240
|
}
|
|
7579
|
-
} else if (decl.type ===
|
|
7241
|
+
} else if (decl.type === AST_NODE_TYPES34.TSTypeAliasDeclaration || decl.type === AST_NODE_TYPES34.TSInterfaceDeclaration) {
|
|
7580
7242
|
exportCount += 1;
|
|
7581
7243
|
if (primaryCandidate === null) {
|
|
7582
7244
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
@@ -7589,7 +7251,7 @@ var findPrimaryExport = (body) => {
|
|
|
7589
7251
|
}
|
|
7590
7252
|
return { ...primaryCandidate, count: exportCount };
|
|
7591
7253
|
};
|
|
7592
|
-
var primary_export_file_name_default =
|
|
7254
|
+
var primary_export_file_name_default = ESLintUtils47.RuleCreator(
|
|
7593
7255
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7594
7256
|
)({
|
|
7595
7257
|
name: "primary-export-file-name",
|
|
@@ -7605,10 +7267,10 @@ var primary_export_file_name_default = ESLintUtils48.RuleCreator(
|
|
|
7605
7267
|
},
|
|
7606
7268
|
defaultOptions: [],
|
|
7607
7269
|
create(context) {
|
|
7608
|
-
const base =
|
|
7270
|
+
const base = basename(context.filename);
|
|
7609
7271
|
if (base.endsWith(".d.ts") || base.startsWith("index.") || base.startsWith("_")) return {};
|
|
7610
7272
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
7611
|
-
const stem3 =
|
|
7273
|
+
const stem3 = stemOf(base);
|
|
7612
7274
|
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("[")) {
|
|
7613
7275
|
return {};
|
|
7614
7276
|
}
|
|
@@ -7616,8 +7278,8 @@ var primary_export_file_name_default = ESLintUtils48.RuleCreator(
|
|
|
7616
7278
|
Program(node) {
|
|
7617
7279
|
const primary = findPrimaryExport(node.body);
|
|
7618
7280
|
if (primary === null) return;
|
|
7619
|
-
if (
|
|
7620
|
-
const expectedStem =
|
|
7281
|
+
if (CONVENTIONAL_BUCKET_EXPORTS.has(primary.name) || GENERIC_ENTRYPOINTS.has(primary.name)) return;
|
|
7282
|
+
const expectedStem = kebabCase(primary.name);
|
|
7621
7283
|
if (stem3 === expectedStem) return;
|
|
7622
7284
|
const ext = base.endsWith(".tsx") ? ".tsx" : ".ts";
|
|
7623
7285
|
context.report({
|
|
@@ -7631,7 +7293,7 @@ var primary_export_file_name_default = ESLintUtils48.RuleCreator(
|
|
|
7631
7293
|
});
|
|
7632
7294
|
|
|
7633
7295
|
// src/rules/no-implicit-attribute-access.ts
|
|
7634
|
-
import { AST_NODE_TYPES as
|
|
7296
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES35, ESLintUtils as ESLintUtils48 } from "@typescript-eslint/utils";
|
|
7635
7297
|
var EXCLUDED_BASES = /* @__PURE__ */ new Set([
|
|
7636
7298
|
"environ",
|
|
7637
7299
|
"headers",
|
|
@@ -7647,15 +7309,15 @@ var EXCLUDED_BASES = /* @__PURE__ */ new Set([
|
|
|
7647
7309
|
"sessionStorage"
|
|
7648
7310
|
]);
|
|
7649
7311
|
function getBaseName(node) {
|
|
7650
|
-
if (node.type ===
|
|
7312
|
+
if (node.type === AST_NODE_TYPES35.Identifier) {
|
|
7651
7313
|
return node.name;
|
|
7652
7314
|
}
|
|
7653
|
-
if (node.type ===
|
|
7315
|
+
if (node.type === AST_NODE_TYPES35.MemberExpression && node.property.type === AST_NODE_TYPES35.Identifier) {
|
|
7654
7316
|
return node.property.name;
|
|
7655
7317
|
}
|
|
7656
7318
|
return null;
|
|
7657
7319
|
}
|
|
7658
|
-
var no_implicit_attribute_access_default =
|
|
7320
|
+
var no_implicit_attribute_access_default = ESLintUtils48.RuleCreator(
|
|
7659
7321
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7660
7322
|
)({
|
|
7661
7323
|
name: "no-implicit-attribute-access",
|
|
@@ -7676,7 +7338,7 @@ var no_implicit_attribute_access_default = ESLintUtils49.RuleCreator(
|
|
|
7676
7338
|
if (!node.computed) {
|
|
7677
7339
|
return;
|
|
7678
7340
|
}
|
|
7679
|
-
if (node.property.type ===
|
|
7341
|
+
if (node.property.type === AST_NODE_TYPES35.Literal && typeof node.property.value === "string") {
|
|
7680
7342
|
const baseName = getBaseName(node.object);
|
|
7681
7343
|
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7682
7344
|
context.report({
|
|
@@ -7689,11 +7351,11 @@ var no_implicit_attribute_access_default = ESLintUtils49.RuleCreator(
|
|
|
7689
7351
|
},
|
|
7690
7352
|
CallExpression(node) {
|
|
7691
7353
|
const callee = node.callee;
|
|
7692
|
-
if (callee.type ===
|
|
7693
|
-
const method = callee.property.type ===
|
|
7354
|
+
if (callee.type === AST_NODE_TYPES35.MemberExpression) {
|
|
7355
|
+
const method = callee.property.type === AST_NODE_TYPES35.Identifier ? callee.property.name : null;
|
|
7694
7356
|
if (method === "get") {
|
|
7695
7357
|
const arg = node.arguments[0];
|
|
7696
|
-
if (arg && arg.type ===
|
|
7358
|
+
if (arg && arg.type === AST_NODE_TYPES35.Literal && typeof arg.value === "string") {
|
|
7697
7359
|
const baseName = getBaseName(callee.object);
|
|
7698
7360
|
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7699
7361
|
context.report({
|
|
@@ -7710,8 +7372,174 @@ var no_implicit_attribute_access_default = ESLintUtils49.RuleCreator(
|
|
|
7710
7372
|
}
|
|
7711
7373
|
});
|
|
7712
7374
|
|
|
7375
|
+
// src/rules/strict-test-assertions.ts
|
|
7376
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES36, ESLintUtils as ESLintUtils49 } from "@typescript-eslint/utils";
|
|
7377
|
+
var strict_test_assertions_default = ESLintUtils49.RuleCreator.withoutDocs({
|
|
7378
|
+
meta: {
|
|
7379
|
+
type: "suggestion",
|
|
7380
|
+
docs: {
|
|
7381
|
+
description: "Replace multiple sequential assertions with a single toMatchObject or toStrictEqual"
|
|
7382
|
+
},
|
|
7383
|
+
fixable: "code",
|
|
7384
|
+
messages: {
|
|
7385
|
+
combineAssertions: "Combine multiple sequential assertions on the same object into a single toMatchObject or toStrictEqual"
|
|
7386
|
+
},
|
|
7387
|
+
schema: []
|
|
7388
|
+
},
|
|
7389
|
+
defaultOptions: [],
|
|
7390
|
+
create(context) {
|
|
7391
|
+
function checkBody(body) {
|
|
7392
|
+
let currentObject = null;
|
|
7393
|
+
let sequence = [];
|
|
7394
|
+
function getExpectObject(expr) {
|
|
7395
|
+
if (expr.type === AST_NODE_TYPES36.CallExpression && expr.callee.type === AST_NODE_TYPES36.MemberExpression && expr.callee.object.type === AST_NODE_TYPES36.CallExpression && expr.callee.object.callee.type === AST_NODE_TYPES36.Identifier && expr.callee.object.callee.name === "expect" && expr.callee.object.arguments.length === 1) {
|
|
7396
|
+
const arg = expr.callee.object.arguments.at(0);
|
|
7397
|
+
if (arg?.type === AST_NODE_TYPES36.MemberExpression) {
|
|
7398
|
+
return arg.object;
|
|
7399
|
+
}
|
|
7400
|
+
}
|
|
7401
|
+
return null;
|
|
7402
|
+
}
|
|
7403
|
+
function reportSequence() {
|
|
7404
|
+
const first = sequence.at(0);
|
|
7405
|
+
if (sequence.length > 1 && first) {
|
|
7406
|
+
context.report({
|
|
7407
|
+
node: first,
|
|
7408
|
+
messageId: "combineAssertions",
|
|
7409
|
+
fix(fixer) {
|
|
7410
|
+
if (!currentObject) return null;
|
|
7411
|
+
const objectText = context.sourceCode.getText(currentObject);
|
|
7412
|
+
const props = sequence.map((stmt) => {
|
|
7413
|
+
if (stmt.expression.type !== AST_NODE_TYPES36.CallExpression || stmt.expression.callee.type !== AST_NODE_TYPES36.MemberExpression || stmt.expression.callee.object.type !== AST_NODE_TYPES36.CallExpression) {
|
|
7414
|
+
return null;
|
|
7415
|
+
}
|
|
7416
|
+
const actual = stmt.expression.callee.object.arguments.at(0);
|
|
7417
|
+
const expected = stmt.expression.arguments.at(0);
|
|
7418
|
+
if (actual?.type === AST_NODE_TYPES36.MemberExpression && actual.property.type === AST_NODE_TYPES36.Identifier && expected) {
|
|
7419
|
+
const propName2 = actual.property.name;
|
|
7420
|
+
const valText = context.sourceCode.getText(expected);
|
|
7421
|
+
return `${propName2}: ${valText}`;
|
|
7422
|
+
}
|
|
7423
|
+
return null;
|
|
7424
|
+
});
|
|
7425
|
+
if (props.some((p) => p === null)) return null;
|
|
7426
|
+
const replacement = `expect(${objectText}).toMatchObject({ ${props.join(", ")} });`;
|
|
7427
|
+
return [
|
|
7428
|
+
fixer.replaceText(first, replacement),
|
|
7429
|
+
...sequence.slice(1).map((stmt) => fixer.remove(stmt))
|
|
7430
|
+
];
|
|
7431
|
+
}
|
|
7432
|
+
});
|
|
7433
|
+
}
|
|
7434
|
+
}
|
|
7435
|
+
for (const statement of body) {
|
|
7436
|
+
if (statement.type === AST_NODE_TYPES36.ExpressionStatement) {
|
|
7437
|
+
const obj = getExpectObject(statement.expression);
|
|
7438
|
+
if (obj && currentObject && context.sourceCode.getText(obj) === context.sourceCode.getText(currentObject)) {
|
|
7439
|
+
sequence.push(statement);
|
|
7440
|
+
} else {
|
|
7441
|
+
reportSequence();
|
|
7442
|
+
if (obj) {
|
|
7443
|
+
currentObject = obj;
|
|
7444
|
+
sequence = [statement];
|
|
7445
|
+
} else {
|
|
7446
|
+
currentObject = null;
|
|
7447
|
+
sequence = [];
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
} else {
|
|
7451
|
+
reportSequence();
|
|
7452
|
+
currentObject = null;
|
|
7453
|
+
sequence = [];
|
|
7454
|
+
}
|
|
7455
|
+
}
|
|
7456
|
+
reportSequence();
|
|
7457
|
+
}
|
|
7458
|
+
return {
|
|
7459
|
+
BlockStatement(node) {
|
|
7460
|
+
checkBody(node.body);
|
|
7461
|
+
},
|
|
7462
|
+
Program(node) {
|
|
7463
|
+
checkBody(node.body);
|
|
7464
|
+
}
|
|
7465
|
+
};
|
|
7466
|
+
}
|
|
7467
|
+
});
|
|
7468
|
+
|
|
7469
|
+
// src/rules/no-async-callback-in-waitfor.ts
|
|
7470
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES37, ESLintUtils as ESLintUtils50 } from "@typescript-eslint/utils";
|
|
7471
|
+
var no_async_callback_in_waitfor_default = ESLintUtils50.RuleCreator(
|
|
7472
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7473
|
+
)({
|
|
7474
|
+
name: "no-async-callback-in-waitfor",
|
|
7475
|
+
meta: {
|
|
7476
|
+
type: "problem",
|
|
7477
|
+
docs: {
|
|
7478
|
+
description: "Disallow async callbacks in `waitFor` to prevent swallowed promise rejections."
|
|
7479
|
+
},
|
|
7480
|
+
schema: [],
|
|
7481
|
+
messages: {
|
|
7482
|
+
noAsyncCallbackInWaitFor: "The callback to `waitFor` should not be async. It expects synchronous assertions and runs the callback repeatedly."
|
|
7483
|
+
}
|
|
7484
|
+
},
|
|
7485
|
+
defaultOptions: [],
|
|
7486
|
+
create(context) {
|
|
7487
|
+
if (!isTestFile(context.filename)) {
|
|
7488
|
+
return {};
|
|
7489
|
+
}
|
|
7490
|
+
return {
|
|
7491
|
+
CallExpression(node) {
|
|
7492
|
+
if (node.callee.type === AST_NODE_TYPES37.Identifier && node.callee.name === "waitFor") {
|
|
7493
|
+
const callback = node.arguments[0];
|
|
7494
|
+
if (callback && (callback.type === AST_NODE_TYPES37.ArrowFunctionExpression || callback.type === AST_NODE_TYPES37.FunctionExpression) && callback.async) {
|
|
7495
|
+
context.report({
|
|
7496
|
+
node: callback,
|
|
7497
|
+
messageId: "noAsyncCallbackInWaitFor"
|
|
7498
|
+
});
|
|
7499
|
+
}
|
|
7500
|
+
}
|
|
7501
|
+
}
|
|
7502
|
+
};
|
|
7503
|
+
}
|
|
7504
|
+
});
|
|
7505
|
+
|
|
7506
|
+
// src/rules/prefer-setup-file-mocks.ts
|
|
7507
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES38, ESLintUtils as ESLintUtils51 } from "@typescript-eslint/utils";
|
|
7508
|
+
var prefer_setup_file_mocks_default = ESLintUtils51.RuleCreator(
|
|
7509
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7510
|
+
)({
|
|
7511
|
+
name: "prefer-setup-file-mocks",
|
|
7512
|
+
meta: {
|
|
7513
|
+
type: "suggestion",
|
|
7514
|
+
docs: {
|
|
7515
|
+
description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
|
|
7516
|
+
},
|
|
7517
|
+
schema: [],
|
|
7518
|
+
messages: {
|
|
7519
|
+
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."
|
|
7520
|
+
}
|
|
7521
|
+
},
|
|
7522
|
+
defaultOptions: [],
|
|
7523
|
+
create(context) {
|
|
7524
|
+
if (!isTestFile(context.filename)) {
|
|
7525
|
+
return {};
|
|
7526
|
+
}
|
|
7527
|
+
return {
|
|
7528
|
+
CallExpression(node) {
|
|
7529
|
+
if (node.callee.type === AST_NODE_TYPES38.MemberExpression && node.callee.object.type === AST_NODE_TYPES38.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === AST_NODE_TYPES38.Identifier && node.callee.property.name === "mock") {
|
|
7530
|
+
context.report({
|
|
7531
|
+
node,
|
|
7532
|
+
messageId: "preferSetupFileMocks"
|
|
7533
|
+
});
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
};
|
|
7537
|
+
}
|
|
7538
|
+
});
|
|
7539
|
+
|
|
7713
7540
|
// src/index.ts
|
|
7714
7541
|
var rules = {
|
|
7542
|
+
"ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
|
|
7715
7543
|
"enforce-file-structure": enforce_file_structure_default,
|
|
7716
7544
|
"no-client-side-data-fetching": no_client_side_data_fetching_default,
|
|
7717
7545
|
"no-comment-cruft": no_comment_cruft_default,
|
|
@@ -7721,32 +7549,30 @@ var rules = {
|
|
|
7721
7549
|
"no-log-only-catch": no_log_only_catch_default,
|
|
7722
7550
|
"no-raw-env": no_raw_env_default,
|
|
7723
7551
|
"no-sentinel-return-on-catch": no_sentinel_return_on_catch_default,
|
|
7724
|
-
"no-sequential-await": no_sequential_await_default,
|
|
7725
7552
|
"no-string-concat-in-loop": no_string_concat_in_loop_default,
|
|
7726
7553
|
"no-unnecessary-use-client": no_unnecessary_use_client_default,
|
|
7727
7554
|
"prefer-discriminated-union": prefer_discriminated_union_default,
|
|
7728
7555
|
"prefer-schema-for-api-payload": prefer_schema_for_api_payload_default,
|
|
7729
7556
|
"prefer-semantic-colors": prefer_semantic_colors_default,
|
|
7730
7557
|
"prefer-server-actions": prefer_server_actions_default,
|
|
7731
|
-
"prefer-shadcn": prefer_shadcn_default,
|
|
7732
7558
|
"require-assert-never": require_assert_never_default,
|
|
7733
7559
|
"require-zod-form-validation": require_zod_form_validation_default,
|
|
7734
7560
|
"zod-naming-convention": zod_naming_convention_default,
|
|
7735
7561
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
7736
7562
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
7737
7563
|
"no-secret-in-log": no_secret_in_log_default,
|
|
7738
|
-
"no-unsafe-
|
|
7564
|
+
"no-unsafe-mock-casting": no_unsafe_mock_casting_default,
|
|
7739
7565
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
7740
|
-
"
|
|
7566
|
+
"prefer-zod-enum": prefer_zod_enum_default,
|
|
7741
7567
|
"primary-export-file-name": primary_export_file_name_default,
|
|
7742
7568
|
"no-silent-promise-catch": no_silent_promise_catch_default,
|
|
7743
7569
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
7744
|
-
"require-schema-validate-search": require_schema_validate_search_default,
|
|
7745
7570
|
"no-offset-pagination": no_offset_pagination_default,
|
|
7746
7571
|
"no-positional-tuple-return": no_positional_tuple_return_default,
|
|
7747
7572
|
"no-repeated-string-literal": no_repeated_string_literal_default,
|
|
7748
7573
|
"no-select-star": no_select_star_default,
|
|
7749
7574
|
"no-sleep-in-test-body": no_sleep_in_test_body_default,
|
|
7575
|
+
"no-conditional-in-test": no_conditional_in_test_default,
|
|
7750
7576
|
"prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
|
|
7751
7577
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
7752
7578
|
"no-dynamic-sql": no_dynamic_sql_default,
|
|
@@ -7759,13 +7585,16 @@ var rules = {
|
|
|
7759
7585
|
"trailing-value-narration": trailing_value_narration_default,
|
|
7760
7586
|
"no-tautological-expect": no_tautological_expect_default,
|
|
7761
7587
|
"require-interface-for-injected-service": require_interface_for_injected_service_default,
|
|
7588
|
+
"strict-test-assertions": strict_test_assertions_default,
|
|
7762
7589
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
7763
|
-
"no-implicit-attribute-access": no_implicit_attribute_access_default
|
|
7590
|
+
"no-implicit-attribute-access": no_implicit_attribute_access_default,
|
|
7591
|
+
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
|
|
7592
|
+
"prefer-setup-file-mocks": prefer_setup_file_mocks_default
|
|
7764
7593
|
};
|
|
7765
7594
|
var plugin = {
|
|
7766
7595
|
meta: {
|
|
7767
7596
|
name: "@sarj/eslint-plugin",
|
|
7768
|
-
version: "
|
|
7597
|
+
version: "3.0.0"
|
|
7769
7598
|
},
|
|
7770
7599
|
rules,
|
|
7771
7600
|
configs: {
|
|
@@ -7775,13 +7604,13 @@ var plugin = {
|
|
|
7775
7604
|
"@sarj/zod-naming-convention": "warn",
|
|
7776
7605
|
"@sarj/require-assert-never": "error",
|
|
7777
7606
|
"@sarj/require-zod-form-validation": "error",
|
|
7607
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7778
7608
|
"@sarj/enforce-file-structure": "warn",
|
|
7779
7609
|
"@sarj/no-client-side-data-fetching": "warn",
|
|
7780
7610
|
"@sarj/prefer-server-actions": "warn",
|
|
7781
7611
|
"@sarj/no-unnecessary-use-client": "warn",
|
|
7782
7612
|
"@sarj/prefer-schema-for-api-payload": "warn",
|
|
7783
7613
|
// Distilled from sarj-audit skills — warn in recommended, error in strict.
|
|
7784
|
-
"@sarj/no-sequential-await": "warn",
|
|
7785
7614
|
"@sarj/no-sentinel-return-on-catch": "warn",
|
|
7786
7615
|
"@sarj/no-log-only-catch": "warn",
|
|
7787
7616
|
"@sarj/no-insecure-random-id": "warn",
|
|
@@ -7798,14 +7627,13 @@ var plugin = {
|
|
|
7798
7627
|
"@sarj/no-fat-try-blocks": "warn",
|
|
7799
7628
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
7800
7629
|
"@sarj/no-secret-in-log": "warn",
|
|
7801
|
-
"@sarj/no-unsafe-
|
|
7802
|
-
"@sarj/single-public-export": "warn",
|
|
7630
|
+
"@sarj/no-unsafe-mock-casting": "warn",
|
|
7803
7631
|
"@sarj/primary-export-file-name": "warn",
|
|
7804
7632
|
"@sarj/prefer-string-literal-union": "warn",
|
|
7633
|
+
"@sarj/prefer-zod-enum": "warn",
|
|
7805
7634
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7806
7635
|
"@sarj/require-fetch-timeout": "warn",
|
|
7807
7636
|
"@sarj/no-silent-promise-catch": "warn",
|
|
7808
|
-
"@sarj/require-schema-validate-search": "warn",
|
|
7809
7637
|
// Second SARJ port wave — the TS/Python parity gap. Each targets a
|
|
7810
7638
|
// defect class seen in production Workers code: timing-leaky secret
|
|
7811
7639
|
// compares, non-idempotent store writes under queue redelivery,
|
|
@@ -7815,6 +7643,7 @@ var plugin = {
|
|
|
7815
7643
|
"@sarj/no-offset-pagination": "warn",
|
|
7816
7644
|
"@sarj/no-select-star": "warn",
|
|
7817
7645
|
"@sarj/no-sleep-in-test-body": "warn",
|
|
7646
|
+
"@sarj/no-conditional-in-test": "warn",
|
|
7818
7647
|
"@sarj/no-repeated-string-literal": "warn",
|
|
7819
7648
|
"@sarj/no-positional-tuple-return": "warn",
|
|
7820
7649
|
// Injection guard — low FP, applies to any repo touching SQL.
|
|
@@ -7851,7 +7680,9 @@ var plugin = {
|
|
|
7851
7680
|
// port, 29 fire, 28 of them true positives.
|
|
7852
7681
|
"@sarj/require-interface-for-injected-service": "warn",
|
|
7853
7682
|
"@sarj/prefer-non-nullable-collection": "warn",
|
|
7854
|
-
"@sarj/no-implicit-attribute-access": "warn"
|
|
7683
|
+
"@sarj/no-implicit-attribute-access": "warn",
|
|
7684
|
+
"@sarj/no-async-callback-in-waitfor": "warn",
|
|
7685
|
+
"@sarj/prefer-setup-file-mocks": "warn"
|
|
7855
7686
|
}
|
|
7856
7687
|
},
|
|
7857
7688
|
strict: {
|
|
@@ -7860,16 +7691,15 @@ var plugin = {
|
|
|
7860
7691
|
"@sarj/zod-naming-convention": "error",
|
|
7861
7692
|
"@sarj/require-assert-never": "error",
|
|
7862
7693
|
"@sarj/require-zod-form-validation": "error",
|
|
7694
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7863
7695
|
"@sarj/enforce-file-structure": "error",
|
|
7864
7696
|
"@sarj/no-raw-env": "error",
|
|
7865
|
-
"@sarj/prefer-shadcn": "error",
|
|
7866
7697
|
"@sarj/no-enum": "error",
|
|
7867
7698
|
"@sarj/no-client-side-data-fetching": "error",
|
|
7868
7699
|
"@sarj/prefer-server-actions": "error",
|
|
7869
7700
|
"@sarj/no-unnecessary-use-client": "error",
|
|
7870
7701
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
7871
7702
|
// Distilled from sarj-audit skills.
|
|
7872
|
-
"@sarj/no-sequential-await": "error",
|
|
7873
7703
|
"@sarj/no-sentinel-return-on-catch": "error",
|
|
7874
7704
|
"@sarj/no-log-only-catch": "error",
|
|
7875
7705
|
"@sarj/no-insecure-random-id": "error",
|
|
@@ -7887,21 +7717,21 @@ var plugin = {
|
|
|
7887
7717
|
"@sarj/no-fat-try-blocks": "error",
|
|
7888
7718
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
7889
7719
|
"@sarj/no-secret-in-log": "error",
|
|
7890
|
-
"@sarj/no-unsafe-
|
|
7891
|
-
"@sarj/single-public-export": "error",
|
|
7720
|
+
"@sarj/no-unsafe-mock-casting": "error",
|
|
7892
7721
|
"@sarj/primary-export-file-name": "error",
|
|
7893
7722
|
// Promoted to error 2026-07-25 — strict means strict (user directive).
|
|
7894
7723
|
"@sarj/prefer-string-literal-union": "error",
|
|
7724
|
+
"@sarj/prefer-zod-enum": "error",
|
|
7895
7725
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7896
7726
|
"@sarj/require-fetch-timeout": "error",
|
|
7897
7727
|
"@sarj/no-silent-promise-catch": "error",
|
|
7898
|
-
"@sarj/require-schema-validate-search": "error",
|
|
7899
7728
|
// Second SARJ port wave — the TS/Python parity gap.
|
|
7900
7729
|
"@sarj/prefer-constant-time-secret-compare": "error",
|
|
7901
7730
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
7902
7731
|
"@sarj/no-offset-pagination": "error",
|
|
7903
7732
|
"@sarj/no-select-star": "error",
|
|
7904
7733
|
"@sarj/no-sleep-in-test-body": "error",
|
|
7734
|
+
"@sarj/no-conditional-in-test": "error",
|
|
7905
7735
|
"@sarj/no-repeated-string-literal": "error",
|
|
7906
7736
|
// API-shape advice rather than a runtime defect — a corpus sweep found its
|
|
7907
7737
|
// only hits are parser `[value, cursor]` returns, which are conventional.
|
|
@@ -7931,7 +7761,9 @@ var plugin = {
|
|
|
7931
7761
|
// corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
|
|
7932
7762
|
"@sarj/require-interface-for-injected-service": "error",
|
|
7933
7763
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
7934
|
-
"@sarj/no-implicit-attribute-access": "error"
|
|
7764
|
+
"@sarj/no-implicit-attribute-access": "error",
|
|
7765
|
+
"@sarj/no-async-callback-in-waitfor": "error",
|
|
7766
|
+
"@sarj/prefer-setup-file-mocks": "error"
|
|
7935
7767
|
}
|
|
7936
7768
|
}
|
|
7937
7769
|
}
|