@sarj/eslint-plugin 2.4.1 → 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 +76 -27
- 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 +77 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3246,8 +3246,54 @@ var no_secret_in_log_default = import_utils25.ESLintUtils.RuleCreator(
|
|
|
3246
3246
|
}
|
|
3247
3247
|
});
|
|
3248
3248
|
|
|
3249
|
-
// src/rules/
|
|
3249
|
+
// src/rules/no-unsafe-cast.ts
|
|
3250
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");
|
|
3251
3297
|
var ts = __toESM(require("typescript"), 1);
|
|
3252
3298
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
3253
3299
|
"status",
|
|
@@ -3290,19 +3336,19 @@ function isChoiceLikeName(name) {
|
|
|
3290
3336
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
3291
3337
|
}
|
|
3292
3338
|
function keyName(key) {
|
|
3293
|
-
if (key.type ===
|
|
3339
|
+
if (key.type === import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3294
3340
|
return key.name;
|
|
3295
3341
|
}
|
|
3296
|
-
if (key.type ===
|
|
3342
|
+
if (key.type === import_utils28.AST_NODE_TYPES.Literal && typeof key.value === "string") {
|
|
3297
3343
|
return key.value;
|
|
3298
3344
|
}
|
|
3299
3345
|
return null;
|
|
3300
3346
|
}
|
|
3301
3347
|
function isStringLiteralMember(t) {
|
|
3302
|
-
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";
|
|
3303
3349
|
}
|
|
3304
3350
|
function isStringLiteralUnion(node) {
|
|
3305
|
-
if (node?.type !==
|
|
3351
|
+
if (node?.type !== import_utils28.AST_NODE_TYPES.TSUnionType) {
|
|
3306
3352
|
return false;
|
|
3307
3353
|
}
|
|
3308
3354
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -3331,12 +3377,12 @@ function bindingSourceExpression(decl) {
|
|
|
3331
3377
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
3332
3378
|
}
|
|
3333
3379
|
function refKey(node) {
|
|
3334
|
-
if (node.type ===
|
|
3380
|
+
if (node.type === import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3335
3381
|
return node.name;
|
|
3336
3382
|
}
|
|
3337
|
-
if (node.type ===
|
|
3383
|
+
if (node.type === import_utils28.AST_NODE_TYPES.MemberExpression && !node.computed) {
|
|
3338
3384
|
const inner = refKey(node.object);
|
|
3339
|
-
if (inner === null || node.property.type !==
|
|
3385
|
+
if (inner === null || node.property.type !== import_utils28.AST_NODE_TYPES.Identifier) {
|
|
3340
3386
|
return null;
|
|
3341
3387
|
}
|
|
3342
3388
|
return `${inner}.${node.property.name}`;
|
|
@@ -3344,12 +3390,12 @@ function refKey(node) {
|
|
|
3344
3390
|
return null;
|
|
3345
3391
|
}
|
|
3346
3392
|
function strLiteral(node) {
|
|
3347
|
-
if (node.type ===
|
|
3393
|
+
if (node.type === import_utils28.AST_NODE_TYPES.Literal && typeof node.value === "string") {
|
|
3348
3394
|
return node.value;
|
|
3349
3395
|
}
|
|
3350
3396
|
return null;
|
|
3351
3397
|
}
|
|
3352
|
-
var prefer_string_literal_union_default =
|
|
3398
|
+
var prefer_string_literal_union_default = import_utils28.ESLintUtils.RuleCreator(
|
|
3353
3399
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3354
3400
|
)({
|
|
3355
3401
|
name: "prefer-string-literal-union",
|
|
@@ -3373,7 +3419,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3373
3419
|
}
|
|
3374
3420
|
let services;
|
|
3375
3421
|
try {
|
|
3376
|
-
services =
|
|
3422
|
+
services = import_utils28.ESLintUtils.getParserServices(context);
|
|
3377
3423
|
} catch {
|
|
3378
3424
|
services = null;
|
|
3379
3425
|
}
|
|
@@ -3457,7 +3503,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3457
3503
|
containersWithUnion.add(container);
|
|
3458
3504
|
return;
|
|
3459
3505
|
}
|
|
3460
|
-
if (typeNode?.type !==
|
|
3506
|
+
if (typeNode?.type !== import_utils28.AST_NODE_TYPES.TSStringKeyword) {
|
|
3461
3507
|
return;
|
|
3462
3508
|
}
|
|
3463
3509
|
const name = keyName(key);
|
|
@@ -3545,10 +3591,10 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3545
3591
|
}
|
|
3546
3592
|
};
|
|
3547
3593
|
function refKeyText(node) {
|
|
3548
|
-
if (node.type ===
|
|
3594
|
+
if (node.type === import_utils28.AST_NODE_TYPES.BinaryExpression) {
|
|
3549
3595
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
3550
3596
|
}
|
|
3551
|
-
if (node.type ===
|
|
3597
|
+
if (node.type === import_utils28.AST_NODE_TYPES.SwitchStatement) {
|
|
3552
3598
|
return refKey(node.discriminant) ?? "value";
|
|
3553
3599
|
}
|
|
3554
3600
|
return "value";
|
|
@@ -3557,7 +3603,7 @@ var prefer_string_literal_union_default = import_utils26.ESLintUtils.RuleCreator
|
|
|
3557
3603
|
});
|
|
3558
3604
|
|
|
3559
3605
|
// src/rules/single-public-export.ts
|
|
3560
|
-
var
|
|
3606
|
+
var import_utils29 = require("@typescript-eslint/utils");
|
|
3561
3607
|
var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
|
|
3562
3608
|
"util",
|
|
3563
3609
|
"utils",
|
|
@@ -3591,12 +3637,12 @@ var kebabCase2 = (name) => {
|
|
|
3591
3637
|
}
|
|
3592
3638
|
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
3593
3639
|
};
|
|
3594
|
-
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);
|
|
3595
3641
|
var functionConstName = (decl) => {
|
|
3596
3642
|
if (decl.declarations.length !== 1) return null;
|
|
3597
3643
|
const [declarator] = decl.declarations;
|
|
3598
3644
|
if (declarator === void 0) return null;
|
|
3599
|
-
if (declarator.id.type !==
|
|
3645
|
+
if (declarator.id.type !== import_utils29.AST_NODE_TYPES.Identifier) return null;
|
|
3600
3646
|
if (!isFunctionExpression(declarator.init)) return null;
|
|
3601
3647
|
return declarator.id.name;
|
|
3602
3648
|
};
|
|
@@ -3610,20 +3656,20 @@ var summarizeExports = (body) => {
|
|
|
3610
3656
|
};
|
|
3611
3657
|
for (const statement of body) {
|
|
3612
3658
|
switch (statement.type) {
|
|
3613
|
-
case
|
|
3659
|
+
case import_utils29.AST_NODE_TYPES.ExportAllDeclaration:
|
|
3614
3660
|
hasReExport = true;
|
|
3615
3661
|
break;
|
|
3616
|
-
case
|
|
3662
|
+
case import_utils29.AST_NODE_TYPES.ExportDefaultDeclaration: {
|
|
3617
3663
|
names += 1;
|
|
3618
3664
|
const decl = statement.declaration;
|
|
3619
|
-
if (decl.type ===
|
|
3665
|
+
if (decl.type === import_utils29.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
|
|
3620
3666
|
candidate = { name: decl.id.name, node: statement };
|
|
3621
|
-
} else if (decl.type ===
|
|
3667
|
+
} else if (decl.type === import_utils29.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
|
|
3622
3668
|
candidate = { name: decl.id.name, node: statement };
|
|
3623
3669
|
}
|
|
3624
3670
|
break;
|
|
3625
3671
|
}
|
|
3626
|
-
case
|
|
3672
|
+
case import_utils29.AST_NODE_TYPES.ExportNamedDeclaration: {
|
|
3627
3673
|
if (statement.source !== null) {
|
|
3628
3674
|
hasReExport = true;
|
|
3629
3675
|
break;
|
|
@@ -3634,15 +3680,15 @@ var summarizeExports = (body) => {
|
|
|
3634
3680
|
break;
|
|
3635
3681
|
}
|
|
3636
3682
|
switch (decl.type) {
|
|
3637
|
-
case
|
|
3683
|
+
case import_utils29.AST_NODE_TYPES.FunctionDeclaration:
|
|
3638
3684
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3639
3685
|
else names += 1;
|
|
3640
3686
|
break;
|
|
3641
|
-
case
|
|
3687
|
+
case import_utils29.AST_NODE_TYPES.ClassDeclaration:
|
|
3642
3688
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3643
3689
|
else names += 1;
|
|
3644
3690
|
break;
|
|
3645
|
-
case
|
|
3691
|
+
case import_utils29.AST_NODE_TYPES.VariableDeclaration: {
|
|
3646
3692
|
const fnName = functionConstName(decl);
|
|
3647
3693
|
if (fnName !== null && decl.declarations.length === 1) {
|
|
3648
3694
|
addCandidate(fnName, statement);
|
|
@@ -3662,7 +3708,7 @@ var summarizeExports = (body) => {
|
|
|
3662
3708
|
}
|
|
3663
3709
|
return { names, hasReExport, candidate };
|
|
3664
3710
|
};
|
|
3665
|
-
var single_public_export_default =
|
|
3711
|
+
var single_public_export_default = import_utils29.ESLintUtils.RuleCreator(
|
|
3666
3712
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3667
3713
|
)({
|
|
3668
3714
|
name: "single-public-export",
|
|
@@ -3726,13 +3772,14 @@ var rules = {
|
|
|
3726
3772
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
3727
3773
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
3728
3774
|
"no-secret-in-log": no_secret_in_log_default,
|
|
3775
|
+
"no-unsafe-cast": no_unsafe_cast_default,
|
|
3729
3776
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
3730
3777
|
"single-public-export": single_public_export_default
|
|
3731
3778
|
};
|
|
3732
3779
|
var plugin = {
|
|
3733
3780
|
meta: {
|
|
3734
3781
|
name: "@sarj/eslint-plugin",
|
|
3735
|
-
version: "2.
|
|
3782
|
+
version: "2.5.0"
|
|
3736
3783
|
},
|
|
3737
3784
|
rules,
|
|
3738
3785
|
configs: {
|
|
@@ -3762,6 +3809,7 @@ var plugin = {
|
|
|
3762
3809
|
"@sarj/no-fat-try-blocks": "warn",
|
|
3763
3810
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
3764
3811
|
"@sarj/no-secret-in-log": "warn",
|
|
3812
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3765
3813
|
"@sarj/single-public-export": "warn",
|
|
3766
3814
|
"@sarj/prefer-string-literal-union": "warn"
|
|
3767
3815
|
}
|
|
@@ -3796,6 +3844,7 @@ var plugin = {
|
|
|
3796
3844
|
"@sarj/no-fat-try-blocks": "error",
|
|
3797
3845
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
3798
3846
|
"@sarj/no-secret-in-log": "error",
|
|
3847
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3799
3848
|
"@sarj/single-public-export": "error",
|
|
3800
3849
|
// High-volume/stylistic — warn until rollout proves FP rate.
|
|
3801
3850
|
"@sarj/prefer-string-literal-union": "warn"
|