@sarj/eslint-plugin 6.0.0 → 7.0.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/README.md CHANGED
@@ -12,10 +12,37 @@ import sarj from "@sarj/eslint-plugin";
12
12
  export default [...sarj.configs.recommended];
13
13
  ```
14
14
 
15
- 51 rules. Each rule's source under `src/rules/` carries its own `@fileoverview` rationale plus `meta.docs.description` + `meta.messages` — read the file for the full reasoning, including the false positives it deliberately does not fire on.
15
+ 51 rules. Each rule's source under `src/rules/` opens with a one-line claim and
16
+ two links: its tests, which are the examples, and `docs/rules/<rule>.md`, which
17
+ holds the measurements, the false-positive family behind every guard, and the
18
+ alternatives that were rejected. `meta.docs.url` points at the same document, so
19
+ `--format=stylish` prints it. Both links are derived from the rule's name, so a
20
+ rename moves them.
16
21
 
17
22
  Presets: `recommended` (warn-first), `strict` (every rule at error), `style-guide` (formatting/naming subset).
18
23
 
24
+ ## Renamed in 7.0.0 (breaking)
25
+
26
+ | Old name | New name |
27
+ | --- | --- |
28
+ | `@sarj/jsdoc-restates-signature` | `@sarj/no-restated-jsdoc` |
29
+ | `@sarj/no-async-callback-in-waitfor` | `@sarj/no-async-callback-in-wait-for` |
30
+ | `@sarj/strict-test-assertions` | `@sarj/prefer-whole-object-assertion` |
31
+ | `@sarj/trailing-value-narration` | `@sarj/no-trailing-value-narration` |
32
+
33
+ Every old name is still REGISTERED, as a deprecated alias of the same rule, so a
34
+ config entry, an `eslint-disable` comment or a suppressions baseline naming it
35
+ keeps working while you migrate; ESLint reports the deprecation and names the
36
+ replacement. Neither preset wires an alias, so nothing double-reports. The map is
37
+ exported for codemods:
38
+
39
+ ```js
40
+ import { renamedRules } from "@sarj/eslint-plugin";
41
+ ```
42
+
43
+ Migration steps, the reasoning behind each name, and why the old keys are kept
44
+ rather than dropped: [`docs/rules/_renames.md`](../../docs/rules/_renames.md).
45
+
19
46
  ## New in 4.1.0 — `no-hand-rolled-sleep`
20
47
 
21
48
  `new Promise((resolve) => setTimeout(resolve, ms))` is `node:timers/promises`'s
@@ -88,14 +115,14 @@ an abandoned placeholder.
88
115
 
89
116
  From a 37,918-comment, nine-repo measurement study. All three are
90
117
  deletion-class, so each was validated against zod / swr / zustand / TanStack
91
- Query as well as the maintained repos. Read the `@fileoverview` in each rule for
92
- the hit counts and the false-positive class every guard was built from.
118
+ Query as well as the maintained repos. `docs/rules/<rule>.md` carries the hit
119
+ counts and the false-positive class every guard was built from.
93
120
 
94
121
  | Rule | What it catches | Preset |
95
122
  |---|---|---|
96
123
  | `no-restated-comment` | A single-line comment whose every content word already appears on the statement below it. Defers to `no-comment-cruft` for the verb-led shape, so a comment is never reported twice. | warn / error |
97
- | `jsdoc-restates-signature` | A JSDoc block whose description and `@param`/`@returns` only re-spell the signature. Offers a delete SUGGESTION, never an auto-`--fix`. | warn / error |
98
- | `trailing-value-narration` | `staleTime: 5 * 60 * 1000, // 5 minutes` — the unit belongs in the name, where it cannot drift. | warn / error |
124
+ | `no-restated-jsdoc` | A JSDoc block whose description and `@param`/`@returns` only re-spell the signature. Offers a delete SUGGESTION, never an auto-`--fix`. | warn / error |
125
+ | `no-trailing-value-narration` | `staleTime: 5 * 60 * 1000, // 5 minutes` — the unit belongs in the name, where it cannot drift. | warn / error |
99
126
  | `no-type-member-comment-wall` | An object type whose member comments mostly re-spell the members' own names and types — the VOLUME arm of the family, reported once for the type. | warn / error |
100
127
 
101
128
  ## New in 2.9.0
@@ -108,6 +135,7 @@ Both distilled from two years of PR-review comments across ~1,065 PRs.
108
135
  | `prefer-zod-enum` | `z.union([z.literal("a"), z.literal("b")])` — autofixes closed string choices to the shorter, equivalent `z.enum(["a", "b"])`. | warn / error |
109
136
  | `prefer-zod-infer` | An `interface`/`type` that restates a Zod schema declared in the same module instead of deriving it with `z.infer`. Options: `ignoreTypeNames`, `requireIdenticalShape` (default `true`). | warn / error |
110
137
  | `prefer-module-level-constant` | A literal-only `const` collection (array, object, `Set`, `Map`, `Object.freeze`) or non-global regex declared inside a function body, never mutated and never escaping — hoist it to module scope. Options: `minElements` (default 3), `checkRegex`, `ignoreTestFiles`. | warn / error |
138
+ | `prefer-module-level-schema` | A Zod schema built inside a function body that closes over nothing the function owns — hoist it to module scope instead of rebuilding it per call, per request, per render. Silent when it references a parameter, local, type parameter, local type, or `this` (that is a schema FACTORY), when it is already memoized, and inside `z.lazy`. Options: `factories` (default: the object-like composites), `minProperties` (default 1), `ignoreTestFiles`. | warn / error |
111
139
  | `prefer-non-nullable-collection` | An array type explicitly combined with `null`/`undefined`, creating two equivalent empty states. | warn / error |
112
140
 
113
141
  ## Options
@@ -259,6 +287,6 @@ Several rules are ports of the Python linter's SARJ rules, retuned for TypeScrip
259
287
  | `single-public-export` | SARJ022 | Modules with no single obvious entry point. |
260
288
  | `prefer-string-literal-union` | SARJ006 | An open `string` where a closed set is intended. |
261
289
 
262
- Shared helpers live in `src/rules/_*.ts` (`_secret_names.ts`, `_sql.ts`, `_logging.ts`, `_paths.ts`, `_tailwind.ts`) so related rules cannot diverge on what counts as a secret, a SQL statement, a logging call, or a test file.
290
+ Shared helpers live in `src/rules/_*.ts` (`_secret-names.ts`, `_sql.ts`, `_logging.ts`, `_paths.ts`, `_tailwind.ts`) so related rules cannot diverge on what counts as a secret, a SQL statement, a logging call, or a test file.
263
291
 
264
292
  Deliberately **not** ported: `no-unreachable-after-terminal` (SARJ010) is already covered by `allowUnreachableCode: false` in `@sarj/tsconfig` plus ESLint core `no-unreachable`; `no-aggregation-in-store-query` (SARJ020) assumes a Postgres-OLTP / columnar-mirror split that D1 does not have; `no-query-with-many-joins` (SARJ019), `stepdown` (SARJ023), `prefer-class-row`, `prefer-struct-over-namedtuple`, `prefer-timedelta-for-durations`, and `no-fstring-in-log` have no TypeScript defect class or target API; `prefer-str-enum` is covered by `prefer-string-literal-union` + `no-enum`.