@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.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
|
-
// src/rules/
|
|
38
|
+
// src/rules/ban-loose-type-guards-in-tests.ts
|
|
39
39
|
var import_utils = require("@typescript-eslint/utils");
|
|
40
40
|
|
|
41
41
|
// src/rules/_paths.ts
|
|
@@ -61,27 +61,63 @@ function isScriptFile(filename) {
|
|
|
61
61
|
return SCRIPT_FILE_RE.test(filename);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// src/rules/ban-loose-type-guards-in-tests.ts
|
|
65
|
+
var ban_loose_type_guards_in_tests_default = import_utils.ESLintUtils.RuleCreator(
|
|
66
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
67
|
+
)({
|
|
68
|
+
name: "ban-loose-type-guards-in-tests",
|
|
69
|
+
meta: {
|
|
70
|
+
type: "problem",
|
|
71
|
+
docs: {
|
|
72
|
+
description: "Disallow loose type guards (`typeof` and `in`) in test files. Enforce Zod schemas or strict matchers for type validation."
|
|
73
|
+
},
|
|
74
|
+
schema: [],
|
|
75
|
+
messages: {
|
|
76
|
+
banLooseTypeGuardsInTests: "Do not use `typeof` or `in` for type validation in tests. Use Zod schemas or strict assertion matchers instead."
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
defaultOptions: [],
|
|
80
|
+
create(context) {
|
|
81
|
+
if (!isTestFile(context.filename)) {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
UnaryExpression(node) {
|
|
86
|
+
if (node.operator === "typeof") {
|
|
87
|
+
context.report({ node, messageId: "banLooseTypeGuardsInTests" });
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
BinaryExpression(node) {
|
|
91
|
+
if (node.operator === "in") {
|
|
92
|
+
context.report({ node, messageId: "banLooseTypeGuardsInTests" });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
64
99
|
// src/rules/enforce-file-structure.ts
|
|
100
|
+
var import_utils2 = require("@typescript-eslint/utils");
|
|
65
101
|
var classifyStatement = (statement) => {
|
|
66
102
|
switch (statement.type) {
|
|
67
|
-
case
|
|
103
|
+
case import_utils2.AST_NODE_TYPES.ImportDeclaration:
|
|
68
104
|
return "import";
|
|
69
|
-
case
|
|
105
|
+
case import_utils2.AST_NODE_TYPES.ExportAllDeclaration:
|
|
70
106
|
return "reexport";
|
|
71
|
-
case
|
|
107
|
+
case import_utils2.AST_NODE_TYPES.ExportNamedDeclaration:
|
|
72
108
|
return statement.declaration === null ? "reexport" : "body";
|
|
73
109
|
default:
|
|
74
110
|
return "body";
|
|
75
111
|
}
|
|
76
112
|
};
|
|
77
|
-
var isStringDirective = (statement) => statement.type ===
|
|
113
|
+
var isStringDirective = (statement) => statement.type === import_utils2.AST_NODE_TYPES.ExpressionStatement && statement.expression.type === import_utils2.AST_NODE_TYPES.Literal && typeof statement.expression.value === "string" && statement.expression.value.startsWith("use ");
|
|
78
114
|
var isUseServerDirective = (statement) => {
|
|
79
|
-
if (statement.type !==
|
|
115
|
+
if (statement.type !== import_utils2.AST_NODE_TYPES.ExpressionStatement) return false;
|
|
80
116
|
const expr = statement.expression;
|
|
81
|
-
if (expr.type !==
|
|
117
|
+
if (expr.type !== import_utils2.AST_NODE_TYPES.Literal) return false;
|
|
82
118
|
return expr.value === "use server";
|
|
83
119
|
};
|
|
84
|
-
var enforce_file_structure_default =
|
|
120
|
+
var enforce_file_structure_default = import_utils2.ESLintUtils.RuleCreator(
|
|
85
121
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
86
122
|
)({
|
|
87
123
|
name: "enforce-file-structure",
|
|
@@ -141,7 +177,7 @@ var enforce_file_structure_default = import_utils.ESLintUtils.RuleCreator(
|
|
|
141
177
|
});
|
|
142
178
|
|
|
143
179
|
// src/rules/no-client-side-data-fetching.ts
|
|
144
|
-
var
|
|
180
|
+
var import_utils3 = require("@typescript-eslint/utils");
|
|
145
181
|
var FETCH_LIBS = /* @__PURE__ */ new Set(["axios", "ky", "superagent"]);
|
|
146
182
|
var HTTP_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
147
183
|
"get",
|
|
@@ -165,25 +201,25 @@ var ANALYTICS_SEGMENTS = /* @__PURE__ */ new Set([
|
|
|
165
201
|
]);
|
|
166
202
|
function isEffectHookCall(node) {
|
|
167
203
|
const callee = node.callee;
|
|
168
|
-
if (callee.type ===
|
|
204
|
+
if (callee.type === import_utils3.AST_NODE_TYPES.Identifier) {
|
|
169
205
|
return callee.name === "useEffect" || callee.name === "useLayoutEffect";
|
|
170
206
|
}
|
|
171
|
-
if (callee.type ===
|
|
207
|
+
if (callee.type === import_utils3.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils3.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === import_utils3.AST_NODE_TYPES.Identifier) {
|
|
172
208
|
return callee.property.name === "useEffect" || callee.property.name === "useLayoutEffect";
|
|
173
209
|
}
|
|
174
210
|
return false;
|
|
175
211
|
}
|
|
176
212
|
function readMethodProperty(optionsArg) {
|
|
177
|
-
if (!optionsArg || optionsArg.type !==
|
|
213
|
+
if (!optionsArg || optionsArg.type !== import_utils3.AST_NODE_TYPES.ObjectExpression) {
|
|
178
214
|
return null;
|
|
179
215
|
}
|
|
180
216
|
for (const prop of optionsArg.properties) {
|
|
181
|
-
if (prop.type !==
|
|
217
|
+
if (prop.type !== import_utils3.AST_NODE_TYPES.Property) continue;
|
|
182
218
|
if (prop.computed) continue;
|
|
183
219
|
const key = prop.key;
|
|
184
|
-
const matchesMethodKey = key.type ===
|
|
220
|
+
const matchesMethodKey = key.type === import_utils3.AST_NODE_TYPES.Identifier && key.name === "method" || key.type === import_utils3.AST_NODE_TYPES.Literal && key.value === "method";
|
|
185
221
|
if (!matchesMethodKey) continue;
|
|
186
|
-
if (prop.value.type ===
|
|
222
|
+
if (prop.value.type === import_utils3.AST_NODE_TYPES.Literal && typeof prop.value.value === "string") {
|
|
187
223
|
return prop.value.value.toUpperCase();
|
|
188
224
|
}
|
|
189
225
|
return null;
|
|
@@ -192,23 +228,23 @@ function readMethodProperty(optionsArg) {
|
|
|
192
228
|
}
|
|
193
229
|
function isFetchCall(node) {
|
|
194
230
|
const callee = node.callee;
|
|
195
|
-
if (callee.type ===
|
|
231
|
+
if (callee.type === import_utils3.AST_NODE_TYPES.Identifier && callee.name === "fetch") {
|
|
196
232
|
const method = readMethodProperty(node.arguments[1]);
|
|
197
233
|
if (method !== null && method !== "GET") {
|
|
198
234
|
return false;
|
|
199
235
|
}
|
|
200
236
|
return true;
|
|
201
237
|
}
|
|
202
|
-
if (callee.type ===
|
|
238
|
+
if (callee.type === import_utils3.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils3.AST_NODE_TYPES.Identifier && FETCH_LIBS.has(callee.object.name) && callee.property.type === import_utils3.AST_NODE_TYPES.Identifier) {
|
|
203
239
|
return HTTP_METHOD_NAMES.has(callee.property.name);
|
|
204
240
|
}
|
|
205
|
-
if (callee.type ===
|
|
241
|
+
if (callee.type === import_utils3.AST_NODE_TYPES.Identifier && (callee.name === "axios" || callee.name === "ky")) {
|
|
206
242
|
const firstArg = node.arguments[0];
|
|
207
243
|
const secondArg = node.arguments[1];
|
|
208
244
|
let configArg;
|
|
209
|
-
if (firstArg?.type ===
|
|
245
|
+
if (firstArg?.type === import_utils3.AST_NODE_TYPES.ObjectExpression) {
|
|
210
246
|
configArg = firstArg;
|
|
211
|
-
} else if (secondArg?.type ===
|
|
247
|
+
} else if (secondArg?.type === import_utils3.AST_NODE_TYPES.ObjectExpression) {
|
|
212
248
|
configArg = secondArg;
|
|
213
249
|
}
|
|
214
250
|
const method = readMethodProperty(configArg);
|
|
@@ -222,13 +258,13 @@ function isFetchCall(node) {
|
|
|
222
258
|
function extractUrlString(node) {
|
|
223
259
|
const firstArg = node.arguments[0];
|
|
224
260
|
if (!firstArg) return "";
|
|
225
|
-
if (firstArg.type ===
|
|
261
|
+
if (firstArg.type === import_utils3.AST_NODE_TYPES.Literal && typeof firstArg.value === "string") {
|
|
226
262
|
return firstArg.value;
|
|
227
263
|
}
|
|
228
|
-
if (firstArg.type ===
|
|
264
|
+
if (firstArg.type === import_utils3.AST_NODE_TYPES.TemplateLiteral) {
|
|
229
265
|
return firstArg.quasis.map((q) => q.value.cooked).join("");
|
|
230
266
|
}
|
|
231
|
-
if (firstArg.type ===
|
|
267
|
+
if (firstArg.type === import_utils3.AST_NODE_TYPES.Identifier) {
|
|
232
268
|
return firstArg.name;
|
|
233
269
|
}
|
|
234
270
|
return "";
|
|
@@ -238,7 +274,7 @@ function isAnalyticsCall(node) {
|
|
|
238
274
|
if (url === "") return false;
|
|
239
275
|
return url.split(/[/.]/).some((segment) => ANALYTICS_SEGMENTS.has(segment));
|
|
240
276
|
}
|
|
241
|
-
var no_client_side_data_fetching_default =
|
|
277
|
+
var no_client_side_data_fetching_default = import_utils3.ESLintUtils.RuleCreator(
|
|
242
278
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
243
279
|
)({
|
|
244
280
|
name: "no-client-side-data-fetching",
|
|
@@ -276,10 +312,10 @@ var no_client_side_data_fetching_default = import_utils2.ESLintUtils.RuleCreator
|
|
|
276
312
|
});
|
|
277
313
|
|
|
278
314
|
// src/rules/no-comment-cruft.ts
|
|
279
|
-
var
|
|
315
|
+
var import_utils5 = require("@typescript-eslint/utils");
|
|
280
316
|
|
|
281
317
|
// src/rules/_comments.ts
|
|
282
|
-
var
|
|
318
|
+
var import_utils4 = require("@typescript-eslint/utils");
|
|
283
319
|
var REF_RE = /https?:\/\/|\bRFC[- ]?\d+|\bPEP[- ]?\d+|\bCVE-\d{4}|\b(?!UTF-|SHA-|ISO-|AES-|CRC-|MD-|PCM-|EOF-|API-|BASE-)[A-Z][A-Z0-9]{1,9}-\d[A-Z0-9]{0,5}\b|(?<![&\w])#\d{2,6}\b|@[a-z][\w.-]*\.(?:us|com|ai|io|net|org|dev)\b/;
|
|
284
320
|
var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
|
|
285
321
|
var UNITS_RE = /[~<>]?\d+(?:\.\d+)?\s?(?:ms|s\b|sec\b|seconds?\b|min\b|minutes?\b|hours?\b|days?\b|KB|MB|MiB|GiB|kHz|Hz|bytes?\b|bit\b|-bit\b|%|px\b|rps\b|qps\b)|\b[1-5]xx\b|\b(?:301|302|304|307|308|400|401|403|404|405|409|410|412|422|425|429|500|501|502|503|504)\b/;
|
|
@@ -365,10 +401,10 @@ var NARRATION_MAX_WORDS = 6;
|
|
|
365
401
|
var NARRATION_MIN_CONTENT = 1;
|
|
366
402
|
var TOKEN_PLURAL_MIN = 4;
|
|
367
403
|
var RESTATABLE_STATEMENTS = /* @__PURE__ */ new Set([
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
404
|
+
import_utils4.AST_NODE_TYPES.ExpressionStatement,
|
|
405
|
+
import_utils4.AST_NODE_TYPES.ReturnStatement,
|
|
406
|
+
import_utils4.AST_NODE_TYPES.ThrowStatement,
|
|
407
|
+
import_utils4.AST_NODE_TYPES.VariableDeclaration
|
|
372
408
|
]);
|
|
373
409
|
var NARRATION_VERB_RE = /^(?:add|append|assign|build|calculate|call|check|clear|close|compute|convert|copy|count|create|declare|decrement|define|delete|extract|fetch|filter|find|format|generate|get|handle|increment|init|initialise|initialize|insert|iterate|join|load|log|loop|make|map|merge|open|parse|print|process|push|read|remove|render|reset|return|save|send|set|setup|sort|split|start|stop|store|update|validate|wrap|write)(?:s|es|d|ed|ing)?$/i;
|
|
374
410
|
var NARRATION_STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -433,19 +469,19 @@ function headTokens(source) {
|
|
|
433
469
|
function isTrivialInitializer(node) {
|
|
434
470
|
return node.declarations.every((declarator) => {
|
|
435
471
|
const init = declarator.init;
|
|
436
|
-
if (init == null || init.type ===
|
|
437
|
-
return init.type ===
|
|
472
|
+
if (init == null || init.type === import_utils4.AST_NODE_TYPES.Literal) return true;
|
|
473
|
+
return init.type === import_utils4.AST_NODE_TYPES.ArrayExpression && init.elements.length === 0 || init.type === import_utils4.AST_NODE_TYPES.ObjectExpression && init.properties.length === 0;
|
|
438
474
|
});
|
|
439
475
|
}
|
|
440
476
|
function restatableStatementBelow(comment, sourceCode) {
|
|
441
477
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
442
478
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) return null;
|
|
443
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
479
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils4.AST_NODE_TYPES.Program; node = node.parent) {
|
|
444
480
|
if (!RESTATABLE_STATEMENTS.has(node.type)) continue;
|
|
445
481
|
if (node.loc.start.line !== token.loc.start.line || node.loc.end.line !== node.loc.start.line) {
|
|
446
482
|
return null;
|
|
447
483
|
}
|
|
448
|
-
if (node.type ===
|
|
484
|
+
if (node.type === import_utils4.AST_NODE_TYPES.VariableDeclaration && isTrivialInitializer(node)) {
|
|
449
485
|
return null;
|
|
450
486
|
}
|
|
451
487
|
return sourceCode.getText(node);
|
|
@@ -598,13 +634,13 @@ function isRedundantNarration(body, statementBelow, standalone, isolatedEnumerat
|
|
|
598
634
|
return restatesStatementHead(t, statementBelow);
|
|
599
635
|
}
|
|
600
636
|
var STATEMENT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
637
|
+
import_utils5.AST_NODE_TYPES.Program,
|
|
638
|
+
import_utils5.AST_NODE_TYPES.BlockStatement,
|
|
639
|
+
import_utils5.AST_NODE_TYPES.ClassBody,
|
|
640
|
+
import_utils5.AST_NODE_TYPES.StaticBlock,
|
|
641
|
+
import_utils5.AST_NODE_TYPES.SwitchCase,
|
|
642
|
+
import_utils5.AST_NODE_TYPES.TSModuleBlock,
|
|
643
|
+
import_utils5.AST_NODE_TYPES.TSInterfaceBody
|
|
608
644
|
]);
|
|
609
645
|
function runCitesAReference(comments, index) {
|
|
610
646
|
for (let i = index; i >= 0; i--) {
|
|
@@ -645,7 +681,7 @@ function hasCommentedOutCode(texts, precedingProse) {
|
|
|
645
681
|
}
|
|
646
682
|
return false;
|
|
647
683
|
}
|
|
648
|
-
var no_comment_cruft_default =
|
|
684
|
+
var no_comment_cruft_default = import_utils5.ESLintUtils.RuleCreator(
|
|
649
685
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
650
686
|
)({
|
|
651
687
|
name: "no-comment-cruft",
|
|
@@ -752,7 +788,7 @@ var no_comment_cruft_default = import_utils4.ESLintUtils.RuleCreator(
|
|
|
752
788
|
});
|
|
753
789
|
|
|
754
790
|
// src/rules/no-enum.ts
|
|
755
|
-
var
|
|
791
|
+
var import_utils6 = require("@typescript-eslint/utils");
|
|
756
792
|
var DEFAULT_IGNORE_PATTERNS = [
|
|
757
793
|
/[\\/]generated[\\/]/,
|
|
758
794
|
/[\\/]openapi-gen[\\/]/,
|
|
@@ -772,7 +808,7 @@ function hasGeneratedMarker(sourceText) {
|
|
|
772
808
|
const head = sourceText.slice(0, 1024);
|
|
773
809
|
return /@generated\b/.test(head);
|
|
774
810
|
}
|
|
775
|
-
var no_enum_default =
|
|
811
|
+
var no_enum_default = import_utils6.ESLintUtils.RuleCreator(
|
|
776
812
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
777
813
|
)({
|
|
778
814
|
name: "no-enum",
|
|
@@ -823,7 +859,7 @@ var no_enum_default = import_utils5.ESLintUtils.RuleCreator(
|
|
|
823
859
|
});
|
|
824
860
|
|
|
825
861
|
// src/rules/no-insecure-random-id.ts
|
|
826
|
-
var
|
|
862
|
+
var import_utils7 = require("@typescript-eslint/utils");
|
|
827
863
|
var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
|
|
828
864
|
var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
|
|
829
865
|
var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
|
|
@@ -964,7 +1000,7 @@ function isConcatenatedIntoPathOrDomId(node) {
|
|
|
964
1000
|
collectStaticStringParts(top, parts);
|
|
965
1001
|
return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
|
|
966
1002
|
}
|
|
967
|
-
var no_insecure_random_id_default =
|
|
1003
|
+
var no_insecure_random_id_default = import_utils7.ESLintUtils.RuleCreator(
|
|
968
1004
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
969
1005
|
)({
|
|
970
1006
|
name: "no-insecure-random-id",
|
|
@@ -1008,7 +1044,7 @@ var no_insecure_random_id_default = import_utils6.ESLintUtils.RuleCreator(
|
|
|
1008
1044
|
});
|
|
1009
1045
|
|
|
1010
1046
|
// src/rules/no-json-stringify-error.ts
|
|
1011
|
-
var
|
|
1047
|
+
var import_utils8 = require("@typescript-eslint/utils");
|
|
1012
1048
|
var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
|
|
1013
1049
|
var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
|
|
1014
1050
|
var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
|
|
@@ -1142,7 +1178,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
1142
1178
|
function isJsonStringify(callee) {
|
|
1143
1179
|
return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
|
|
1144
1180
|
}
|
|
1145
|
-
var no_json_stringify_error_default =
|
|
1181
|
+
var no_json_stringify_error_default = import_utils8.ESLintUtils.RuleCreator(
|
|
1146
1182
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1147
1183
|
)({
|
|
1148
1184
|
name: "no-json-stringify-error",
|
|
@@ -1192,10 +1228,10 @@ var no_json_stringify_error_default = import_utils7.ESLintUtils.RuleCreator(
|
|
|
1192
1228
|
});
|
|
1193
1229
|
|
|
1194
1230
|
// src/rules/no-log-only-catch.ts
|
|
1195
|
-
var
|
|
1231
|
+
var import_utils10 = require("@typescript-eslint/utils");
|
|
1196
1232
|
|
|
1197
1233
|
// src/rules/_logging.ts
|
|
1198
|
-
var
|
|
1234
|
+
var import_utils9 = require("@typescript-eslint/utils");
|
|
1199
1235
|
var LOG_METHODS = /* @__PURE__ */ new Set([
|
|
1200
1236
|
"debug",
|
|
1201
1237
|
"info",
|
|
@@ -1302,7 +1338,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
|
|
|
1302
1338
|
/\.spec\./,
|
|
1303
1339
|
/[\\/]__tests__[\\/]/
|
|
1304
1340
|
];
|
|
1305
|
-
var no_log_only_catch_default =
|
|
1341
|
+
var no_log_only_catch_default = import_utils10.ESLintUtils.RuleCreator(
|
|
1306
1342
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1307
1343
|
)({
|
|
1308
1344
|
name: "no-log-only-catch",
|
|
@@ -1365,7 +1401,7 @@ var no_log_only_catch_default = import_utils9.ESLintUtils.RuleCreator(
|
|
|
1365
1401
|
});
|
|
1366
1402
|
|
|
1367
1403
|
// src/rules/no-raw-env.ts
|
|
1368
|
-
var
|
|
1404
|
+
var import_utils11 = require("@typescript-eslint/utils");
|
|
1369
1405
|
var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
|
|
1370
1406
|
var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
|
|
1371
1407
|
function isValidatedEnvBoundary(filename, sourceText) {
|
|
@@ -1403,7 +1439,7 @@ function isWholeEnvSpread(node) {
|
|
|
1403
1439
|
const parent = node.parent;
|
|
1404
1440
|
return parent.type === "SpreadElement" && parent.argument === node;
|
|
1405
1441
|
}
|
|
1406
|
-
var no_raw_env_default =
|
|
1442
|
+
var no_raw_env_default = import_utils11.ESLintUtils.RuleCreator(
|
|
1407
1443
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1408
1444
|
)({
|
|
1409
1445
|
name: "no-raw-env",
|
|
@@ -1437,12 +1473,12 @@ var no_raw_env_default = import_utils10.ESLintUtils.RuleCreator(
|
|
|
1437
1473
|
});
|
|
1438
1474
|
|
|
1439
1475
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
1440
|
-
var
|
|
1476
|
+
var import_utils12 = require("@typescript-eslint/utils");
|
|
1441
1477
|
function sentinelKind(arg) {
|
|
1442
1478
|
if (arg === null) {
|
|
1443
1479
|
return null;
|
|
1444
1480
|
}
|
|
1445
|
-
if (arg.type ===
|
|
1481
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.Literal) {
|
|
1446
1482
|
if (arg.value === null) {
|
|
1447
1483
|
return "nullish";
|
|
1448
1484
|
}
|
|
@@ -1454,13 +1490,13 @@ function sentinelKind(arg) {
|
|
|
1454
1490
|
}
|
|
1455
1491
|
return null;
|
|
1456
1492
|
}
|
|
1457
|
-
if (arg.type ===
|
|
1493
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
|
|
1458
1494
|
return "nullish";
|
|
1459
1495
|
}
|
|
1460
|
-
if (arg.type ===
|
|
1496
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.ArrayExpression) {
|
|
1461
1497
|
return "array";
|
|
1462
1498
|
}
|
|
1463
|
-
if (arg.type ===
|
|
1499
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.ObjectExpression) {
|
|
1464
1500
|
return "object";
|
|
1465
1501
|
}
|
|
1466
1502
|
return null;
|
|
@@ -1469,25 +1505,25 @@ function isSentinelArgument(arg) {
|
|
|
1469
1505
|
if (arg === null) {
|
|
1470
1506
|
return false;
|
|
1471
1507
|
}
|
|
1472
|
-
if (arg.type ===
|
|
1508
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.Literal && arg.value === null) {
|
|
1473
1509
|
return true;
|
|
1474
1510
|
}
|
|
1475
|
-
if (arg.type ===
|
|
1511
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.Literal && arg.value === false) {
|
|
1476
1512
|
return true;
|
|
1477
1513
|
}
|
|
1478
|
-
if (arg.type ===
|
|
1514
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
|
|
1479
1515
|
return true;
|
|
1480
1516
|
}
|
|
1481
|
-
if (arg.type ===
|
|
1517
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.ArrayExpression && arg.elements.length === 0) {
|
|
1482
1518
|
return true;
|
|
1483
1519
|
}
|
|
1484
|
-
if (arg.type ===
|
|
1520
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.ObjectExpression && arg.properties.length === 0) {
|
|
1485
1521
|
return true;
|
|
1486
1522
|
}
|
|
1487
1523
|
return false;
|
|
1488
1524
|
}
|
|
1489
1525
|
function isFunctionNode(node) {
|
|
1490
|
-
return node.type ===
|
|
1526
|
+
return node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils12.AST_NODE_TYPES.FunctionExpression || node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression;
|
|
1491
1527
|
}
|
|
1492
1528
|
function isNode(value) {
|
|
1493
1529
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
@@ -1527,24 +1563,24 @@ function walkWithinScope(node, visit) {
|
|
|
1527
1563
|
function containsThrow(node) {
|
|
1528
1564
|
return walkWithinScope(
|
|
1529
1565
|
node,
|
|
1530
|
-
(current) => current.type ===
|
|
1566
|
+
(current) => current.type === import_utils12.AST_NODE_TYPES.ThrowStatement
|
|
1531
1567
|
);
|
|
1532
1568
|
}
|
|
1533
1569
|
function bindsName(param, name) {
|
|
1534
1570
|
switch (param.type) {
|
|
1535
|
-
case
|
|
1571
|
+
case import_utils12.AST_NODE_TYPES.Identifier:
|
|
1536
1572
|
return param.name === name;
|
|
1537
|
-
case
|
|
1573
|
+
case import_utils12.AST_NODE_TYPES.AssignmentPattern:
|
|
1538
1574
|
return bindsName(param.left, name);
|
|
1539
|
-
case
|
|
1575
|
+
case import_utils12.AST_NODE_TYPES.RestElement:
|
|
1540
1576
|
return bindsName(param.argument, name);
|
|
1541
|
-
case
|
|
1577
|
+
case import_utils12.AST_NODE_TYPES.ArrayPattern:
|
|
1542
1578
|
return param.elements.some(
|
|
1543
1579
|
(element) => element !== null && bindsName(element, name)
|
|
1544
1580
|
);
|
|
1545
|
-
case
|
|
1581
|
+
case import_utils12.AST_NODE_TYPES.ObjectPattern:
|
|
1546
1582
|
return param.properties.some(
|
|
1547
|
-
(property) => property.type ===
|
|
1583
|
+
(property) => property.type === import_utils12.AST_NODE_TYPES.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
|
|
1548
1584
|
);
|
|
1549
1585
|
default:
|
|
1550
1586
|
return false;
|
|
@@ -1559,7 +1595,7 @@ function subtreeReadsName(node, name) {
|
|
|
1559
1595
|
if (found) {
|
|
1560
1596
|
return;
|
|
1561
1597
|
}
|
|
1562
|
-
if (current.type ===
|
|
1598
|
+
if (current.type === import_utils12.AST_NODE_TYPES.Identifier && current.name === name) {
|
|
1563
1599
|
found = true;
|
|
1564
1600
|
return;
|
|
1565
1601
|
}
|
|
@@ -1570,10 +1606,10 @@ function subtreeReadsName(node, name) {
|
|
|
1570
1606
|
if (key === "parent") {
|
|
1571
1607
|
continue;
|
|
1572
1608
|
}
|
|
1573
|
-
if (key === "key" && current.type ===
|
|
1609
|
+
if (key === "key" && current.type === import_utils12.AST_NODE_TYPES.Property && !current.computed) {
|
|
1574
1610
|
continue;
|
|
1575
1611
|
}
|
|
1576
|
-
if (key === "property" && current.type ===
|
|
1612
|
+
if (key === "property" && current.type === import_utils12.AST_NODE_TYPES.MemberExpression && !current.computed) {
|
|
1577
1613
|
continue;
|
|
1578
1614
|
}
|
|
1579
1615
|
const value = current[key];
|
|
@@ -1606,10 +1642,10 @@ var SAFE_PARSE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
1606
1642
|
"URLPattern"
|
|
1607
1643
|
]);
|
|
1608
1644
|
function isParseShapedNode(node) {
|
|
1609
|
-
if (node.type ===
|
|
1645
|
+
if (node.type === import_utils12.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils12.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
1610
1646
|
return node.callee.property.name === "parse";
|
|
1611
1647
|
}
|
|
1612
|
-
if (node.type ===
|
|
1648
|
+
if (node.type === import_utils12.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
1613
1649
|
return SAFE_PARSE_CONSTRUCTORS.has(node.callee.name);
|
|
1614
1650
|
}
|
|
1615
1651
|
return false;
|
|
@@ -1620,10 +1656,10 @@ var BODY_DECODE_METHODS = /* @__PURE__ */ new Set([
|
|
|
1620
1656
|
"arrayBuffer"
|
|
1621
1657
|
]);
|
|
1622
1658
|
function isBodyDecodeNode(node) {
|
|
1623
|
-
return node.type ===
|
|
1659
|
+
return node.type === import_utils12.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils12.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils12.AST_NODE_TYPES.Identifier && BODY_DECODE_METHODS.has(node.callee.property.name);
|
|
1624
1660
|
}
|
|
1625
1661
|
function returnsMatching(stmt, predicate) {
|
|
1626
|
-
return stmt.type ===
|
|
1662
|
+
return stmt.type === import_utils12.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
|
|
1627
1663
|
}
|
|
1628
1664
|
function enclosingReturnTypeNode(node) {
|
|
1629
1665
|
let current = node.parent;
|
|
@@ -1641,11 +1677,11 @@ function enclosingFunctionName(node) {
|
|
|
1641
1677
|
let current = node.parent;
|
|
1642
1678
|
while (current !== void 0 && current !== null) {
|
|
1643
1679
|
if (isFunctionNode(current)) {
|
|
1644
|
-
if ("id" in current && isNode(current.id) && current.id.type ===
|
|
1680
|
+
if ("id" in current && isNode(current.id) && current.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
1645
1681
|
return current.id.name;
|
|
1646
1682
|
}
|
|
1647
1683
|
const parent = current.parent;
|
|
1648
|
-
if (parent?.type ===
|
|
1684
|
+
if (parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
1649
1685
|
return parent.id.name;
|
|
1650
1686
|
}
|
|
1651
1687
|
return null;
|
|
@@ -1666,10 +1702,10 @@ function isDeclaredBooleanPredicate(catchNode, kind) {
|
|
|
1666
1702
|
return false;
|
|
1667
1703
|
}
|
|
1668
1704
|
let declared = enclosingReturnTypeNode(catchNode);
|
|
1669
|
-
if (declared?.type ===
|
|
1705
|
+
if (declared?.type === import_utils12.AST_NODE_TYPES.TSTypeReference && declared.typeName.type === import_utils12.AST_NODE_TYPES.Identifier && declared.typeName.name === "Promise") {
|
|
1670
1706
|
declared = declared.typeArguments?.params[0] ?? null;
|
|
1671
1707
|
}
|
|
1672
|
-
return declared?.type ===
|
|
1708
|
+
return declared?.type === import_utils12.AST_NODE_TYPES.TSBooleanKeyword;
|
|
1673
1709
|
}
|
|
1674
1710
|
function tryReturnsSafeParse(catchNode) {
|
|
1675
1711
|
const tryBlock = tryBlockOf(catchNode);
|
|
@@ -1685,7 +1721,7 @@ function tryReturnsSafeParse(catchNode) {
|
|
|
1685
1721
|
function enclosingFunctionBody(node) {
|
|
1686
1722
|
let current = node.parent;
|
|
1687
1723
|
while (current !== void 0 && current !== null) {
|
|
1688
|
-
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type ===
|
|
1724
|
+
if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
1689
1725
|
return current.body;
|
|
1690
1726
|
}
|
|
1691
1727
|
current = current.parent;
|
|
@@ -1698,7 +1734,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
|
|
|
1698
1734
|
return false;
|
|
1699
1735
|
}
|
|
1700
1736
|
return walkWithinScope(functionBody, (current) => {
|
|
1701
|
-
if (current.type !==
|
|
1737
|
+
if (current.type !== import_utils12.AST_NODE_TYPES.ReturnStatement) {
|
|
1702
1738
|
return false;
|
|
1703
1739
|
}
|
|
1704
1740
|
if (isWithin(current, catchNode.body)) {
|
|
@@ -1717,13 +1753,13 @@ function returnedSentinelKinds(arg) {
|
|
|
1717
1753
|
kinds.add(direct);
|
|
1718
1754
|
return kinds;
|
|
1719
1755
|
}
|
|
1720
|
-
if (arg.type ===
|
|
1756
|
+
if (arg.type === import_utils12.AST_NODE_TYPES.ConditionalExpression) {
|
|
1721
1757
|
for (const branch of [arg.consequent, arg.alternate]) {
|
|
1722
1758
|
for (const nested of returnedSentinelKinds(branch)) {
|
|
1723
1759
|
kinds.add(nested);
|
|
1724
1760
|
}
|
|
1725
1761
|
}
|
|
1726
|
-
} else if (arg.type ===
|
|
1762
|
+
} else if (arg.type === import_utils12.AST_NODE_TYPES.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
|
|
1727
1763
|
for (const nested of returnedSentinelKinds(arg.right)) {
|
|
1728
1764
|
kinds.add(nested);
|
|
1729
1765
|
}
|
|
@@ -1740,7 +1776,7 @@ function isWithin(node, ancestor) {
|
|
|
1740
1776
|
}
|
|
1741
1777
|
return false;
|
|
1742
1778
|
}
|
|
1743
|
-
var no_sentinel_return_on_catch_default =
|
|
1779
|
+
var no_sentinel_return_on_catch_default = import_utils12.ESLintUtils.RuleCreator(
|
|
1744
1780
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1745
1781
|
)({
|
|
1746
1782
|
name: "no-sentinel-return-on-catch",
|
|
@@ -1768,7 +1804,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
|
|
|
1768
1804
|
const matcher = createLogMatcher(loggingOptions);
|
|
1769
1805
|
function logsOrReportsError(catchBody, caughtName) {
|
|
1770
1806
|
return walkWithinScope(catchBody, (current) => {
|
|
1771
|
-
if (current.type !==
|
|
1807
|
+
if (current.type !== import_utils12.AST_NODE_TYPES.CallExpression) {
|
|
1772
1808
|
return false;
|
|
1773
1809
|
}
|
|
1774
1810
|
if (matcher.isLoggingCall(current)) {
|
|
@@ -1785,7 +1821,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
|
|
|
1785
1821
|
return;
|
|
1786
1822
|
}
|
|
1787
1823
|
const last = body[body.length - 1];
|
|
1788
|
-
if (last === void 0 || last.type !==
|
|
1824
|
+
if (last === void 0 || last.type !== import_utils12.AST_NODE_TYPES.ReturnStatement) {
|
|
1789
1825
|
return;
|
|
1790
1826
|
}
|
|
1791
1827
|
if (!isSentinelArgument(last.argument)) {
|
|
@@ -1794,7 +1830,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
|
|
|
1794
1830
|
if (containsThrow(node.body)) {
|
|
1795
1831
|
return;
|
|
1796
1832
|
}
|
|
1797
|
-
const caughtName = node.param?.type ===
|
|
1833
|
+
const caughtName = node.param?.type === import_utils12.AST_NODE_TYPES.Identifier ? node.param.name : null;
|
|
1798
1834
|
if (logsOrReportsError(node.body, caughtName)) {
|
|
1799
1835
|
return;
|
|
1800
1836
|
}
|
|
@@ -1820,255 +1856,6 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
|
|
|
1820
1856
|
}
|
|
1821
1857
|
});
|
|
1822
1858
|
|
|
1823
|
-
// src/rules/no-sequential-await.ts
|
|
1824
|
-
var import_utils12 = require("@typescript-eslint/utils");
|
|
1825
|
-
var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
|
|
1826
|
-
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;
|
|
1827
|
-
var BENCH_FILE_RE = /(^|[\\/])bench(marks?)?[\\/]|\.bench\.[cm]?[jt]sx?$/i;
|
|
1828
|
-
function isFunctionLike(node) {
|
|
1829
|
-
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
1830
|
-
}
|
|
1831
|
-
function isLoop(node) {
|
|
1832
|
-
return node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
|
|
1833
|
-
}
|
|
1834
|
-
function isNode2(value) {
|
|
1835
|
-
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
1836
|
-
}
|
|
1837
|
-
function visitScope(root, visit) {
|
|
1838
|
-
visit(root);
|
|
1839
|
-
for (const key of Object.keys(root)) {
|
|
1840
|
-
if (key === "parent") {
|
|
1841
|
-
continue;
|
|
1842
|
-
}
|
|
1843
|
-
const value = root[key];
|
|
1844
|
-
const children = Array.isArray(value) ? value : [value];
|
|
1845
|
-
for (const child of children) {
|
|
1846
|
-
if (isNode2(child) && !isFunctionLike(child) && !isLoop(child)) {
|
|
1847
|
-
visitScope(child, visit);
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
function collectAwaits(root) {
|
|
1853
|
-
const awaits = [];
|
|
1854
|
-
visitScope(root, (node) => {
|
|
1855
|
-
if (node.type === "AwaitExpression") {
|
|
1856
|
-
awaits.push(node);
|
|
1857
|
-
}
|
|
1858
|
-
});
|
|
1859
|
-
return awaits;
|
|
1860
|
-
}
|
|
1861
|
-
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
1862
|
-
function hasEarlyExit(root) {
|
|
1863
|
-
let found = false;
|
|
1864
|
-
visitScope(root, (node) => {
|
|
1865
|
-
if (node.type === "ReturnStatement" || node.type === "BreakStatement" || node.type === "ContinueStatement") {
|
|
1866
|
-
found = true;
|
|
1867
|
-
}
|
|
1868
|
-
});
|
|
1869
|
-
return found;
|
|
1870
|
-
}
|
|
1871
|
-
var TIMER_HELPER_RE = /^(sleep|timeout|delay|wait|pause|tick)$/i;
|
|
1872
|
-
function calleeName2(callee) {
|
|
1873
|
-
if (callee.type === "Identifier") return callee.name;
|
|
1874
|
-
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier") {
|
|
1875
|
-
return callee.property.name;
|
|
1876
|
-
}
|
|
1877
|
-
return null;
|
|
1878
|
-
}
|
|
1879
|
-
function isTimerYield(node) {
|
|
1880
|
-
const arg = node.argument;
|
|
1881
|
-
if (arg.type === "NewExpression" && arg.callee.type === "Identifier" && arg.callee.name === "Promise") {
|
|
1882
|
-
return true;
|
|
1883
|
-
}
|
|
1884
|
-
if (arg.type === "CallExpression") {
|
|
1885
|
-
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")) {
|
|
1886
|
-
return true;
|
|
1887
|
-
}
|
|
1888
|
-
const name = calleeName2(arg.callee);
|
|
1889
|
-
return name !== null && TIMER_HELPER_RE.test(name);
|
|
1890
|
-
}
|
|
1891
|
-
return false;
|
|
1892
|
-
}
|
|
1893
|
-
var QUEUE_DRAIN_METHODS = /^(shift|pop|dequeue|next|poll)$/;
|
|
1894
|
-
function isQueueDrain(node) {
|
|
1895
|
-
const arg = node.argument;
|
|
1896
|
-
return arg.type === "CallExpression" && arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.property.type === "Identifier" && QUEUE_DRAIN_METHODS.test(arg.callee.property.name);
|
|
1897
|
-
}
|
|
1898
|
-
function hasAssertion(root) {
|
|
1899
|
-
let found = false;
|
|
1900
|
-
visitScope(root, (node) => {
|
|
1901
|
-
if (node.type !== "CallExpression") {
|
|
1902
|
-
return;
|
|
1903
|
-
}
|
|
1904
|
-
let callee = node.callee;
|
|
1905
|
-
while (callee.type === "MemberExpression") {
|
|
1906
|
-
callee = callee.object;
|
|
1907
|
-
}
|
|
1908
|
-
if (callee.type === "CallExpression") {
|
|
1909
|
-
callee = callee.callee;
|
|
1910
|
-
}
|
|
1911
|
-
if (callee.type === "Identifier" && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
1912
|
-
found = true;
|
|
1913
|
-
}
|
|
1914
|
-
});
|
|
1915
|
-
return found;
|
|
1916
|
-
}
|
|
1917
|
-
function referencesName(root, name) {
|
|
1918
|
-
let found = false;
|
|
1919
|
-
visitScope(root, (node) => {
|
|
1920
|
-
if (node.type === "Identifier" && node.name === name) {
|
|
1921
|
-
found = true;
|
|
1922
|
-
}
|
|
1923
|
-
});
|
|
1924
|
-
return found;
|
|
1925
|
-
}
|
|
1926
|
-
function isThreadedAccumulator(node) {
|
|
1927
|
-
const parent = node.parent;
|
|
1928
|
-
let target = null;
|
|
1929
|
-
if (parent.type === "AssignmentExpression" && parent.operator === "=" && parent.right === node && parent.left.type === "Identifier") {
|
|
1930
|
-
target = parent.left.name;
|
|
1931
|
-
} else if (parent.type === "VariableDeclarator" && parent.init === node && parent.id.type === "Identifier") {
|
|
1932
|
-
target = parent.id.name;
|
|
1933
|
-
}
|
|
1934
|
-
if (target === null) {
|
|
1935
|
-
return false;
|
|
1936
|
-
}
|
|
1937
|
-
return referencesName(node.argument, target);
|
|
1938
|
-
}
|
|
1939
|
-
function namesReadBy(test) {
|
|
1940
|
-
const names = /* @__PURE__ */ new Set();
|
|
1941
|
-
visitScope(test, (node) => {
|
|
1942
|
-
if (node.type === "Identifier") {
|
|
1943
|
-
names.add(node.name);
|
|
1944
|
-
}
|
|
1945
|
-
});
|
|
1946
|
-
return names;
|
|
1947
|
-
}
|
|
1948
|
-
function testStateIsAssignedInBody(test, body) {
|
|
1949
|
-
const testNames = namesReadBy(test);
|
|
1950
|
-
if (testNames.size === 0) {
|
|
1951
|
-
return false;
|
|
1952
|
-
}
|
|
1953
|
-
let found = false;
|
|
1954
|
-
visitScope(body, (node) => {
|
|
1955
|
-
if (node.type === "AssignmentExpression" && node.operator === "=" && node.left.type === "Identifier" && testNames.has(node.left.name)) {
|
|
1956
|
-
found = true;
|
|
1957
|
-
}
|
|
1958
|
-
});
|
|
1959
|
-
return found;
|
|
1960
|
-
}
|
|
1961
|
-
function shouldReport(awaits, earlyExit, iterableText, asserts = false) {
|
|
1962
|
-
if (awaits.length === 0) {
|
|
1963
|
-
return false;
|
|
1964
|
-
}
|
|
1965
|
-
if (earlyExit) {
|
|
1966
|
-
return false;
|
|
1967
|
-
}
|
|
1968
|
-
if (asserts) {
|
|
1969
|
-
return false;
|
|
1970
|
-
}
|
|
1971
|
-
if (iterableText !== null && SEQUENTIAL_ITERABLE_HINT.test(iterableText)) {
|
|
1972
|
-
return false;
|
|
1973
|
-
}
|
|
1974
|
-
return awaits.some(
|
|
1975
|
-
(node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
|
|
1976
|
-
);
|
|
1977
|
-
}
|
|
1978
|
-
var no_sequential_await_default = import_utils12.ESLintUtils.RuleCreator(
|
|
1979
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
1980
|
-
)({
|
|
1981
|
-
name: "no-sequential-await",
|
|
1982
|
-
meta: {
|
|
1983
|
-
type: "problem",
|
|
1984
|
-
docs: {
|
|
1985
|
-
description: "Disallow serial `await` inside a loop; use `await Promise.all(...)` to run the operations concurrently."
|
|
1986
|
-
},
|
|
1987
|
-
schema: [],
|
|
1988
|
-
messages: {
|
|
1989
|
-
noSequentialAwait: "Avoid `await` inside a loop \u2014 it serializes I/O. Collect the promises and `await Promise.all(xs.map(async (x) => ...))` instead."
|
|
1990
|
-
}
|
|
1991
|
-
},
|
|
1992
|
-
defaultOptions: [],
|
|
1993
|
-
create(context) {
|
|
1994
|
-
if (isTestFile(context.filename) || BENCH_FILE_RE.test(context.filename)) {
|
|
1995
|
-
return {};
|
|
1996
|
-
}
|
|
1997
|
-
function loopParts(node) {
|
|
1998
|
-
if (node.type === "ForStatement") {
|
|
1999
|
-
return [node.body, node.test, node.update];
|
|
2000
|
-
}
|
|
2001
|
-
if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
|
|
2002
|
-
return [node.body];
|
|
2003
|
-
}
|
|
2004
|
-
return [node.body, node.test];
|
|
2005
|
-
}
|
|
2006
|
-
function iterableTextOf(node) {
|
|
2007
|
-
if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
|
|
2008
|
-
return context.sourceCode.getText(node.right);
|
|
2009
|
-
}
|
|
2010
|
-
return null;
|
|
2011
|
-
}
|
|
2012
|
-
function checkLoop(node) {
|
|
2013
|
-
if ((node.type === "WhileStatement" || node.type === "DoWhileStatement") && testStateIsAssignedInBody(node.test, node.body)) {
|
|
2014
|
-
return;
|
|
2015
|
-
}
|
|
2016
|
-
const awaits = [];
|
|
2017
|
-
let earlyExit = false;
|
|
2018
|
-
let asserts = false;
|
|
2019
|
-
for (const part of loopParts(node)) {
|
|
2020
|
-
if (part === null || isLoop(part)) {
|
|
2021
|
-
continue;
|
|
2022
|
-
}
|
|
2023
|
-
awaits.push(...collectAwaits(part));
|
|
2024
|
-
if (!earlyExit && hasEarlyExit(part)) {
|
|
2025
|
-
earlyExit = true;
|
|
2026
|
-
}
|
|
2027
|
-
if (!asserts && hasAssertion(part)) {
|
|
2028
|
-
asserts = true;
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
|
-
if (shouldReport(awaits, earlyExit, iterableTextOf(node), asserts)) {
|
|
2032
|
-
context.report({ node, messageId: "noSequentialAwait" });
|
|
2033
|
-
}
|
|
2034
|
-
}
|
|
2035
|
-
return {
|
|
2036
|
-
ForStatement: checkLoop,
|
|
2037
|
-
ForInStatement: checkLoop,
|
|
2038
|
-
WhileStatement: checkLoop,
|
|
2039
|
-
DoWhileStatement: checkLoop,
|
|
2040
|
-
ForOfStatement(node) {
|
|
2041
|
-
if (node.await) {
|
|
2042
|
-
return;
|
|
2043
|
-
}
|
|
2044
|
-
checkLoop(node);
|
|
2045
|
-
},
|
|
2046
|
-
CallExpression(node) {
|
|
2047
|
-
const callee = node.callee;
|
|
2048
|
-
if (callee.type !== "MemberExpression" || callee.computed) {
|
|
2049
|
-
return;
|
|
2050
|
-
}
|
|
2051
|
-
if (callee.property.type !== "Identifier" || !ARRAY_ITERATION_METHODS.has(callee.property.name)) {
|
|
2052
|
-
return;
|
|
2053
|
-
}
|
|
2054
|
-
const callback = node.arguments[0];
|
|
2055
|
-
if (callback === void 0 || !isFunctionLike(callback) || !("async" in callback && callback.async)) {
|
|
2056
|
-
return;
|
|
2057
|
-
}
|
|
2058
|
-
if (callee.property.name !== "forEach" && node.parent.type !== "ExpressionStatement") {
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
const awaits = collectAwaits(callback.body);
|
|
2062
|
-
const earlyExit = hasEarlyExit(callback.body);
|
|
2063
|
-
const iterableText = context.sourceCode.getText(callee.object);
|
|
2064
|
-
if (shouldReport(awaits, earlyExit, iterableText, hasAssertion(callback.body))) {
|
|
2065
|
-
context.report({ node, messageId: "noSequentialAwait" });
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
};
|
|
2069
|
-
}
|
|
2070
|
-
});
|
|
2071
|
-
|
|
2072
1859
|
// src/rules/no-string-concat-in-loop.ts
|
|
2073
1860
|
var import_utils13 = require("@typescript-eslint/utils");
|
|
2074
1861
|
var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2564,7 +2351,7 @@ var isLocalFileRead = (node) => {
|
|
|
2564
2351
|
visit(node);
|
|
2565
2352
|
return found;
|
|
2566
2353
|
};
|
|
2567
|
-
var
|
|
2354
|
+
var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
|
|
2568
2355
|
var isInsideAssertion = (node) => {
|
|
2569
2356
|
for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
|
|
2570
2357
|
if (current.type !== import_utils17.AST_NODE_TYPES.CallExpression) continue;
|
|
@@ -2575,7 +2362,7 @@ var isInsideAssertion = (node) => {
|
|
|
2575
2362
|
if (callee.type === import_utils17.AST_NODE_TYPES.CallExpression) {
|
|
2576
2363
|
callee = callee.callee;
|
|
2577
2364
|
}
|
|
2578
|
-
if (callee.type === import_utils17.AST_NODE_TYPES.Identifier &&
|
|
2365
|
+
if (callee.type === import_utils17.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
|
|
2579
2366
|
return true;
|
|
2580
2367
|
}
|
|
2581
2368
|
}
|
|
@@ -2789,6 +2576,7 @@ var DETECTION_FILES = [
|
|
|
2789
2576
|
"src/styles/globals.css",
|
|
2790
2577
|
"styles/globals.css"
|
|
2791
2578
|
];
|
|
2579
|
+
var MAX_UPWARD_DEPTH = 8;
|
|
2792
2580
|
var semanticTokenCache = /* @__PURE__ */ new Map();
|
|
2793
2581
|
var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
|
|
2794
2582
|
"mask",
|
|
@@ -2843,9 +2631,15 @@ var isInsideIconFactoryPath = (node) => {
|
|
|
2843
2631
|
var hasSemanticTokenSystem = (filename) => {
|
|
2844
2632
|
let dir = (0, import_path.dirname)(filename);
|
|
2845
2633
|
const root = (0, import_path.parse)(dir).root;
|
|
2846
|
-
|
|
2634
|
+
const visited = [];
|
|
2635
|
+
let answer;
|
|
2636
|
+
for (let depth = 0; depth < MAX_UPWARD_DEPTH; depth += 1) {
|
|
2847
2637
|
const cached = semanticTokenCache.get(dir);
|
|
2848
|
-
if (cached !== void 0)
|
|
2638
|
+
if (cached !== void 0) {
|
|
2639
|
+
answer = cached;
|
|
2640
|
+
break;
|
|
2641
|
+
}
|
|
2642
|
+
visited.push(dir);
|
|
2849
2643
|
let found = false;
|
|
2850
2644
|
for (const rel of DETECTION_FILES) {
|
|
2851
2645
|
const candidate = (0, import_path.join)(dir, rel);
|
|
@@ -2862,11 +2656,19 @@ var hasSemanticTokenSystem = (filename) => {
|
|
|
2862
2656
|
} catch {
|
|
2863
2657
|
}
|
|
2864
2658
|
}
|
|
2865
|
-
|
|
2866
|
-
|
|
2659
|
+
if (found) {
|
|
2660
|
+
answer = true;
|
|
2661
|
+
break;
|
|
2662
|
+
}
|
|
2663
|
+
if (dir === root) {
|
|
2664
|
+
answer = false;
|
|
2665
|
+
break;
|
|
2666
|
+
}
|
|
2867
2667
|
dir = (0, import_path.dirname)(dir);
|
|
2868
2668
|
}
|
|
2869
|
-
return false;
|
|
2669
|
+
if (answer === void 0) return false;
|
|
2670
|
+
for (const seen of visited) semanticTokenCache.set(seen, answer);
|
|
2671
|
+
return answer;
|
|
2870
2672
|
};
|
|
2871
2673
|
var propName = (key) => {
|
|
2872
2674
|
if (key.type === import_utils18.AST_NODE_TYPES.Identifier) return key.name;
|
|
@@ -3149,116 +2951,37 @@ var prefer_server_actions_default = import_utils19.ESLintUtils.RuleCreator(
|
|
|
3149
2951
|
}
|
|
3150
2952
|
});
|
|
3151
2953
|
|
|
3152
|
-
// src/rules/prefer-shadcn.ts
|
|
3153
|
-
var import_utils20 = require("@typescript-eslint/utils");
|
|
3154
|
-
var REPLACEMENTS = {
|
|
3155
|
-
select: "Select",
|
|
3156
|
-
textarea: "Textarea",
|
|
3157
|
-
dialog: "Dialog"
|
|
3158
|
-
};
|
|
3159
|
-
var INPUT_TYPE_REPLACEMENTS = {
|
|
3160
|
-
checkbox: "Checkbox",
|
|
3161
|
-
radio: "RadioGroup",
|
|
3162
|
-
range: "Slider"
|
|
3163
|
-
};
|
|
3164
|
-
var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
|
|
3165
|
-
var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
3166
|
-
var literalTypeAttr = (node) => {
|
|
3167
|
-
for (const attribute of node.attributes) {
|
|
3168
|
-
if (attribute.type !== import_utils20.AST_NODE_TYPES.JSXAttribute || attribute.name.type !== import_utils20.AST_NODE_TYPES.JSXIdentifier || attribute.name.name !== "type") {
|
|
3169
|
-
continue;
|
|
3170
|
-
}
|
|
3171
|
-
if (attribute.value?.type === import_utils20.AST_NODE_TYPES.Literal && typeof attribute.value.value === "string") {
|
|
3172
|
-
return { kind: "literal", value: attribute.value.value.toLowerCase() };
|
|
3173
|
-
}
|
|
3174
|
-
return { kind: "dynamic" };
|
|
3175
|
-
}
|
|
3176
|
-
return null;
|
|
3177
|
-
};
|
|
3178
|
-
var hasFileAcceptAttr = (node) => node.attributes.some(
|
|
3179
|
-
(attribute) => attribute.type === import_utils20.AST_NODE_TYPES.JSXAttribute && attribute.name.type === import_utils20.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "accept"
|
|
3180
|
-
);
|
|
3181
|
-
var resolveInputReplacement = (node) => {
|
|
3182
|
-
const typeAttr = literalTypeAttr(node);
|
|
3183
|
-
if (hasFileAcceptAttr(node)) return null;
|
|
3184
|
-
if (typeAttr === null || typeAttr.kind === "dynamic") return "Input";
|
|
3185
|
-
if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
|
|
3186
|
-
return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
|
|
3187
|
-
};
|
|
3188
|
-
var prefer_shadcn_default = import_utils20.ESLintUtils.RuleCreator(
|
|
3189
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3190
|
-
)({
|
|
3191
|
-
name: "prefer-shadcn",
|
|
3192
|
-
meta: {
|
|
3193
|
-
type: "suggestion",
|
|
3194
|
-
docs: {
|
|
3195
|
-
description: "Prefer shadcn/ui form primitives over native `<input>`, `<select>`, `<textarea>`, and `<dialog>` elements."
|
|
3196
|
-
},
|
|
3197
|
-
schema: [],
|
|
3198
|
-
messages: {
|
|
3199
|
-
preferShadcn: "Use the shadcn <{{replacement}}> component from @/components/ui/{{lowercase}} instead of native <{{element}}>."
|
|
3200
|
-
}
|
|
3201
|
-
},
|
|
3202
|
-
defaultOptions: [],
|
|
3203
|
-
create(context) {
|
|
3204
|
-
if (isTestFile(context.filename) || isStoryFile(context.filename)) {
|
|
3205
|
-
return {};
|
|
3206
|
-
}
|
|
3207
|
-
return {
|
|
3208
|
-
JSXOpeningElement(node) {
|
|
3209
|
-
if (node.name.type !== "JSXIdentifier") {
|
|
3210
|
-
return;
|
|
3211
|
-
}
|
|
3212
|
-
const elementName = node.name.name;
|
|
3213
|
-
const replacement = elementName === "input" ? resolveInputReplacement(node) : REPLACEMENTS[elementName];
|
|
3214
|
-
if (replacement === void 0 || replacement === null) {
|
|
3215
|
-
return;
|
|
3216
|
-
}
|
|
3217
|
-
context.report({
|
|
3218
|
-
node,
|
|
3219
|
-
messageId: "preferShadcn",
|
|
3220
|
-
data: {
|
|
3221
|
-
element: elementName,
|
|
3222
|
-
replacement,
|
|
3223
|
-
lowercase: kebabCase(replacement)
|
|
3224
|
-
}
|
|
3225
|
-
});
|
|
3226
|
-
}
|
|
3227
|
-
};
|
|
3228
|
-
}
|
|
3229
|
-
});
|
|
3230
|
-
|
|
3231
2954
|
// src/rules/require-assert-never.ts
|
|
3232
|
-
var
|
|
2955
|
+
var import_utils20 = require("@typescript-eslint/utils");
|
|
3233
2956
|
var isAssertNeverCall = (expression) => {
|
|
3234
|
-
if (expression.type !==
|
|
2957
|
+
if (expression.type !== import_utils20.AST_NODE_TYPES.CallExpression) return false;
|
|
3235
2958
|
const callee = expression.callee;
|
|
3236
|
-
if (callee.type ===
|
|
2959
|
+
if (callee.type === import_utils20.AST_NODE_TYPES.Identifier) {
|
|
3237
2960
|
return callee.name === "assertNever";
|
|
3238
2961
|
}
|
|
3239
|
-
if (callee.type ===
|
|
2962
|
+
if (callee.type === import_utils20.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils20.AST_NODE_TYPES.Identifier) {
|
|
3240
2963
|
return callee.property.name === "assertNever";
|
|
3241
2964
|
}
|
|
3242
2965
|
return false;
|
|
3243
2966
|
};
|
|
3244
2967
|
var statementContainsAssertNever = (statement) => {
|
|
3245
|
-
if (statement.type ===
|
|
2968
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.ExpressionStatement) {
|
|
3246
2969
|
return isAssertNeverCall(statement.expression);
|
|
3247
2970
|
}
|
|
3248
|
-
if (statement.type ===
|
|
2971
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.ThrowStatement) {
|
|
3249
2972
|
return isAssertNeverCall(statement.argument);
|
|
3250
2973
|
}
|
|
3251
|
-
if (statement.type ===
|
|
2974
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.ReturnStatement) {
|
|
3252
2975
|
return statement.argument !== null && isAssertNeverCall(statement.argument);
|
|
3253
2976
|
}
|
|
3254
|
-
if (statement.type ===
|
|
2977
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
|
|
3255
2978
|
return statement.body.some(statementContainsAssertNever);
|
|
3256
2979
|
}
|
|
3257
2980
|
return false;
|
|
3258
2981
|
};
|
|
3259
2982
|
var isRuntimeHandlingStatement = (statement) => {
|
|
3260
|
-
if (statement.type ===
|
|
3261
|
-
if (statement.type ===
|
|
2983
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.EmptyStatement) return false;
|
|
2984
|
+
if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
|
|
3262
2985
|
return statement.body.some(isRuntimeHandlingStatement);
|
|
3263
2986
|
}
|
|
3264
2987
|
return true;
|
|
@@ -3274,12 +2997,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
|
|
|
3274
2997
|
return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
|
|
3275
2998
|
}
|
|
3276
2999
|
const only = defaultCase.consequent[0];
|
|
3277
|
-
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type ===
|
|
3000
|
+
if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils20.AST_NODE_TYPES.BlockStatement && only.body.length === 0) {
|
|
3278
3001
|
return sourceCode.getCommentsInside(only).length > 0;
|
|
3279
3002
|
}
|
|
3280
3003
|
return false;
|
|
3281
3004
|
};
|
|
3282
|
-
var require_assert_never_default =
|
|
3005
|
+
var require_assert_never_default = import_utils20.ESLintUtils.RuleCreator(
|
|
3283
3006
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3284
3007
|
)({
|
|
3285
3008
|
name: "require-assert-never",
|
|
@@ -3317,7 +3040,7 @@ var require_assert_never_default = import_utils21.ESLintUtils.RuleCreator(
|
|
|
3317
3040
|
});
|
|
3318
3041
|
|
|
3319
3042
|
// src/rules/require-zod-form-validation.ts
|
|
3320
|
-
var
|
|
3043
|
+
var import_utils21 = require("@typescript-eslint/utils");
|
|
3321
3044
|
|
|
3322
3045
|
// src/rules/_zod.ts
|
|
3323
3046
|
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
@@ -3328,14 +3051,14 @@ var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
|
|
|
3328
3051
|
var looksLikeZodSchema = (node) => {
|
|
3329
3052
|
let current = node;
|
|
3330
3053
|
while (true) {
|
|
3331
|
-
if (current.type ===
|
|
3054
|
+
if (current.type === import_utils21.AST_NODE_TYPES.Identifier) {
|
|
3332
3055
|
return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
|
|
3333
3056
|
}
|
|
3334
|
-
if (current.type ===
|
|
3057
|
+
if (current.type === import_utils21.AST_NODE_TYPES.CallExpression) {
|
|
3335
3058
|
current = current.callee;
|
|
3336
3059
|
continue;
|
|
3337
3060
|
}
|
|
3338
|
-
if (current.type ===
|
|
3061
|
+
if (current.type === import_utils21.AST_NODE_TYPES.MemberExpression) {
|
|
3339
3062
|
current = current.object;
|
|
3340
3063
|
continue;
|
|
3341
3064
|
}
|
|
@@ -3343,25 +3066,25 @@ var looksLikeZodSchema = (node) => {
|
|
|
3343
3066
|
}
|
|
3344
3067
|
};
|
|
3345
3068
|
var isZodParseCall = (node) => {
|
|
3346
|
-
if (node.type !==
|
|
3069
|
+
if (node.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
|
|
3347
3070
|
const callee = node.callee;
|
|
3348
|
-
if (callee.type !==
|
|
3071
|
+
if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
|
|
3349
3072
|
if (callee.computed) return false;
|
|
3350
|
-
if (callee.property.type !==
|
|
3073
|
+
if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
|
|
3351
3074
|
const method = callee.property.name;
|
|
3352
3075
|
if (method !== "parse" && method !== "safeParse") return false;
|
|
3353
3076
|
return looksLikeZodSchema(callee.object);
|
|
3354
3077
|
};
|
|
3355
3078
|
var isFormDataMethodCall = (node) => {
|
|
3356
3079
|
let current = node;
|
|
3357
|
-
if (current.type ===
|
|
3080
|
+
if (current.type === import_utils21.AST_NODE_TYPES.AwaitExpression) {
|
|
3358
3081
|
current = current.argument;
|
|
3359
3082
|
}
|
|
3360
|
-
if (current.type !==
|
|
3083
|
+
if (current.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
|
|
3361
3084
|
const callee = current.callee;
|
|
3362
|
-
return callee.type ===
|
|
3085
|
+
return callee.type === import_utils21.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils21.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
|
|
3363
3086
|
};
|
|
3364
|
-
var require_zod_form_validation_default =
|
|
3087
|
+
var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator(
|
|
3365
3088
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3366
3089
|
)({
|
|
3367
3090
|
name: "require-zod-form-validation",
|
|
@@ -3381,14 +3104,14 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
|
|
|
3381
3104
|
return {};
|
|
3382
3105
|
}
|
|
3383
3106
|
const isFormSourceIdentifier = (node) => {
|
|
3384
|
-
if (node.type !==
|
|
3107
|
+
if (node.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
|
|
3385
3108
|
if (/formdata/i.test(node.name)) return true;
|
|
3386
3109
|
let scope = context.sourceCode.getScope(node);
|
|
3387
3110
|
while (scope !== null) {
|
|
3388
3111
|
const variable = scope.set.get(node.name);
|
|
3389
3112
|
if (variable !== void 0 && variable.defs.length === 1) {
|
|
3390
3113
|
const def = variable.defs[0];
|
|
3391
|
-
if (def !== void 0 && def.type === "Variable" && def.node.type ===
|
|
3114
|
+
if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
|
|
3392
3115
|
return isFormDataMethodCall(def.node.init);
|
|
3393
3116
|
}
|
|
3394
3117
|
return false;
|
|
@@ -3399,8 +3122,8 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
|
|
|
3399
3122
|
};
|
|
3400
3123
|
const isFormDataGetCall = (node) => {
|
|
3401
3124
|
const callee = node.callee;
|
|
3402
|
-
if (callee.type !==
|
|
3403
|
-
if (callee.property.type !==
|
|
3125
|
+
if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
|
|
3126
|
+
if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier || callee.property.name !== "get") {
|
|
3404
3127
|
return false;
|
|
3405
3128
|
}
|
|
3406
3129
|
return isFormSourceIdentifier(callee.object);
|
|
@@ -3415,11 +3138,11 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
|
|
|
3415
3138
|
};
|
|
3416
3139
|
const isInstanceofNarrowing = (node) => {
|
|
3417
3140
|
const parent = node.parent;
|
|
3418
|
-
return parent !== null && parent !== void 0 && parent.type ===
|
|
3141
|
+
return parent !== null && parent !== void 0 && parent.type === import_utils21.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
|
|
3419
3142
|
};
|
|
3420
3143
|
const boundDeclarator = (node) => {
|
|
3421
3144
|
const parent = node.parent;
|
|
3422
|
-
if (parent.type ===
|
|
3145
|
+
if (parent.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && parent.init === node && parent.id.type === import_utils21.AST_NODE_TYPES.Identifier) {
|
|
3423
3146
|
return parent;
|
|
3424
3147
|
}
|
|
3425
3148
|
return null;
|
|
@@ -3447,7 +3170,7 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
|
|
|
3447
3170
|
});
|
|
3448
3171
|
|
|
3449
3172
|
// src/rules/zod-naming-convention.ts
|
|
3450
|
-
var
|
|
3173
|
+
var import_utils22 = require("@typescript-eslint/utils");
|
|
3451
3174
|
var CONVENTIONS = {
|
|
3452
3175
|
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
3453
3176
|
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
@@ -3471,15 +3194,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
|
3471
3194
|
"registry",
|
|
3472
3195
|
"implement"
|
|
3473
3196
|
]);
|
|
3474
|
-
var terminalMethodName = (callee) => !callee.computed && callee.property.type ===
|
|
3197
|
+
var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils22.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
3475
3198
|
var calleeChainStartsWithZ = (node) => {
|
|
3476
3199
|
let current = node;
|
|
3477
|
-
while (current.type ===
|
|
3200
|
+
while (current.type === import_utils22.AST_NODE_TYPES.MemberExpression) {
|
|
3478
3201
|
const receiver = current.object;
|
|
3479
|
-
if (receiver.type ===
|
|
3202
|
+
if (receiver.type === import_utils22.AST_NODE_TYPES.Identifier && receiver.name === "z") {
|
|
3480
3203
|
return true;
|
|
3481
3204
|
}
|
|
3482
|
-
if (receiver.type ===
|
|
3205
|
+
if (receiver.type === import_utils22.AST_NODE_TYPES.CallExpression) {
|
|
3483
3206
|
current = receiver.callee;
|
|
3484
3207
|
continue;
|
|
3485
3208
|
}
|
|
@@ -3487,7 +3210,7 @@ var calleeChainStartsWithZ = (node) => {
|
|
|
3487
3210
|
}
|
|
3488
3211
|
return false;
|
|
3489
3212
|
};
|
|
3490
|
-
var zod_naming_convention_default =
|
|
3213
|
+
var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
|
|
3491
3214
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3492
3215
|
)({
|
|
3493
3216
|
name: "zod-naming-convention",
|
|
@@ -3526,13 +3249,13 @@ var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
|
|
|
3526
3249
|
VariableDeclarator(node) {
|
|
3527
3250
|
const init = node.init;
|
|
3528
3251
|
if (init === null || init === void 0) return;
|
|
3529
|
-
if (init.type !==
|
|
3252
|
+
if (init.type !== import_utils22.AST_NODE_TYPES.CallExpression) return;
|
|
3530
3253
|
const callee = init.callee;
|
|
3531
|
-
if (callee.type !==
|
|
3254
|
+
if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return;
|
|
3532
3255
|
if (!calleeChainStartsWithZ(callee)) return;
|
|
3533
3256
|
const terminal = terminalMethodName(callee);
|
|
3534
3257
|
if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
|
|
3535
|
-
if (node.id.type !==
|
|
3258
|
+
if (node.id.type !== import_utils22.AST_NODE_TYPES.Identifier) return;
|
|
3536
3259
|
if (test.test(node.id.name)) return;
|
|
3537
3260
|
if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
|
|
3538
3261
|
context.report({
|
|
@@ -3545,7 +3268,7 @@ var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
|
|
|
3545
3268
|
});
|
|
3546
3269
|
|
|
3547
3270
|
// src/rules/no-cors-wildcard-with-credentials.ts
|
|
3548
|
-
var
|
|
3271
|
+
var import_utils23 = require("@typescript-eslint/utils");
|
|
3549
3272
|
var ACAO_HEADER = "access-control-allow-origin";
|
|
3550
3273
|
var ACAC_HEADER = "access-control-allow-credentials";
|
|
3551
3274
|
var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
|
|
@@ -3577,17 +3300,17 @@ function subtreeContainsStarLiteral(node) {
|
|
|
3577
3300
|
const value = node[key];
|
|
3578
3301
|
if (Array.isArray(value)) {
|
|
3579
3302
|
for (const child of value) {
|
|
3580
|
-
if (
|
|
3303
|
+
if (isNode2(child) && subtreeContainsStarLiteral(child)) {
|
|
3581
3304
|
return true;
|
|
3582
3305
|
}
|
|
3583
3306
|
}
|
|
3584
|
-
} else if (
|
|
3307
|
+
} else if (isNode2(value) && subtreeContainsStarLiteral(value)) {
|
|
3585
3308
|
return true;
|
|
3586
3309
|
}
|
|
3587
3310
|
}
|
|
3588
3311
|
return false;
|
|
3589
3312
|
}
|
|
3590
|
-
function
|
|
3313
|
+
function isNode2(value) {
|
|
3591
3314
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
3592
3315
|
}
|
|
3593
3316
|
function propertyKeyName(prop) {
|
|
@@ -3603,7 +3326,7 @@ function propertyKeyName(prop) {
|
|
|
3603
3326
|
}
|
|
3604
3327
|
return void 0;
|
|
3605
3328
|
}
|
|
3606
|
-
function
|
|
3329
|
+
function calleeName2(node) {
|
|
3607
3330
|
const callee = node.callee;
|
|
3608
3331
|
if (callee.type === "Identifier") {
|
|
3609
3332
|
return callee.name;
|
|
@@ -3614,7 +3337,7 @@ function calleeName3(node) {
|
|
|
3614
3337
|
return void 0;
|
|
3615
3338
|
}
|
|
3616
3339
|
function isCorsWildcardCredentialsCall(node) {
|
|
3617
|
-
const name =
|
|
3340
|
+
const name = calleeName2(node);
|
|
3618
3341
|
if (name === void 0 || name.toLowerCase() !== "cors") {
|
|
3619
3342
|
return false;
|
|
3620
3343
|
}
|
|
@@ -3687,7 +3410,7 @@ function enclosingScope(node) {
|
|
|
3687
3410
|
}
|
|
3688
3411
|
return void 0;
|
|
3689
3412
|
}
|
|
3690
|
-
var no_cors_wildcard_with_credentials_default =
|
|
3413
|
+
var no_cors_wildcard_with_credentials_default = import_utils23.ESLintUtils.RuleCreator(
|
|
3691
3414
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3692
3415
|
)({
|
|
3693
3416
|
name: "no-cors-wildcard-with-credentials",
|
|
@@ -3755,9 +3478,9 @@ var no_cors_wildcard_with_credentials_default = import_utils24.ESLintUtils.RuleC
|
|
|
3755
3478
|
});
|
|
3756
3479
|
|
|
3757
3480
|
// src/rules/no-silent-promise-catch.ts
|
|
3758
|
-
var
|
|
3481
|
+
var import_utils24 = require("@typescript-eslint/utils");
|
|
3759
3482
|
function isBodyParseCall(node) {
|
|
3760
|
-
return node.type ===
|
|
3483
|
+
return node.type === import_utils24.AST_NODE_TYPES.CallExpression && node.arguments.length === 0 && node.callee.type === import_utils24.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils24.AST_NODE_TYPES.Identifier && (node.callee.property.name === "json" || node.callee.property.name === "text");
|
|
3761
3484
|
}
|
|
3762
3485
|
var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
3763
3486
|
"cancel",
|
|
@@ -3772,21 +3495,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
|
|
|
3772
3495
|
var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
|
|
3773
3496
|
var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
|
|
3774
3497
|
function isTeardownCall(node) {
|
|
3775
|
-
return node.type ===
|
|
3498
|
+
return node.type === import_utils24.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils24.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils24.AST_NODE_TYPES.Identifier && TEARDOWN_METHODS.has(node.callee.property.name);
|
|
3776
3499
|
}
|
|
3777
3500
|
function isSilentExpression(node) {
|
|
3778
3501
|
switch (node.type) {
|
|
3779
|
-
case
|
|
3502
|
+
case import_utils24.AST_NODE_TYPES.Literal:
|
|
3780
3503
|
return !("regex" in node);
|
|
3781
|
-
case
|
|
3504
|
+
case import_utils24.AST_NODE_TYPES.Identifier:
|
|
3782
3505
|
return node.name === "undefined";
|
|
3783
|
-
case
|
|
3784
|
-
return node.operator === "void" && node.argument.type ===
|
|
3785
|
-
case
|
|
3506
|
+
case import_utils24.AST_NODE_TYPES.UnaryExpression:
|
|
3507
|
+
return node.operator === "void" && node.argument.type === import_utils24.AST_NODE_TYPES.Literal;
|
|
3508
|
+
case import_utils24.AST_NODE_TYPES.ObjectExpression:
|
|
3786
3509
|
return node.properties.length === 0;
|
|
3787
|
-
case
|
|
3510
|
+
case import_utils24.AST_NODE_TYPES.ArrayExpression:
|
|
3788
3511
|
return node.elements.length === 0;
|
|
3789
|
-
case
|
|
3512
|
+
case import_utils24.AST_NODE_TYPES.TSAsExpression:
|
|
3790
3513
|
return isSilentExpression(node.expression);
|
|
3791
3514
|
default:
|
|
3792
3515
|
return false;
|
|
@@ -3794,7 +3517,7 @@ function isSilentExpression(node) {
|
|
|
3794
3517
|
}
|
|
3795
3518
|
function isSilentHandler(handler) {
|
|
3796
3519
|
const body = handler.body;
|
|
3797
|
-
if (body.type !==
|
|
3520
|
+
if (body.type !== import_utils24.AST_NODE_TYPES.BlockStatement) {
|
|
3798
3521
|
return isSilentExpression(body);
|
|
3799
3522
|
}
|
|
3800
3523
|
if (body.body.length === 0) {
|
|
@@ -3802,13 +3525,13 @@ function isSilentHandler(handler) {
|
|
|
3802
3525
|
}
|
|
3803
3526
|
if (body.body.length === 1) {
|
|
3804
3527
|
const only = body.body[0];
|
|
3805
|
-
if (only !== void 0 && only.type ===
|
|
3528
|
+
if (only !== void 0 && only.type === import_utils24.AST_NODE_TYPES.ReturnStatement) {
|
|
3806
3529
|
return only.argument === null || isSilentExpression(only.argument);
|
|
3807
3530
|
}
|
|
3808
3531
|
}
|
|
3809
3532
|
return false;
|
|
3810
3533
|
}
|
|
3811
|
-
var no_silent_promise_catch_default =
|
|
3534
|
+
var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
|
|
3812
3535
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3813
3536
|
)({
|
|
3814
3537
|
name: "no-silent-promise-catch",
|
|
@@ -3833,7 +3556,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3833
3556
|
return true;
|
|
3834
3557
|
}
|
|
3835
3558
|
let statement = call;
|
|
3836
|
-
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !==
|
|
3559
|
+
while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== import_utils24.AST_NODE_TYPES.VariableDeclaration) {
|
|
3837
3560
|
statement = statement.parent;
|
|
3838
3561
|
}
|
|
3839
3562
|
if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
|
|
@@ -3845,7 +3568,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3845
3568
|
};
|
|
3846
3569
|
return {
|
|
3847
3570
|
CallExpression(node) {
|
|
3848
|
-
if (node.callee.type !==
|
|
3571
|
+
if (node.callee.type !== import_utils24.AST_NODE_TYPES.MemberExpression || node.callee.computed || node.callee.property.type !== import_utils24.AST_NODE_TYPES.Identifier || node.callee.property.name !== "catch") {
|
|
3849
3572
|
return;
|
|
3850
3573
|
}
|
|
3851
3574
|
if (isBodyParseCall(node.callee.object)) {
|
|
@@ -3854,14 +3577,14 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3854
3577
|
if (isTeardownCall(node.callee.object)) {
|
|
3855
3578
|
return;
|
|
3856
3579
|
}
|
|
3857
|
-
if (node.parent.type ===
|
|
3580
|
+
if (node.parent.type === import_utils24.AST_NODE_TYPES.MemberExpression && node.parent.object === node) {
|
|
3858
3581
|
return;
|
|
3859
3582
|
}
|
|
3860
3583
|
if (node.arguments.length !== 1) {
|
|
3861
3584
|
return;
|
|
3862
3585
|
}
|
|
3863
3586
|
const handler = node.arguments[0];
|
|
3864
|
-
if (handler === void 0 || handler.type !==
|
|
3587
|
+
if (handler === void 0 || handler.type !== import_utils24.AST_NODE_TYPES.ArrowFunctionExpression && handler.type !== import_utils24.AST_NODE_TYPES.FunctionExpression) {
|
|
3865
3588
|
return;
|
|
3866
3589
|
}
|
|
3867
3590
|
if (hasExplanatoryComment(node, handler)) {
|
|
@@ -3876,7 +3599,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3876
3599
|
});
|
|
3877
3600
|
|
|
3878
3601
|
// src/rules/require-fetch-timeout.ts
|
|
3879
|
-
var
|
|
3602
|
+
var import_utils25 = require("@typescript-eslint/utils");
|
|
3880
3603
|
var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
|
|
3881
3604
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
|
|
3882
3605
|
"globalThis",
|
|
@@ -3893,14 +3616,14 @@ function matchesAnyPattern2(filename, patterns) {
|
|
|
3893
3616
|
return false;
|
|
3894
3617
|
}
|
|
3895
3618
|
function initProvablyLacksSignal(init) {
|
|
3896
|
-
if (init.type !==
|
|
3619
|
+
if (init.type !== import_utils25.AST_NODE_TYPES.ObjectExpression) {
|
|
3897
3620
|
return false;
|
|
3898
3621
|
}
|
|
3899
3622
|
for (const prop of init.properties) {
|
|
3900
|
-
if (prop.type ===
|
|
3623
|
+
if (prop.type === import_utils25.AST_NODE_TYPES.SpreadElement) {
|
|
3901
3624
|
return false;
|
|
3902
3625
|
}
|
|
3903
|
-
if (prop.key.type ===
|
|
3626
|
+
if (prop.key.type === import_utils25.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils25.AST_NODE_TYPES.Literal && prop.key.value === "signal") {
|
|
3904
3627
|
return false;
|
|
3905
3628
|
}
|
|
3906
3629
|
if (prop.computed) {
|
|
@@ -3910,9 +3633,9 @@ function initProvablyLacksSignal(init) {
|
|
|
3910
3633
|
return true;
|
|
3911
3634
|
}
|
|
3912
3635
|
function isStringish(node) {
|
|
3913
|
-
return node.type ===
|
|
3636
|
+
return node.type === import_utils25.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils25.AST_NODE_TYPES.TemplateLiteral;
|
|
3914
3637
|
}
|
|
3915
|
-
var require_fetch_timeout_default =
|
|
3638
|
+
var require_fetch_timeout_default = import_utils25.ESLintUtils.RuleCreator(
|
|
3916
3639
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3917
3640
|
)({
|
|
3918
3641
|
name: "require-fetch-timeout",
|
|
@@ -3949,14 +3672,14 @@ var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
|
|
|
3949
3672
|
}
|
|
3950
3673
|
function resolvesToGlobal(identifier) {
|
|
3951
3674
|
const scope = context.sourceCode.getScope(identifier);
|
|
3952
|
-
const variable =
|
|
3675
|
+
const variable = import_utils25.ASTUtils.findVariable(scope, identifier.name);
|
|
3953
3676
|
return variable === null || variable.defs.length === 0;
|
|
3954
3677
|
}
|
|
3955
3678
|
function isGlobalFetchCall2(callee) {
|
|
3956
|
-
if (callee.type ===
|
|
3679
|
+
if (callee.type === import_utils25.AST_NODE_TYPES.Identifier) {
|
|
3957
3680
|
return callee.name === "fetch" && resolvesToGlobal(callee);
|
|
3958
3681
|
}
|
|
3959
|
-
return callee.type ===
|
|
3682
|
+
return callee.type === import_utils25.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils25.AST_NODE_TYPES.Identifier && callee.property.name === "fetch" && callee.object.type === import_utils25.AST_NODE_TYPES.Identifier && GLOBAL_OBJECTS.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
3960
3683
|
}
|
|
3961
3684
|
return {
|
|
3962
3685
|
CallExpression(node) {
|
|
@@ -3975,100 +3698,13 @@ var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
|
|
|
3975
3698
|
}
|
|
3976
3699
|
});
|
|
3977
3700
|
|
|
3978
|
-
// src/rules/
|
|
3979
|
-
var
|
|
3980
|
-
var
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
function isConstTypeAnnotation(typeAnnotation) {
|
|
3986
|
-
return typeAnnotation.type === import_utils27.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils27.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
|
|
3987
|
-
}
|
|
3988
|
-
function isValidatorCall(node) {
|
|
3989
|
-
return node.callee.type === import_utils27.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils27.AST_NODE_TYPES.Identifier && VALIDATOR_METHODS.has(node.callee.property.name);
|
|
3990
|
-
}
|
|
3991
|
-
function findCastExpression(node, insideValidatorArg) {
|
|
3992
|
-
if ((node.type === import_utils27.AST_NODE_TYPES.TSAsExpression || node.type === import_utils27.AST_NODE_TYPES.TSTypeAssertion) && !isConstTypeAnnotation(node.typeAnnotation) && !insideValidatorArg) {
|
|
3993
|
-
return node;
|
|
3994
|
-
}
|
|
3995
|
-
if (node.type === import_utils27.AST_NODE_TYPES.CallExpression && isValidatorCall(node)) {
|
|
3996
|
-
const inCallee = findCastExpression(node.callee, insideValidatorArg);
|
|
3997
|
-
if (inCallee !== null) {
|
|
3998
|
-
return inCallee;
|
|
3999
|
-
}
|
|
4000
|
-
for (const arg of node.arguments) {
|
|
4001
|
-
const found = findCastExpression(arg, true);
|
|
4002
|
-
if (found !== null) {
|
|
4003
|
-
return found;
|
|
4004
|
-
}
|
|
4005
|
-
}
|
|
4006
|
-
return null;
|
|
4007
|
-
}
|
|
4008
|
-
for (const key of Object.keys(node)) {
|
|
4009
|
-
if (key === "parent") {
|
|
4010
|
-
continue;
|
|
4011
|
-
}
|
|
4012
|
-
const value = node[key];
|
|
4013
|
-
const children = Array.isArray(value) ? value : [value];
|
|
4014
|
-
for (const child of children) {
|
|
4015
|
-
if (child !== null && typeof child === "object" && "type" in child && typeof child.type === "string") {
|
|
4016
|
-
const found = findCastExpression(
|
|
4017
|
-
child,
|
|
4018
|
-
insideValidatorArg
|
|
4019
|
-
);
|
|
4020
|
-
if (found !== null) {
|
|
4021
|
-
return found;
|
|
4022
|
-
}
|
|
4023
|
-
}
|
|
4024
|
-
}
|
|
4025
|
-
}
|
|
4026
|
-
return null;
|
|
4027
|
-
}
|
|
4028
|
-
var require_schema_validate_search_default = import_utils27.ESLintUtils.RuleCreator(
|
|
4029
|
-
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4030
|
-
)({
|
|
4031
|
-
name: "require-schema-validate-search",
|
|
4032
|
-
meta: {
|
|
4033
|
-
type: "problem",
|
|
4034
|
-
docs: {
|
|
4035
|
-
description: "Disallow `as` casts inside hand-rolled `validateSearch` functions; use a schema validator (e.g. zodValidator) so search params are validated at runtime."
|
|
4036
|
-
},
|
|
4037
|
-
schema: [],
|
|
4038
|
-
messages: {
|
|
4039
|
-
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."
|
|
4040
|
-
}
|
|
4041
|
-
},
|
|
4042
|
-
defaultOptions: [],
|
|
4043
|
-
create(context) {
|
|
4044
|
-
if (isTestFile(context.filename)) {
|
|
4045
|
-
return {};
|
|
4046
|
-
}
|
|
4047
|
-
return {
|
|
4048
|
-
Property(node) {
|
|
4049
|
-
const isValidateSearchKey = !node.computed && node.key.type === import_utils27.AST_NODE_TYPES.Identifier && node.key.name === "validateSearch" || node.key.type === import_utils27.AST_NODE_TYPES.Literal && node.key.value === "validateSearch";
|
|
4050
|
-
if (!isValidateSearchKey) {
|
|
4051
|
-
return;
|
|
4052
|
-
}
|
|
4053
|
-
if (node.value.type !== import_utils27.AST_NODE_TYPES.ArrowFunctionExpression && node.value.type !== import_utils27.AST_NODE_TYPES.FunctionExpression) {
|
|
4054
|
-
return;
|
|
4055
|
-
}
|
|
4056
|
-
const cast = findCastExpression(node.value.body, false);
|
|
4057
|
-
if (cast !== null) {
|
|
4058
|
-
context.report({ node: cast, messageId: "castInValidateSearch" });
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
};
|
|
4062
|
-
}
|
|
4063
|
-
});
|
|
4064
|
-
|
|
4065
|
-
// src/rules/no-fat-try-blocks.ts
|
|
4066
|
-
var import_utils28 = require("@typescript-eslint/utils");
|
|
4067
|
-
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
4068
|
-
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
4069
|
-
import_utils28.AST_NODE_TYPES.FunctionDeclaration,
|
|
4070
|
-
import_utils28.AST_NODE_TYPES.FunctionExpression,
|
|
4071
|
-
import_utils28.AST_NODE_TYPES.ArrowFunctionExpression
|
|
3701
|
+
// src/rules/no-fat-try-blocks.ts
|
|
3702
|
+
var import_utils26 = require("@typescript-eslint/utils");
|
|
3703
|
+
var MAX_TRY_BODY_STATEMENTS = 3;
|
|
3704
|
+
var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
3705
|
+
import_utils26.AST_NODE_TYPES.FunctionDeclaration,
|
|
3706
|
+
import_utils26.AST_NODE_TYPES.FunctionExpression,
|
|
3707
|
+
import_utils26.AST_NODE_TYPES.ArrowFunctionExpression
|
|
4072
3708
|
]);
|
|
4073
3709
|
var PURE_METHODS = /* @__PURE__ */ new Set([
|
|
4074
3710
|
"map",
|
|
@@ -4161,25 +3797,25 @@ var PURE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
4161
3797
|
"Response",
|
|
4162
3798
|
"AbortController"
|
|
4163
3799
|
]);
|
|
4164
|
-
function
|
|
3800
|
+
function isNode3(value) {
|
|
4165
3801
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
4166
3802
|
}
|
|
4167
3803
|
function isPureCall(node) {
|
|
4168
3804
|
const callee = node.callee;
|
|
4169
|
-
if (callee.type !==
|
|
3805
|
+
if (callee.type !== import_utils26.AST_NODE_TYPES.MemberExpression) {
|
|
4170
3806
|
return false;
|
|
4171
3807
|
}
|
|
4172
3808
|
const property = callee.property;
|
|
4173
|
-
if (property.type !==
|
|
3809
|
+
if (property.type !== import_utils26.AST_NODE_TYPES.Identifier) {
|
|
4174
3810
|
return false;
|
|
4175
3811
|
}
|
|
4176
|
-
if (callee.object.type ===
|
|
3812
|
+
if (callee.object.type === import_utils26.AST_NODE_TYPES.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
|
|
4177
3813
|
return true;
|
|
4178
3814
|
}
|
|
4179
3815
|
return PURE_METHODS.has(property.name);
|
|
4180
3816
|
}
|
|
4181
3817
|
function isPureNew(node) {
|
|
4182
|
-
return node.callee.type ===
|
|
3818
|
+
return node.callee.type === import_utils26.AST_NODE_TYPES.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
|
|
4183
3819
|
}
|
|
4184
3820
|
function subtreeMatches(stmt, predicate) {
|
|
4185
3821
|
let found = false;
|
|
@@ -4201,11 +3837,11 @@ function subtreeMatches(stmt, predicate) {
|
|
|
4201
3837
|
const value = current[key];
|
|
4202
3838
|
if (Array.isArray(value)) {
|
|
4203
3839
|
for (const child of value) {
|
|
4204
|
-
if (
|
|
3840
|
+
if (isNode3(child)) {
|
|
4205
3841
|
visit(child);
|
|
4206
3842
|
}
|
|
4207
3843
|
}
|
|
4208
|
-
} else if (
|
|
3844
|
+
} else if (isNode3(value)) {
|
|
4209
3845
|
visit(value);
|
|
4210
3846
|
}
|
|
4211
3847
|
if (found) {
|
|
@@ -4216,20 +3852,20 @@ function subtreeMatches(stmt, predicate) {
|
|
|
4216
3852
|
visit(stmt);
|
|
4217
3853
|
return found;
|
|
4218
3854
|
}
|
|
4219
|
-
var hasAwait = (node) => subtreeMatches(node, (n) => n.type ===
|
|
3855
|
+
var hasAwait = (node) => subtreeMatches(node, (n) => n.type === import_utils26.AST_NODE_TYPES.AwaitExpression);
|
|
4220
3856
|
var hasThrowingCallOrNew = (node) => subtreeMatches(
|
|
4221
3857
|
node,
|
|
4222
|
-
(n) => n.type ===
|
|
3858
|
+
(n) => n.type === import_utils26.AST_NODE_TYPES.CallExpression && !isPureCall(n) || n.type === import_utils26.AST_NODE_TYPES.NewExpression && !isPureNew(n)
|
|
4223
3859
|
);
|
|
4224
3860
|
function unwrap2(expr) {
|
|
4225
3861
|
let current = expr;
|
|
4226
|
-
while (current.type ===
|
|
3862
|
+
while (current.type === import_utils26.AST_NODE_TYPES.ChainExpression || current.type === import_utils26.AST_NODE_TYPES.TSNonNullExpression) {
|
|
4227
3863
|
current = current.expression;
|
|
4228
3864
|
}
|
|
4229
3865
|
return current;
|
|
4230
3866
|
}
|
|
4231
3867
|
function isBareCallStatement(stmt) {
|
|
4232
|
-
return stmt.type ===
|
|
3868
|
+
return stmt.type === import_utils26.AST_NODE_TYPES.ExpressionStatement && unwrap2(stmt.expression).type === import_utils26.AST_NODE_TYPES.CallExpression;
|
|
4233
3869
|
}
|
|
4234
3870
|
function canThrow(stmt) {
|
|
4235
3871
|
if (hasAwait(stmt)) {
|
|
@@ -4238,10 +3874,10 @@ function canThrow(stmt) {
|
|
|
4238
3874
|
if (isBareCallStatement(stmt)) {
|
|
4239
3875
|
return false;
|
|
4240
3876
|
}
|
|
4241
|
-
if (stmt.type ===
|
|
3877
|
+
if (stmt.type === import_utils26.AST_NODE_TYPES.BlockStatement) {
|
|
4242
3878
|
return stmt.body.some(canThrow);
|
|
4243
3879
|
}
|
|
4244
|
-
if (stmt.type ===
|
|
3880
|
+
if (stmt.type === import_utils26.AST_NODE_TYPES.IfStatement) {
|
|
4245
3881
|
return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
|
|
4246
3882
|
}
|
|
4247
3883
|
return hasThrowingCallOrNew(stmt);
|
|
@@ -4252,9 +3888,9 @@ function handlerRethrows(handler) {
|
|
|
4252
3888
|
}
|
|
4253
3889
|
const body = handler.body.body;
|
|
4254
3890
|
const last = body[body.length - 1];
|
|
4255
|
-
return last !== void 0 && last.type ===
|
|
3891
|
+
return last !== void 0 && last.type === import_utils26.AST_NODE_TYPES.ThrowStatement;
|
|
4256
3892
|
}
|
|
4257
|
-
var no_fat_try_blocks_default =
|
|
3893
|
+
var no_fat_try_blocks_default = import_utils26.ESLintUtils.RuleCreator(
|
|
4258
3894
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4259
3895
|
)({
|
|
4260
3896
|
name: "no-fat-try-blocks",
|
|
@@ -4298,7 +3934,7 @@ var no_fat_try_blocks_default = import_utils28.ESLintUtils.RuleCreator(
|
|
|
4298
3934
|
});
|
|
4299
3935
|
|
|
4300
3936
|
// src/rules/no-secret-in-log.ts
|
|
4301
|
-
var
|
|
3937
|
+
var import_utils27 = require("@typescript-eslint/utils");
|
|
4302
3938
|
|
|
4303
3939
|
// src/rules/_secret_names.ts
|
|
4304
3940
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4560,7 +4196,7 @@ function propertyKeyName2(prop) {
|
|
|
4560
4196
|
}
|
|
4561
4197
|
return null;
|
|
4562
4198
|
}
|
|
4563
|
-
var no_secret_in_log_default =
|
|
4199
|
+
var no_secret_in_log_default = import_utils27.ESLintUtils.RuleCreator(
|
|
4564
4200
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4565
4201
|
)({
|
|
4566
4202
|
name: "no-secret-in-log",
|
|
@@ -4636,46 +4272,46 @@ var no_secret_in_log_default = import_utils29.ESLintUtils.RuleCreator(
|
|
|
4636
4272
|
}
|
|
4637
4273
|
});
|
|
4638
4274
|
|
|
4639
|
-
// src/rules/no-unsafe-
|
|
4640
|
-
var
|
|
4641
|
-
var
|
|
4642
|
-
function
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4275
|
+
// src/rules/no-unsafe-mock-casting.ts
|
|
4276
|
+
var import_utils28 = require("@typescript-eslint/utils");
|
|
4277
|
+
var import_utils29 = require("@typescript-eslint/utils");
|
|
4278
|
+
function isMockTypeReference(node) {
|
|
4279
|
+
if (node.type !== import_utils29.AST_NODE_TYPES.TSTypeReference) {
|
|
4280
|
+
return false;
|
|
4281
|
+
}
|
|
4282
|
+
const typeName = node.typeName;
|
|
4283
|
+
if (typeName.type === import_utils29.AST_NODE_TYPES.Identifier) {
|
|
4284
|
+
const name = typeName.name;
|
|
4285
|
+
return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
|
|
4286
|
+
}
|
|
4287
|
+
if (typeName.type === import_utils29.AST_NODE_TYPES.TSQualifiedName) {
|
|
4288
|
+
const rightName = typeName.right.name;
|
|
4289
|
+
return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
|
|
4290
|
+
}
|
|
4291
|
+
return false;
|
|
4647
4292
|
}
|
|
4648
|
-
var
|
|
4293
|
+
var no_unsafe_mock_casting_default = import_utils28.ESLintUtils.RuleCreator(
|
|
4649
4294
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4650
4295
|
)({
|
|
4651
|
-
name: "no-unsafe-
|
|
4296
|
+
name: "no-unsafe-mock-casting",
|
|
4652
4297
|
meta: {
|
|
4653
4298
|
type: "problem",
|
|
4654
4299
|
docs: {
|
|
4655
|
-
description: "Disallow
|
|
4300
|
+
description: "Disallow casting to mock types like `jest.Mock` or `vi.Mock`. Use `vi.mocked()` or `jest.mocked()` instead."
|
|
4656
4301
|
},
|
|
4657
4302
|
schema: [],
|
|
4658
4303
|
messages: {
|
|
4659
|
-
|
|
4660
|
-
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."
|
|
4304
|
+
unsafeMockCast: "Do not cast to a Mock type. Use `vi.mocked(fn)` or `jest.mocked(fn)` instead to preserve type safety."
|
|
4661
4305
|
}
|
|
4662
4306
|
},
|
|
4663
4307
|
defaultOptions: [],
|
|
4664
4308
|
create(context) {
|
|
4665
|
-
if (
|
|
4309
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
4666
4310
|
return {};
|
|
4667
4311
|
}
|
|
4668
4312
|
function checkAssertion(node) {
|
|
4669
|
-
if (
|
|
4670
|
-
|
|
4671
|
-
}
|
|
4672
|
-
if (isAnyAnnotation(node.typeAnnotation)) {
|
|
4673
|
-
context.report({ node, messageId: "asAny" });
|
|
4674
|
-
return;
|
|
4675
|
-
}
|
|
4676
|
-
const inner = node.expression;
|
|
4677
|
-
if (inner.type === import_utils31.AST_NODE_TYPES.TSAsExpression || inner.type === import_utils31.AST_NODE_TYPES.TSTypeAssertion) {
|
|
4678
|
-
context.report({ node, messageId: "doubleCast" });
|
|
4313
|
+
if (isMockTypeReference(node.typeAnnotation)) {
|
|
4314
|
+
context.report({ node, messageId: "unsafeMockCast" });
|
|
4679
4315
|
}
|
|
4680
4316
|
}
|
|
4681
4317
|
return {
|
|
@@ -4686,7 +4322,7 @@ var no_unsafe_cast_default = import_utils30.ESLintUtils.RuleCreator(
|
|
|
4686
4322
|
});
|
|
4687
4323
|
|
|
4688
4324
|
// src/rules/prefer-string-literal-union.ts
|
|
4689
|
-
var
|
|
4325
|
+
var import_utils30 = require("@typescript-eslint/utils");
|
|
4690
4326
|
var ts = __toESM(require("typescript"), 1);
|
|
4691
4327
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
4692
4328
|
"status",
|
|
@@ -4729,19 +4365,19 @@ function isChoiceLikeName(name) {
|
|
|
4729
4365
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
4730
4366
|
}
|
|
4731
4367
|
function keyName(key) {
|
|
4732
|
-
if (key.type ===
|
|
4368
|
+
if (key.type === import_utils30.AST_NODE_TYPES.Identifier) {
|
|
4733
4369
|
return key.name;
|
|
4734
4370
|
}
|
|
4735
|
-
if (key.type ===
|
|
4371
|
+
if (key.type === import_utils30.AST_NODE_TYPES.Literal && typeof key.value === "string") {
|
|
4736
4372
|
return key.value;
|
|
4737
4373
|
}
|
|
4738
4374
|
return null;
|
|
4739
4375
|
}
|
|
4740
4376
|
function isStringLiteralMember(t) {
|
|
4741
|
-
return t.type ===
|
|
4377
|
+
return t.type === import_utils30.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils30.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
|
|
4742
4378
|
}
|
|
4743
4379
|
function isStringLiteralUnion(node) {
|
|
4744
|
-
if (node?.type !==
|
|
4380
|
+
if (node?.type !== import_utils30.AST_NODE_TYPES.TSUnionType) {
|
|
4745
4381
|
return false;
|
|
4746
4382
|
}
|
|
4747
4383
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -4770,12 +4406,12 @@ function bindingSourceExpression(decl) {
|
|
|
4770
4406
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
4771
4407
|
}
|
|
4772
4408
|
function refKey(node) {
|
|
4773
|
-
if (node.type ===
|
|
4409
|
+
if (node.type === import_utils30.AST_NODE_TYPES.Identifier) {
|
|
4774
4410
|
return node.name;
|
|
4775
4411
|
}
|
|
4776
|
-
if (node.type ===
|
|
4412
|
+
if (node.type === import_utils30.AST_NODE_TYPES.MemberExpression && !node.computed) {
|
|
4777
4413
|
const inner = refKey(node.object);
|
|
4778
|
-
if (inner === null || node.property.type !==
|
|
4414
|
+
if (inner === null || node.property.type !== import_utils30.AST_NODE_TYPES.Identifier) {
|
|
4779
4415
|
return null;
|
|
4780
4416
|
}
|
|
4781
4417
|
return `${inner}.${node.property.name}`;
|
|
@@ -4783,12 +4419,12 @@ function refKey(node) {
|
|
|
4783
4419
|
return null;
|
|
4784
4420
|
}
|
|
4785
4421
|
function strLiteral(node) {
|
|
4786
|
-
if (node.type ===
|
|
4422
|
+
if (node.type === import_utils30.AST_NODE_TYPES.Literal && typeof node.value === "string") {
|
|
4787
4423
|
return node.value;
|
|
4788
4424
|
}
|
|
4789
4425
|
return null;
|
|
4790
4426
|
}
|
|
4791
|
-
var prefer_string_literal_union_default =
|
|
4427
|
+
var prefer_string_literal_union_default = import_utils30.ESLintUtils.RuleCreator(
|
|
4792
4428
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4793
4429
|
)({
|
|
4794
4430
|
name: "prefer-string-literal-union",
|
|
@@ -4826,7 +4462,7 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
|
|
|
4826
4462
|
);
|
|
4827
4463
|
let services;
|
|
4828
4464
|
try {
|
|
4829
|
-
services =
|
|
4465
|
+
services = import_utils30.ESLintUtils.getParserServices(context);
|
|
4830
4466
|
} catch {
|
|
4831
4467
|
services = null;
|
|
4832
4468
|
}
|
|
@@ -4938,7 +4574,7 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
|
|
|
4938
4574
|
containersWithUnion.add(container);
|
|
4939
4575
|
return;
|
|
4940
4576
|
}
|
|
4941
|
-
if (typeNode?.type !==
|
|
4577
|
+
if (typeNode?.type !== import_utils30.AST_NODE_TYPES.TSStringKeyword) {
|
|
4942
4578
|
return;
|
|
4943
4579
|
}
|
|
4944
4580
|
const name = keyName(key);
|
|
@@ -5026,10 +4662,10 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
|
|
|
5026
4662
|
}
|
|
5027
4663
|
};
|
|
5028
4664
|
function refKeyText(node) {
|
|
5029
|
-
if (node.type ===
|
|
4665
|
+
if (node.type === import_utils30.AST_NODE_TYPES.BinaryExpression) {
|
|
5030
4666
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
5031
4667
|
}
|
|
5032
|
-
if (node.type ===
|
|
4668
|
+
if (node.type === import_utils30.AST_NODE_TYPES.SwitchStatement) {
|
|
5033
4669
|
return refKey(node.discriminant) ?? "value";
|
|
5034
4670
|
}
|
|
5035
4671
|
return "value";
|
|
@@ -5037,146 +4673,90 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
|
|
|
5037
4673
|
}
|
|
5038
4674
|
});
|
|
5039
4675
|
|
|
5040
|
-
// src/rules/
|
|
5041
|
-
var
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
"common",
|
|
5048
|
-
"constant",
|
|
5049
|
-
"constants",
|
|
5050
|
-
"type",
|
|
5051
|
-
"types",
|
|
5052
|
-
"model",
|
|
5053
|
-
"models",
|
|
5054
|
-
"shared",
|
|
5055
|
-
"misc"
|
|
5056
|
-
]);
|
|
5057
|
-
var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
|
|
5058
|
-
var ACRONYM_OVERRIDES = [
|
|
5059
|
-
[/OAuth/g, "Oauth"],
|
|
5060
|
-
[/GraphQL/g, "Graphql"],
|
|
5061
|
-
[/gRPC/g, "Grpc"]
|
|
5062
|
-
];
|
|
5063
|
-
var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
|
|
5064
|
-
var TEST_FILE_RE = /\.(test|spec)\.[cm]?[jt]sx?$/i;
|
|
5065
|
-
var SCRIPT_EXT_RE = /\.[cm]?[jt]sx?$/i;
|
|
5066
|
-
var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
|
|
5067
|
-
var stemOf = (base) => base.replace(SCRIPT_EXT_RE, "");
|
|
5068
|
-
var kebabCase2 = (name) => {
|
|
5069
|
-
let normalized = name;
|
|
5070
|
-
for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
|
|
5071
|
-
normalized = normalized.replace(pattern, replacement);
|
|
5072
|
-
}
|
|
5073
|
-
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
5074
|
-
};
|
|
5075
|
-
var isFunctionExpression = (node) => node !== null && (node.type === import_utils33.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils33.AST_NODE_TYPES.FunctionExpression);
|
|
5076
|
-
var functionConstName = (decl) => {
|
|
5077
|
-
if (decl.declarations.length !== 1) return null;
|
|
5078
|
-
const [declarator] = decl.declarations;
|
|
5079
|
-
if (declarator === void 0) return null;
|
|
5080
|
-
if (declarator.id.type !== import_utils33.AST_NODE_TYPES.Identifier) return null;
|
|
5081
|
-
if (!isFunctionExpression(declarator.init)) return null;
|
|
5082
|
-
return declarator.id.name;
|
|
5083
|
-
};
|
|
5084
|
-
var summarizeExports = (body) => {
|
|
5085
|
-
let names = 0;
|
|
5086
|
-
let hasReExport = false;
|
|
5087
|
-
let candidate = null;
|
|
5088
|
-
const addCandidate = (name, node) => {
|
|
5089
|
-
names += 1;
|
|
5090
|
-
candidate = { name, node };
|
|
5091
|
-
};
|
|
5092
|
-
for (const statement of body) {
|
|
5093
|
-
switch (statement.type) {
|
|
5094
|
-
case import_utils33.AST_NODE_TYPES.ExportAllDeclaration:
|
|
5095
|
-
hasReExport = true;
|
|
5096
|
-
break;
|
|
5097
|
-
case import_utils33.AST_NODE_TYPES.ExportDefaultDeclaration: {
|
|
5098
|
-
names += 1;
|
|
5099
|
-
const decl = statement.declaration;
|
|
5100
|
-
if (decl.type === import_utils33.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
|
|
5101
|
-
candidate = { name: decl.id.name, node: statement };
|
|
5102
|
-
} else if (decl.type === import_utils33.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
|
|
5103
|
-
candidate = { name: decl.id.name, node: statement };
|
|
5104
|
-
}
|
|
5105
|
-
break;
|
|
5106
|
-
}
|
|
5107
|
-
case import_utils33.AST_NODE_TYPES.ExportNamedDeclaration: {
|
|
5108
|
-
if (statement.source !== null) {
|
|
5109
|
-
hasReExport = true;
|
|
5110
|
-
break;
|
|
5111
|
-
}
|
|
5112
|
-
const decl = statement.declaration;
|
|
5113
|
-
if (decl === null) {
|
|
5114
|
-
names += statement.specifiers.length;
|
|
5115
|
-
break;
|
|
5116
|
-
}
|
|
5117
|
-
switch (decl.type) {
|
|
5118
|
-
case import_utils33.AST_NODE_TYPES.FunctionDeclaration:
|
|
5119
|
-
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5120
|
-
else names += 1;
|
|
5121
|
-
break;
|
|
5122
|
-
case import_utils33.AST_NODE_TYPES.ClassDeclaration:
|
|
5123
|
-
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
5124
|
-
else names += 1;
|
|
5125
|
-
break;
|
|
5126
|
-
case import_utils33.AST_NODE_TYPES.VariableDeclaration: {
|
|
5127
|
-
const fnName = functionConstName(decl);
|
|
5128
|
-
if (fnName !== null && decl.declarations.length === 1) {
|
|
5129
|
-
addCandidate(fnName, statement);
|
|
5130
|
-
} else {
|
|
5131
|
-
names += decl.declarations.length;
|
|
5132
|
-
}
|
|
5133
|
-
break;
|
|
5134
|
-
}
|
|
5135
|
-
default:
|
|
5136
|
-
names += 1;
|
|
5137
|
-
}
|
|
5138
|
-
break;
|
|
5139
|
-
}
|
|
5140
|
-
default:
|
|
5141
|
-
break;
|
|
5142
|
-
}
|
|
5143
|
-
}
|
|
5144
|
-
return { names, hasReExport, candidate };
|
|
5145
|
-
};
|
|
5146
|
-
var single_public_export_default = import_utils33.ESLintUtils.RuleCreator(
|
|
5147
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
4676
|
+
// src/rules/prefer-zod-enum.ts
|
|
4677
|
+
var import_utils31 = require("@typescript-eslint/utils");
|
|
4678
|
+
function isZodModule(source) {
|
|
4679
|
+
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
4680
|
+
}
|
|
4681
|
+
var prefer_zod_enum_default = import_utils31.ESLintUtils.RuleCreator(
|
|
4682
|
+
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
5148
4683
|
)({
|
|
5149
|
-
name: "
|
|
4684
|
+
name: "prefer-zod-enum",
|
|
5150
4685
|
meta: {
|
|
5151
4686
|
type: "suggestion",
|
|
5152
4687
|
docs: {
|
|
5153
|
-
description: "
|
|
4688
|
+
description: "Prefer z.enum([...]) over z.union([z.literal(...), ...]) for string choices"
|
|
5154
4689
|
},
|
|
4690
|
+
fixable: "code",
|
|
5155
4691
|
schema: [],
|
|
5156
4692
|
messages: {
|
|
5157
|
-
|
|
4693
|
+
preferEnum: "Use `z.enum([...])` instead of a union of string-literal schemas."
|
|
5158
4694
|
}
|
|
5159
4695
|
},
|
|
5160
4696
|
defaultOptions: [],
|
|
5161
4697
|
create(context) {
|
|
5162
|
-
const
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
4698
|
+
const sourceCode = context.sourceCode;
|
|
4699
|
+
const zodNamespaces = /* @__PURE__ */ new Set();
|
|
4700
|
+
function enumValues(node) {
|
|
4701
|
+
const callee = node.callee;
|
|
4702
|
+
if (callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || callee.computed || callee.object.type !== import_utils31.AST_NODE_TYPES.Identifier || !zodNamespaces.has(callee.object.name) || callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier || callee.property.name !== "union" || node.arguments.length !== 1) {
|
|
4703
|
+
return null;
|
|
4704
|
+
}
|
|
4705
|
+
const argument = node.arguments[0];
|
|
4706
|
+
if (argument === void 0 || argument.type !== import_utils31.AST_NODE_TYPES.ArrayExpression || argument.elements.length === 0) {
|
|
4707
|
+
return null;
|
|
4708
|
+
}
|
|
4709
|
+
const values = [];
|
|
4710
|
+
for (const element of argument.elements) {
|
|
4711
|
+
if (element === null || element.type !== import_utils31.AST_NODE_TYPES.CallExpression || element.arguments.length !== 1 || element.callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || element.callee.computed || element.callee.object.type !== import_utils31.AST_NODE_TYPES.Identifier || !zodNamespaces.has(element.callee.object.name) || element.callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier || element.callee.property.name !== "literal") {
|
|
4712
|
+
return null;
|
|
4713
|
+
}
|
|
4714
|
+
const value = element.arguments[0];
|
|
4715
|
+
if (value === void 0 || value.type !== import_utils31.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
|
|
4716
|
+
return null;
|
|
4717
|
+
}
|
|
4718
|
+
values.push(value);
|
|
4719
|
+
}
|
|
4720
|
+
return values;
|
|
4721
|
+
}
|
|
4722
|
+
function buildFix(node, values) {
|
|
4723
|
+
const argument = node.arguments[0];
|
|
4724
|
+
if (argument === void 0 || argument.type !== import_utils31.AST_NODE_TYPES.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
|
|
4725
|
+
return void 0;
|
|
4726
|
+
}
|
|
4727
|
+
const callee = node.callee;
|
|
4728
|
+
if (callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier) {
|
|
4729
|
+
return void 0;
|
|
4730
|
+
}
|
|
4731
|
+
return (fixer) => [
|
|
4732
|
+
fixer.replaceText(callee.property, "enum"),
|
|
4733
|
+
fixer.replaceText(
|
|
4734
|
+
argument,
|
|
4735
|
+
`[${values.map((value) => sourceCode.getText(value)).join(", ")}]`
|
|
4736
|
+
)
|
|
4737
|
+
];
|
|
4738
|
+
}
|
|
5168
4739
|
return {
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
4740
|
+
ImportDeclaration(node) {
|
|
4741
|
+
if (!isZodModule(node.source.value)) {
|
|
4742
|
+
return;
|
|
4743
|
+
}
|
|
4744
|
+
for (const specifier of node.specifiers) {
|
|
4745
|
+
if (specifier.type === import_utils31.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils31.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils31.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === import_utils31.AST_NODE_TYPES.Identifier && specifier.imported.name === "z") {
|
|
4746
|
+
zodNamespaces.add(specifier.local.name);
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
},
|
|
4750
|
+
CallExpression(node) {
|
|
4751
|
+
const values = enumValues(node);
|
|
4752
|
+
if (values === null) {
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
const fix = buildFix(node, values);
|
|
5176
4756
|
context.report({
|
|
5177
|
-
node
|
|
5178
|
-
messageId: "
|
|
5179
|
-
|
|
4757
|
+
node,
|
|
4758
|
+
messageId: "preferEnum",
|
|
4759
|
+
...fix === void 0 ? {} : { fix }
|
|
5180
4760
|
});
|
|
5181
4761
|
}
|
|
5182
4762
|
};
|
|
@@ -5184,10 +4764,10 @@ var single_public_export_default = import_utils33.ESLintUtils.RuleCreator(
|
|
|
5184
4764
|
});
|
|
5185
4765
|
|
|
5186
4766
|
// src/rules/no-offset-pagination.ts
|
|
5187
|
-
var
|
|
4767
|
+
var import_utils33 = require("@typescript-eslint/utils");
|
|
5188
4768
|
|
|
5189
4769
|
// src/rules/_sql.ts
|
|
5190
|
-
var
|
|
4770
|
+
var import_utils32 = require("@typescript-eslint/utils");
|
|
5191
4771
|
function stripSqlNoise(text) {
|
|
5192
4772
|
const out = [...text];
|
|
5193
4773
|
const n = text.length;
|
|
@@ -5248,13 +4828,13 @@ function stripSqlNoise(text) {
|
|
|
5248
4828
|
var SUBSTITUTION_MARKER = "?";
|
|
5249
4829
|
function sqlTextOf(node) {
|
|
5250
4830
|
switch (node.type) {
|
|
5251
|
-
case
|
|
4831
|
+
case import_utils32.AST_NODE_TYPES.Literal:
|
|
5252
4832
|
return typeof node.value === "string" ? node.value : null;
|
|
5253
|
-
case
|
|
4833
|
+
case import_utils32.AST_NODE_TYPES.TemplateLiteral:
|
|
5254
4834
|
return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
|
|
5255
|
-
case
|
|
4835
|
+
case import_utils32.AST_NODE_TYPES.TaggedTemplateExpression:
|
|
5256
4836
|
return sqlTextOf(node.quasi);
|
|
5257
|
-
case
|
|
4837
|
+
case import_utils32.AST_NODE_TYPES.BinaryExpression: {
|
|
5258
4838
|
if (node.operator !== "+") {
|
|
5259
4839
|
return null;
|
|
5260
4840
|
}
|
|
@@ -5262,7 +4842,7 @@ function sqlTextOf(node) {
|
|
|
5262
4842
|
const right = sqlTextOf(node.right);
|
|
5263
4843
|
return left !== null && right !== null ? left + right : null;
|
|
5264
4844
|
}
|
|
5265
|
-
case
|
|
4845
|
+
case import_utils32.AST_NODE_TYPES.ArrayExpression: {
|
|
5266
4846
|
const parts = [];
|
|
5267
4847
|
for (const element of node.elements) {
|
|
5268
4848
|
if (element === null) {
|
|
@@ -5282,7 +4862,7 @@ function sqlTextOf(node) {
|
|
|
5282
4862
|
}
|
|
5283
4863
|
function isJoinedFragmentArray(node) {
|
|
5284
4864
|
const parent = node.parent;
|
|
5285
|
-
return parent?.type ===
|
|
4865
|
+
return parent?.type === import_utils32.AST_NODE_TYPES.MemberExpression && parent.object === node && !parent.computed && parent.property.type === import_utils32.AST_NODE_TYPES.Identifier && parent.property.name === "join" && parent.parent?.type === import_utils32.AST_NODE_TYPES.CallExpression;
|
|
5286
4866
|
}
|
|
5287
4867
|
function markConsumed(node, consumed) {
|
|
5288
4868
|
consumed.add(node);
|
|
@@ -5332,7 +4912,7 @@ function createSqlListener(handler) {
|
|
|
5332
4912
|
// src/rules/no-offset-pagination.ts
|
|
5333
4913
|
var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
|
|
5334
4914
|
var OFFSET_GATE = /offset/i;
|
|
5335
|
-
var no_offset_pagination_default =
|
|
4915
|
+
var no_offset_pagination_default = import_utils33.ESLintUtils.RuleCreator(
|
|
5336
4916
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5337
4917
|
)({
|
|
5338
4918
|
name: "no-offset-pagination",
|
|
@@ -5361,15 +4941,15 @@ var no_offset_pagination_default = import_utils35.ESLintUtils.RuleCreator(
|
|
|
5361
4941
|
});
|
|
5362
4942
|
|
|
5363
4943
|
// src/rules/no-positional-tuple-return.ts
|
|
5364
|
-
var
|
|
4944
|
+
var import_utils34 = require("@typescript-eslint/utils");
|
|
5365
4945
|
var MIN_ELEMENTS = 2;
|
|
5366
4946
|
var ACCESSOR_PAIR_LENGTH = 2;
|
|
5367
4947
|
var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
|
|
5368
4948
|
function tupleReturnType(node) {
|
|
5369
|
-
if (node.type ===
|
|
4949
|
+
if (node.type === import_utils34.AST_NODE_TYPES.TSTupleType) {
|
|
5370
4950
|
return node;
|
|
5371
4951
|
}
|
|
5372
|
-
if (node.type ===
|
|
4952
|
+
if (node.type === import_utils34.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils34.AST_NODE_TYPES.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
|
|
5373
4953
|
const argument = node.typeArguments?.params[0];
|
|
5374
4954
|
return argument === void 0 ? null : tupleReturnType(argument);
|
|
5375
4955
|
}
|
|
@@ -5383,30 +4963,30 @@ function isPermittedTuple(tuple, sourceCode) {
|
|
|
5383
4963
|
if (elements.length < MIN_ELEMENTS) {
|
|
5384
4964
|
return true;
|
|
5385
4965
|
}
|
|
5386
|
-
if (elements.some((element) => element.type ===
|
|
4966
|
+
if (elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSRestType)) {
|
|
5387
4967
|
return true;
|
|
5388
4968
|
}
|
|
5389
|
-
if (elements.some((element) => element.type ===
|
|
4969
|
+
if (elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSNamedTupleMember)) {
|
|
5390
4970
|
return true;
|
|
5391
4971
|
}
|
|
5392
|
-
if (elements[0]?.type ===
|
|
4972
|
+
if (elements[0]?.type === import_utils34.AST_NODE_TYPES.TSLiteralType) {
|
|
5393
4973
|
return true;
|
|
5394
4974
|
}
|
|
5395
|
-
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type ===
|
|
4975
|
+
if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSFunctionType)) {
|
|
5396
4976
|
return true;
|
|
5397
4977
|
}
|
|
5398
4978
|
const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
|
|
5399
4979
|
return texts.size === 1;
|
|
5400
4980
|
}
|
|
5401
4981
|
function functionName(node) {
|
|
5402
|
-
if (node.type ===
|
|
4982
|
+
if (node.type === import_utils34.AST_NODE_TYPES.FunctionDeclaration) {
|
|
5403
4983
|
return node.id?.name ?? null;
|
|
5404
4984
|
}
|
|
5405
4985
|
const parent = node.parent;
|
|
5406
|
-
if (parent?.type ===
|
|
4986
|
+
if (parent?.type === import_utils34.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5407
4987
|
return parent.id.name;
|
|
5408
4988
|
}
|
|
5409
|
-
if ((parent?.type ===
|
|
4989
|
+
if ((parent?.type === import_utils34.AST_NODE_TYPES.MethodDefinition || parent?.type === import_utils34.AST_NODE_TYPES.PropertyDefinition || parent?.type === import_utils34.AST_NODE_TYPES.Property) && parent.key.type === import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5410
4990
|
return parent.key.name;
|
|
5411
4991
|
}
|
|
5412
4992
|
return null;
|
|
@@ -5414,7 +4994,7 @@ function functionName(node) {
|
|
|
5414
4994
|
function isInlineExported(node) {
|
|
5415
4995
|
for (let current = node; current != null; current = current.parent) {
|
|
5416
4996
|
const parent = current.parent;
|
|
5417
|
-
if (parent?.type ===
|
|
4997
|
+
if (parent?.type === import_utils34.AST_NODE_TYPES.ExportNamedDeclaration || parent?.type === import_utils34.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
|
5418
4998
|
return true;
|
|
5419
4999
|
}
|
|
5420
5000
|
}
|
|
@@ -5423,18 +5003,18 @@ function isInlineExported(node) {
|
|
|
5423
5003
|
function moduleScopeBindingName(node) {
|
|
5424
5004
|
let current = node;
|
|
5425
5005
|
let child = node;
|
|
5426
|
-
while (current.parent != null && current.parent.type !==
|
|
5006
|
+
while (current.parent != null && current.parent.type !== import_utils34.AST_NODE_TYPES.Program) {
|
|
5427
5007
|
child = current;
|
|
5428
5008
|
current = current.parent;
|
|
5429
5009
|
}
|
|
5430
|
-
if (current.parent?.type !==
|
|
5010
|
+
if (current.parent?.type !== import_utils34.AST_NODE_TYPES.Program) {
|
|
5431
5011
|
return null;
|
|
5432
5012
|
}
|
|
5433
|
-
if (current.type ===
|
|
5013
|
+
if (current.type === import_utils34.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils34.AST_NODE_TYPES.ClassDeclaration) {
|
|
5434
5014
|
return current.id?.name ?? null;
|
|
5435
5015
|
}
|
|
5436
|
-
if (current.type ===
|
|
5437
|
-
if (child.type !==
|
|
5016
|
+
if (current.type === import_utils34.AST_NODE_TYPES.VariableDeclaration) {
|
|
5017
|
+
if (child.type !== import_utils34.AST_NODE_TYPES.VariableDeclarator || child.id.type !== import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5438
5018
|
return null;
|
|
5439
5019
|
}
|
|
5440
5020
|
return child.id.name;
|
|
@@ -5444,19 +5024,19 @@ function moduleScopeBindingName(node) {
|
|
|
5444
5024
|
function specifierExportedNames(program) {
|
|
5445
5025
|
const names = /* @__PURE__ */ new Set();
|
|
5446
5026
|
for (const statement of program.body) {
|
|
5447
|
-
if (statement.type ===
|
|
5027
|
+
if (statement.type === import_utils34.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
|
|
5448
5028
|
for (const specifier of statement.specifiers) {
|
|
5449
|
-
if (specifier.exportKind !== "type" && specifier.local.type ===
|
|
5029
|
+
if (specifier.exportKind !== "type" && specifier.local.type === import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5450
5030
|
names.add(specifier.local.name);
|
|
5451
5031
|
}
|
|
5452
5032
|
}
|
|
5453
5033
|
continue;
|
|
5454
5034
|
}
|
|
5455
|
-
if (statement.type ===
|
|
5035
|
+
if (statement.type === import_utils34.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5456
5036
|
names.add(statement.declaration.name);
|
|
5457
5037
|
continue;
|
|
5458
5038
|
}
|
|
5459
|
-
if (statement.type ===
|
|
5039
|
+
if (statement.type === import_utils34.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils34.AST_NODE_TYPES.Identifier) {
|
|
5460
5040
|
names.add(statement.expression.name);
|
|
5461
5041
|
}
|
|
5462
5042
|
}
|
|
@@ -5472,7 +5052,7 @@ function isExported(node, specifierExports) {
|
|
|
5472
5052
|
const binding = moduleScopeBindingName(node);
|
|
5473
5053
|
return binding !== null && specifierExports.has(binding);
|
|
5474
5054
|
}
|
|
5475
|
-
var no_positional_tuple_return_default =
|
|
5055
|
+
var no_positional_tuple_return_default = import_utils34.ESLintUtils.RuleCreator(
|
|
5476
5056
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5477
5057
|
)({
|
|
5478
5058
|
name: "no-positional-tuple-return",
|
|
@@ -5520,16 +5100,16 @@ var no_positional_tuple_return_default = import_utils36.ESLintUtils.RuleCreator(
|
|
|
5520
5100
|
});
|
|
5521
5101
|
|
|
5522
5102
|
// src/rules/no-repeated-string-literal.ts
|
|
5523
|
-
var
|
|
5103
|
+
var import_utils35 = require("@typescript-eslint/utils");
|
|
5524
5104
|
var MIN_LENGTH = 40;
|
|
5525
5105
|
var MIN_DISTINCT_SCOPES = 2;
|
|
5526
5106
|
var PREVIEW_LENGTH = 40;
|
|
5527
5107
|
var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
|
|
5528
5108
|
var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
|
|
5529
5109
|
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5110
|
+
import_utils35.AST_NODE_TYPES.FunctionDeclaration,
|
|
5111
|
+
import_utils35.AST_NODE_TYPES.FunctionExpression,
|
|
5112
|
+
import_utils35.AST_NODE_TYPES.ArrowFunctionExpression
|
|
5533
5113
|
]);
|
|
5534
5114
|
function isStructured(value) {
|
|
5535
5115
|
return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
|
|
@@ -5551,9 +5131,9 @@ function isScaffolding(node) {
|
|
|
5551
5131
|
if (parent === void 0) {
|
|
5552
5132
|
return true;
|
|
5553
5133
|
}
|
|
5554
|
-
return parent.type ===
|
|
5134
|
+
return parent.type === import_utils35.AST_NODE_TYPES.ImportDeclaration || parent.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration || parent.type === import_utils35.AST_NODE_TYPES.ExportAllDeclaration || parent.type === import_utils35.AST_NODE_TYPES.TSImportType || parent.type === import_utils35.AST_NODE_TYPES.JSXAttribute || parent.type === import_utils35.AST_NODE_TYPES.TSLiteralType;
|
|
5555
5135
|
}
|
|
5556
|
-
var no_repeated_string_literal_default =
|
|
5136
|
+
var no_repeated_string_literal_default = import_utils35.ESLintUtils.RuleCreator(
|
|
5557
5137
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5558
5138
|
)({
|
|
5559
5139
|
name: "no-repeated-string-literal",
|
|
@@ -5593,7 +5173,7 @@ var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
|
|
|
5593
5173
|
}
|
|
5594
5174
|
},
|
|
5595
5175
|
TemplateLiteral(node) {
|
|
5596
|
-
if (node.parent.type ===
|
|
5176
|
+
if (node.parent.type === import_utils35.AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
5597
5177
|
return;
|
|
5598
5178
|
}
|
|
5599
5179
|
const [only] = node.quasis;
|
|
@@ -5627,7 +5207,7 @@ var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
|
|
|
5627
5207
|
});
|
|
5628
5208
|
|
|
5629
5209
|
// src/rules/no-select-star.ts
|
|
5630
|
-
var
|
|
5210
|
+
var import_utils36 = require("@typescript-eslint/utils");
|
|
5631
5211
|
var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
|
|
5632
5212
|
var SELECT_KEYWORD = /\bSELECT\b/gi;
|
|
5633
5213
|
var FROM_KEYWORD = /^FROM\b/i;
|
|
@@ -5667,7 +5247,7 @@ function hasRealSelectStar(sql) {
|
|
|
5667
5247
|
}
|
|
5668
5248
|
return false;
|
|
5669
5249
|
}
|
|
5670
|
-
var no_select_star_default =
|
|
5250
|
+
var no_select_star_default = import_utils36.ESLintUtils.RuleCreator(
|
|
5671
5251
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5672
5252
|
)({
|
|
5673
5253
|
name: "no-select-star",
|
|
@@ -5696,7 +5276,7 @@ var no_select_star_default = import_utils38.ESLintUtils.RuleCreator(
|
|
|
5696
5276
|
});
|
|
5697
5277
|
|
|
5698
5278
|
// src/rules/no-sleep-in-test-body.ts
|
|
5699
|
-
var
|
|
5279
|
+
var import_utils37 = require("@typescript-eslint/utils");
|
|
5700
5280
|
var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
|
|
5701
5281
|
var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
5702
5282
|
"it",
|
|
@@ -5705,34 +5285,34 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
|
|
|
5705
5285
|
"afterEach"
|
|
5706
5286
|
]);
|
|
5707
5287
|
var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5288
|
+
import_utils37.AST_NODE_TYPES.FunctionDeclaration,
|
|
5289
|
+
import_utils37.AST_NODE_TYPES.FunctionExpression,
|
|
5290
|
+
import_utils37.AST_NODE_TYPES.ArrowFunctionExpression
|
|
5711
5291
|
]);
|
|
5712
5292
|
function isNonzeroNumericLiteral(node) {
|
|
5713
|
-
return node?.type ===
|
|
5293
|
+
return node?.type === import_utils37.AST_NODE_TYPES.Literal && typeof node.value === "number" && node.value !== 0;
|
|
5714
5294
|
}
|
|
5715
5295
|
function isTimedSetTimeout(node) {
|
|
5716
|
-
return node.type ===
|
|
5296
|
+
return node.type === import_utils37.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils37.AST_NODE_TYPES.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
|
|
5717
5297
|
}
|
|
5718
5298
|
function isPromiseSleep(node) {
|
|
5719
|
-
if (node.callee.type !==
|
|
5299
|
+
if (node.callee.type !== import_utils37.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise") {
|
|
5720
5300
|
return false;
|
|
5721
5301
|
}
|
|
5722
5302
|
const executor = node.arguments[0];
|
|
5723
|
-
if (executor?.type !==
|
|
5303
|
+
if (executor?.type !== import_utils37.AST_NODE_TYPES.ArrowFunctionExpression && executor?.type !== import_utils37.AST_NODE_TYPES.FunctionExpression) {
|
|
5724
5304
|
return false;
|
|
5725
5305
|
}
|
|
5726
5306
|
const body = executor.body;
|
|
5727
|
-
if (body.type !==
|
|
5307
|
+
if (body.type !== import_utils37.AST_NODE_TYPES.BlockStatement) {
|
|
5728
5308
|
return isTimedSetTimeout(body);
|
|
5729
5309
|
}
|
|
5730
5310
|
return body.body.some(
|
|
5731
|
-
(stmt) => stmt.type ===
|
|
5311
|
+
(stmt) => stmt.type === import_utils37.AST_NODE_TYPES.ExpressionStatement && isTimedSetTimeout(stmt.expression)
|
|
5732
5312
|
);
|
|
5733
5313
|
}
|
|
5734
5314
|
function isHelperSleep(node) {
|
|
5735
|
-
return node.callee.type ===
|
|
5315
|
+
return node.callee.type === import_utils37.AST_NODE_TYPES.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
|
|
5736
5316
|
}
|
|
5737
5317
|
function nearestEnclosingFunction(node) {
|
|
5738
5318
|
for (let current = node.parent; current != null; current = current.parent) {
|
|
@@ -5740,7 +5320,7 @@ function nearestEnclosingFunction(node) {
|
|
|
5740
5320
|
continue;
|
|
5741
5321
|
}
|
|
5742
5322
|
const grandparent = current.parent;
|
|
5743
|
-
const isPromiseExecutor = grandparent?.type ===
|
|
5323
|
+
const isPromiseExecutor = grandparent?.type === import_utils37.AST_NODE_TYPES.NewExpression && isPromiseSleep(grandparent);
|
|
5744
5324
|
if (!isPromiseExecutor) {
|
|
5745
5325
|
return current;
|
|
5746
5326
|
}
|
|
@@ -5748,29 +5328,29 @@ function nearestEnclosingFunction(node) {
|
|
|
5748
5328
|
return null;
|
|
5749
5329
|
}
|
|
5750
5330
|
function testCallerName(callee) {
|
|
5751
|
-
if (callee.type ===
|
|
5331
|
+
if (callee.type === import_utils37.AST_NODE_TYPES.Identifier) {
|
|
5752
5332
|
return callee.name;
|
|
5753
5333
|
}
|
|
5754
|
-
if (callee.type ===
|
|
5334
|
+
if (callee.type === import_utils37.AST_NODE_TYPES.MemberExpression) {
|
|
5755
5335
|
return testCallerName(callee.object);
|
|
5756
5336
|
}
|
|
5757
|
-
if (callee.type ===
|
|
5337
|
+
if (callee.type === import_utils37.AST_NODE_TYPES.CallExpression) {
|
|
5758
5338
|
return testCallerName(callee.callee);
|
|
5759
5339
|
}
|
|
5760
|
-
if (callee.type ===
|
|
5340
|
+
if (callee.type === import_utils37.AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
5761
5341
|
return testCallerName(callee.tag);
|
|
5762
5342
|
}
|
|
5763
5343
|
return null;
|
|
5764
5344
|
}
|
|
5765
5345
|
function isTestBody(fn) {
|
|
5766
5346
|
const call = fn.parent;
|
|
5767
|
-
if (call?.type !==
|
|
5347
|
+
if (call?.type !== import_utils37.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5768
5348
|
return false;
|
|
5769
5349
|
}
|
|
5770
5350
|
const name = testCallerName(call.callee);
|
|
5771
5351
|
return name !== null && TEST_CALLERS.has(name);
|
|
5772
5352
|
}
|
|
5773
|
-
var no_sleep_in_test_body_default =
|
|
5353
|
+
var no_sleep_in_test_body_default = import_utils37.ESLintUtils.RuleCreator(
|
|
5774
5354
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5775
5355
|
)({
|
|
5776
5356
|
name: "no-sleep-in-test-body",
|
|
@@ -5811,8 +5391,90 @@ var no_sleep_in_test_body_default = import_utils39.ESLintUtils.RuleCreator(
|
|
|
5811
5391
|
}
|
|
5812
5392
|
});
|
|
5813
5393
|
|
|
5394
|
+
// src/rules/no-conditional-in-test.ts
|
|
5395
|
+
var import_utils38 = require("@typescript-eslint/utils");
|
|
5396
|
+
var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
5397
|
+
var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
|
|
5398
|
+
import_utils38.AST_NODE_TYPES.FunctionDeclaration,
|
|
5399
|
+
import_utils38.AST_NODE_TYPES.FunctionExpression,
|
|
5400
|
+
import_utils38.AST_NODE_TYPES.ArrowFunctionExpression
|
|
5401
|
+
]);
|
|
5402
|
+
function nearestEnclosingFunction2(node) {
|
|
5403
|
+
for (let current = node.parent; current != null; current = current.parent) {
|
|
5404
|
+
if (FUNCTION_TYPES3.has(current.type)) {
|
|
5405
|
+
return current;
|
|
5406
|
+
}
|
|
5407
|
+
}
|
|
5408
|
+
return null;
|
|
5409
|
+
}
|
|
5410
|
+
function testCallerName2(callee) {
|
|
5411
|
+
if (callee.type === import_utils38.AST_NODE_TYPES.Identifier) {
|
|
5412
|
+
return callee.name;
|
|
5413
|
+
}
|
|
5414
|
+
if (callee.type === import_utils38.AST_NODE_TYPES.MemberExpression) {
|
|
5415
|
+
return testCallerName2(callee.object);
|
|
5416
|
+
}
|
|
5417
|
+
if (callee.type === import_utils38.AST_NODE_TYPES.CallExpression) {
|
|
5418
|
+
return testCallerName2(callee.callee);
|
|
5419
|
+
}
|
|
5420
|
+
if (callee.type === import_utils38.AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
5421
|
+
return testCallerName2(callee.tag);
|
|
5422
|
+
}
|
|
5423
|
+
return null;
|
|
5424
|
+
}
|
|
5425
|
+
function isTestBody2(fn) {
|
|
5426
|
+
const call = fn.parent;
|
|
5427
|
+
if (call?.type !== import_utils38.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
|
|
5428
|
+
return false;
|
|
5429
|
+
}
|
|
5430
|
+
const name = testCallerName2(call.callee);
|
|
5431
|
+
return name !== null && TEST_CALLERS2.has(name);
|
|
5432
|
+
}
|
|
5433
|
+
var no_conditional_in_test_default = import_utils38.ESLintUtils.RuleCreator(
|
|
5434
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5435
|
+
)({
|
|
5436
|
+
name: "no-conditional-in-test",
|
|
5437
|
+
meta: {
|
|
5438
|
+
type: "problem",
|
|
5439
|
+
docs: {
|
|
5440
|
+
description: "Disallow conditional logic (if, switch, ternary) in test bodies, which can hide missing assertions or test multiple code paths."
|
|
5441
|
+
},
|
|
5442
|
+
schema: [],
|
|
5443
|
+
messages: {
|
|
5444
|
+
noConditionalInTest: "Avoid using conditional logic in tests. It can obscure intent and hide unexecuted assertions. Split the test instead."
|
|
5445
|
+
}
|
|
5446
|
+
},
|
|
5447
|
+
defaultOptions: [],
|
|
5448
|
+
create(context) {
|
|
5449
|
+
if (!isTestFile(context.filename)) {
|
|
5450
|
+
return {};
|
|
5451
|
+
}
|
|
5452
|
+
const report = (node) => {
|
|
5453
|
+
const enclosing = nearestEnclosingFunction2(node);
|
|
5454
|
+
if (enclosing === null || !isTestBody2(enclosing)) {
|
|
5455
|
+
return;
|
|
5456
|
+
}
|
|
5457
|
+
context.report({ node, messageId: "noConditionalInTest" });
|
|
5458
|
+
};
|
|
5459
|
+
return {
|
|
5460
|
+
IfStatement(node) {
|
|
5461
|
+
report(node);
|
|
5462
|
+
},
|
|
5463
|
+
SwitchStatement(node) {
|
|
5464
|
+
report(node);
|
|
5465
|
+
},
|
|
5466
|
+
ConditionalExpression(node) {
|
|
5467
|
+
report(node);
|
|
5468
|
+
},
|
|
5469
|
+
LogicalExpression(node) {
|
|
5470
|
+
report(node);
|
|
5471
|
+
}
|
|
5472
|
+
};
|
|
5473
|
+
}
|
|
5474
|
+
});
|
|
5475
|
+
|
|
5814
5476
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
5815
|
-
var
|
|
5477
|
+
var import_utils39 = require("@typescript-eslint/utils");
|
|
5816
5478
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
5817
5479
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
5818
5480
|
var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
|
|
@@ -5825,36 +5487,36 @@ function isConstantReference(identifier) {
|
|
|
5825
5487
|
}
|
|
5826
5488
|
function isExcludedOperand(node) {
|
|
5827
5489
|
switch (node.type) {
|
|
5828
|
-
case
|
|
5490
|
+
case import_utils39.AST_NODE_TYPES.Literal:
|
|
5829
5491
|
return true;
|
|
5830
|
-
case
|
|
5492
|
+
case import_utils39.AST_NODE_TYPES.TemplateLiteral:
|
|
5831
5493
|
return node.expressions.length === 0;
|
|
5832
|
-
case
|
|
5494
|
+
case import_utils39.AST_NODE_TYPES.Identifier:
|
|
5833
5495
|
return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
|
|
5834
|
-
case
|
|
5835
|
-
return !node.computed && node.property.type ===
|
|
5496
|
+
case import_utils39.AST_NODE_TYPES.MemberExpression:
|
|
5497
|
+
return !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
|
|
5836
5498
|
default:
|
|
5837
5499
|
return false;
|
|
5838
5500
|
}
|
|
5839
5501
|
}
|
|
5840
5502
|
function operandName(node) {
|
|
5841
|
-
if (node.type ===
|
|
5503
|
+
if (node.type === import_utils39.AST_NODE_TYPES.Identifier) {
|
|
5842
5504
|
return node.name;
|
|
5843
5505
|
}
|
|
5844
|
-
if (node.type ===
|
|
5506
|
+
if (node.type === import_utils39.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier) {
|
|
5845
5507
|
return node.property.name;
|
|
5846
5508
|
}
|
|
5847
5509
|
return null;
|
|
5848
5510
|
}
|
|
5849
5511
|
function isSecretOperand(node) {
|
|
5850
|
-
if (node.type ===
|
|
5512
|
+
if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
|
|
5851
5513
|
return node.expressions.some((expression) => isSecretOperand(expression));
|
|
5852
5514
|
}
|
|
5853
5515
|
const name = operandName(node);
|
|
5854
5516
|
return name !== null && isAuthSecretName(name);
|
|
5855
5517
|
}
|
|
5856
5518
|
function secretNameOf(node) {
|
|
5857
|
-
if (node.type ===
|
|
5519
|
+
if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
|
|
5858
5520
|
for (const expression of node.expressions) {
|
|
5859
5521
|
const nested = secretNameOf(expression);
|
|
5860
5522
|
if (nested !== null) {
|
|
@@ -5865,7 +5527,7 @@ function secretNameOf(node) {
|
|
|
5865
5527
|
}
|
|
5866
5528
|
return operandName(node);
|
|
5867
5529
|
}
|
|
5868
|
-
var prefer_constant_time_secret_compare_default =
|
|
5530
|
+
var prefer_constant_time_secret_compare_default = import_utils39.ESLintUtils.RuleCreator(
|
|
5869
5531
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5870
5532
|
)({
|
|
5871
5533
|
name: "prefer-constant-time-secret-compare",
|
|
@@ -5908,11 +5570,11 @@ var prefer_constant_time_secret_compare_default = import_utils40.ESLintUtils.Rul
|
|
|
5908
5570
|
});
|
|
5909
5571
|
|
|
5910
5572
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
5911
|
-
var
|
|
5573
|
+
var import_utils40 = require("@typescript-eslint/utils");
|
|
5912
5574
|
var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
|
|
5913
5575
|
var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
|
|
5914
5576
|
var INSERT_GATE = /insert/i;
|
|
5915
|
-
var store_insert_requires_on_conflict_default =
|
|
5577
|
+
var store_insert_requires_on_conflict_default = import_utils40.ESLintUtils.RuleCreator(
|
|
5916
5578
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
5917
5579
|
)({
|
|
5918
5580
|
name: "store-insert-requires-on-conflict",
|
|
@@ -5941,17 +5603,17 @@ var store_insert_requires_on_conflict_default = import_utils41.ESLintUtils.RuleC
|
|
|
5941
5603
|
});
|
|
5942
5604
|
|
|
5943
5605
|
// src/rules/no-dynamic-sql.ts
|
|
5944
|
-
var
|
|
5606
|
+
var import_utils41 = require("@typescript-eslint/utils");
|
|
5945
5607
|
var DEFAULT_METHODS = ["prepare", "exec", "query"];
|
|
5946
5608
|
var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
5947
5609
|
function isStaticFragment(expression) {
|
|
5948
|
-
if (expression.type ===
|
|
5610
|
+
if (expression.type === import_utils41.AST_NODE_TYPES.Identifier) {
|
|
5949
5611
|
return CONSTANT_CASE_RE.test(expression.name);
|
|
5950
5612
|
}
|
|
5951
|
-
if (expression.type ===
|
|
5613
|
+
if (expression.type === import_utils41.AST_NODE_TYPES.MemberExpression && !expression.computed && expression.property.type === import_utils41.AST_NODE_TYPES.Identifier) {
|
|
5952
5614
|
return CONSTANT_CASE_RE.test(expression.property.name);
|
|
5953
5615
|
}
|
|
5954
|
-
if (expression.type ===
|
|
5616
|
+
if (expression.type === import_utils41.AST_NODE_TYPES.Literal) {
|
|
5955
5617
|
return typeof expression.value === "string";
|
|
5956
5618
|
}
|
|
5957
5619
|
return false;
|
|
@@ -5962,36 +5624,36 @@ function runtimeInterpolations(template) {
|
|
|
5962
5624
|
);
|
|
5963
5625
|
}
|
|
5964
5626
|
function concatOperands(node) {
|
|
5965
|
-
if (node.type ===
|
|
5627
|
+
if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
|
|
5966
5628
|
return [...concatOperands(node.left), ...concatOperands(node.right)];
|
|
5967
5629
|
}
|
|
5968
5630
|
return [node];
|
|
5969
5631
|
}
|
|
5970
5632
|
function runtimeConcatOperands(node) {
|
|
5971
|
-
if (node.type !==
|
|
5633
|
+
if (node.type !== import_utils41.AST_NODE_TYPES.BinaryExpression || node.operator !== "+") {
|
|
5972
5634
|
return [];
|
|
5973
5635
|
}
|
|
5974
5636
|
const operands = concatOperands(node);
|
|
5975
5637
|
const hasStringLiteral = operands.some(
|
|
5976
|
-
(operand) => operand.type ===
|
|
5638
|
+
(operand) => operand.type === import_utils41.AST_NODE_TYPES.Literal && typeof operand.value === "string"
|
|
5977
5639
|
);
|
|
5978
5640
|
if (!hasStringLiteral) {
|
|
5979
5641
|
return [];
|
|
5980
5642
|
}
|
|
5981
5643
|
return operands.filter(
|
|
5982
|
-
(operand) => operand.type !==
|
|
5644
|
+
(operand) => operand.type !== import_utils41.AST_NODE_TYPES.Literal && !isStaticFragment(operand)
|
|
5983
5645
|
);
|
|
5984
5646
|
}
|
|
5985
5647
|
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;
|
|
5986
5648
|
var RUNTIME_MARKER = " ? ";
|
|
5987
5649
|
function staticStatementText(node) {
|
|
5988
|
-
if (node.type ===
|
|
5650
|
+
if (node.type === import_utils41.AST_NODE_TYPES.TemplateLiteral) {
|
|
5989
5651
|
return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
|
|
5990
5652
|
}
|
|
5991
|
-
if (node.type ===
|
|
5653
|
+
if (node.type === import_utils41.AST_NODE_TYPES.Literal) {
|
|
5992
5654
|
return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
|
|
5993
5655
|
}
|
|
5994
|
-
if (node.type ===
|
|
5656
|
+
if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
|
|
5995
5657
|
return staticStatementText(node.left) + staticStatementText(node.right);
|
|
5996
5658
|
}
|
|
5997
5659
|
return RUNTIME_MARKER;
|
|
@@ -6001,13 +5663,13 @@ function looksLikeSql(node) {
|
|
|
6001
5663
|
}
|
|
6002
5664
|
function statementMethodName(node, methods) {
|
|
6003
5665
|
const callee = node.callee;
|
|
6004
|
-
if (callee.type !==
|
|
5666
|
+
if (callee.type !== import_utils41.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils41.AST_NODE_TYPES.Identifier) {
|
|
6005
5667
|
return null;
|
|
6006
5668
|
}
|
|
6007
5669
|
const name = callee.property.name;
|
|
6008
5670
|
return methods.has(name) ? name : null;
|
|
6009
5671
|
}
|
|
6010
|
-
var no_dynamic_sql_default =
|
|
5672
|
+
var no_dynamic_sql_default = import_utils41.ESLintUtils.RuleCreator(
|
|
6011
5673
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6012
5674
|
)({
|
|
6013
5675
|
name: "no-dynamic-sql",
|
|
@@ -6046,7 +5708,7 @@ var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
|
|
|
6046
5708
|
if (statement === void 0 || !looksLikeSql(statement)) {
|
|
6047
5709
|
return;
|
|
6048
5710
|
}
|
|
6049
|
-
const offenders = statement.type ===
|
|
5711
|
+
const offenders = statement.type === import_utils41.AST_NODE_TYPES.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
|
|
6050
5712
|
for (const offender of offenders) {
|
|
6051
5713
|
context.report({
|
|
6052
5714
|
node: offender,
|
|
@@ -6060,7 +5722,7 @@ var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
|
|
|
6060
5722
|
});
|
|
6061
5723
|
|
|
6062
5724
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
6063
|
-
var
|
|
5725
|
+
var import_utils42 = require("@typescript-eslint/utils");
|
|
6064
5726
|
var DEFAULT_ALLOW = [
|
|
6065
5727
|
"[\\\\/]clients?[\\\\/]",
|
|
6066
5728
|
"-client\\.[cm]?[jt]sx?$",
|
|
@@ -6124,7 +5786,7 @@ function compile(patterns) {
|
|
|
6124
5786
|
}
|
|
6125
5787
|
return compiled;
|
|
6126
5788
|
}
|
|
6127
|
-
var no_raw_fetch_outside_clients_default =
|
|
5789
|
+
var no_raw_fetch_outside_clients_default = import_utils42.ESLintUtils.RuleCreator(
|
|
6128
5790
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6129
5791
|
)({
|
|
6130
5792
|
name: "no-raw-fetch-outside-clients",
|
|
@@ -6172,7 +5834,7 @@ var no_raw_fetch_outside_clients_default = import_utils43.ESLintUtils.RuleCreato
|
|
|
6172
5834
|
});
|
|
6173
5835
|
|
|
6174
5836
|
// src/rules/no-storage-in-stateless-modules.ts
|
|
6175
|
-
var
|
|
5837
|
+
var import_utils43 = require("@typescript-eslint/utils");
|
|
6176
5838
|
var DEFAULT_METHODS2 = [
|
|
6177
5839
|
"prepare",
|
|
6178
5840
|
"put",
|
|
@@ -6191,7 +5853,7 @@ function compile2(patterns) {
|
|
|
6191
5853
|
}
|
|
6192
5854
|
function storageMethodName(node, methods) {
|
|
6193
5855
|
const callee = node.callee;
|
|
6194
|
-
if (callee.type !==
|
|
5856
|
+
if (callee.type !== import_utils43.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils43.AST_NODE_TYPES.Identifier) {
|
|
6195
5857
|
return null;
|
|
6196
5858
|
}
|
|
6197
5859
|
const name = callee.property.name;
|
|
@@ -6203,7 +5865,7 @@ function storageMethodName(node, methods) {
|
|
|
6203
5865
|
}
|
|
6204
5866
|
return name;
|
|
6205
5867
|
}
|
|
6206
|
-
var no_storage_in_stateless_modules_default =
|
|
5868
|
+
var no_storage_in_stateless_modules_default = import_utils43.ESLintUtils.RuleCreator(
|
|
6207
5869
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6208
5870
|
)({
|
|
6209
5871
|
name: "no-storage-in-stateless-modules",
|
|
@@ -6261,7 +5923,7 @@ var no_storage_in_stateless_modules_default = import_utils44.ESLintUtils.RuleCre
|
|
|
6261
5923
|
});
|
|
6262
5924
|
|
|
6263
5925
|
// src/rules/no-zod-native-enum.ts
|
|
6264
|
-
var
|
|
5926
|
+
var import_utils44 = require("@typescript-eslint/utils");
|
|
6265
5927
|
var ts2 = __toESM(require("typescript"), 1);
|
|
6266
5928
|
var IGNORE_PATTERNS2 = [
|
|
6267
5929
|
/[\\/]generated[\\/]/,
|
|
@@ -6275,11 +5937,11 @@ function isIgnoredFile2(filename, sourceText) {
|
|
|
6275
5937
|
}
|
|
6276
5938
|
return /@generated\b/.test(sourceText.slice(0, 1024));
|
|
6277
5939
|
}
|
|
6278
|
-
function
|
|
5940
|
+
function isZodModule2(source) {
|
|
6279
5941
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
6280
5942
|
}
|
|
6281
5943
|
function unwrap3(node) {
|
|
6282
|
-
if (node.type ===
|
|
5944
|
+
if (node.type === import_utils44.AST_NODE_TYPES.TSAsExpression || node.type === import_utils44.AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
6283
5945
|
return unwrap3(node.expression);
|
|
6284
5946
|
}
|
|
6285
5947
|
return node;
|
|
@@ -6287,14 +5949,14 @@ function unwrap3(node) {
|
|
|
6287
5949
|
function stringValueTexts(node, sourceCode) {
|
|
6288
5950
|
const texts = [];
|
|
6289
5951
|
for (const prop of node.properties) {
|
|
6290
|
-
if (prop.type !==
|
|
5952
|
+
if (prop.type !== import_utils44.AST_NODE_TYPES.Property) {
|
|
6291
5953
|
return null;
|
|
6292
5954
|
}
|
|
6293
5955
|
if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6294
5956
|
return null;
|
|
6295
5957
|
}
|
|
6296
5958
|
const value = prop.value;
|
|
6297
|
-
if (value.type !==
|
|
5959
|
+
if (value.type !== import_utils44.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
|
|
6298
5960
|
return null;
|
|
6299
5961
|
}
|
|
6300
5962
|
const text = sourceCode.getText(value);
|
|
@@ -6310,7 +5972,7 @@ function resolvesToLocalEnum(node, scope) {
|
|
|
6310
5972
|
const variable = current.variables.find((v) => v.name === node.name);
|
|
6311
5973
|
if (variable !== void 0) {
|
|
6312
5974
|
return variable.defs.some(
|
|
6313
|
-
(def) => def.node.type ===
|
|
5975
|
+
(def) => def.node.type === import_utils44.AST_NODE_TYPES.TSEnumDeclaration
|
|
6314
5976
|
);
|
|
6315
5977
|
}
|
|
6316
5978
|
current = current.upper;
|
|
@@ -6330,7 +5992,7 @@ function resolvesToImportedEnum(node, services) {
|
|
|
6330
5992
|
}
|
|
6331
5993
|
return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
|
|
6332
5994
|
}
|
|
6333
|
-
var no_zod_native_enum_default =
|
|
5995
|
+
var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
|
|
6334
5996
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6335
5997
|
)({
|
|
6336
5998
|
name: "no-zod-native-enum",
|
|
@@ -6357,32 +6019,32 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
|
|
|
6357
6019
|
}
|
|
6358
6020
|
let services;
|
|
6359
6021
|
try {
|
|
6360
|
-
services =
|
|
6022
|
+
services = import_utils44.ESLintUtils.getParserServices(context);
|
|
6361
6023
|
} catch {
|
|
6362
6024
|
services = null;
|
|
6363
6025
|
}
|
|
6364
6026
|
const zodImportedNames = /* @__PURE__ */ new Map();
|
|
6365
6027
|
function isZodMemberCall(node, api) {
|
|
6366
6028
|
const callee = node.callee;
|
|
6367
|
-
if (callee.type ===
|
|
6029
|
+
if (callee.type === import_utils44.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils44.AST_NODE_TYPES.Identifier) {
|
|
6368
6030
|
return callee.property.name === api;
|
|
6369
6031
|
}
|
|
6370
|
-
if (callee.type ===
|
|
6032
|
+
if (callee.type === import_utils44.AST_NODE_TYPES.Identifier) {
|
|
6371
6033
|
return zodImportedNames.get(callee.name) === api;
|
|
6372
6034
|
}
|
|
6373
6035
|
return false;
|
|
6374
6036
|
}
|
|
6375
6037
|
function buildFix(node) {
|
|
6376
6038
|
const callee = node.callee;
|
|
6377
|
-
if (callee.type !==
|
|
6039
|
+
if (callee.type !== import_utils44.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils44.AST_NODE_TYPES.Identifier) {
|
|
6378
6040
|
return null;
|
|
6379
6041
|
}
|
|
6380
6042
|
const arg = node.arguments[0];
|
|
6381
|
-
if (arg === void 0 || node.arguments.length !== 1 || arg.type ===
|
|
6043
|
+
if (arg === void 0 || node.arguments.length !== 1 || arg.type === import_utils44.AST_NODE_TYPES.SpreadElement) {
|
|
6382
6044
|
return null;
|
|
6383
6045
|
}
|
|
6384
6046
|
const inner = unwrap3(arg);
|
|
6385
|
-
if (inner.type !==
|
|
6047
|
+
if (inner.type !== import_utils44.AST_NODE_TYPES.ObjectExpression) {
|
|
6386
6048
|
return null;
|
|
6387
6049
|
}
|
|
6388
6050
|
const values = stringValueTexts(inner, sourceCode);
|
|
@@ -6398,11 +6060,11 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
|
|
|
6398
6060
|
}
|
|
6399
6061
|
return {
|
|
6400
6062
|
ImportDeclaration(node) {
|
|
6401
|
-
if (!
|
|
6063
|
+
if (!isZodModule2(node.source.value)) {
|
|
6402
6064
|
return;
|
|
6403
6065
|
}
|
|
6404
6066
|
for (const spec of node.specifiers) {
|
|
6405
|
-
if (spec.type ===
|
|
6067
|
+
if (spec.type === import_utils44.AST_NODE_TYPES.ImportSpecifier && spec.imported.type === import_utils44.AST_NODE_TYPES.Identifier) {
|
|
6406
6068
|
zodImportedNames.set(spec.local.name, spec.imported.name);
|
|
6407
6069
|
}
|
|
6408
6070
|
}
|
|
@@ -6421,7 +6083,7 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
|
|
|
6421
6083
|
return;
|
|
6422
6084
|
}
|
|
6423
6085
|
const arg = node.arguments[0];
|
|
6424
|
-
if (arg === void 0 || arg.type !==
|
|
6086
|
+
if (arg === void 0 || arg.type !== import_utils44.AST_NODE_TYPES.Identifier) {
|
|
6425
6087
|
return;
|
|
6426
6088
|
}
|
|
6427
6089
|
const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
|
|
@@ -6438,7 +6100,7 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
|
|
|
6438
6100
|
});
|
|
6439
6101
|
|
|
6440
6102
|
// src/rules/prefer-module-level-constant.ts
|
|
6441
|
-
var
|
|
6103
|
+
var import_utils45 = require("@typescript-eslint/utils");
|
|
6442
6104
|
var DEFAULT_MIN_ELEMENTS = 3;
|
|
6443
6105
|
var MAX_LITERAL_DEPTH = 4;
|
|
6444
6106
|
var IGNORE_PATTERNS3 = [
|
|
@@ -6473,10 +6135,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
6473
6135
|
// Object-ish escape hatches
|
|
6474
6136
|
"assign"
|
|
6475
6137
|
]);
|
|
6476
|
-
var
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6138
|
+
var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
6139
|
+
import_utils45.AST_NODE_TYPES.FunctionDeclaration,
|
|
6140
|
+
import_utils45.AST_NODE_TYPES.FunctionExpression,
|
|
6141
|
+
import_utils45.AST_NODE_TYPES.ArrowFunctionExpression
|
|
6480
6142
|
]);
|
|
6481
6143
|
var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
|
|
6482
6144
|
function isIgnoredFile3(filename, sourceText) {
|
|
@@ -6489,13 +6151,13 @@ function isTestFile2(filename) {
|
|
|
6489
6151
|
return TEST_FILE_PATTERNS.some((re) => re.test(filename));
|
|
6490
6152
|
}
|
|
6491
6153
|
function unwrap4(node) {
|
|
6492
|
-
if (node.type ===
|
|
6154
|
+
if (node.type === import_utils45.AST_NODE_TYPES.TSAsExpression || node.type === import_utils45.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils45.AST_NODE_TYPES.TSNonNullExpression) {
|
|
6493
6155
|
return unwrap4(node.expression);
|
|
6494
6156
|
}
|
|
6495
6157
|
return node;
|
|
6496
6158
|
}
|
|
6497
6159
|
function isRegexLiteral(node) {
|
|
6498
|
-
return node.type ===
|
|
6160
|
+
return node.type === import_utils45.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
|
|
6499
6161
|
}
|
|
6500
6162
|
function isLiteralOnly(node, depth) {
|
|
6501
6163
|
if (depth > MAX_LITERAL_DEPTH) {
|
|
@@ -6503,29 +6165,29 @@ function isLiteralOnly(node, depth) {
|
|
|
6503
6165
|
}
|
|
6504
6166
|
const inner = unwrap4(node);
|
|
6505
6167
|
switch (inner.type) {
|
|
6506
|
-
case
|
|
6168
|
+
case import_utils45.AST_NODE_TYPES.Literal: {
|
|
6507
6169
|
return true;
|
|
6508
6170
|
}
|
|
6509
|
-
case
|
|
6171
|
+
case import_utils45.AST_NODE_TYPES.TemplateLiteral: {
|
|
6510
6172
|
return inner.expressions.length === 0;
|
|
6511
6173
|
}
|
|
6512
|
-
case
|
|
6513
|
-
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type ===
|
|
6174
|
+
case import_utils45.AST_NODE_TYPES.UnaryExpression: {
|
|
6175
|
+
return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === import_utils45.AST_NODE_TYPES.Literal && typeof inner.argument.value === "number";
|
|
6514
6176
|
}
|
|
6515
|
-
case
|
|
6177
|
+
case import_utils45.AST_NODE_TYPES.ArrayExpression: {
|
|
6516
6178
|
return inner.elements.every(
|
|
6517
|
-
(el) => el !== null && el.type !==
|
|
6179
|
+
(el) => el !== null && el.type !== import_utils45.AST_NODE_TYPES.SpreadElement && isLiteralOnly(el, depth + 1)
|
|
6518
6180
|
);
|
|
6519
6181
|
}
|
|
6520
|
-
case
|
|
6182
|
+
case import_utils45.AST_NODE_TYPES.ObjectExpression: {
|
|
6521
6183
|
return inner.properties.every((prop) => {
|
|
6522
|
-
if (prop.type !==
|
|
6184
|
+
if (prop.type !== import_utils45.AST_NODE_TYPES.Property) {
|
|
6523
6185
|
return false;
|
|
6524
6186
|
}
|
|
6525
6187
|
if (prop.shorthand || prop.method || prop.kind !== "init") {
|
|
6526
6188
|
return false;
|
|
6527
6189
|
}
|
|
6528
|
-
if (prop.computed && prop.key.type !==
|
|
6190
|
+
if (prop.computed && prop.key.type !== import_utils45.AST_NODE_TYPES.Literal) {
|
|
6529
6191
|
return false;
|
|
6530
6192
|
}
|
|
6531
6193
|
return isLiteralOnly(prop.value, depth + 1);
|
|
@@ -6538,7 +6200,7 @@ function isLiteralOnly(node, depth) {
|
|
|
6538
6200
|
}
|
|
6539
6201
|
function unwrapObjectFreeze(node) {
|
|
6540
6202
|
const inner = unwrap4(node);
|
|
6541
|
-
if (inner.type ===
|
|
6203
|
+
if (inner.type === import_utils45.AST_NODE_TYPES.CallExpression && inner.callee.type === import_utils45.AST_NODE_TYPES.MemberExpression && !inner.callee.computed && inner.callee.object.type === import_utils45.AST_NODE_TYPES.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === import_utils45.AST_NODE_TYPES.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== import_utils45.AST_NODE_TYPES.SpreadElement) {
|
|
6542
6204
|
return unwrap4(inner.arguments[0]);
|
|
6543
6205
|
}
|
|
6544
6206
|
return inner;
|
|
@@ -6554,19 +6216,19 @@ function classify(init, checkRegex) {
|
|
|
6554
6216
|
}
|
|
6555
6217
|
return { kind: "regex", size: 1 };
|
|
6556
6218
|
}
|
|
6557
|
-
if (node.type ===
|
|
6219
|
+
if (node.type === import_utils45.AST_NODE_TYPES.ArrayExpression) {
|
|
6558
6220
|
return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
|
|
6559
6221
|
}
|
|
6560
|
-
if (node.type ===
|
|
6222
|
+
if (node.type === import_utils45.AST_NODE_TYPES.ObjectExpression) {
|
|
6561
6223
|
return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
|
|
6562
6224
|
}
|
|
6563
|
-
if (node.type ===
|
|
6225
|
+
if (node.type === import_utils45.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils45.AST_NODE_TYPES.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
|
|
6564
6226
|
const arg = node.arguments[0];
|
|
6565
|
-
if (node.arguments.length !== 1 || arg === void 0 || arg.type ===
|
|
6227
|
+
if (node.arguments.length !== 1 || arg === void 0 || arg.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
|
|
6566
6228
|
return null;
|
|
6567
6229
|
}
|
|
6568
6230
|
const entries = unwrap4(arg);
|
|
6569
|
-
if (entries.type !==
|
|
6231
|
+
if (entries.type !== import_utils45.AST_NODE_TYPES.ArrayExpression) {
|
|
6570
6232
|
return null;
|
|
6571
6233
|
}
|
|
6572
6234
|
return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
|
|
@@ -6576,7 +6238,7 @@ function classify(init, checkRegex) {
|
|
|
6576
6238
|
function enclosingFunction2(node) {
|
|
6577
6239
|
let current = node.parent;
|
|
6578
6240
|
while (current !== void 0 && current !== null) {
|
|
6579
|
-
if (
|
|
6241
|
+
if (FUNCTION_TYPES4.has(current.type)) {
|
|
6580
6242
|
return current;
|
|
6581
6243
|
}
|
|
6582
6244
|
current = current.parent;
|
|
@@ -6595,10 +6257,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
|
|
|
6595
6257
|
);
|
|
6596
6258
|
function isNonRetainingBuiltinCall(node, argument) {
|
|
6597
6259
|
const callee = node.callee;
|
|
6598
|
-
if (callee.type ===
|
|
6260
|
+
if (callee.type === import_utils45.AST_NODE_TYPES.Identifier && callee.name === "structuredClone") {
|
|
6599
6261
|
return true;
|
|
6600
6262
|
}
|
|
6601
|
-
if (callee.type !==
|
|
6263
|
+
if (callee.type !== import_utils45.AST_NODE_TYPES.MemberExpression || callee.computed || callee.object.type !== import_utils45.AST_NODE_TYPES.Identifier || callee.property.type !== import_utils45.AST_NODE_TYPES.Identifier) {
|
|
6602
6264
|
return false;
|
|
6603
6265
|
}
|
|
6604
6266
|
const members = NON_RETAINING_BUILTINS.get(callee.object.name);
|
|
@@ -6612,43 +6274,43 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
6612
6274
|
}
|
|
6613
6275
|
function isSafeRead(identifier) {
|
|
6614
6276
|
const parent = identifier.parent;
|
|
6615
|
-
if (parent.type ===
|
|
6277
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.MemberExpression) {
|
|
6616
6278
|
if (parent.object !== identifier) {
|
|
6617
6279
|
return true;
|
|
6618
6280
|
}
|
|
6619
6281
|
const grandparent = parent.parent;
|
|
6620
|
-
if (grandparent.type ===
|
|
6282
|
+
if (grandparent.type === import_utils45.AST_NODE_TYPES.AssignmentExpression && grandparent.left === parent) {
|
|
6621
6283
|
return false;
|
|
6622
6284
|
}
|
|
6623
|
-
if (grandparent.type ===
|
|
6285
|
+
if (grandparent.type === import_utils45.AST_NODE_TYPES.UpdateExpression) {
|
|
6624
6286
|
return false;
|
|
6625
6287
|
}
|
|
6626
|
-
if (grandparent.type ===
|
|
6288
|
+
if (grandparent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && grandparent.operator === "delete") {
|
|
6627
6289
|
return false;
|
|
6628
6290
|
}
|
|
6629
|
-
if (!parent.computed && parent.property.type ===
|
|
6291
|
+
if (!parent.computed && parent.property.type === import_utils45.AST_NODE_TYPES.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === import_utils45.AST_NODE_TYPES.CallExpression && grandparent.callee === parent) {
|
|
6630
6292
|
return false;
|
|
6631
6293
|
}
|
|
6632
6294
|
return true;
|
|
6633
6295
|
}
|
|
6634
|
-
if (parent.type ===
|
|
6296
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.ForOfStatement && parent.right === identifier) {
|
|
6635
6297
|
return true;
|
|
6636
6298
|
}
|
|
6637
|
-
if (parent.type ===
|
|
6299
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
|
|
6638
6300
|
return true;
|
|
6639
6301
|
}
|
|
6640
|
-
if (parent.type ===
|
|
6302
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.BinaryExpression) {
|
|
6641
6303
|
return true;
|
|
6642
6304
|
}
|
|
6643
|
-
if (parent.type ===
|
|
6305
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
|
|
6644
6306
|
return true;
|
|
6645
6307
|
}
|
|
6646
|
-
if (parent.type ===
|
|
6308
|
+
if (parent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && parent.operator !== "delete") {
|
|
6647
6309
|
return true;
|
|
6648
6310
|
}
|
|
6649
6311
|
return false;
|
|
6650
6312
|
}
|
|
6651
|
-
var prefer_module_level_constant_default =
|
|
6313
|
+
var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreator(
|
|
6652
6314
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6653
6315
|
)({
|
|
6654
6316
|
name: "prefer-module-level-constant",
|
|
@@ -6700,7 +6362,7 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
|
|
|
6700
6362
|
if (reference.isWrite()) {
|
|
6701
6363
|
return false;
|
|
6702
6364
|
}
|
|
6703
|
-
if (reference.identifier.type !==
|
|
6365
|
+
if (reference.identifier.type !== import_utils45.AST_NODE_TYPES.Identifier) {
|
|
6704
6366
|
return false;
|
|
6705
6367
|
}
|
|
6706
6368
|
if (!isSafeRead(reference.identifier)) {
|
|
@@ -6712,10 +6374,10 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
|
|
|
6712
6374
|
return {
|
|
6713
6375
|
VariableDeclarator(node) {
|
|
6714
6376
|
const declaration = node.parent;
|
|
6715
|
-
if (declaration.type !==
|
|
6377
|
+
if (declaration.type !== import_utils45.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
|
|
6716
6378
|
return;
|
|
6717
6379
|
}
|
|
6718
|
-
if (node.id.type !==
|
|
6380
|
+
if (node.id.type !== import_utils45.AST_NODE_TYPES.Identifier || node.init === null) {
|
|
6719
6381
|
return;
|
|
6720
6382
|
}
|
|
6721
6383
|
if (enclosingFunction2(node) === null) {
|
|
@@ -6742,7 +6404,7 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
|
|
|
6742
6404
|
});
|
|
6743
6405
|
|
|
6744
6406
|
// src/rules/jsdoc-restates-signature.ts
|
|
6745
|
-
var
|
|
6407
|
+
var import_utils46 = require("@typescript-eslint/utils");
|
|
6746
6408
|
var VALUE_TAGS = /* @__PURE__ */ new Set([
|
|
6747
6409
|
"alpha",
|
|
6748
6410
|
"author",
|
|
@@ -6825,30 +6487,30 @@ function declarationNames(node) {
|
|
|
6825
6487
|
switch (node.type) {
|
|
6826
6488
|
// `export function f()` — the JSDoc sits above the `export`, so the token
|
|
6827
6489
|
// after it resolves to the wrapper, not to the thing being documented.
|
|
6828
|
-
case
|
|
6829
|
-
case
|
|
6490
|
+
case import_utils46.AST_NODE_TYPES.ExportNamedDeclaration:
|
|
6491
|
+
case import_utils46.AST_NODE_TYPES.ExportDefaultDeclaration:
|
|
6830
6492
|
return node.declaration == null ? null : declarationNames(node.declaration);
|
|
6831
|
-
case
|
|
6832
|
-
case
|
|
6493
|
+
case import_utils46.AST_NODE_TYPES.FunctionDeclaration:
|
|
6494
|
+
case import_utils46.AST_NODE_TYPES.TSDeclareFunction:
|
|
6833
6495
|
return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
|
|
6834
|
-
case
|
|
6835
|
-
case
|
|
6836
|
-
case
|
|
6837
|
-
case
|
|
6496
|
+
case import_utils46.AST_NODE_TYPES.ClassDeclaration:
|
|
6497
|
+
case import_utils46.AST_NODE_TYPES.TSInterfaceDeclaration:
|
|
6498
|
+
case import_utils46.AST_NODE_TYPES.TSTypeAliasDeclaration:
|
|
6499
|
+
case import_utils46.AST_NODE_TYPES.TSEnumDeclaration:
|
|
6838
6500
|
return node.id === null ? null : { name: node.id.name, params: [] };
|
|
6839
|
-
case
|
|
6501
|
+
case import_utils46.AST_NODE_TYPES.VariableDeclaration: {
|
|
6840
6502
|
const declarator = node.declarations[0];
|
|
6841
|
-
if (declarator === void 0 || declarator.id.type !==
|
|
6503
|
+
if (declarator === void 0 || declarator.id.type !== import_utils46.AST_NODE_TYPES.Identifier) return null;
|
|
6842
6504
|
const init = declarator.init;
|
|
6843
|
-
const params = init != null && (init.type ===
|
|
6505
|
+
const params = init != null && (init.type === import_utils46.AST_NODE_TYPES.ArrowFunctionExpression || init.type === import_utils46.AST_NODE_TYPES.FunctionExpression) ? paramNames(init.params) : [];
|
|
6844
6506
|
return { name: declarator.id.name, params };
|
|
6845
6507
|
}
|
|
6846
|
-
case
|
|
6847
|
-
case
|
|
6848
|
-
case
|
|
6849
|
-
case
|
|
6850
|
-
if (node.key.type !==
|
|
6851
|
-
const params = node.type ===
|
|
6508
|
+
case import_utils46.AST_NODE_TYPES.MethodDefinition:
|
|
6509
|
+
case import_utils46.AST_NODE_TYPES.PropertyDefinition:
|
|
6510
|
+
case import_utils46.AST_NODE_TYPES.TSMethodSignature:
|
|
6511
|
+
case import_utils46.AST_NODE_TYPES.TSPropertySignature: {
|
|
6512
|
+
if (node.key.type !== import_utils46.AST_NODE_TYPES.Identifier) return null;
|
|
6513
|
+
const params = node.type === import_utils46.AST_NODE_TYPES.MethodDefinition ? paramNames(node.value.params) : node.type === import_utils46.AST_NODE_TYPES.TSMethodSignature ? paramNames(node.params) : [];
|
|
6852
6514
|
return { name: node.key.name, params };
|
|
6853
6515
|
}
|
|
6854
6516
|
default:
|
|
@@ -6858,9 +6520,9 @@ function declarationNames(node) {
|
|
|
6858
6520
|
function paramNames(params) {
|
|
6859
6521
|
const names = [];
|
|
6860
6522
|
for (const param of params) {
|
|
6861
|
-
const target = param.type ===
|
|
6862
|
-
if (target.type ===
|
|
6863
|
-
else if (target.type ===
|
|
6523
|
+
const target = param.type === import_utils46.AST_NODE_TYPES.AssignmentPattern ? param.left : param;
|
|
6524
|
+
if (target.type === import_utils46.AST_NODE_TYPES.Identifier) names.push(target.name);
|
|
6525
|
+
else if (target.type === import_utils46.AST_NODE_TYPES.TSParameterProperty) continue;
|
|
6864
6526
|
}
|
|
6865
6527
|
return names;
|
|
6866
6528
|
}
|
|
@@ -6869,7 +6531,7 @@ function tokensOf(names) {
|
|
|
6869
6531
|
for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
|
|
6870
6532
|
return tokens;
|
|
6871
6533
|
}
|
|
6872
|
-
var jsdoc_restates_signature_default =
|
|
6534
|
+
var jsdoc_restates_signature_default = import_utils46.ESLintUtils.RuleCreator(
|
|
6873
6535
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6874
6536
|
)({
|
|
6875
6537
|
name: "jsdoc-restates-signature",
|
|
@@ -6905,7 +6567,7 @@ var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
|
|
|
6905
6567
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
|
|
6906
6568
|
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
|
6907
6569
|
let declaration = null;
|
|
6908
|
-
while (node != null && node.type !==
|
|
6570
|
+
while (node != null && node.type !== import_utils46.AST_NODE_TYPES.Program) {
|
|
6909
6571
|
declaration = declarationNames(node);
|
|
6910
6572
|
if (declaration !== null) break;
|
|
6911
6573
|
node = node.parent ?? null;
|
|
@@ -6960,7 +6622,7 @@ var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
|
|
|
6960
6622
|
});
|
|
6961
6623
|
|
|
6962
6624
|
// src/rules/no-restated-comment.ts
|
|
6963
|
-
var
|
|
6625
|
+
var import_utils47 = require("@typescript-eslint/utils");
|
|
6964
6626
|
var MAX_WORDS = 8;
|
|
6965
6627
|
var MIN_CONTENT_TOKENS = 2;
|
|
6966
6628
|
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;
|
|
@@ -6984,7 +6646,7 @@ function headsSiblingRun(node) {
|
|
|
6984
6646
|
const next = index >= 0 ? body[index + 1] : void 0;
|
|
6985
6647
|
return next !== void 0 && next.type === node.type;
|
|
6986
6648
|
}
|
|
6987
|
-
var no_restated_comment_default =
|
|
6649
|
+
var no_restated_comment_default = import_utils47.ESLintUtils.RuleCreator(
|
|
6988
6650
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
6989
6651
|
)({
|
|
6990
6652
|
name: "no-restated-comment",
|
|
@@ -7012,7 +6674,7 @@ var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
|
|
|
7012
6674
|
function labelsASiblingRun(comment) {
|
|
7013
6675
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
7014
6676
|
if (token === null) return false;
|
|
7015
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
6677
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils47.AST_NODE_TYPES.Program; node = node.parent) {
|
|
7016
6678
|
if (headsSiblingRun(node)) return true;
|
|
7017
6679
|
}
|
|
7018
6680
|
return false;
|
|
@@ -7052,7 +6714,7 @@ var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
|
|
|
7052
6714
|
});
|
|
7053
6715
|
|
|
7054
6716
|
// src/rules/trailing-value-narration.ts
|
|
7055
|
-
var
|
|
6717
|
+
var import_utils48 = require("@typescript-eslint/utils");
|
|
7056
6718
|
var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
|
|
7057
6719
|
var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
|
|
7058
6720
|
var UNIT_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -7136,7 +6798,7 @@ function narratesValue(body, code) {
|
|
|
7136
6798
|
(word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
|
|
7137
6799
|
);
|
|
7138
6800
|
}
|
|
7139
|
-
var trailing_value_narration_default =
|
|
6801
|
+
var trailing_value_narration_default = import_utils48.ESLintUtils.RuleCreator(
|
|
7140
6802
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7141
6803
|
)({
|
|
7142
6804
|
name: "trailing-value-narration",
|
|
@@ -7177,7 +6839,7 @@ var trailing_value_narration_default = import_utils49.ESLintUtils.RuleCreator(
|
|
|
7177
6839
|
});
|
|
7178
6840
|
|
|
7179
6841
|
// src/rules/no-tautological-expect.ts
|
|
7180
|
-
var
|
|
6842
|
+
var import_utils49 = require("@typescript-eslint/utils");
|
|
7181
6843
|
var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
7182
6844
|
var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
|
|
7183
6845
|
"toBeDefined",
|
|
@@ -7191,17 +6853,17 @@ var OPERAND_PREVIEW_CHARS = 40;
|
|
|
7191
6853
|
var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
|
|
7192
6854
|
function isLiteral(node) {
|
|
7193
6855
|
switch (node.type) {
|
|
7194
|
-
case
|
|
6856
|
+
case import_utils49.AST_NODE_TYPES.Literal:
|
|
7195
6857
|
return true;
|
|
7196
|
-
case
|
|
6858
|
+
case import_utils49.AST_NODE_TYPES.TemplateLiteral:
|
|
7197
6859
|
return node.expressions.length === 0;
|
|
7198
|
-
case
|
|
6860
|
+
case import_utils49.AST_NODE_TYPES.UnaryExpression:
|
|
7199
6861
|
return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
|
|
7200
|
-
case
|
|
6862
|
+
case import_utils49.AST_NODE_TYPES.ArrayExpression:
|
|
7201
6863
|
return node.elements.every((element) => element !== null && isLiteral(element));
|
|
7202
|
-
case
|
|
6864
|
+
case import_utils49.AST_NODE_TYPES.ObjectExpression:
|
|
7203
6865
|
return node.properties.every(
|
|
7204
|
-
(property) => property.type ===
|
|
6866
|
+
(property) => property.type === import_utils49.AST_NODE_TYPES.Property && !property.computed && isLiteral(property.value)
|
|
7205
6867
|
);
|
|
7206
6868
|
default:
|
|
7207
6869
|
return false;
|
|
@@ -7209,12 +6871,12 @@ function isLiteral(node) {
|
|
|
7209
6871
|
}
|
|
7210
6872
|
function expectOperand(callee) {
|
|
7211
6873
|
const receiver = callee.object;
|
|
7212
|
-
if (receiver.type !==
|
|
6874
|
+
if (receiver.type !== import_utils49.AST_NODE_TYPES.CallExpression || receiver.callee.type !== import_utils49.AST_NODE_TYPES.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
|
|
7213
6875
|
return null;
|
|
7214
6876
|
}
|
|
7215
6877
|
return receiver.arguments[0] ?? null;
|
|
7216
6878
|
}
|
|
7217
|
-
var no_tautological_expect_default =
|
|
6879
|
+
var no_tautological_expect_default = import_utils49.ESLintUtils.RuleCreator(
|
|
7218
6880
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7219
6881
|
)({
|
|
7220
6882
|
name: "no-tautological-expect",
|
|
@@ -7241,10 +6903,10 @@ var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
|
|
|
7241
6903
|
return {
|
|
7242
6904
|
CallExpression(node) {
|
|
7243
6905
|
const callee = node.callee;
|
|
7244
|
-
if (callee.type !==
|
|
6906
|
+
if (callee.type !== import_utils49.AST_NODE_TYPES.MemberExpression || callee.computed) {
|
|
7245
6907
|
return;
|
|
7246
6908
|
}
|
|
7247
|
-
if (callee.property.type !==
|
|
6909
|
+
if (callee.property.type !== import_utils49.AST_NODE_TYPES.Identifier) {
|
|
7248
6910
|
return;
|
|
7249
6911
|
}
|
|
7250
6912
|
const matcher = callee.property.name;
|
|
@@ -7278,26 +6940,26 @@ var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
|
|
|
7278
6940
|
});
|
|
7279
6941
|
|
|
7280
6942
|
// src/rules/require-interface-for-injected-service.ts
|
|
7281
|
-
var
|
|
6943
|
+
var import_utils50 = require("@typescript-eslint/utils");
|
|
7282
6944
|
var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
|
|
7283
6945
|
var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
|
|
7284
6946
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
7285
6947
|
var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
|
|
7286
6948
|
var ROUTER_FACTORY_NAME = "Router";
|
|
7287
6949
|
var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
|
|
7288
|
-
var isExportedClass = (node) => node.parent.type ===
|
|
7289
|
-
var qualifiedName = (name) => name.type ===
|
|
6950
|
+
var isExportedClass = (node) => node.parent.type === import_utils50.AST_NODE_TYPES.ExportNamedDeclaration || node.parent.type === import_utils50.AST_NODE_TYPES.ExportDefaultDeclaration;
|
|
6951
|
+
var qualifiedName = (name) => name.type === import_utils50.AST_NODE_TYPES.Identifier ? name.name : name.type === import_utils50.AST_NODE_TYPES.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
7290
6952
|
var typeReferenceName = (annotated) => {
|
|
7291
6953
|
let target = annotated;
|
|
7292
|
-
if (target.type ===
|
|
7293
|
-
if (target.type ===
|
|
7294
|
-
if (target.type !==
|
|
6954
|
+
if (target.type === import_utils50.AST_NODE_TYPES.TSParameterProperty) target = target.parameter;
|
|
6955
|
+
if (target.type === import_utils50.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
6956
|
+
if (target.type !== import_utils50.AST_NODE_TYPES.Identifier) return null;
|
|
7295
6957
|
const annotation = target.typeAnnotation?.typeAnnotation;
|
|
7296
|
-
if (annotation === void 0 || annotation.type !==
|
|
6958
|
+
if (annotation === void 0 || annotation.type !== import_utils50.AST_NODE_TYPES.TSTypeReference) {
|
|
7297
6959
|
return null;
|
|
7298
6960
|
}
|
|
7299
6961
|
const { typeName } = annotation;
|
|
7300
|
-
const rightmost = typeName.type ===
|
|
6962
|
+
const rightmost = typeName.type === import_utils50.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils50.AST_NODE_TYPES.TSQualifiedName ? typeName.right.name : null;
|
|
7301
6963
|
if (rightmost === null) return null;
|
|
7302
6964
|
return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
|
|
7303
6965
|
};
|
|
@@ -7307,17 +6969,17 @@ var readConstructor = (ctor) => {
|
|
|
7307
6969
|
let constructedFields = 0;
|
|
7308
6970
|
if (body !== null && body !== void 0) {
|
|
7309
6971
|
for (const statement of body.body) {
|
|
7310
|
-
if (statement.type !==
|
|
6972
|
+
if (statement.type !== import_utils50.AST_NODE_TYPES.ExpressionStatement) continue;
|
|
7311
6973
|
const expression = statement.expression;
|
|
7312
|
-
if (expression.type !==
|
|
6974
|
+
if (expression.type !== import_utils50.AST_NODE_TYPES.AssignmentExpression || expression.operator !== "=" || expression.left.type !== import_utils50.AST_NODE_TYPES.MemberExpression || expression.left.object.type !== import_utils50.AST_NODE_TYPES.ThisExpression) {
|
|
7313
6975
|
continue;
|
|
7314
6976
|
}
|
|
7315
6977
|
const source = expression.right;
|
|
7316
|
-
if (source.type ===
|
|
6978
|
+
if (source.type === import_utils50.AST_NODE_TYPES.NewExpression) {
|
|
7317
6979
|
constructedFields += 1;
|
|
7318
|
-
} else if (source.type ===
|
|
6980
|
+
} else if (source.type === import_utils50.AST_NODE_TYPES.Identifier) {
|
|
7319
6981
|
storedFrom.add(source.name);
|
|
7320
|
-
} else if (source.type ===
|
|
6982
|
+
} else if (source.type === import_utils50.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils50.AST_NODE_TYPES.Identifier) {
|
|
7321
6983
|
storedFrom.add(source.object.name);
|
|
7322
6984
|
}
|
|
7323
6985
|
}
|
|
@@ -7326,7 +6988,7 @@ var readConstructor = (ctor) => {
|
|
|
7326
6988
|
for (const parameter of ctor.value.params) {
|
|
7327
6989
|
const reference = typeReferenceName(parameter);
|
|
7328
6990
|
if (reference === null) continue;
|
|
7329
|
-
const stored = parameter.type ===
|
|
6991
|
+
const stored = parameter.type === import_utils50.AST_NODE_TYPES.TSParameterProperty || storedFrom.has(reference.name);
|
|
7330
6992
|
if (!stored) continue;
|
|
7331
6993
|
if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
|
|
7332
6994
|
if (CONFIGISH_NAME_RE.test(reference.name)) continue;
|
|
@@ -7356,19 +7018,19 @@ var subtreeHas = (root, found) => {
|
|
|
7356
7018
|
return hit;
|
|
7357
7019
|
};
|
|
7358
7020
|
var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
|
|
7359
|
-
if (node.type ===
|
|
7021
|
+
if (node.type === import_utils50.AST_NODE_TYPES.CallExpression) {
|
|
7360
7022
|
const { callee } = node;
|
|
7361
|
-
if (callee.type ===
|
|
7362
|
-
return callee.type ===
|
|
7023
|
+
if (callee.type === import_utils50.AST_NODE_TYPES.Identifier) return callee.name === ROUTER_FACTORY_NAME;
|
|
7024
|
+
return callee.type === import_utils50.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils50.AST_NODE_TYPES.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
7363
7025
|
}
|
|
7364
|
-
return node.type ===
|
|
7026
|
+
return node.type === import_utils50.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils50.AST_NODE_TYPES.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
7365
7027
|
});
|
|
7366
7028
|
var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
|
|
7367
7029
|
var fileInterfaceNames = (program) => {
|
|
7368
7030
|
const names = [];
|
|
7369
7031
|
for (const statement of program.body) {
|
|
7370
|
-
const declaration = statement.type ===
|
|
7371
|
-
if (declaration?.type ===
|
|
7032
|
+
const declaration = statement.type === import_utils50.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
7033
|
+
if (declaration?.type === import_utils50.AST_NODE_TYPES.TSInterfaceDeclaration) names.push(declaration.id.name);
|
|
7372
7034
|
}
|
|
7373
7035
|
return names;
|
|
7374
7036
|
};
|
|
@@ -7386,16 +7048,16 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
7386
7048
|
var publicMethodNames = (body) => {
|
|
7387
7049
|
const names = [];
|
|
7388
7050
|
for (const member of body.body) {
|
|
7389
|
-
if (member.type !==
|
|
7051
|
+
if (member.type !== import_utils50.AST_NODE_TYPES.MethodDefinition) continue;
|
|
7390
7052
|
if (member.kind !== "method" || member.static) continue;
|
|
7391
7053
|
if (member.accessibility === "private" || member.accessibility === "protected") continue;
|
|
7392
|
-
if (member.key.type ===
|
|
7393
|
-
if (member.key.type ===
|
|
7054
|
+
if (member.key.type === import_utils50.AST_NODE_TYPES.PrivateIdentifier) continue;
|
|
7055
|
+
if (member.key.type === import_utils50.AST_NODE_TYPES.Identifier) names.push(member.key.name);
|
|
7394
7056
|
else names.push("\u2026");
|
|
7395
7057
|
}
|
|
7396
7058
|
return names;
|
|
7397
7059
|
};
|
|
7398
|
-
var require_interface_for_injected_service_default =
|
|
7060
|
+
var require_interface_for_injected_service_default = import_utils50.ESLintUtils.RuleCreator(
|
|
7399
7061
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7400
7062
|
)({
|
|
7401
7063
|
name: "require-interface-for-injected-service",
|
|
@@ -7423,7 +7085,7 @@ var require_interface_for_injected_service_default = import_utils51.ESLintUtils.
|
|
|
7423
7085
|
if (node.implements.length > 0) return;
|
|
7424
7086
|
if (node.decorators.length > 0) return;
|
|
7425
7087
|
const ctor = node.body.body.find(
|
|
7426
|
-
(member) => member.type ===
|
|
7088
|
+
(member) => member.type === import_utils50.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
|
|
7427
7089
|
);
|
|
7428
7090
|
if (ctor === void 0) return;
|
|
7429
7091
|
const { collaborators, constructedFields } = readConstructor(ctor);
|
|
@@ -7448,26 +7110,26 @@ var require_interface_for_injected_service_default = import_utils51.ESLintUtils.
|
|
|
7448
7110
|
});
|
|
7449
7111
|
|
|
7450
7112
|
// src/rules/prefer-non-nullable-collection.ts
|
|
7451
|
-
var
|
|
7113
|
+
var import_utils51 = require("@typescript-eslint/utils");
|
|
7452
7114
|
var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
7453
7115
|
function propertyName(node) {
|
|
7454
7116
|
const key = node.key;
|
|
7455
|
-
if (key.type ===
|
|
7456
|
-
if (key.type ===
|
|
7117
|
+
if (key.type === import_utils51.AST_NODE_TYPES.Identifier) return key.name;
|
|
7118
|
+
if (key.type === import_utils51.AST_NODE_TYPES.Literal) return String(key.value);
|
|
7457
7119
|
return "collection";
|
|
7458
7120
|
}
|
|
7459
7121
|
function isArrayType(node) {
|
|
7460
|
-
if (node.type ===
|
|
7461
|
-
return node.type ===
|
|
7122
|
+
if (node.type === import_utils51.AST_NODE_TYPES.TSArrayType) return true;
|
|
7123
|
+
return node.type === import_utils51.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils51.AST_NODE_TYPES.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
|
|
7462
7124
|
}
|
|
7463
7125
|
function isNullishType(node) {
|
|
7464
|
-
return node.type ===
|
|
7126
|
+
return node.type === import_utils51.AST_NODE_TYPES.TSNullKeyword || node.type === import_utils51.AST_NODE_TYPES.TSUndefinedKeyword;
|
|
7465
7127
|
}
|
|
7466
7128
|
function isNullableArrayOnly(node) {
|
|
7467
7129
|
const values = node.types.filter((member) => !isNullishType(member));
|
|
7468
7130
|
return values.length > 0 && values.length < node.types.length && values.every(isArrayType);
|
|
7469
7131
|
}
|
|
7470
|
-
var prefer_non_nullable_collection_default =
|
|
7132
|
+
var prefer_non_nullable_collection_default = import_utils51.ESLintUtils.RuleCreator(
|
|
7471
7133
|
(name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
|
|
7472
7134
|
)({
|
|
7473
7135
|
name: "prefer-non-nullable-collection",
|
|
@@ -7490,7 +7152,7 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
|
|
|
7490
7152
|
function checkOptionalProperty(node) {
|
|
7491
7153
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
7492
7154
|
if (annotation === void 0) return;
|
|
7493
|
-
if (annotation.type !==
|
|
7155
|
+
if (annotation.type !== import_utils51.AST_NODE_TYPES.TSUnionType || !isNullableArrayOnly(annotation)) {
|
|
7494
7156
|
return;
|
|
7495
7157
|
}
|
|
7496
7158
|
context.report({
|
|
@@ -7503,7 +7165,7 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
|
|
|
7503
7165
|
TSPropertySignature: checkOptionalProperty,
|
|
7504
7166
|
PropertyDefinition: checkOptionalProperty,
|
|
7505
7167
|
TSTypeAliasDeclaration(node) {
|
|
7506
|
-
if (node.typeAnnotation.type !==
|
|
7168
|
+
if (node.typeAnnotation.type !== import_utils51.AST_NODE_TYPES.TSUnionType) return;
|
|
7507
7169
|
if (!isNullableArrayOnly(node.typeAnnotation)) return;
|
|
7508
7170
|
context.report({
|
|
7509
7171
|
node,
|
|
@@ -7516,41 +7178,41 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
|
|
|
7516
7178
|
});
|
|
7517
7179
|
|
|
7518
7180
|
// src/rules/primary-export-file-name.ts
|
|
7519
|
-
var
|
|
7520
|
-
var
|
|
7181
|
+
var import_utils52 = require("@typescript-eslint/utils");
|
|
7182
|
+
var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
|
|
7521
7183
|
var GENERIC_ENTRYPOINTS = /* @__PURE__ */ new Set(["main", "run", "cli", "setup", "teardown", "execute"]);
|
|
7522
|
-
var
|
|
7184
|
+
var ACRONYM_OVERRIDES = [
|
|
7523
7185
|
[/OAuth/g, "Oauth"],
|
|
7524
7186
|
[/GraphQL/g, "Graphql"],
|
|
7525
7187
|
[/gRPC/g, "Grpc"]
|
|
7526
7188
|
];
|
|
7527
|
-
var
|
|
7528
|
-
var
|
|
7529
|
-
var
|
|
7530
|
-
var
|
|
7189
|
+
var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
|
|
7190
|
+
var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
|
|
7191
|
+
var stemOf = (base) => base.replace(/\.(test|spec|config|d|stories)\.[cm]?[jt]sx?$/i, "").replace(/\.[cm]?[jt]sx?$/i, "");
|
|
7192
|
+
var kebabCase = (name) => {
|
|
7531
7193
|
let normalized = name;
|
|
7532
|
-
for (const [pattern, replacement] of
|
|
7194
|
+
for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
|
|
7533
7195
|
normalized = normalized.replace(pattern, replacement);
|
|
7534
7196
|
}
|
|
7535
|
-
return normalized.replace(
|
|
7197
|
+
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
7536
7198
|
};
|
|
7537
|
-
var isFunctionOrClass = (node) => node.type ===
|
|
7199
|
+
var isFunctionOrClass = (node) => node.type === import_utils52.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils52.AST_NODE_TYPES.FunctionExpression;
|
|
7538
7200
|
var findPrimaryExport = (body) => {
|
|
7539
7201
|
let exportCount = 0;
|
|
7540
7202
|
let primaryCandidate = null;
|
|
7541
7203
|
for (const statement of body) {
|
|
7542
|
-
if (statement.type ===
|
|
7204
|
+
if (statement.type === import_utils52.AST_NODE_TYPES.ExportAllDeclaration) {
|
|
7543
7205
|
return null;
|
|
7544
7206
|
}
|
|
7545
|
-
if (statement.type ===
|
|
7207
|
+
if (statement.type === import_utils52.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
|
7546
7208
|
exportCount += 1;
|
|
7547
7209
|
const decl = statement.declaration;
|
|
7548
|
-
if ((decl.type ===
|
|
7210
|
+
if ((decl.type === import_utils52.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils52.AST_NODE_TYPES.ClassDeclaration) && decl.id !== null) {
|
|
7549
7211
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: true };
|
|
7550
|
-
} else if (decl.type ===
|
|
7212
|
+
} else if (decl.type === import_utils52.AST_NODE_TYPES.Identifier) {
|
|
7551
7213
|
primaryCandidate = { name: decl.name, node: statement, isDefault: true };
|
|
7552
7214
|
}
|
|
7553
|
-
} else if (statement.type ===
|
|
7215
|
+
} else if (statement.type === import_utils52.AST_NODE_TYPES.ExportNamedDeclaration) {
|
|
7554
7216
|
if (statement.source !== null) {
|
|
7555
7217
|
return null;
|
|
7556
7218
|
}
|
|
@@ -7559,27 +7221,27 @@ var findPrimaryExport = (body) => {
|
|
|
7559
7221
|
exportCount += statement.specifiers.length;
|
|
7560
7222
|
if (statement.specifiers.length === 1 && primaryCandidate === null) {
|
|
7561
7223
|
const spec = statement.specifiers[0];
|
|
7562
|
-
if (spec && spec.exported.type ===
|
|
7224
|
+
if (spec && spec.exported.type === import_utils52.AST_NODE_TYPES.Identifier) {
|
|
7563
7225
|
primaryCandidate = { name: spec.exported.name, node: statement, isDefault: false };
|
|
7564
7226
|
}
|
|
7565
7227
|
}
|
|
7566
|
-
} else if (decl.type ===
|
|
7228
|
+
} else if (decl.type === import_utils52.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils52.AST_NODE_TYPES.ClassDeclaration) {
|
|
7567
7229
|
if (decl.id !== null) {
|
|
7568
7230
|
exportCount += 1;
|
|
7569
7231
|
if (primaryCandidate === null) {
|
|
7570
7232
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
7571
7233
|
}
|
|
7572
7234
|
}
|
|
7573
|
-
} else if (decl.type ===
|
|
7235
|
+
} else if (decl.type === import_utils52.AST_NODE_TYPES.VariableDeclaration) {
|
|
7574
7236
|
for (const declarator of decl.declarations) {
|
|
7575
|
-
if (declarator.id.type ===
|
|
7237
|
+
if (declarator.id.type === import_utils52.AST_NODE_TYPES.Identifier) {
|
|
7576
7238
|
exportCount += 1;
|
|
7577
7239
|
if (primaryCandidate === null && declarator.init && isFunctionOrClass(declarator.init)) {
|
|
7578
7240
|
primaryCandidate = { name: declarator.id.name, node: statement, isDefault: false };
|
|
7579
7241
|
}
|
|
7580
7242
|
}
|
|
7581
7243
|
}
|
|
7582
|
-
} else if (decl.type ===
|
|
7244
|
+
} else if (decl.type === import_utils52.AST_NODE_TYPES.TSTypeAliasDeclaration || decl.type === import_utils52.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
7583
7245
|
exportCount += 1;
|
|
7584
7246
|
if (primaryCandidate === null) {
|
|
7585
7247
|
primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
|
|
@@ -7592,7 +7254,7 @@ var findPrimaryExport = (body) => {
|
|
|
7592
7254
|
}
|
|
7593
7255
|
return { ...primaryCandidate, count: exportCount };
|
|
7594
7256
|
};
|
|
7595
|
-
var primary_export_file_name_default =
|
|
7257
|
+
var primary_export_file_name_default = import_utils52.ESLintUtils.RuleCreator(
|
|
7596
7258
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7597
7259
|
)({
|
|
7598
7260
|
name: "primary-export-file-name",
|
|
@@ -7608,10 +7270,10 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
|
|
|
7608
7270
|
},
|
|
7609
7271
|
defaultOptions: [],
|
|
7610
7272
|
create(context) {
|
|
7611
|
-
const base =
|
|
7273
|
+
const base = basename(context.filename);
|
|
7612
7274
|
if (base.endsWith(".d.ts") || base.startsWith("index.") || base.startsWith("_")) return {};
|
|
7613
7275
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
7614
|
-
const stem3 =
|
|
7276
|
+
const stem3 = stemOf(base);
|
|
7615
7277
|
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("[")) {
|
|
7616
7278
|
return {};
|
|
7617
7279
|
}
|
|
@@ -7619,8 +7281,8 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
|
|
|
7619
7281
|
Program(node) {
|
|
7620
7282
|
const primary = findPrimaryExport(node.body);
|
|
7621
7283
|
if (primary === null) return;
|
|
7622
|
-
if (
|
|
7623
|
-
const expectedStem =
|
|
7284
|
+
if (CONVENTIONAL_BUCKET_EXPORTS.has(primary.name) || GENERIC_ENTRYPOINTS.has(primary.name)) return;
|
|
7285
|
+
const expectedStem = kebabCase(primary.name);
|
|
7624
7286
|
if (stem3 === expectedStem) return;
|
|
7625
7287
|
const ext = base.endsWith(".tsx") ? ".tsx" : ".ts";
|
|
7626
7288
|
context.report({
|
|
@@ -7634,7 +7296,7 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
|
|
|
7634
7296
|
});
|
|
7635
7297
|
|
|
7636
7298
|
// src/rules/no-implicit-attribute-access.ts
|
|
7637
|
-
var
|
|
7299
|
+
var import_utils53 = require("@typescript-eslint/utils");
|
|
7638
7300
|
var EXCLUDED_BASES = /* @__PURE__ */ new Set([
|
|
7639
7301
|
"environ",
|
|
7640
7302
|
"headers",
|
|
@@ -7650,15 +7312,15 @@ var EXCLUDED_BASES = /* @__PURE__ */ new Set([
|
|
|
7650
7312
|
"sessionStorage"
|
|
7651
7313
|
]);
|
|
7652
7314
|
function getBaseName(node) {
|
|
7653
|
-
if (node.type ===
|
|
7315
|
+
if (node.type === import_utils53.AST_NODE_TYPES.Identifier) {
|
|
7654
7316
|
return node.name;
|
|
7655
7317
|
}
|
|
7656
|
-
if (node.type ===
|
|
7318
|
+
if (node.type === import_utils53.AST_NODE_TYPES.MemberExpression && node.property.type === import_utils53.AST_NODE_TYPES.Identifier) {
|
|
7657
7319
|
return node.property.name;
|
|
7658
7320
|
}
|
|
7659
7321
|
return null;
|
|
7660
7322
|
}
|
|
7661
|
-
var no_implicit_attribute_access_default =
|
|
7323
|
+
var no_implicit_attribute_access_default = import_utils53.ESLintUtils.RuleCreator(
|
|
7662
7324
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7663
7325
|
)({
|
|
7664
7326
|
name: "no-implicit-attribute-access",
|
|
@@ -7679,7 +7341,7 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
|
|
|
7679
7341
|
if (!node.computed) {
|
|
7680
7342
|
return;
|
|
7681
7343
|
}
|
|
7682
|
-
if (node.property.type ===
|
|
7344
|
+
if (node.property.type === import_utils53.AST_NODE_TYPES.Literal && typeof node.property.value === "string") {
|
|
7683
7345
|
const baseName = getBaseName(node.object);
|
|
7684
7346
|
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7685
7347
|
context.report({
|
|
@@ -7692,11 +7354,11 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
|
|
|
7692
7354
|
},
|
|
7693
7355
|
CallExpression(node) {
|
|
7694
7356
|
const callee = node.callee;
|
|
7695
|
-
if (callee.type ===
|
|
7696
|
-
const method = callee.property.type ===
|
|
7357
|
+
if (callee.type === import_utils53.AST_NODE_TYPES.MemberExpression) {
|
|
7358
|
+
const method = callee.property.type === import_utils53.AST_NODE_TYPES.Identifier ? callee.property.name : null;
|
|
7697
7359
|
if (method === "get") {
|
|
7698
7360
|
const arg = node.arguments[0];
|
|
7699
|
-
if (arg && arg.type ===
|
|
7361
|
+
if (arg && arg.type === import_utils53.AST_NODE_TYPES.Literal && typeof arg.value === "string") {
|
|
7700
7362
|
const baseName = getBaseName(callee.object);
|
|
7701
7363
|
if (!baseName || !EXCLUDED_BASES.has(baseName)) {
|
|
7702
7364
|
context.report({
|
|
@@ -7713,8 +7375,174 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
|
|
|
7713
7375
|
}
|
|
7714
7376
|
});
|
|
7715
7377
|
|
|
7378
|
+
// src/rules/strict-test-assertions.ts
|
|
7379
|
+
var import_utils54 = require("@typescript-eslint/utils");
|
|
7380
|
+
var strict_test_assertions_default = import_utils54.ESLintUtils.RuleCreator.withoutDocs({
|
|
7381
|
+
meta: {
|
|
7382
|
+
type: "suggestion",
|
|
7383
|
+
docs: {
|
|
7384
|
+
description: "Replace multiple sequential assertions with a single toMatchObject or toStrictEqual"
|
|
7385
|
+
},
|
|
7386
|
+
fixable: "code",
|
|
7387
|
+
messages: {
|
|
7388
|
+
combineAssertions: "Combine multiple sequential assertions on the same object into a single toMatchObject or toStrictEqual"
|
|
7389
|
+
},
|
|
7390
|
+
schema: []
|
|
7391
|
+
},
|
|
7392
|
+
defaultOptions: [],
|
|
7393
|
+
create(context) {
|
|
7394
|
+
function checkBody(body) {
|
|
7395
|
+
let currentObject = null;
|
|
7396
|
+
let sequence = [];
|
|
7397
|
+
function getExpectObject(expr) {
|
|
7398
|
+
if (expr.type === import_utils54.AST_NODE_TYPES.CallExpression && expr.callee.type === import_utils54.AST_NODE_TYPES.MemberExpression && expr.callee.object.type === import_utils54.AST_NODE_TYPES.CallExpression && expr.callee.object.callee.type === import_utils54.AST_NODE_TYPES.Identifier && expr.callee.object.callee.name === "expect" && expr.callee.object.arguments.length === 1) {
|
|
7399
|
+
const arg = expr.callee.object.arguments.at(0);
|
|
7400
|
+
if (arg?.type === import_utils54.AST_NODE_TYPES.MemberExpression) {
|
|
7401
|
+
return arg.object;
|
|
7402
|
+
}
|
|
7403
|
+
}
|
|
7404
|
+
return null;
|
|
7405
|
+
}
|
|
7406
|
+
function reportSequence() {
|
|
7407
|
+
const first = sequence.at(0);
|
|
7408
|
+
if (sequence.length > 1 && first) {
|
|
7409
|
+
context.report({
|
|
7410
|
+
node: first,
|
|
7411
|
+
messageId: "combineAssertions",
|
|
7412
|
+
fix(fixer) {
|
|
7413
|
+
if (!currentObject) return null;
|
|
7414
|
+
const objectText = context.sourceCode.getText(currentObject);
|
|
7415
|
+
const props = sequence.map((stmt) => {
|
|
7416
|
+
if (stmt.expression.type !== import_utils54.AST_NODE_TYPES.CallExpression || stmt.expression.callee.type !== import_utils54.AST_NODE_TYPES.MemberExpression || stmt.expression.callee.object.type !== import_utils54.AST_NODE_TYPES.CallExpression) {
|
|
7417
|
+
return null;
|
|
7418
|
+
}
|
|
7419
|
+
const actual = stmt.expression.callee.object.arguments.at(0);
|
|
7420
|
+
const expected = stmt.expression.arguments.at(0);
|
|
7421
|
+
if (actual?.type === import_utils54.AST_NODE_TYPES.MemberExpression && actual.property.type === import_utils54.AST_NODE_TYPES.Identifier && expected) {
|
|
7422
|
+
const propName2 = actual.property.name;
|
|
7423
|
+
const valText = context.sourceCode.getText(expected);
|
|
7424
|
+
return `${propName2}: ${valText}`;
|
|
7425
|
+
}
|
|
7426
|
+
return null;
|
|
7427
|
+
});
|
|
7428
|
+
if (props.some((p) => p === null)) return null;
|
|
7429
|
+
const replacement = `expect(${objectText}).toMatchObject({ ${props.join(", ")} });`;
|
|
7430
|
+
return [
|
|
7431
|
+
fixer.replaceText(first, replacement),
|
|
7432
|
+
...sequence.slice(1).map((stmt) => fixer.remove(stmt))
|
|
7433
|
+
];
|
|
7434
|
+
}
|
|
7435
|
+
});
|
|
7436
|
+
}
|
|
7437
|
+
}
|
|
7438
|
+
for (const statement of body) {
|
|
7439
|
+
if (statement.type === import_utils54.AST_NODE_TYPES.ExpressionStatement) {
|
|
7440
|
+
const obj = getExpectObject(statement.expression);
|
|
7441
|
+
if (obj && currentObject && context.sourceCode.getText(obj) === context.sourceCode.getText(currentObject)) {
|
|
7442
|
+
sequence.push(statement);
|
|
7443
|
+
} else {
|
|
7444
|
+
reportSequence();
|
|
7445
|
+
if (obj) {
|
|
7446
|
+
currentObject = obj;
|
|
7447
|
+
sequence = [statement];
|
|
7448
|
+
} else {
|
|
7449
|
+
currentObject = null;
|
|
7450
|
+
sequence = [];
|
|
7451
|
+
}
|
|
7452
|
+
}
|
|
7453
|
+
} else {
|
|
7454
|
+
reportSequence();
|
|
7455
|
+
currentObject = null;
|
|
7456
|
+
sequence = [];
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
reportSequence();
|
|
7460
|
+
}
|
|
7461
|
+
return {
|
|
7462
|
+
BlockStatement(node) {
|
|
7463
|
+
checkBody(node.body);
|
|
7464
|
+
},
|
|
7465
|
+
Program(node) {
|
|
7466
|
+
checkBody(node.body);
|
|
7467
|
+
}
|
|
7468
|
+
};
|
|
7469
|
+
}
|
|
7470
|
+
});
|
|
7471
|
+
|
|
7472
|
+
// src/rules/no-async-callback-in-waitfor.ts
|
|
7473
|
+
var import_utils55 = require("@typescript-eslint/utils");
|
|
7474
|
+
var no_async_callback_in_waitfor_default = import_utils55.ESLintUtils.RuleCreator(
|
|
7475
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7476
|
+
)({
|
|
7477
|
+
name: "no-async-callback-in-waitfor",
|
|
7478
|
+
meta: {
|
|
7479
|
+
type: "problem",
|
|
7480
|
+
docs: {
|
|
7481
|
+
description: "Disallow async callbacks in `waitFor` to prevent swallowed promise rejections."
|
|
7482
|
+
},
|
|
7483
|
+
schema: [],
|
|
7484
|
+
messages: {
|
|
7485
|
+
noAsyncCallbackInWaitFor: "The callback to `waitFor` should not be async. It expects synchronous assertions and runs the callback repeatedly."
|
|
7486
|
+
}
|
|
7487
|
+
},
|
|
7488
|
+
defaultOptions: [],
|
|
7489
|
+
create(context) {
|
|
7490
|
+
if (!isTestFile(context.filename)) {
|
|
7491
|
+
return {};
|
|
7492
|
+
}
|
|
7493
|
+
return {
|
|
7494
|
+
CallExpression(node) {
|
|
7495
|
+
if (node.callee.type === import_utils55.AST_NODE_TYPES.Identifier && node.callee.name === "waitFor") {
|
|
7496
|
+
const callback = node.arguments[0];
|
|
7497
|
+
if (callback && (callback.type === import_utils55.AST_NODE_TYPES.ArrowFunctionExpression || callback.type === import_utils55.AST_NODE_TYPES.FunctionExpression) && callback.async) {
|
|
7498
|
+
context.report({
|
|
7499
|
+
node: callback,
|
|
7500
|
+
messageId: "noAsyncCallbackInWaitFor"
|
|
7501
|
+
});
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
};
|
|
7506
|
+
}
|
|
7507
|
+
});
|
|
7508
|
+
|
|
7509
|
+
// src/rules/prefer-setup-file-mocks.ts
|
|
7510
|
+
var import_utils56 = require("@typescript-eslint/utils");
|
|
7511
|
+
var prefer_setup_file_mocks_default = import_utils56.ESLintUtils.RuleCreator(
|
|
7512
|
+
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
7513
|
+
)({
|
|
7514
|
+
name: "prefer-setup-file-mocks",
|
|
7515
|
+
meta: {
|
|
7516
|
+
type: "suggestion",
|
|
7517
|
+
docs: {
|
|
7518
|
+
description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
|
|
7519
|
+
},
|
|
7520
|
+
schema: [],
|
|
7521
|
+
messages: {
|
|
7522
|
+
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."
|
|
7523
|
+
}
|
|
7524
|
+
},
|
|
7525
|
+
defaultOptions: [],
|
|
7526
|
+
create(context) {
|
|
7527
|
+
if (!isTestFile(context.filename)) {
|
|
7528
|
+
return {};
|
|
7529
|
+
}
|
|
7530
|
+
return {
|
|
7531
|
+
CallExpression(node) {
|
|
7532
|
+
if (node.callee.type === import_utils56.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils56.AST_NODE_TYPES.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === import_utils56.AST_NODE_TYPES.Identifier && node.callee.property.name === "mock") {
|
|
7533
|
+
context.report({
|
|
7534
|
+
node,
|
|
7535
|
+
messageId: "preferSetupFileMocks"
|
|
7536
|
+
});
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
7539
|
+
};
|
|
7540
|
+
}
|
|
7541
|
+
});
|
|
7542
|
+
|
|
7716
7543
|
// src/index.ts
|
|
7717
7544
|
var rules = {
|
|
7545
|
+
"ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
|
|
7718
7546
|
"enforce-file-structure": enforce_file_structure_default,
|
|
7719
7547
|
"no-client-side-data-fetching": no_client_side_data_fetching_default,
|
|
7720
7548
|
"no-comment-cruft": no_comment_cruft_default,
|
|
@@ -7724,32 +7552,30 @@ var rules = {
|
|
|
7724
7552
|
"no-log-only-catch": no_log_only_catch_default,
|
|
7725
7553
|
"no-raw-env": no_raw_env_default,
|
|
7726
7554
|
"no-sentinel-return-on-catch": no_sentinel_return_on_catch_default,
|
|
7727
|
-
"no-sequential-await": no_sequential_await_default,
|
|
7728
7555
|
"no-string-concat-in-loop": no_string_concat_in_loop_default,
|
|
7729
7556
|
"no-unnecessary-use-client": no_unnecessary_use_client_default,
|
|
7730
7557
|
"prefer-discriminated-union": prefer_discriminated_union_default,
|
|
7731
7558
|
"prefer-schema-for-api-payload": prefer_schema_for_api_payload_default,
|
|
7732
7559
|
"prefer-semantic-colors": prefer_semantic_colors_default,
|
|
7733
7560
|
"prefer-server-actions": prefer_server_actions_default,
|
|
7734
|
-
"prefer-shadcn": prefer_shadcn_default,
|
|
7735
7561
|
"require-assert-never": require_assert_never_default,
|
|
7736
7562
|
"require-zod-form-validation": require_zod_form_validation_default,
|
|
7737
7563
|
"zod-naming-convention": zod_naming_convention_default,
|
|
7738
7564
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
7739
7565
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
7740
7566
|
"no-secret-in-log": no_secret_in_log_default,
|
|
7741
|
-
"no-unsafe-
|
|
7567
|
+
"no-unsafe-mock-casting": no_unsafe_mock_casting_default,
|
|
7742
7568
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
7743
|
-
"
|
|
7569
|
+
"prefer-zod-enum": prefer_zod_enum_default,
|
|
7744
7570
|
"primary-export-file-name": primary_export_file_name_default,
|
|
7745
7571
|
"no-silent-promise-catch": no_silent_promise_catch_default,
|
|
7746
7572
|
"require-fetch-timeout": require_fetch_timeout_default,
|
|
7747
|
-
"require-schema-validate-search": require_schema_validate_search_default,
|
|
7748
7573
|
"no-offset-pagination": no_offset_pagination_default,
|
|
7749
7574
|
"no-positional-tuple-return": no_positional_tuple_return_default,
|
|
7750
7575
|
"no-repeated-string-literal": no_repeated_string_literal_default,
|
|
7751
7576
|
"no-select-star": no_select_star_default,
|
|
7752
7577
|
"no-sleep-in-test-body": no_sleep_in_test_body_default,
|
|
7578
|
+
"no-conditional-in-test": no_conditional_in_test_default,
|
|
7753
7579
|
"prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
|
|
7754
7580
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
7755
7581
|
"no-dynamic-sql": no_dynamic_sql_default,
|
|
@@ -7762,13 +7588,16 @@ var rules = {
|
|
|
7762
7588
|
"trailing-value-narration": trailing_value_narration_default,
|
|
7763
7589
|
"no-tautological-expect": no_tautological_expect_default,
|
|
7764
7590
|
"require-interface-for-injected-service": require_interface_for_injected_service_default,
|
|
7591
|
+
"strict-test-assertions": strict_test_assertions_default,
|
|
7765
7592
|
"prefer-non-nullable-collection": prefer_non_nullable_collection_default,
|
|
7766
|
-
"no-implicit-attribute-access": no_implicit_attribute_access_default
|
|
7593
|
+
"no-implicit-attribute-access": no_implicit_attribute_access_default,
|
|
7594
|
+
"no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
|
|
7595
|
+
"prefer-setup-file-mocks": prefer_setup_file_mocks_default
|
|
7767
7596
|
};
|
|
7768
7597
|
var plugin = {
|
|
7769
7598
|
meta: {
|
|
7770
7599
|
name: "@sarj/eslint-plugin",
|
|
7771
|
-
version: "
|
|
7600
|
+
version: "3.0.0"
|
|
7772
7601
|
},
|
|
7773
7602
|
rules,
|
|
7774
7603
|
configs: {
|
|
@@ -7778,13 +7607,13 @@ var plugin = {
|
|
|
7778
7607
|
"@sarj/zod-naming-convention": "warn",
|
|
7779
7608
|
"@sarj/require-assert-never": "error",
|
|
7780
7609
|
"@sarj/require-zod-form-validation": "error",
|
|
7610
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7781
7611
|
"@sarj/enforce-file-structure": "warn",
|
|
7782
7612
|
"@sarj/no-client-side-data-fetching": "warn",
|
|
7783
7613
|
"@sarj/prefer-server-actions": "warn",
|
|
7784
7614
|
"@sarj/no-unnecessary-use-client": "warn",
|
|
7785
7615
|
"@sarj/prefer-schema-for-api-payload": "warn",
|
|
7786
7616
|
// Distilled from sarj-audit skills — warn in recommended, error in strict.
|
|
7787
|
-
"@sarj/no-sequential-await": "warn",
|
|
7788
7617
|
"@sarj/no-sentinel-return-on-catch": "warn",
|
|
7789
7618
|
"@sarj/no-log-only-catch": "warn",
|
|
7790
7619
|
"@sarj/no-insecure-random-id": "warn",
|
|
@@ -7801,14 +7630,13 @@ var plugin = {
|
|
|
7801
7630
|
"@sarj/no-fat-try-blocks": "warn",
|
|
7802
7631
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
7803
7632
|
"@sarj/no-secret-in-log": "warn",
|
|
7804
|
-
"@sarj/no-unsafe-
|
|
7805
|
-
"@sarj/single-public-export": "warn",
|
|
7633
|
+
"@sarj/no-unsafe-mock-casting": "warn",
|
|
7806
7634
|
"@sarj/primary-export-file-name": "warn",
|
|
7807
7635
|
"@sarj/prefer-string-literal-union": "warn",
|
|
7636
|
+
"@sarj/prefer-zod-enum": "warn",
|
|
7808
7637
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7809
7638
|
"@sarj/require-fetch-timeout": "warn",
|
|
7810
7639
|
"@sarj/no-silent-promise-catch": "warn",
|
|
7811
|
-
"@sarj/require-schema-validate-search": "warn",
|
|
7812
7640
|
// Second SARJ port wave — the TS/Python parity gap. Each targets a
|
|
7813
7641
|
// defect class seen in production Workers code: timing-leaky secret
|
|
7814
7642
|
// compares, non-idempotent store writes under queue redelivery,
|
|
@@ -7818,6 +7646,7 @@ var plugin = {
|
|
|
7818
7646
|
"@sarj/no-offset-pagination": "warn",
|
|
7819
7647
|
"@sarj/no-select-star": "warn",
|
|
7820
7648
|
"@sarj/no-sleep-in-test-body": "warn",
|
|
7649
|
+
"@sarj/no-conditional-in-test": "warn",
|
|
7821
7650
|
"@sarj/no-repeated-string-literal": "warn",
|
|
7822
7651
|
"@sarj/no-positional-tuple-return": "warn",
|
|
7823
7652
|
// Injection guard — low FP, applies to any repo touching SQL.
|
|
@@ -7854,7 +7683,9 @@ var plugin = {
|
|
|
7854
7683
|
// port, 29 fire, 28 of them true positives.
|
|
7855
7684
|
"@sarj/require-interface-for-injected-service": "warn",
|
|
7856
7685
|
"@sarj/prefer-non-nullable-collection": "warn",
|
|
7857
|
-
"@sarj/no-implicit-attribute-access": "warn"
|
|
7686
|
+
"@sarj/no-implicit-attribute-access": "warn",
|
|
7687
|
+
"@sarj/no-async-callback-in-waitfor": "warn",
|
|
7688
|
+
"@sarj/prefer-setup-file-mocks": "warn"
|
|
7858
7689
|
}
|
|
7859
7690
|
},
|
|
7860
7691
|
strict: {
|
|
@@ -7863,16 +7694,15 @@ var plugin = {
|
|
|
7863
7694
|
"@sarj/zod-naming-convention": "error",
|
|
7864
7695
|
"@sarj/require-assert-never": "error",
|
|
7865
7696
|
"@sarj/require-zod-form-validation": "error",
|
|
7697
|
+
"@sarj/ban-loose-type-guards-in-tests": "error",
|
|
7866
7698
|
"@sarj/enforce-file-structure": "error",
|
|
7867
7699
|
"@sarj/no-raw-env": "error",
|
|
7868
|
-
"@sarj/prefer-shadcn": "error",
|
|
7869
7700
|
"@sarj/no-enum": "error",
|
|
7870
7701
|
"@sarj/no-client-side-data-fetching": "error",
|
|
7871
7702
|
"@sarj/prefer-server-actions": "error",
|
|
7872
7703
|
"@sarj/no-unnecessary-use-client": "error",
|
|
7873
7704
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
7874
7705
|
// Distilled from sarj-audit skills.
|
|
7875
|
-
"@sarj/no-sequential-await": "error",
|
|
7876
7706
|
"@sarj/no-sentinel-return-on-catch": "error",
|
|
7877
7707
|
"@sarj/no-log-only-catch": "error",
|
|
7878
7708
|
"@sarj/no-insecure-random-id": "error",
|
|
@@ -7890,21 +7720,21 @@ var plugin = {
|
|
|
7890
7720
|
"@sarj/no-fat-try-blocks": "error",
|
|
7891
7721
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
7892
7722
|
"@sarj/no-secret-in-log": "error",
|
|
7893
|
-
"@sarj/no-unsafe-
|
|
7894
|
-
"@sarj/single-public-export": "error",
|
|
7723
|
+
"@sarj/no-unsafe-mock-casting": "error",
|
|
7895
7724
|
"@sarj/primary-export-file-name": "error",
|
|
7896
7725
|
// Promoted to error 2026-07-25 — strict means strict (user directive).
|
|
7897
7726
|
"@sarj/prefer-string-literal-union": "error",
|
|
7727
|
+
"@sarj/prefer-zod-enum": "error",
|
|
7898
7728
|
// Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
|
|
7899
7729
|
"@sarj/require-fetch-timeout": "error",
|
|
7900
7730
|
"@sarj/no-silent-promise-catch": "error",
|
|
7901
|
-
"@sarj/require-schema-validate-search": "error",
|
|
7902
7731
|
// Second SARJ port wave — the TS/Python parity gap.
|
|
7903
7732
|
"@sarj/prefer-constant-time-secret-compare": "error",
|
|
7904
7733
|
"@sarj/store-insert-requires-on-conflict": "error",
|
|
7905
7734
|
"@sarj/no-offset-pagination": "error",
|
|
7906
7735
|
"@sarj/no-select-star": "error",
|
|
7907
7736
|
"@sarj/no-sleep-in-test-body": "error",
|
|
7737
|
+
"@sarj/no-conditional-in-test": "error",
|
|
7908
7738
|
"@sarj/no-repeated-string-literal": "error",
|
|
7909
7739
|
// API-shape advice rather than a runtime defect — a corpus sweep found its
|
|
7910
7740
|
// only hits are parser `[value, cursor]` returns, which are conventional.
|
|
@@ -7934,7 +7764,9 @@ var plugin = {
|
|
|
7934
7764
|
// corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
|
|
7935
7765
|
"@sarj/require-interface-for-injected-service": "error",
|
|
7936
7766
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
7937
|
-
"@sarj/no-implicit-attribute-access": "error"
|
|
7767
|
+
"@sarj/no-implicit-attribute-access": "error",
|
|
7768
|
+
"@sarj/no-async-callback-in-waitfor": "error",
|
|
7769
|
+
"@sarj/prefer-setup-file-mocks": "error"
|
|
7938
7770
|
}
|
|
7939
7771
|
}
|
|
7940
7772
|
}
|