eslint-plugin-reliability 3.1.9 → 3.1.11
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 -1
- package/package.json +2 -3
- package/src/index.js +1 -52
- package/src/lib/eslint-plugin-reliability.js +1 -6
- package/src/oxlint.js +1 -3
- package/src/rules/error-handling/error-message.js +1 -131
- package/src/rules/error-handling/no-missing-error-context.js +1 -180
- package/src/rules/error-handling/no-silent-errors.js +1 -157
- package/src/rules/error-handling/no-unhandled-promise.js +1 -321
- package/src/rules/reliability/no-await-in-loop.js +1 -218
- package/src/rules/reliability/no-jsdoc-terminator-in-example.js +1 -109
- package/src/rules/reliability/no-missing-null-checks.js +1 -413
- package/src/rules/reliability/no-unsafe-type-narrowing.js +1 -155
- package/src/rules/reliability/require-network-timeout.js +1 -50
|
@@ -1,155 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noUnsafeTypeNarrowing = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
function isUnsafeTypeAssertion(node) {
|
|
7
|
-
if (node.expression.type === 'TSAsExpression') {
|
|
8
|
-
const innerAssertion = node.expression;
|
|
9
|
-
if (innerAssertion.typeAnnotation.type === 'TSUnknownKeyword') {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
if (innerAssertion.typeAnnotation.type === 'TSAnyKeyword') {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
function hasExplanatoryComment(node, sourceCode) {
|
|
19
|
-
const comments = sourceCode.getAllComments();
|
|
20
|
-
const nodeStart = node.loc?.start;
|
|
21
|
-
if (!nodeStart || !comments.length) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const explanatoryPatterns = [
|
|
25
|
-
/type.?guard/i,
|
|
26
|
-
/validated/i,
|
|
27
|
-
/checked/i,
|
|
28
|
-
/safe/i,
|
|
29
|
-
/known/i,
|
|
30
|
-
/intentional/i,
|
|
31
|
-
/necessary/i,
|
|
32
|
-
/framework/i,
|
|
33
|
-
/library/i,
|
|
34
|
-
/third.?party/i,
|
|
35
|
-
/legacy/i,
|
|
36
|
-
/todo/i,
|
|
37
|
-
/fixme/i,
|
|
38
|
-
];
|
|
39
|
-
for (const comment of comments) {
|
|
40
|
-
if (comment.loc && nodeStart.line - comment.loc.end.line <= 1) {
|
|
41
|
-
const commentText = comment.value.toLowerCase();
|
|
42
|
-
if (explanatoryPatterns.some((pattern) => pattern.test(commentText))) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
exports.noUnsafeTypeNarrowing = (0, eslint_devkit_2.createRule)({
|
|
50
|
-
name: 'no-unsafe-type-narrowing',
|
|
51
|
-
meta: {
|
|
52
|
-
type: 'problem',
|
|
53
|
-
docs: {
|
|
54
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-unsafe-type-narrowing.md',
|
|
55
|
-
description: 'Detects unsafe type narrowing patterns',
|
|
56
|
-
},
|
|
57
|
-
hasSuggestions: true,
|
|
58
|
-
messages: {
|
|
59
|
-
unsafeTypeNarrowing: (0, eslint_devkit_1.formatLLMMessage)({
|
|
60
|
-
icon: eslint_devkit_1.MessageIcons.WARNING,
|
|
61
|
-
issueName: 'Unsafe type narrowing',
|
|
62
|
-
description: 'Unsafe type assertion or narrowing detected',
|
|
63
|
-
severity: 'MEDIUM',
|
|
64
|
-
fix: 'Use type guards or proper validation before type assertion',
|
|
65
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-4326/',
|
|
66
|
-
}),
|
|
67
|
-
useTypeGuard: (0, eslint_devkit_1.formatLLMMessage)({
|
|
68
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
69
|
-
issueName: 'Use Type Guard',
|
|
70
|
-
description: 'Use type guard function',
|
|
71
|
-
severity: 'LOW',
|
|
72
|
-
fix: 'function isType(value: unknown): value is Type { return ... }',
|
|
73
|
-
documentationLink: 'https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates',
|
|
74
|
-
}),
|
|
75
|
-
useProperNarrowing: (0, eslint_devkit_1.formatLLMMessage)({
|
|
76
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
77
|
-
issueName: 'Use Type Narrowing',
|
|
78
|
-
description: 'Use proper type narrowing',
|
|
79
|
-
severity: 'LOW',
|
|
80
|
-
fix: 'if (typeof value === "string") { ... }',
|
|
81
|
-
documentationLink: 'https://www.typescriptlang.org/docs/handbook/2/narrowing.html',
|
|
82
|
-
}),
|
|
83
|
-
validateBeforeAssert: (0, eslint_devkit_1.formatLLMMessage)({
|
|
84
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
85
|
-
issueName: 'Validate First',
|
|
86
|
-
description: 'Validate before type assertion',
|
|
87
|
-
severity: 'LOW',
|
|
88
|
-
fix: 'if (isValid(value)) { const typed = value as Type; }',
|
|
89
|
-
documentationLink: 'https://www.typescriptlang.org/docs/handbook/2/narrowing.html',
|
|
90
|
-
}),
|
|
91
|
-
},
|
|
92
|
-
schema: [
|
|
93
|
-
{
|
|
94
|
-
type: 'object',
|
|
95
|
-
properties: {
|
|
96
|
-
ignoreInTests: {
|
|
97
|
-
type: 'boolean',
|
|
98
|
-
default: true,
|
|
99
|
-
description: 'Ignore in test files',
|
|
100
|
-
},
|
|
101
|
-
allowWithComment: {
|
|
102
|
-
type: 'boolean',
|
|
103
|
-
default: false,
|
|
104
|
-
description: 'Allow type assertions with comments',
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
additionalProperties: false,
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
},
|
|
111
|
-
defaultOptions: [
|
|
112
|
-
{
|
|
113
|
-
ignoreInTests: true,
|
|
114
|
-
allowWithComment: false,
|
|
115
|
-
},
|
|
116
|
-
],
|
|
117
|
-
create(context, [options = {}]) {
|
|
118
|
-
const { ignoreInTests = true, allowWithComment = false } = options || {};
|
|
119
|
-
const filename = context.filename;
|
|
120
|
-
const isTestFile = ignoreInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
|
|
121
|
-
if (isTestFile) {
|
|
122
|
-
return {};
|
|
123
|
-
}
|
|
124
|
-
const sourceCode = context.sourceCode;
|
|
125
|
-
function checkTypeAssertion(node) {
|
|
126
|
-
if (!isUnsafeTypeAssertion(node)) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if (allowWithComment && hasExplanatoryComment(node, sourceCode)) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
context.report({
|
|
133
|
-
node,
|
|
134
|
-
messageId: 'unsafeTypeNarrowing',
|
|
135
|
-
suggest: [
|
|
136
|
-
{
|
|
137
|
-
messageId: 'useTypeGuard',
|
|
138
|
-
fix: () => null,
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
messageId: 'useProperNarrowing',
|
|
142
|
-
fix: () => null,
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
messageId: 'validateBeforeAssert',
|
|
146
|
-
fix: () => null,
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
TSAsExpression: checkTypeAssertion,
|
|
153
|
-
};
|
|
154
|
-
},
|
|
155
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noUnsafeTypeNarrowing=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");function isUnsafeTypeAssertion(node){if(node.expression.type==="TSAsExpression"){const innerAssertion=node.expression;if(innerAssertion.typeAnnotation.type==="TSUnknownKeyword"){return true}if(innerAssertion.typeAnnotation.type==="TSAnyKeyword"){return true}}return false}function hasExplanatoryComment(node,sourceCode){const comments=sourceCode.getAllComments();const nodeStart=node.loc?.start;if(!nodeStart||!comments.length){return false}const explanatoryPatterns=[/type.?guard/i,/validated/i,/checked/i,/safe/i,/known/i,/intentional/i,/necessary/i,/framework/i,/library/i,/third.?party/i,/legacy/i,/todo/i,/fixme/i];for(const comment of comments){if(comment.loc&&nodeStart.line-comment.loc.end.line<=1){const commentText=comment.value.toLowerCase();if(explanatoryPatterns.some(pattern=>pattern.test(commentText))){return true}}}return false}exports.noUnsafeTypeNarrowing=(0,eslint_devkit_2.createRule)({name:"no-unsafe-type-narrowing",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-unsafe-type-narrowing.md",description:"Detects unsafe type narrowing patterns"},hasSuggestions:true,messages:{unsafeTypeNarrowing:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.WARNING,issueName:"Unsafe type narrowing",description:"Unsafe type assertion or narrowing detected",severity:"MEDIUM",fix:"Use type guards or proper validation before type assertion",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-4326/"}),useTypeGuard:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Type Guard",description:"Use type guard function",severity:"LOW",fix:"function isType(value: unknown): value is Type { return ... }",documentationLink:"https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates"}),useProperNarrowing:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Type Narrowing",description:"Use proper type narrowing",severity:"LOW",fix:'if (typeof value === "string") { ... }',documentationLink:"https://www.typescriptlang.org/docs/handbook/2/narrowing.html"}),validateBeforeAssert:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Validate First",description:"Validate before type assertion",severity:"LOW",fix:"if (isValid(value)) { const typed = value as Type; }",documentationLink:"https://www.typescriptlang.org/docs/handbook/2/narrowing.html"})},schema:[{type:"object",properties:{ignoreInTests:{type:"boolean",default:true,description:"Ignore in test files"},allowWithComment:{type:"boolean",default:false,description:"Allow type assertions with comments"}},additionalProperties:false}]},defaultOptions:[{ignoreInTests:true,allowWithComment:false}],create(context,[options={}]){const{ignoreInTests=true,allowWithComment=false}=options||{};const filename=context.filename;const isTestFile=ignoreInTests&&/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);if(isTestFile){return{}}const sourceCode=context.sourceCode;function checkTypeAssertion(node){if(!isUnsafeTypeAssertion(node)){return}if(allowWithComment&&hasExplanatoryComment(node,sourceCode)){return}context.report({node,messageId:"unsafeTypeNarrowing",suggest:[{messageId:"useTypeGuard",fix:()=>null},{messageId:"useProperNarrowing",fix:()=>null},{messageId:"validateBeforeAssert",fix:()=>null}]})}return{TSAsExpression:checkTypeAssertion}}});
|
|
@@ -1,50 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.requireNetworkTimeout = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
exports.requireNetworkTimeout = (0, eslint_devkit_1.createRule)({
|
|
6
|
-
name: 'require-network-timeout',
|
|
7
|
-
meta: {
|
|
8
|
-
type: 'problem',
|
|
9
|
-
docs: {
|
|
10
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/require-network-timeout.md',
|
|
11
|
-
description: 'Require timeout limits for network requests',
|
|
12
|
-
cwe: 'CWE-400',
|
|
13
|
-
cvss: 5,
|
|
14
|
-
},
|
|
15
|
-
messages: {
|
|
16
|
-
violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_1.MessageIcons.SECURITY,
|
|
18
|
-
issueName: 'violation Detected',
|
|
19
|
-
cwe: 'CWE-400',
|
|
20
|
-
description: 'Require timeout limits for network requests detected - fetch/axios without timeout option',
|
|
21
|
-
severity: 'MEDIUM',
|
|
22
|
-
fix: 'Review and apply secure practices',
|
|
23
|
-
documentationLink: 'https://cwe.mitre.org/data/definitions/400.html',
|
|
24
|
-
}),
|
|
25
|
-
},
|
|
26
|
-
schema: [],
|
|
27
|
-
},
|
|
28
|
-
defaultOptions: [],
|
|
29
|
-
create(context) {
|
|
30
|
-
return {
|
|
31
|
-
CallExpression(node) {
|
|
32
|
-
const callee = node.callee;
|
|
33
|
-
const isFetch = callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier && callee.name === 'fetch';
|
|
34
|
-
const isAxios = callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
|
|
35
|
-
callee.object.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
36
|
-
callee.object.name === 'axios';
|
|
37
|
-
if (isFetch || isAxios) {
|
|
38
|
-
const optionsArg = node.arguments[1];
|
|
39
|
-
const hasBound = optionsArg?.type === eslint_devkit_1.AST_NODE_TYPES.ObjectExpression &&
|
|
40
|
-
optionsArg.properties.some((p) => p.type === eslint_devkit_1.AST_NODE_TYPES.Property &&
|
|
41
|
-
p.key.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
42
|
-
(p.key.name === 'timeout' || p.key.name === 'signal'));
|
|
43
|
-
if (!hasBound) {
|
|
44
|
-
context.report({ node, messageId: 'violationDetected' });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
},
|
|
50
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireNetworkTimeout=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.requireNetworkTimeout=(0,eslint_devkit_1.createRule)({name:"require-network-timeout",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/require-network-timeout.md",description:"Require timeout limits for network requests",cwe:"CWE-400",cvss:5},messages:{violationDetected:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"violation Detected",cwe:"CWE-400",description:"Require timeout limits for network requests detected - fetch/axios without timeout option",severity:"MEDIUM",fix:"Review and apply secure practices",documentationLink:"https://cwe.mitre.org/data/definitions/400.html"})},schema:[]},defaultOptions:[],create(context){return{CallExpression(node){const callee=node.callee;const isFetch=callee.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&callee.name==="fetch";const isAxios=callee.type===eslint_devkit_1.AST_NODE_TYPES.MemberExpression&&callee.object.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&callee.object.name==="axios";if(isFetch||isAxios){const optionsArg=node.arguments[1];const hasBound=optionsArg?.type===eslint_devkit_1.AST_NODE_TYPES.ObjectExpression&&optionsArg.properties.some(p=>p.type===eslint_devkit_1.AST_NODE_TYPES.Property&&p.key.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&(p.key.name==="timeout"||p.key.name==="signal"));if(!hasBound){context.report({node,messageId:"violationDetected"})}}}}}});
|