@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.d.cts
CHANGED
|
@@ -72,6 +72,9 @@ declare const rules: {
|
|
|
72
72
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
73
73
|
name: string;
|
|
74
74
|
};
|
|
75
|
+
"no-unsafe-cast": _typescript_eslint_utils_ts_eslint.RuleModule<"asAny" | "doubleCast", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
|
+
name: string;
|
|
77
|
+
};
|
|
75
78
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
79
|
name: string;
|
|
77
80
|
};
|
|
@@ -156,6 +159,9 @@ declare const plugin: {
|
|
|
156
159
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
157
160
|
name: string;
|
|
158
161
|
};
|
|
162
|
+
"no-unsafe-cast": _typescript_eslint_utils_ts_eslint.RuleModule<"asAny" | "doubleCast", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
163
|
+
name: string;
|
|
164
|
+
};
|
|
159
165
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
160
166
|
name: string;
|
|
161
167
|
};
|
|
@@ -187,6 +193,7 @@ declare const plugin: {
|
|
|
187
193
|
"@sarj/no-fat-try-blocks": string;
|
|
188
194
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
189
195
|
"@sarj/no-secret-in-log": string;
|
|
196
|
+
"@sarj/no-unsafe-cast": string;
|
|
190
197
|
"@sarj/single-public-export": string;
|
|
191
198
|
"@sarj/prefer-string-literal-union": string;
|
|
192
199
|
};
|
|
@@ -217,6 +224,7 @@ declare const plugin: {
|
|
|
217
224
|
"@sarj/no-fat-try-blocks": string;
|
|
218
225
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
219
226
|
"@sarj/no-secret-in-log": string;
|
|
227
|
+
"@sarj/no-unsafe-cast": string;
|
|
220
228
|
"@sarj/single-public-export": string;
|
|
221
229
|
"@sarj/prefer-string-literal-union": string;
|
|
222
230
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,9 @@ declare const rules: {
|
|
|
72
72
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
73
73
|
name: string;
|
|
74
74
|
};
|
|
75
|
+
"no-unsafe-cast": _typescript_eslint_utils_ts_eslint.RuleModule<"asAny" | "doubleCast", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
|
+
name: string;
|
|
77
|
+
};
|
|
75
78
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
79
|
name: string;
|
|
77
80
|
};
|
|
@@ -156,6 +159,9 @@ declare const plugin: {
|
|
|
156
159
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
157
160
|
name: string;
|
|
158
161
|
};
|
|
162
|
+
"no-unsafe-cast": _typescript_eslint_utils_ts_eslint.RuleModule<"asAny" | "doubleCast", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
163
|
+
name: string;
|
|
164
|
+
};
|
|
159
165
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
160
166
|
name: string;
|
|
161
167
|
};
|
|
@@ -187,6 +193,7 @@ declare const plugin: {
|
|
|
187
193
|
"@sarj/no-fat-try-blocks": string;
|
|
188
194
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
189
195
|
"@sarj/no-secret-in-log": string;
|
|
196
|
+
"@sarj/no-unsafe-cast": string;
|
|
190
197
|
"@sarj/single-public-export": string;
|
|
191
198
|
"@sarj/prefer-string-literal-union": string;
|
|
192
199
|
};
|
|
@@ -217,6 +224,7 @@ declare const plugin: {
|
|
|
217
224
|
"@sarj/no-fat-try-blocks": string;
|
|
218
225
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
219
226
|
"@sarj/no-secret-in-log": string;
|
|
227
|
+
"@sarj/no-unsafe-cast": string;
|
|
220
228
|
"@sarj/single-public-export": string;
|
|
221
229
|
"@sarj/prefer-string-literal-union": string;
|
|
222
230
|
};
|
package/dist/index.js
CHANGED
|
@@ -3230,10 +3230,56 @@ var no_secret_in_log_default = ESLintUtils23.RuleCreator(
|
|
|
3230
3230
|
}
|
|
3231
3231
|
});
|
|
3232
3232
|
|
|
3233
|
+
// src/rules/no-unsafe-cast.ts
|
|
3234
|
+
import { ESLintUtils as ESLintUtils24 } from "@typescript-eslint/utils";
|
|
3235
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
3236
|
+
function isAnyAnnotation(node) {
|
|
3237
|
+
return node.type === AST_NODE_TYPES13.TSAnyKeyword;
|
|
3238
|
+
}
|
|
3239
|
+
function isConstAssertion(typeAnnotation) {
|
|
3240
|
+
return typeAnnotation.type === AST_NODE_TYPES13.TSTypeReference && typeAnnotation.typeName.type === AST_NODE_TYPES13.Identifier && typeAnnotation.typeName.name === "const";
|
|
3241
|
+
}
|
|
3242
|
+
var no_unsafe_cast_default = ESLintUtils24.RuleCreator(
|
|
3243
|
+
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3244
|
+
)({
|
|
3245
|
+
name: "no-unsafe-cast",
|
|
3246
|
+
meta: {
|
|
3247
|
+
type: "problem",
|
|
3248
|
+
docs: {
|
|
3249
|
+
description: "Disallow `as any`/`<any>` casts and `as unknown as T` double-casts, which fully disable type checking."
|
|
3250
|
+
},
|
|
3251
|
+
schema: [],
|
|
3252
|
+
messages: {
|
|
3253
|
+
asAny: "`as any` disables type checking on this value. Narrow with a type guard, model the shape, or cast to a specific type instead.",
|
|
3254
|
+
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."
|
|
3255
|
+
}
|
|
3256
|
+
},
|
|
3257
|
+
defaultOptions: [],
|
|
3258
|
+
create(context) {
|
|
3259
|
+
function checkAssertion(node) {
|
|
3260
|
+
if (isConstAssertion(node.typeAnnotation)) {
|
|
3261
|
+
return;
|
|
3262
|
+
}
|
|
3263
|
+
if (isAnyAnnotation(node.typeAnnotation)) {
|
|
3264
|
+
context.report({ node, messageId: "asAny" });
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3267
|
+
const inner = node.expression;
|
|
3268
|
+
if (inner.type === AST_NODE_TYPES13.TSAsExpression || inner.type === AST_NODE_TYPES13.TSTypeAssertion) {
|
|
3269
|
+
context.report({ node, messageId: "doubleCast" });
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
return {
|
|
3273
|
+
TSAsExpression: checkAssertion,
|
|
3274
|
+
TSTypeAssertion: checkAssertion
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
});
|
|
3278
|
+
|
|
3233
3279
|
// src/rules/prefer-string-literal-union.ts
|
|
3234
3280
|
import {
|
|
3235
|
-
ESLintUtils as
|
|
3236
|
-
AST_NODE_TYPES as
|
|
3281
|
+
ESLintUtils as ESLintUtils25,
|
|
3282
|
+
AST_NODE_TYPES as AST_NODE_TYPES14
|
|
3237
3283
|
} from "@typescript-eslint/utils";
|
|
3238
3284
|
import * as ts from "typescript";
|
|
3239
3285
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -3277,19 +3323,19 @@ function isChoiceLikeName(name) {
|
|
|
3277
3323
|
return CHOICE_TOKENS.has(lastWord(name));
|
|
3278
3324
|
}
|
|
3279
3325
|
function keyName(key) {
|
|
3280
|
-
if (key.type ===
|
|
3326
|
+
if (key.type === AST_NODE_TYPES14.Identifier) {
|
|
3281
3327
|
return key.name;
|
|
3282
3328
|
}
|
|
3283
|
-
if (key.type ===
|
|
3329
|
+
if (key.type === AST_NODE_TYPES14.Literal && typeof key.value === "string") {
|
|
3284
3330
|
return key.value;
|
|
3285
3331
|
}
|
|
3286
3332
|
return null;
|
|
3287
3333
|
}
|
|
3288
3334
|
function isStringLiteralMember(t) {
|
|
3289
|
-
return t.type ===
|
|
3335
|
+
return t.type === AST_NODE_TYPES14.TSLiteralType && t.literal.type === AST_NODE_TYPES14.Literal && typeof t.literal.value === "string";
|
|
3290
3336
|
}
|
|
3291
3337
|
function isStringLiteralUnion(node) {
|
|
3292
|
-
if (node?.type !==
|
|
3338
|
+
if (node?.type !== AST_NODE_TYPES14.TSUnionType) {
|
|
3293
3339
|
return false;
|
|
3294
3340
|
}
|
|
3295
3341
|
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
@@ -3318,12 +3364,12 @@ function bindingSourceExpression(decl) {
|
|
|
3318
3364
|
return ts.isForOfStatement(node) ? node.expression : node.initializer;
|
|
3319
3365
|
}
|
|
3320
3366
|
function refKey(node) {
|
|
3321
|
-
if (node.type ===
|
|
3367
|
+
if (node.type === AST_NODE_TYPES14.Identifier) {
|
|
3322
3368
|
return node.name;
|
|
3323
3369
|
}
|
|
3324
|
-
if (node.type ===
|
|
3370
|
+
if (node.type === AST_NODE_TYPES14.MemberExpression && !node.computed) {
|
|
3325
3371
|
const inner = refKey(node.object);
|
|
3326
|
-
if (inner === null || node.property.type !==
|
|
3372
|
+
if (inner === null || node.property.type !== AST_NODE_TYPES14.Identifier) {
|
|
3327
3373
|
return null;
|
|
3328
3374
|
}
|
|
3329
3375
|
return `${inner}.${node.property.name}`;
|
|
@@ -3331,12 +3377,12 @@ function refKey(node) {
|
|
|
3331
3377
|
return null;
|
|
3332
3378
|
}
|
|
3333
3379
|
function strLiteral(node) {
|
|
3334
|
-
if (node.type ===
|
|
3380
|
+
if (node.type === AST_NODE_TYPES14.Literal && typeof node.value === "string") {
|
|
3335
3381
|
return node.value;
|
|
3336
3382
|
}
|
|
3337
3383
|
return null;
|
|
3338
3384
|
}
|
|
3339
|
-
var prefer_string_literal_union_default =
|
|
3385
|
+
var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
3340
3386
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3341
3387
|
)({
|
|
3342
3388
|
name: "prefer-string-literal-union",
|
|
@@ -3360,7 +3406,7 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
|
|
|
3360
3406
|
}
|
|
3361
3407
|
let services;
|
|
3362
3408
|
try {
|
|
3363
|
-
services =
|
|
3409
|
+
services = ESLintUtils25.getParserServices(context);
|
|
3364
3410
|
} catch {
|
|
3365
3411
|
services = null;
|
|
3366
3412
|
}
|
|
@@ -3444,7 +3490,7 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
|
|
|
3444
3490
|
containersWithUnion.add(container);
|
|
3445
3491
|
return;
|
|
3446
3492
|
}
|
|
3447
|
-
if (typeNode?.type !==
|
|
3493
|
+
if (typeNode?.type !== AST_NODE_TYPES14.TSStringKeyword) {
|
|
3448
3494
|
return;
|
|
3449
3495
|
}
|
|
3450
3496
|
const name = keyName(key);
|
|
@@ -3532,10 +3578,10 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
|
|
|
3532
3578
|
}
|
|
3533
3579
|
};
|
|
3534
3580
|
function refKeyText(node) {
|
|
3535
|
-
if (node.type ===
|
|
3581
|
+
if (node.type === AST_NODE_TYPES14.BinaryExpression) {
|
|
3536
3582
|
return refKey(node.left) ?? refKey(node.right) ?? "value";
|
|
3537
3583
|
}
|
|
3538
|
-
if (node.type ===
|
|
3584
|
+
if (node.type === AST_NODE_TYPES14.SwitchStatement) {
|
|
3539
3585
|
return refKey(node.discriminant) ?? "value";
|
|
3540
3586
|
}
|
|
3541
3587
|
return "value";
|
|
@@ -3544,7 +3590,7 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
|
|
|
3544
3590
|
});
|
|
3545
3591
|
|
|
3546
3592
|
// src/rules/single-public-export.ts
|
|
3547
|
-
import { ESLintUtils as
|
|
3593
|
+
import { ESLintUtils as ESLintUtils26, AST_NODE_TYPES as AST_NODE_TYPES15 } from "@typescript-eslint/utils";
|
|
3548
3594
|
var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
|
|
3549
3595
|
"util",
|
|
3550
3596
|
"utils",
|
|
@@ -3578,12 +3624,12 @@ var kebabCase2 = (name) => {
|
|
|
3578
3624
|
}
|
|
3579
3625
|
return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
|
|
3580
3626
|
};
|
|
3581
|
-
var isFunctionExpression = (node) => node !== null && (node.type ===
|
|
3627
|
+
var isFunctionExpression = (node) => node !== null && (node.type === AST_NODE_TYPES15.ArrowFunctionExpression || node.type === AST_NODE_TYPES15.FunctionExpression);
|
|
3582
3628
|
var functionConstName = (decl) => {
|
|
3583
3629
|
if (decl.declarations.length !== 1) return null;
|
|
3584
3630
|
const [declarator] = decl.declarations;
|
|
3585
3631
|
if (declarator === void 0) return null;
|
|
3586
|
-
if (declarator.id.type !==
|
|
3632
|
+
if (declarator.id.type !== AST_NODE_TYPES15.Identifier) return null;
|
|
3587
3633
|
if (!isFunctionExpression(declarator.init)) return null;
|
|
3588
3634
|
return declarator.id.name;
|
|
3589
3635
|
};
|
|
@@ -3597,20 +3643,20 @@ var summarizeExports = (body) => {
|
|
|
3597
3643
|
};
|
|
3598
3644
|
for (const statement of body) {
|
|
3599
3645
|
switch (statement.type) {
|
|
3600
|
-
case
|
|
3646
|
+
case AST_NODE_TYPES15.ExportAllDeclaration:
|
|
3601
3647
|
hasReExport = true;
|
|
3602
3648
|
break;
|
|
3603
|
-
case
|
|
3649
|
+
case AST_NODE_TYPES15.ExportDefaultDeclaration: {
|
|
3604
3650
|
names += 1;
|
|
3605
3651
|
const decl = statement.declaration;
|
|
3606
|
-
if (decl.type ===
|
|
3652
|
+
if (decl.type === AST_NODE_TYPES15.FunctionDeclaration && decl.id !== null) {
|
|
3607
3653
|
candidate = { name: decl.id.name, node: statement };
|
|
3608
|
-
} else if (decl.type ===
|
|
3654
|
+
} else if (decl.type === AST_NODE_TYPES15.ClassDeclaration && decl.id !== null) {
|
|
3609
3655
|
candidate = { name: decl.id.name, node: statement };
|
|
3610
3656
|
}
|
|
3611
3657
|
break;
|
|
3612
3658
|
}
|
|
3613
|
-
case
|
|
3659
|
+
case AST_NODE_TYPES15.ExportNamedDeclaration: {
|
|
3614
3660
|
if (statement.source !== null) {
|
|
3615
3661
|
hasReExport = true;
|
|
3616
3662
|
break;
|
|
@@ -3621,15 +3667,15 @@ var summarizeExports = (body) => {
|
|
|
3621
3667
|
break;
|
|
3622
3668
|
}
|
|
3623
3669
|
switch (decl.type) {
|
|
3624
|
-
case
|
|
3670
|
+
case AST_NODE_TYPES15.FunctionDeclaration:
|
|
3625
3671
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3626
3672
|
else names += 1;
|
|
3627
3673
|
break;
|
|
3628
|
-
case
|
|
3674
|
+
case AST_NODE_TYPES15.ClassDeclaration:
|
|
3629
3675
|
if (decl.id !== null) addCandidate(decl.id.name, statement);
|
|
3630
3676
|
else names += 1;
|
|
3631
3677
|
break;
|
|
3632
|
-
case
|
|
3678
|
+
case AST_NODE_TYPES15.VariableDeclaration: {
|
|
3633
3679
|
const fnName = functionConstName(decl);
|
|
3634
3680
|
if (fnName !== null && decl.declarations.length === 1) {
|
|
3635
3681
|
addCandidate(fnName, statement);
|
|
@@ -3649,7 +3695,7 @@ var summarizeExports = (body) => {
|
|
|
3649
3695
|
}
|
|
3650
3696
|
return { names, hasReExport, candidate };
|
|
3651
3697
|
};
|
|
3652
|
-
var single_public_export_default =
|
|
3698
|
+
var single_public_export_default = ESLintUtils26.RuleCreator(
|
|
3653
3699
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3654
3700
|
)({
|
|
3655
3701
|
name: "single-public-export",
|
|
@@ -3713,13 +3759,14 @@ var rules = {
|
|
|
3713
3759
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
3714
3760
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
3715
3761
|
"no-secret-in-log": no_secret_in_log_default,
|
|
3762
|
+
"no-unsafe-cast": no_unsafe_cast_default,
|
|
3716
3763
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
3717
3764
|
"single-public-export": single_public_export_default
|
|
3718
3765
|
};
|
|
3719
3766
|
var plugin = {
|
|
3720
3767
|
meta: {
|
|
3721
3768
|
name: "@sarj/eslint-plugin",
|
|
3722
|
-
version: "2.
|
|
3769
|
+
version: "2.5.0"
|
|
3723
3770
|
},
|
|
3724
3771
|
rules,
|
|
3725
3772
|
configs: {
|
|
@@ -3749,6 +3796,7 @@ var plugin = {
|
|
|
3749
3796
|
"@sarj/no-fat-try-blocks": "warn",
|
|
3750
3797
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
3751
3798
|
"@sarj/no-secret-in-log": "warn",
|
|
3799
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3752
3800
|
"@sarj/single-public-export": "warn",
|
|
3753
3801
|
"@sarj/prefer-string-literal-union": "warn"
|
|
3754
3802
|
}
|
|
@@ -3783,6 +3831,7 @@ var plugin = {
|
|
|
3783
3831
|
"@sarj/no-fat-try-blocks": "error",
|
|
3784
3832
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
3785
3833
|
"@sarj/no-secret-in-log": "error",
|
|
3834
|
+
"@sarj/no-unsafe-cast": "warn",
|
|
3786
3835
|
"@sarj/single-public-export": "error",
|
|
3787
3836
|
// High-volume/stylistic — warn until rollout proves FP rate.
|
|
3788
3837
|
"@sarj/prefer-string-literal-union": "warn"
|