@sarj/eslint-plugin 9.13.1 → 9.14.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
@@ -331,6 +331,25 @@ false-positive rate, relevant to any repo touching SQL). The two architectural
331
331
  rules are **`strict`-only**, since they need per-repo configuration to say
332
332
  anything useful.
333
333
 
334
+ `no-generic-single-export-module` warns when a `utils`, `helpers`, `common`,
335
+ `constants`, or similarly generic module has one runtime export that already
336
+ provides a precise filename. Ambiguous re-exports, type-only modules,
337
+ conventional framework filenames, tests, generated files, and CommonJS modules
338
+ are excluded. It is warning-first while corpus evidence accumulates.
339
+
340
+ `stepdown` is likewise warning-first: measured adoption is intentionally broad,
341
+ so it only owns ordering within a private-method band. The strict preset gives
342
+ public/protected/private band ordering to `@typescript-eslint/member-ordering`
343
+ and disables `perfectionist/sort-classes`, avoiding contradictory owners. The
344
+ rule resolves module helpers, private methods, recursion and cycles, but leaves
345
+ function-valued private fields and mutable receiver aliases alone.
346
+
347
+ `no-positional-tuple-return` now rejects every fixed multi-field tuple on an
348
+ exported TypeScript boundary—including homogeneous, labelled, tagged, readonly,
349
+ hook-style, interface, function-type, declaration and abstract-method returns.
350
+ The runtime alternative is a named object. Private/local implementation helpers
351
+ and sequence-shaped arrays remain outside the public-boundary rule.
352
+
334
353
  ## Ported from `sarj_python_lint`
335
354
 
336
355
  Several rules are ports of the Python linter's SARJ rules, retuned for TypeScript. The false-positive tuning documented in the Python docstrings is ported with them — that tuning is the valuable part.
@@ -343,13 +362,14 @@ Several rules are ports of the Python linter's SARJ rules, retuned for TypeScrip
343
362
  | `no-select-star` | SARJ021 | An implicit row contract that changes silently when a column is added or reordered. |
344
363
  | `no-offset-pagination` | SARJ025 | O(N)-per-page scans, and rows repeated or skipped when the offset window shifts under concurrent inserts. |
345
364
  | `no-repeated-string-literal` | SARJ024 | Copies of a structured literal (SQL, column lists, prompt templates) drifting apart when only one is edited. |
346
- | `no-positional-tuple-return` | SARJ026 | Call sites re-inventingand disagreeing onthe field names of a positional tuple return. |
365
+ | `no-positional-tuple-return` | SARJ026 | Public APIs exposing multi-field tupleseven labelled or hook-style tuplesinstead of named objects. |
347
366
  | `no-sleep-in-test-body` | SARJ031 | Tests that assert on wall-clock time and flake under CI load. |
348
367
  | `no-fat-try-blocks` | SARJ007 | Over-broad `catch` handlers swallowing unrelated failures. |
349
368
  | `no-cors-wildcard-with-credentials` | SARJ008 | Credentialed cross-origin requests from any origin. |
350
369
  | `single-public-export` | SARJ022 | Modules with no single obvious entry point. |
370
+ | `stepdown` | SARJ023 | A private helper placed above its only direct same-scope caller. Indirect references, callbacks, cycles, overloads, and multi-caller helpers are excluded. |
351
371
  | `prefer-string-literal-union` | SARJ006 | An open `string` where a closed set is intended. |
352
372
 
353
373
  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.
354
374
 
355
- 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`.
375
+ 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), `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`.