eslint-plugin-reliability 3.1.3 → 3.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  ## [3.1.3] - 2026-05-03
2
2
 
3
+ ## 3.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#141](https://github.com/ofri-peretz/eslint/pull/141) [`38ab670`](https://github.com/ofri-peretz/eslint/commit/38ab670a0221684f4fd3d5dc3c05ddec7458ca2b) Thanks [@ofri-peretz](https://github.com/ofri-peretz)! - fix: remove false `meta.fixable: 'code'` declarations from 21 rules that had no `fix()` function
8
+
9
+ Rules that declared `fixable: 'code'` in their ESLint meta without an actual `fix()` implementation would show the ⚡ auto-fix icon in editors and CI formatters but apply no change when `--fix` was run. This patch removes the misleading declaration from:
10
+ - `browser-security/no-clickjacking`
11
+ - `import-next/first`, `named`, `no-barrel-import`, `no-import-module-exports`, `no-namespace`
12
+ - `node-security/no-buffer-overread`, `no-unsafe-dynamic-require`, `no-zip-slip`
13
+ - `react-features/react-no-inline-functions`
14
+ - `reliability/no-jsdoc-terminator-in-example` (uses `suggest`, not auto-fix; corrected to `hasSuggestions: true` only)
15
+ - `secure-coding/no-directive-injection`, `no-electron-security-issues`, `no-graphql-injection`, `no-improper-sanitization`, `no-improper-type-validation`, `no-ldap-injection`, `no-unchecked-loop-condition`, `no-unlimited-resource-allocation`, `no-weak-password-recovery`, `no-xpath-injection`
16
+
17
+ - [#143](https://github.com/ofri-peretz/eslint/pull/143) [`213cde1`](https://github.com/ofri-peretz/eslint/commit/213cde190ff2aea49ca7c1b533170940f879d9b4) Thanks [@ofri-peretz](https://github.com/ofri-peretz)! - fix(no-missing-null-checks): eliminate 53 false positives via three new narrowing patterns
18
+
19
+ Rules that were recognized as null guards are now correctly identified as safe:
20
+ 1. **Truthy if guard** — `if (obj) { obj.prop }` — direct truthy check proves non-null. Also covers chains: `if (response)` protects `response.data.items`.
21
+ 2. **Short-circuit AND** — `obj && obj.prop` — right side of `&&` only runs when left is truthy.
22
+ 3. **Ternary consequent** — `obj ? obj.prop : fallback` — truthy test guards the consequent.
23
+
24
+ Also: bumped `beforeAll` timeout to 30 seconds in 7 compatibility test files (`__compatibility__/*.spec.ts`). Native-addon packages routinely exceed the previous 10-second default on a cold ESM load.
25
+
26
+ - Updated dependencies [[`736a5fe`](https://github.com/ofri-peretz/eslint/commit/736a5fed47e673f6157ea900b29fe2a54e4bc7df)]:
27
+ - @interlace/eslint-devkit@1.4.1
28
+
3
29
  ### Bug Fixes
4
30
 
5
31
  - `no-missing-null-checks`: exempt provably-non-null identifiers (built-in singletons like `Math`, `JSON`, `console`, error classes; catch-clause params; constructor results; top-level imports) from the null-check requirement. Eliminates a large class of false positives without weakening real coverage.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="https://eslint.interlace.tools" target="blank"><img src="https://eslint.interlace.tools/eslint-interlace-logo-light.svg" alt="ESLint Interlace Logo" width="120" /></a>
2
+ <a href="https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability" target="blank"><img src="https://eslint.interlace.tools/eslint-interlace-logo-light.svg" alt="ESLint Interlace Logo" width="120" /></a>
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -14,6 +14,8 @@
14
14
  <a href="https://github.com/ofri-peretz/eslint" target="_blank"><img src="https://img.shields.io/badge/Since-Dec_2025-blue?logo=rocket&logoColor=white" alt="Since Dec 2025" /></a>
15
15
  </p>
16
16
 
17
+ > ⭐ If this plugin caught a real bug for you, [**star the repo**](https://github.com/ofri-peretz/eslint) — it's the signal that keeps these rules maintained.
18
+
17
19
  ## Description
18
20
 
19
21
  This plugin provides Reliability rules for defensive programming, error handling, and async correctness.
@@ -24,12 +26,12 @@ This plugin provides Reliability rules for defensive programming, error handling
24
26
 
25
27
  ## Getting Started
26
28
 
27
- - To check out the [guide](https://eslint.interlace.tools/docs/quality/plugin-reliability), visit [eslint.interlace.tools](https://eslint.interlace.tools). 📚
28
- - 要查看中文 [指南](https://eslint.interlace.tools/docs/quality/plugin-reliability), 请访问 [eslint.interlace.tools](https://eslint.interlace.tools). 📚
29
- - [가이드](https://eslint.interlace.tools/docs/quality/plugin-reliability) 문서는 [eslint.interlace.tools](https://eslint.interlace.tools)에서 확인하실 수 있습니다. 📚
30
- - [ガイド](https://eslint.interlace.tools/docs/quality/plugin-reliability)は [eslint.interlace.tools](https://eslint.interlace.tools)でご確認ください。 📚
31
- - Para ver la [guía](https://eslint.interlace.tools/docs/quality/plugin-reliability), visita [eslint.interlace.tools](https://eslint.interlace.tools). 📚
32
- - للاطلاع على [الدليل](https://eslint.interlace.tools/docs/quality/plugin-reliability)، قم بزيارة [eslint.interlace.tools](https://eslint.interlace.tools). 📚
29
+ - To check out the [guide](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability), visit [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability). 📚
30
+ - 要查看中文 [指南](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability), 请访问 [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability). 📚
31
+ - [가이드](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) 문서는 [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability)에서 확인하실 수 있습니다. 📚
32
+ - [ガイド](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability)は [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability)でご確認ください。 📚
33
+ - Para ver la [guía](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability), visita [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability). 📚
34
+ - للاطلاع على [الدليل](https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability)، قم بزيارة [eslint.interlace.tools](https://eslint.interlace.tools/?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability). 📚
33
35
 
34
36
  ```bash
35
37
  npm install eslint-plugin-reliability --save-dev
@@ -151,15 +153,15 @@ See the [ESLint Version Support Policy](../../docs/ESLINT_VERSION_SUPPORT.md)
151
153
  <!-- AUTO-GENERATED:RULES_TABLE:START - Do not edit manually -->
152
154
  | Rule | CWE | OWASP | CVSS | Description | 🧠 | 💼 | ⚠️ | 🔧 | 💡 | 🚫 |
153
155
  | :--- | :---: | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
154
- | [error-message](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/error-message) | | | | Enforce providing a message when creating built-in Error objects for better debugging. This rule is part of… | 🟢 | | | | 💡 | |
155
- | [no-await-in-loop](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-await-in-loop) | | | | Disallow await inside loops without considering concurrency implications | 🟢 | | | | 💡 | |
156
- | [no-jsdoc-terminator-in-example](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-jsdoc-terminator-in-example) | | | | Detect `*/` sequences inside JSDoc `@example` blocks that prematurely close the JSDoc comment. | 🟢 | | | | 💡 | |
157
- | [no-missing-error-context](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-error-context) | | | | ESLint Rule: no-missing-error-context with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | | | 💡 | |
158
- | [no-missing-null-checks](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-null-checks) | CWE-476 | | | ESLint Rule: no-missing-null-checks with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | ⚠️ | | 💡 | |
159
- | [no-silent-errors](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-silent-errors) | | | | ESLint Rule: no-silent-errors with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | ⚠️ | | 💡 | |
160
- | [no-unhandled-promise](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unhandled-promise) | CWE-1024 | | | Disallow unhandled Promise rejections with LLM-optimized suggestions for proper async error handling. This… | 🟢 | | | | 💡 | |
161
- | [no-unsafe-type-narrowing](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unsafe-type-narrowing) | | | | ESLint Rule: no-unsafe-type-narrowing with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | | | 💡 | |
162
- | [require-network-timeout](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/require-network-timeout) | | | | Require timeout configuration for network requests. This rule is part of eslint-plugin-reliability and prov… | 🟢 | 💼 | | | 💡 | |
156
+ | [error-message](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/error-message?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Enforce providing a message when creating built-in Error objects for better debugging. This rule is part of… | 🟢 | | | | 💡 | |
157
+ | [no-await-in-loop](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-await-in-loop?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Disallow await inside loops without considering concurrency implications | 🟢 | | | | 💡 | |
158
+ | [no-jsdoc-terminator-in-example](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-jsdoc-terminator-in-example?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Detect `*/` sequences inside JSDoc `@example` blocks that prematurely close the JSDoc comment. | 🟢 | | | | 💡 | |
159
+ | [no-missing-error-context](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-error-context?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-missing-error-context with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | | | 💡 | |
160
+ | [no-missing-null-checks](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-null-checks?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | CWE-476 | | | ESLint Rule: no-missing-null-checks with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | ⚠️ | | 💡 | |
161
+ | [no-silent-errors](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-silent-errors?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-silent-errors with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | ⚠️ | | 💡 | |
162
+ | [no-unhandled-promise](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unhandled-promise?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | CWE-1024 | | | Disallow unhandled Promise rejections with LLM-optimized suggestions for proper async error handling. This… | 🟢 | | | | 💡 | |
163
+ | [no-unsafe-type-narrowing](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unsafe-type-narrowing?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-unsafe-type-narrowing with LLM-optimized suggestions and auto-fix capabilities. | 🟢 | | | | 💡 | |
164
+ | [require-network-timeout](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/require-network-timeout?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Require timeout configuration for network requests. This rule is part of eslint-plugin-reliability and prov… | 🟢 | 💼 | | | 💡 | |
163
165
  <!-- AUTO-GENERATED:RULES_TABLE:END -->
164
166
  ## 🔗 Related ESLint Plugins
165
167
 
@@ -179,10 +181,19 @@ Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with L
179
181
  | [`eslint-plugin-vercel-ai-security`](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-vercel-ai-security.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | Vercel AI SDK security hardening. |
180
182
  | [`eslint-plugin-import-next`](https://www.npmjs.com/package/eslint-plugin-import-next) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-import-next.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-import-next) | Next-gen import sorting & architecture. |
181
183
 
184
+ <!-- INTERLACE:STAR_CTA:START -->
185
+ ## ⭐ Support & follow
186
+
187
+ If this plugin caught a real bug for you, **[star the repo](https://github.com/ofri-peretz/eslint)** — stars are the signal that keeps the Interlace ESLint ecosystem maintained — and **[follow the writeups on Dev.to](https://dev.to/ofri-peretz)** for the benchmarks and security research behind these rules.
188
+
189
+ [![GitHub stars](https://img.shields.io/github/stars/ofri-peretz/eslint?style=social)](https://github.com/ofri-peretz/eslint)
190
+
191
+ <!-- INTERLACE:STAR_CTA:END -->
192
+
182
193
  ## 📄 License
183
194
 
184
195
  MIT © [Ofri Peretz](https://github.com/ofri-peretz)
185
196
 
186
197
  <p align="center">
187
- <a href="https://eslint.interlace.tools/docs/quality/plugin-reliability"><img src="https://eslint.interlace.tools/images/og-reliability.png" alt="ESLint Interlace Plugin" width="100%" /></a>
198
+ <a href="https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability"><img src="https://eslint.interlace.tools/images/og-reliability.png" alt="ESLint Interlace Plugin" width="100%" /></a>
188
199
  </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-reliability",
3
- "version": "3.1.3",
3
+ "version": "3.1.4",
4
4
  "description": "ESLint rules for runtime stability, fault tolerance, and type safety.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -52,7 +52,7 @@
52
52
  "url": "https://github.com/ofri-peretz/eslint",
53
53
  "directory": "packages/eslint-plugin-reliability"
54
54
  },
55
- "homepage": "https://github.com/ofri-peretz/eslint/tree/main/packages/eslint-plugin-reliability#readme",
55
+ "homepage": "https://eslint.interlace.tools/docs/quality/plugin-reliability?utm_source=npm&utm_medium=referral&utm_campaign=eslint-plugin-reliability",
56
56
  "bugs": {
57
57
  "url": "https://github.com/ofri-peretz/eslint/issues"
58
58
  },
@@ -64,5 +64,9 @@
64
64
  },
65
65
  "peerDependencies": {
66
66
  "eslint": "^8.0.0 || ^9.0.0 || ^10.0.0"
67
+ },
68
+ "funding": {
69
+ "type": "github",
70
+ "url": "https://github.com/ofri-peretz/eslint"
67
71
  }
68
72
  }
package/src/index.d.ts CHANGED
@@ -189,7 +189,7 @@ export declare const configs: {
189
189
  };
190
190
  };
191
191
  rules: {
192
- 'reliability/no-silent-errors': "warn";
192
+ 'reliability/no-silent-errors': "error";
193
193
  'reliability/no-missing-null-checks': "warn";
194
194
  'reliability/require-network-timeout': "error";
195
195
  };
package/src/index.js CHANGED
@@ -41,7 +41,7 @@ exports.rules = {
41
41
  exports.plugin = {
42
42
  meta: {
43
43
  name: 'eslint-plugin-reliability',
44
- version: '3.1.3',
44
+ version: '3.1.4',
45
45
  },
46
46
  rules: exports.rules,
47
47
  };
@@ -51,7 +51,7 @@ exports.configs = {
51
51
  reliability: exports.plugin,
52
52
  },
53
53
  rules: {
54
- 'reliability/no-silent-errors': 'warn',
54
+ 'reliability/no-silent-errors': 'error',
55
55
  'reliability/no-missing-null-checks': 'warn',
56
56
  'reliability/require-network-timeout': 'error',
57
57
  },
@@ -63,7 +63,6 @@ exports.noJsdocTerminatorInExample = (0, eslint_devkit_1.createRule)({
63
63
  url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-jsdoc-terminator-in-example.md',
64
64
  description: 'Detects `*/` sequences inside JSDoc @example blocks that prematurely close the comment',
65
65
  },
66
- fixable: 'code',
67
66
  hasSuggestions: true,
68
67
  messages: {
69
68
  jsdocTerminatorInExample: (0, eslint_devkit_1.formatLLMMessage)({
@@ -137,20 +137,49 @@ function hasNullCheck(node, sourceCode) {
137
137
  // Check if parent is optional chaining
138
138
  const parent = node.parent;
139
139
  if (parent && parent.type === 'ChainExpression') {
140
- return true; // Optional chaining handles null/undefined
140
+ return true;
141
141
  }
142
142
  // Check if used with nullish coalescing
143
143
  if (usesNullishCoalescing(node)) {
144
144
  return true;
145
145
  }
146
- // Check for basic explicit null checks in if statements
147
- // This is a simplified check that looks for patterns like:
148
- // if (obj !== null) { obj.property; }
146
+ const objectText = sourceCode.getText(node.object);
147
+ // Short-circuit AND: `obj && obj.prop` the right side of && runs only
148
+ // when the left side is truthy, so obj is guaranteed non-null here.
149
+ // Walk up one level (CallExpression wraps MemberExpression for `obj && obj.method()`)
150
+ const immediateParent = parent;
151
+ const nodeOrCall = immediateParent?.type === 'CallExpression' &&
152
+ immediateParent.callee === node
153
+ ? immediateParent
154
+ : node;
155
+ const andParent = nodeOrCall
156
+ .parent;
157
+ if (andParent?.type === 'LogicalExpression' &&
158
+ andParent.operator === '&&' &&
159
+ andParent.right === nodeOrCall) {
160
+ const leftText = sourceCode.getText(andParent.left);
161
+ if (leftText === objectText || leftText.endsWith(objectText))
162
+ return true;
163
+ }
164
+ // Ternary consequent: `obj ? obj.prop : fallback` — the test being truthy
165
+ // guarantees obj is non-null before the consequent evaluates.
166
+ let cur = node;
167
+ for (let depth = 0; depth < 8; depth++) {
168
+ const p = cur.parent;
169
+ if (!p)
170
+ break;
171
+ if (p.type === 'ConditionalExpression' &&
172
+ p.consequent === cur) {
173
+ if (sourceCode.getText(p.test) === objectText) {
174
+ return true;
175
+ }
176
+ }
177
+ cur = p;
178
+ }
179
+ // Explicit null/truthy check in enclosing if statement
149
180
  if (hasExplicitNullCheck(node, sourceCode)) {
150
181
  return true;
151
182
  }
152
- // For more sophisticated null checking, we'd need control flow analysis
153
- // This is a simplified implementation that checks for basic patterns
154
183
  return false;
155
184
  }
156
185
  /**
@@ -180,7 +209,17 @@ function hasExplicitNullCheck(node, sourceCode) {
180
209
  * Check if a test expression is a null check for a specific object
181
210
  */
182
211
  function isNullCheckForObject(test, object, sourceCode) {
183
- // Handle binary expressions like obj !== null
212
+ const objectText = sourceCode.getText(object);
213
+ // Truthy check: `if (obj)` or `if (obj.prop)` — direct truthy guard proves
214
+ // non-null. Also covers nested chains: `if (response) { response.data.items }`
215
+ // because checking the root (response) implicitly protects the full chain.
216
+ if (test.type === 'Identifier' || test.type === 'MemberExpression') {
217
+ const testText = sourceCode.getText(test);
218
+ if (testText === objectText || objectText.startsWith(testText + '.')) {
219
+ return true;
220
+ }
221
+ }
222
+ // Handle binary expressions like obj !== null, obj != undefined
184
223
  if (test.type === 'BinaryExpression') {
185
224
  const { left, right, operator } = test;
186
225
  if (operator === '!==' ||
@@ -189,8 +228,6 @@ function isNullCheckForObject(test, object, sourceCode) {
189
228
  operator === '==') {
190
229
  const leftText = sourceCode.getText(left);
191
230
  const rightText = sourceCode.getText(right);
192
- const objectText = sourceCode.getText(object);
193
- // Check if one side matches our object and the other is null/undefined
194
231
  if ((leftText === objectText &&
195
232
  (rightText === 'null' || rightText === 'undefined')) ||
196
233
  (rightText === objectText &&
@@ -204,6 +241,8 @@ function isNullCheckForObject(test, object, sourceCode) {
204
241
  return (isNullCheckForObject(test.left, object, sourceCode) ||
205
242
  isNullCheckForObject(test.right, object, sourceCode));
206
243
  }
244
+ // Unary negation: `if (!obj)` is a FALSY guard — only safe when paired
245
+ // with early return, which requires control-flow analysis. Skip for now.
207
246
  return false;
208
247
  }
209
248
  /**