@sarj/eslint-plugin 2.4.0 → 2.5.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/dist/index.cjs +166 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +167 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -37,7 +37,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
37
|
|
|
38
38
|
// src/rules/enforce-file-structure.ts
|
|
39
39
|
var import_utils = require("@typescript-eslint/utils");
|
|
40
|
-
var SERVER_ACTION_FILE_RE = /(?:^|\/)actions\/|\.action\.[jt]sx?$|(?:^|\/)actions\.[jt]sx?$/;
|
|
41
40
|
var classifyStatement = (statement) => {
|
|
42
41
|
switch (statement.type) {
|
|
43
42
|
case import_utils.AST_NODE_TYPES.ImportDeclaration:
|
|
@@ -52,7 +51,6 @@ var classifyStatement = (statement) => {
|
|
|
52
51
|
};
|
|
53
52
|
var isStringDirective = (statement) => statement.type === import_utils.AST_NODE_TYPES.ExpressionStatement && statement.expression.type === import_utils.AST_NODE_TYPES.Literal && typeof statement.expression.value === "string" && statement.expression.value.startsWith("use ");
|
|
54
53
|
var isUseServerDirective = (statement) => {
|
|
55
|
-
if (statement === void 0) return false;
|
|
56
54
|
if (statement.type !== import_utils.AST_NODE_TYPES.ExpressionStatement) return false;
|
|
57
55
|
const expr = statement.expression;
|
|
58
56
|
if (expr.type !== import_utils.AST_NODE_TYPES.Literal) return false;
|
|
@@ -65,23 +63,25 @@ var enforce_file_structure_default = import_utils.ESLintUtils.RuleCreator(
|
|
|
65
63
|
meta: {
|
|
66
64
|
type: "suggestion",
|
|
67
65
|
docs: {
|
|
68
|
-
description: "Require `import` statements to come first, then allow step-down ordering (public API first, private helpers below) for the rest of the file. Exported statements are classified by WHAT they export \u2014 an exported interface is a declaration, an exported function is a function \u2014 so a public exported function followed by a private helper, or an exported interface among declarations, is allowed. Re-exports (`export { \u2026 } from`, `export *`, `export { \u2026 }`) are a neutral group, so generated namespace barrels pass.
|
|
66
|
+
description: "Require `import` statements to come first, then allow step-down ordering (public API first, private helpers below) for the rest of the file. Exported statements are classified by WHAT they export \u2014 an exported interface is a declaration, an exported function is a function \u2014 so a public exported function followed by a private helper, or an exported interface among declarations, is allowed. Re-exports (`export { \u2026 } from`, `export *`, `export { \u2026 }`) are a neutral group, so generated namespace barrels pass. When a module contains a `use server` directive, it must be the first statement in the file."
|
|
69
67
|
},
|
|
70
68
|
schema: [],
|
|
71
69
|
messages: {
|
|
72
70
|
importsFirst: "File structure violation: import statements must come before other declarations",
|
|
73
|
-
useServerDirective: "
|
|
71
|
+
useServerDirective: "A 'use server' directive must be the first statement in the file"
|
|
74
72
|
}
|
|
75
73
|
},
|
|
76
74
|
defaultOptions: [],
|
|
77
75
|
create(context) {
|
|
78
|
-
const isServerAction = SERVER_ACTION_FILE_RE.test(context.filename);
|
|
79
76
|
return {
|
|
80
77
|
Program(node) {
|
|
81
78
|
const body = node.body;
|
|
82
|
-
|
|
79
|
+
const misplacedUseServer = body.find(
|
|
80
|
+
(statement, index) => index > 0 && isUseServerDirective(statement)
|
|
81
|
+
);
|
|
82
|
+
if (misplacedUseServer !== void 0) {
|
|
83
83
|
context.report({
|
|
84
|
-
node,
|
|
84
|
+
node: misplacedUseServer,
|
|
85
85
|
messageId: "useServerDirective"
|
|
86
86
|
});
|
|
87
87
|
}
|
|
@@ -663,12 +663,49 @@ function instanceofErrorSubject(test) {
|
|
|
663
663
|
}
|
|
664
664
|
return null;
|
|
665
665
|
}
|
|
666
|
+
var TYPE_GUARD_PATTERN = /^(is|has)[A-Z]/;
|
|
667
|
+
function typeGuardSubject(test) {
|
|
668
|
+
const arg = test.type === "CallExpression" ? test.arguments[0] : void 0;
|
|
669
|
+
if (test.type === "CallExpression" && test.callee.type === "Identifier" && TYPE_GUARD_PATTERN.test(test.callee.name) && test.arguments.length === 1 && arg !== void 0 && arg.type !== "SpreadElement") {
|
|
670
|
+
return arg;
|
|
671
|
+
}
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
function positiveErrorSubject(test) {
|
|
675
|
+
return instanceofErrorSubject(test) ?? typeGuardSubject(test);
|
|
676
|
+
}
|
|
666
677
|
function negatedInstanceofErrorSubject(test) {
|
|
667
678
|
if (test.type === "UnaryExpression" && test.operator === "!") {
|
|
668
|
-
return
|
|
679
|
+
return positiveErrorSubject(test.argument);
|
|
669
680
|
}
|
|
670
681
|
return null;
|
|
671
682
|
}
|
|
683
|
+
function branchTerminates(branch) {
|
|
684
|
+
const body = branch.type === "BlockStatement" ? branch.body : [branch];
|
|
685
|
+
const last = body[body.length - 1];
|
|
686
|
+
return last !== void 0 && (last.type === "ReturnStatement" || last.type === "ThrowStatement");
|
|
687
|
+
}
|
|
688
|
+
function isNarrowedByEarlyReturn(node, argExpr, sourceCode) {
|
|
689
|
+
const argText = sourceCode.getText(argExpr);
|
|
690
|
+
let current = node.parent;
|
|
691
|
+
while (current) {
|
|
692
|
+
if (current.type === "BlockStatement" || current.type === "Program") {
|
|
693
|
+
for (const stmt of current.body) {
|
|
694
|
+
if (stmt.range[0] >= node.range[0]) {
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
if (stmt.type === "IfStatement" && stmt.alternate === null && branchTerminates(stmt.consequent)) {
|
|
698
|
+
const subject = positiveErrorSubject(stmt.test);
|
|
699
|
+
if (subject && sourceCode.getText(subject) === argText) {
|
|
700
|
+
return true;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
current = current.parent;
|
|
706
|
+
}
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
672
709
|
function nodeWithin(node, container) {
|
|
673
710
|
return container !== null && node.range[0] >= container.range[0] && node.range[1] <= container.range[1];
|
|
674
711
|
}
|
|
@@ -678,7 +715,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
678
715
|
let current = node.parent;
|
|
679
716
|
while (current) {
|
|
680
717
|
if (current.type === "ConditionalExpression") {
|
|
681
|
-
const subject =
|
|
718
|
+
const subject = positiveErrorSubject(current.test);
|
|
682
719
|
if (subject && sameSubject(subject) && nodeWithin(node, current.alternate)) {
|
|
683
720
|
return true;
|
|
684
721
|
}
|
|
@@ -687,7 +724,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
|
|
|
687
724
|
return true;
|
|
688
725
|
}
|
|
689
726
|
} else if (current.type === "IfStatement") {
|
|
690
|
-
const subject =
|
|
727
|
+
const subject = positiveErrorSubject(current.test);
|
|
691
728
|
if (subject && sameSubject(subject) && nodeWithin(node, current.alternate)) {
|
|
692
729
|
return true;
|
|
693
730
|
}
|
|
@@ -740,7 +777,7 @@ var no_json_stringify_error_default = import_utils6.ESLintUtils.RuleCreator(
|
|
|
740
777
|
if (!suggestsError) {
|
|
741
778
|
return;
|
|
742
779
|
}
|
|
743
|
-
if (isGuardedByInstanceofError(node, firstArg, context.sourceCode)) {
|
|
780
|
+
if (isGuardedByInstanceofError(node, firstArg, context.sourceCode) || isNarrowedByEarlyReturn(node, firstArg, context.sourceCode)) {
|
|
744
781
|
return;
|
|
745
782
|
}
|
|
746
783
|
context.report({
|
|
@@ -883,6 +920,17 @@ function isProcessEnv(node) {
|
|
|
883
920
|
function isImportMetaEnv(node) {
|
|
884
921
|
return !node.computed && node.property.type === "Identifier" && node.property.name === "env" && node.object.type === "MetaProperty" && node.object.meta.name === "import" && node.object.property.name === "meta";
|
|
885
922
|
}
|
|
923
|
+
var BUILD_TIME_CONSTANTS = /* @__PURE__ */ new Set([
|
|
924
|
+
"NODE_ENV",
|
|
925
|
+
"MODE",
|
|
926
|
+
"DEV",
|
|
927
|
+
"PROD",
|
|
928
|
+
"SSR"
|
|
929
|
+
]);
|
|
930
|
+
function isBuildTimeConstantAccess(node) {
|
|
931
|
+
const parent = node.parent;
|
|
932
|
+
return parent.type === "MemberExpression" && parent.object === node && !parent.computed && parent.property.type === "Identifier" && BUILD_TIME_CONSTANTS.has(parent.property.name);
|
|
933
|
+
}
|
|
886
934
|
var no_raw_env_default = import_utils9.ESLintUtils.RuleCreator(
|
|
887
935
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
888
936
|
)({
|
|
@@ -901,7 +949,7 @@ var no_raw_env_default = import_utils9.ESLintUtils.RuleCreator(
|
|
|
901
949
|
create(context) {
|
|
902
950
|
return {
|
|
903
951
|
MemberExpression(node) {
|
|
904
|
-
if (isProcessEnv(node) || isImportMetaEnv(node)) {
|
|
952
|
+
if ((isProcessEnv(node) || isImportMetaEnv(node)) && !isBuildTimeConstantAccess(node)) {
|
|
905
953
|
context.report({
|
|
906
954
|
node,
|
|
907
955
|
messageId: "noRawEnv"
|
|
@@ -1137,7 +1185,7 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
|
|
|
1137
1185
|
// src/rules/no-sequential-await.ts
|
|
1138
1186
|
var import_utils11 = require("@typescript-eslint/utils");
|
|
1139
1187
|
var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
|
|
1140
|
-
var SEQUENTIAL_ITERABLE_HINT = /sort|reverse|ordered|sequence|hook|middleware|pipeline|\bstage|\bstep|\bphase|migration|chain/i;
|
|
1188
|
+
var SEQUENTIAL_ITERABLE_HINT = /sort|reverse|ordered|sequence|hook|middleware|pipeline|\bstage|\bstep|\bphase|migration|chain|buffer|stream|teleport|chunk|\bqueue|drain/i;
|
|
1141
1189
|
function isFunctionLike(node) {
|
|
1142
1190
|
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
1143
1191
|
}
|
|
@@ -1180,9 +1228,29 @@ function hasEarlyExit(root) {
|
|
|
1180
1228
|
});
|
|
1181
1229
|
return found;
|
|
1182
1230
|
}
|
|
1231
|
+
var TIMER_HELPER_RE = /^(sleep|timeout|delay|wait|pause|tick)$/i;
|
|
1232
|
+
function calleeName2(callee) {
|
|
1233
|
+
if (callee.type === "Identifier") return callee.name;
|
|
1234
|
+
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier") {
|
|
1235
|
+
return callee.property.name;
|
|
1236
|
+
}
|
|
1237
|
+
return null;
|
|
1238
|
+
}
|
|
1183
1239
|
function isTimerYield(node) {
|
|
1184
1240
|
const arg = node.argument;
|
|
1185
|
-
|
|
1241
|
+
if (arg.type === "NewExpression" && arg.callee.type === "Identifier" && arg.callee.name === "Promise") {
|
|
1242
|
+
return true;
|
|
1243
|
+
}
|
|
1244
|
+
if (arg.type === "CallExpression") {
|
|
1245
|
+
const name = calleeName2(arg.callee);
|
|
1246
|
+
return name !== null && TIMER_HELPER_RE.test(name);
|
|
1247
|
+
}
|
|
1248
|
+
return false;
|
|
1249
|
+
}
|
|
1250
|
+
var QUEUE_DRAIN_METHODS = /^(shift|pop|dequeue|next|poll)$/;
|
|
1251
|
+
function isQueueDrain(node) {
|
|
1252
|
+
const arg = node.argument;
|
|
1253
|
+
return arg.type === "CallExpression" && arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.property.type === "Identifier" && QUEUE_DRAIN_METHODS.test(arg.callee.property.name);
|
|
1186
1254
|
}
|
|
1187
1255
|
function referencesName(root, name) {
|
|
1188
1256
|
let found = false;
|
|
@@ -1217,7 +1285,7 @@ function shouldReport(awaits, earlyExit, iterableText) {
|
|
|
1217
1285
|
return false;
|
|
1218
1286
|
}
|
|
1219
1287
|
return awaits.some(
|
|
1220
|
-
(node) => !isTimerYield(node) && !isThreadedAccumulator(node)
|
|
1288
|
+
(node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
|
|
1221
1289
|
);
|
|
1222
1290
|
}
|
|
1223
1291
|
var no_sequential_await_default = import_utils11.ESLintUtils.RuleCreator(
|
|
@@ -1238,10 +1306,10 @@ var no_sequential_await_default = import_utils11.ESLintUtils.RuleCreator(
|
|
|
1238
1306
|
create(context) {
|
|
1239
1307
|
function loopParts(node) {
|
|
1240
1308
|
if (node.type === "ForStatement") {
|
|
1241
|
-
return [node.body, node.
|
|
1309
|
+
return [node.body, node.test, node.update];
|
|
1242
1310
|
}
|
|
1243
1311
|
if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
|
|
1244
|
-
return [node.body
|
|
1312
|
+
return [node.body];
|
|
1245
1313
|
}
|
|
1246
1314
|
return [node.body, node.test];
|
|
1247
1315
|
}
|
|
@@ -1897,10 +1965,10 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
|
|
|
1897
1965
|
"currentcolor",
|
|
1898
1966
|
"inherit"
|
|
1899
1967
|
]);
|
|
1900
|
-
var
|
|
1968
|
+
var isInsideSvg = (node) => {
|
|
1901
1969
|
let current = node.parent;
|
|
1902
1970
|
while (current !== void 0 && current !== null) {
|
|
1903
|
-
if (current.type === import_utils17.AST_NODE_TYPES.JSXElement && current.openingElement.name.type === import_utils17.AST_NODE_TYPES.JSXIdentifier && SVG_DEFS_CONTAINERS.has(current.openingElement.name.name)) {
|
|
1971
|
+
if (current.type === import_utils17.AST_NODE_TYPES.JSXElement && current.openingElement.name.type === import_utils17.AST_NODE_TYPES.JSXIdentifier && (current.openingElement.name.name === "svg" || SVG_DEFS_CONTAINERS.has(current.openingElement.name.name))) {
|
|
1904
1972
|
return true;
|
|
1905
1973
|
}
|
|
1906
1974
|
current = current.parent;
|
|
@@ -2010,7 +2078,7 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
|
|
|
2010
2078
|
if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
|
|
2011
2079
|
return;
|
|
2012
2080
|
}
|
|
2013
|
-
if (
|
|
2081
|
+
if (isInsideSvg(node)) return;
|
|
2014
2082
|
checkColorValueNode(node.value);
|
|
2015
2083
|
},
|
|
2016
2084
|
// Inline style objects: style={{ color: "#111827", backgroundColor: "#fff" }}
|
|
@@ -2538,7 +2606,7 @@ function propertyKeyName(prop) {
|
|
|
2538
2606
|
}
|
|
2539
2607
|
return void 0;
|
|
2540
2608
|
}
|
|
2541
|
-
function
|
|
2609
|
+
function calleeName3(node) {
|
|
2542
2610
|
const callee = node.callee;
|
|
2543
2611
|
if (callee.type === "Identifier") {
|
|
2544
2612
|
return callee.name;
|
|
@@ -2549,7 +2617,7 @@ function calleeName2(node) {
|
|
|
2549
2617
|
return void 0;
|
|
2550
2618
|
}
|
|
2551
2619
|
function isCorsWildcardCredentialsCall(node) {
|
|
2552
|
-
const name =
|
|
2620
|
+
const name = calleeName3(node);
|
|
2553
2621
|
if (name === void 0 || name.toLowerCase() !== "cors") {
|
|
2554
2622
|
return false;
|
|
2555
2623
|
}
|
|
@@ -3178,8 +3246,54 @@ var no_secret_in_log_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3178
3246
|
}
|
|
3179
3247
|
});
|
|
3180
3248
|
|
|
3181
|
-
// src/rules/
|
|
3249
|
+
// src/rules/no-unsafe-cast.ts
|
|
3182
3250
|
var import_utils26 = require("@typescript-eslint/utils");
|
|
3251
|
+
var import_utils27 = require("@typescript-eslint/utils");
|
|
3252
|
+
function isAnyAnnotation(node) {
|
|
3253
|
+
return node.type === import_utils27.AST_NODE_TYPES.TSAnyKeyword;
|
|
3254
|
+
}
|
|
3255
|
+
function isConstAssertion(typeAnnotation) {
|
|
3256
|
+
return typeAnnotation.type === import_utils27.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils27.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
|
|
3257
|
+
}
|
|
3258
|
+
var no_unsafe_cast_default = import_utils26.ESLintUtils.RuleCreator(
|
|
3259
|
+
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3260
|
+
)({
|
|
3261
|
+
name: "no-unsafe-cast",
|
|
3262
|
+
meta: {
|
|
3263
|
+
type: "problem",
|
|
3264
|
+
docs: {
|
|
3265
|
+
description: "Disallow `as any`/`<any>` casts and `as unknown as T` double-casts, which fully disable type checking."
|
|
3266
|
+
},
|
|
3267
|
+
schema: [],
|
|
3268
|
+
messages: {
|
|
3269
|
+
asAny: "`as any` disables type checking on this value. Narrow with a type guard, model the shape, or cast to a specific type instead.",
|
|
3270
|
+
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."
|
|
3271
|
+
}
|
|
3272
|
+
},
|
|
3273
|
+
defaultOptions: [],
|
|
3274
|
+
create(context) {
|
|
3275
|
+
function checkAssertion(node) {
|
|
3276
|
+
if (isConstAssertion(node.typeAnnotation)) {
|
|
3277
|
+
return;
|
|
3278
|
+
}
|
|
3279
|
+
if (isAnyAnnotation(node.typeAnnotation)) {
|
|
3280
|
+
context.report({ node, messageId: "asAny" });
|
|
3281
|
+
return;
|
|
3282
|
+
}
|
|
3283
|
+
const inner = node.expression;
|
|
3284
|
+
if (inner.type === import_utils27.AST_NODE_TYPES.TSAsExpression || inner.type === import_utils27.AST_NODE_TYPES.TSTypeAssertion) {
|
|
3285
|
+
context.report({ node, messageId: "doubleCast" });
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
return {
|
|
3289
|
+
TSAsExpression: checkAssertion,
|
|
3290
|
+
TSTypeAssertion: checkAssertion
|
|
3291
|
+
};
|
|
3292
|
+
}
|
|
3293
|
+
});
|
|
3294
|
+
|
|
3295
|
+
// src/rules/prefer-string-literal-union.ts
|
|
3296
|
+
var import_utils28 = require("@typescript-eslint/utils");
|
|
3183
3297
|
var ts = __toESM(require("typescript"), 1);
|
|
3184
3298
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
3185
3299
|
"status",
|
|
@@ -3222,19 +3336,19 @@ function isChoiceLikeName(name) {
|
|
|
3222
3336
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
3223
3337
|
}
|
|
3224
3338
|
function keyName(key) {
|
|
3225
|
-
if (key.type ===
|
|
3339
|
+
if (key.type === import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3226
3340
|
return key.name;
|
|
3227
3341
|
}
|
|
3228
|
-
if (key.type ===
|
|
3342
|
+
if (key.type === import_utils28.AST_NODE_TYPES.Literal && typeof key.value === "string") {
|
|
3229
3343
|
return key.value;
|
|
3230
3344
|
}
|
|
3231
3345
|
return null;
|
|
3232
3346
|
}
|
|
3233
3347
|
function isStringLiteralMember(t) {
|
|
3234
|
-
return t.type ===
|
|
3348
|
+
return t.type === import_utils28.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils28.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
|
|
3235
3349
|
}
|
|
3236
3350
|
function isStringLiteralUnion(node) {
|
|
3237
|
-
if (node?.type !==
|
|
3351
|
+
if (node?.type !== import_utils28.AST_NODE_TYPES.TSUnionType) {
|
|
3238
3352
|
return false;
|
|
3239
3353
|
}
|
|
3240
3354
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -3263,12 +3377,12 @@ function bindingSourceExpression(decl) {
|
|
|
3263
3377
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
3264
3378
|
}
|
|
3265
3379
|
function refKey(node) {
|
|
3266
|
-
if (node.type ===
|
|
3380
|
+
if (node.type === import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3267
3381
|
return node.name;
|
|
3268
3382
|
}
|
|
3269
|
-
if (node.type ===
|
|
3383
|
+
if (node.type === import_utils28.AST_NODE_TYPES.MemberExpression && !node.computed) {
|
|
3270
3384
|
const inner = refKey(node.object);
|
|
3271
|
-
if (inner === null || node.property.type !==
|
|
3385
|
+
if (inner === null || node.property.type !== import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3272
3386
|
return null;
|
|
3273
3387
|
}
|
|
3274
3388
|
return `${inner}.${node.property.name}`;
|
|
@@ -3276,12 +3390,12 @@ function refKey(node) {
|
|
|
3276
3390
|
return null;
|
|
3277
3391
|
}
|
|
3278
3392
|
function strLiteral(node) {
|
|
3279
|
-
if (node.type ===
|
|
3393
|
+
if (node.type === import_utils28.AST_NODE_TYPES.Literal && typeof node.value === "string") {
|
|
3280
3394
|
return node.value;
|
|
3281
3395
|
}
|
|
3282
3396
|
return null;
|
|
3283
3397
|
}
|
|
3284
|
-
var prefer_string_literal_union_default =
|
|
3398
|
+
var prefer_string_literal_union_default = import_utils28.ESLintUtils.RuleCreator(
|
|
3285
3399
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3286
3400
|
)({
|
|
3287
3401
|
name: "prefer-string-literal-union",
|
|
@@ -3305,7 +3419,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3305
3419
|
}
|
|
3306
3420
|
let services;
|
|
3307
3421
|
try {
|
|
3308
|
-
services =
|
|
3422
|
+
services = import_utils28.ESLintUtils.getParserServices(context);
|
|
3309
3423
|
} catch {
|
|
3310
3424
|
services = null;
|
|
3311
3425
|
}
|
|
@@ -3389,7 +3503,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3389
3503
|
containersWithUnion.add(container);
|
|
3390
3504
|
return;
|
|
3391
3505
|
}
|
|
3392
|
-
if (typeNode?.type !==
|
|
3506
|
+
if (typeNode?.type !== import_utils28.AST_NODE_TYPES.TSStringKeyword) {
|
|
3393
3507
|
return;
|
|
3394
3508
|
}
|
|
3395
3509
|
const name = keyName(key);
|
|
@@ -3477,10 +3591,10 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3477
3591
|
}
|
|
3478
3592
|
};
|
|
3479
3593
|
function refKeyText(node) {
|
|
3480
|
-
if (node.type ===
|
|
3594
|
+
if (node.type === import_utils28.AST_NODE_TYPES.BinaryExpression) {
|
|
3481
3595
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
3482
3596
|
}
|
|
3483
|
-
if (node.type ===
|
|
3597
|
+
if (node.type === import_utils28.AST_NODE_TYPES.SwitchStatement) {
|
|
3484
3598
|
return refKey(node.discriminant) ?? "value";
|
|
3485
3599
|
}
|
|
3486
3600
|
return "value";
|
|
@@ -3489,7 +3603,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3489
3603
|
});
|
|
3490
3604
|
|
|
3491
3605
|
// src/rules/single-public-export.ts
|
|
3492
|
-
var
|
|
3606
|
+
var import_utils29 = require("@typescript-eslint/utils");
|
|
3493
3607
|
var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
|
|
3494
3608
|
"util",
|
|
3495
3609
|
"utils",
|
|
@@ -3523,12 +3637,12 @@ var kebabCase2 = (name) => {
|
|
|
3523
3637
|
}
|
|
3524
3638
|
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
3525
3639
|
};
|
|
3526
|
-
var isFunctionExpression = (node) => node !== null && (node.type ===
|
|
3640
|
+
var isFunctionExpression = (node) => node !== null && (node.type === import_utils29.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils29.AST_NODE_TYPES.FunctionExpression);
|
|
3527
3641
|
var functionConstName = (decl) => {
|
|
3528
3642
|
if (decl.declarations.length !== 1) return null;
|
|
3529
3643
|
const [declarator] = decl.declarations;
|
|
3530
3644
|
if (declarator === void 0) return null;
|
|
3531
|
-
if (declarator.id.type !==
|
|
3645
|
+
if (declarator.id.type !== import_utils29.AST_NODE_TYPES.Identifier) return null;
|
|
3532
3646
|
if (!isFunctionExpression(declarator.init)) return null;
|
|
3533
3647
|
return declarator.id.name;
|
|
3534
3648
|
};
|
|
@@ -3542,20 +3656,20 @@ var summarizeExports = (body) => {
|
|
|
3542
3656
|
};
|
|
3543
3657
|
for (const statement of body) {
|
|
3544
3658
|
switch (statement.type) {
|
|
3545
|
-
case
|
|
3659
|
+
case import_utils29.AST_NODE_TYPES.ExportAllDeclaration:
|
|
3546
3660
|
hasReExport = true;
|
|
3547
3661
|
break;
|
|
3548
|
-
case
|
|
3662
|
+
case import_utils29.AST_NODE_TYPES.ExportDefaultDeclaration: {
|
|
3549
3663
|
names += 1;
|
|
3550
3664
|
const decl = statement.declaration;
|
|
3551
|
-
if (decl.type ===
|
|
3665
|
+
if (decl.type === import_utils29.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
|
|
3552
3666
|
candidate = { name: decl.id.name, node: statement };
|
|
3553
|
-
} else if (decl.type ===
|
|
3667
|
+
} else if (decl.type === import_utils29.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
|
|
3554
3668
|
candidate = { name: decl.id.name, node: statement };
|
|
3555
3669
|
}
|
|
3556
3670
|
break;
|
|
3557
3671
|
}
|
|
3558
|
-
case
|
|
3672
|
+
case import_utils29.AST_NODE_TYPES.ExportNamedDeclaration: {
|
|
3559
3673
|
if (statement.source !== null) {
|
|
3560
3674
|
hasReExport = true;
|
|
3561
3675
|
break;
|
|
@@ -3566,15 +3680,15 @@ var summarizeExports = (body) => {
|
|
|
3566
3680
|
break;
|
|
3567
3681
|
}
|
|
3568
3682
|
switch (decl.type) {
|
|
3569
|
-
case
|
|
3683
|
+
case import_utils29.AST_NODE_TYPES.FunctionDeclaration:
|
|
3570
3684
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3571
3685
|
else names += 1;
|
|
3572
3686
|
break;
|
|
3573
|
-
case
|
|
3687
|
+
case import_utils29.AST_NODE_TYPES.ClassDeclaration:
|
|
3574
3688
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3575
3689
|
else names += 1;
|
|
3576
3690
|
break;
|
|
3577
|
-
case
|
|
3691
|
+
case import_utils29.AST_NODE_TYPES.VariableDeclaration: {
|
|
3578
3692
|
const fnName = functionConstName(decl);
|
|
3579
3693
|
if (fnName !== null && decl.declarations.length === 1) {
|
|
3580
3694
|
addCandidate(fnName, statement);
|
|
@@ -3594,7 +3708,7 @@ var summarizeExports = (body) => {
|
|
|
3594
3708
|
}
|
|
3595
3709
|
return { names, hasReExport, candidate };
|
|
3596
3710
|
};
|
|
3597
|
-
var single_public_export_default =
|
|
3711
|
+
var single_public_export_default = import_utils29.ESLintUtils.RuleCreator(
|
|
3598
3712
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3599
3713
|
)({
|
|
3600
3714
|
name: "single-public-export",
|
|
@@ -3658,13 +3772,14 @@ var rules = {
|
|
|
3658
3772
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
3659
3773
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
3660
3774
|
"no-secret-in-log": no_secret_in_log_default,
|
|
3775
|
+
"no-unsafe-cast": no_unsafe_cast_default,
|
|
3661
3776
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
3662
3777
|
"single-public-export": single_public_export_default
|
|
3663
3778
|
};
|
|
3664
3779
|
var plugin = {
|
|
3665
3780
|
meta: {
|
|
3666
3781
|
name: "@sarj/eslint-plugin",
|
|
3667
|
-
version: "2.
|
|
3782
|
+
version: "2.5.0"
|
|
3668
3783
|
},
|
|
3669
3784
|
rules,
|
|
3670
3785
|
configs: {
|
|
@@ -3694,6 +3809,7 @@ var plugin = {
|
|
|
3694
3809
|
"@sarj/no-fat-try-blocks": "warn",
|
|
3695
3810
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
3696
3811
|
"@sarj/no-secret-in-log": "warn",
|
|
3812
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3697
3813
|
"@sarj/single-public-export": "warn",
|
|
3698
3814
|
"@sarj/prefer-string-literal-union": "warn"
|
|
3699
3815
|
}
|
|
@@ -3728,6 +3844,7 @@ var plugin = {
|
|
|
3728
3844
|
"@sarj/no-fat-try-blocks": "error",
|
|
3729
3845
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
3730
3846
|
"@sarj/no-secret-in-log": "error",
|
|
3847
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3731
3848
|
"@sarj/single-public-export": "error",
|
|
3732
3849
|
// High-volume/stylistic — warn until rollout proves FP rate.
|
|
3733
3850
|
"@sarj/prefer-string-literal-union": "warn"
|