@sarj/eslint-plugin 19.12.0 → 19.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/dist/catalog.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  publicDocumentation,
3
3
  ruleSpec,
4
4
  src_default
5
- } from "./chunk-7SYRLUE7.js";
5
+ } from "./chunk-YWEV6GQM.js";
6
6
 
7
7
  // src/docs/directive-disable-enable-pair.ts
8
8
  var DIRECTIVE_DISABLE_ENABLE_PAIR_DOCUMENTATION = {
@@ -4165,7 +4165,7 @@ var PREFER_CODED_ERROR_RESULT_DOCUMENTATION = {
4165
4165
  "Broad string and unknown error channels, unshadowed native Error-family types and open string/unknown code fields receive review. Explicit Any stays with the existing no-explicit-any rule. Finite literal codes need no invented payload. Imported domain errors, validation-library errors, generic error parameters, ordinary formatters, legitimate absence and redacted failure states remain valid.",
4166
4166
  "Local aliases, unmerged interfaces without inheritance and generic substitutions are bounded to 16 resolution levels, 64 union members and 256 traversal steps. Transparent aliases retain the proven neverthrow Result/ResultAsync error position, including renamed/namespace imports, generic defaults and unshadowed native Promise/PromiseLike wrappers. Imported local declarations, conditional/intersection/mapped types and unresolved contracts abstain. Optional discriminants, independent success/error payloads and partial-data failures are excluded.",
4167
4167
  "Required code/kind/type/tag fields of unresolved or imported type defer to the type checker; a finite code does not prove that its cases or payloads are useful. Generic error parameters are retained rather than guessed. Ordinary string formatters, absence, validation-library errors and redacted failure states without a string payload are not flagged.",
4168
- "A directly returned failure object, neverthrow err/errAsync call or new Err with an interpolated template or proven string concatenation receives review. Without a code, the diagnostic asks for a domain contract; with a literal code, it asks for consumer formatting. Literal-only compositions, including earlier stable local constants, remain valid codes. Nested plain error objects, expression-bodied arrows and one direct await are supported. Import identity and value-space shadowing are checked; arbitrary aliases, spreads, accessors, computed keys, helper formatting calls and nonliteral codes abstain. This proves formatting ownership, not which context the domain must expose; presentation adapters remain a reviewed exception.",
4168
+ "A directly returned failure object, neverthrow err/errAsync call or new Err with an interpolated template or proven string concatenation receives review. Without a code, the diagnostic asks for a domain contract; with a literal code, it asks for consumer formatting. Literal-only compositions, including earlier stable local constants, remain valid codes. Nested plain error objects, expression-bodied arrows and awaited returns are supported. Returned conditional branches are followed without visiting their conditions, call arguments or containers; logical/sequence expressions and arbitrary aliases abstain. The entire return expression abstains beyond 16 levels, 64 leaves or 256 traversal steps. Import identity and value-space shadowing are checked; spreads, accessors, computed keys, helper formatting calls and nonliteral codes abstain. This proves formatting ownership, not which context the domain must expose; presentation adapters remain a reviewed exception.",
4169
4169
  "This warning requests domain review: an infrastructure adapter may intentionally retain unknown/Error, and a final presentation boundary may accept every failure and render one message. Neither proves a recoverable domain rejection. No fix invents error codes, fields, handlers or changes serialization, exception unwinding, transactions, retries or logging."
4170
4170
  ],
4171
4171
  references: [
@@ -4173,6 +4173,36 @@ var PREFER_CODED_ERROR_RESULT_DOCUMENTATION = {
4173
4173
  "https://github.com/supermacro/neverthrow"
4174
4174
  ],
4175
4175
  examples: [
4176
+ {
4177
+ id: "conditional-message-failure",
4178
+ scenarioId: "conditional-result-producer",
4179
+ title: "A conditional return still needs a useful error contract",
4180
+ outcome: "match",
4181
+ files: [
4182
+ {
4183
+ path: "app/result.ts",
4184
+ source: "import { err, ok } from 'neverthrow'; export const save = (name: string, allowed: boolean) => allowed ? ok(name) : err(`Denied ${name}`);"
4185
+ }
4186
+ ],
4187
+ focusPath: "app/result.ts",
4188
+ expectedCount: 1,
4189
+ public: true
4190
+ },
4191
+ {
4192
+ id: "conditional-coded-failure",
4193
+ scenarioId: "conditional-result-producer",
4194
+ title: "Preserve the code and context and let the consumer format",
4195
+ outcome: "no-match",
4196
+ files: [
4197
+ {
4198
+ path: "app/result.ts",
4199
+ source: "import { err, ok, type Result } from 'neverthrow'; type Denied = { code: 'denied'; name: string }; export function save(name: string, allowed: boolean): Result<string, Denied> { return allowed ? ok(name) : err({ code: 'denied', name }); } export function format(error: Denied): string { return `Denied ${error.name}`; }"
4200
+ }
4201
+ ],
4202
+ focusPath: "app/result.ts",
4203
+ expectedCount: 0,
4204
+ public: true
4205
+ },
4176
4206
  {
4177
4207
  id: "aliased-library-message",
4178
4208
  scenarioId: "aliased-library-error",
@@ -21911,6 +21911,19 @@ function libraryReference(node) {
21911
21911
  return { root: node.object, member: node.property.name };
21912
21912
  return null;
21913
21913
  }
21914
+ function returnedValues(node, depth = 0, budget = { remaining: MAX_TYPE_STEPS }) {
21915
+ if (depth >= MAX_DEPTH || --budget.remaining < 0) return null;
21916
+ const value = unwrapExpression(node);
21917
+ if (value.type === "AwaitExpression")
21918
+ return returnedValues(value.argument, depth + 1, budget);
21919
+ if (value.type !== "ConditionalExpression") return [value];
21920
+ const consequent = returnedValues(value.consequent, depth + 1, budget);
21921
+ if (consequent === null) return null;
21922
+ const alternate = returnedValues(value.alternate, depth + 1, budget);
21923
+ if (alternate === null || consequent.length + alternate.length > MAX_VARIANTS)
21924
+ return null;
21925
+ return [...consequent, ...alternate];
21926
+ }
21914
21927
  function renderedFailure(node, source) {
21915
21928
  let value = unwrapExpression(node);
21916
21929
  if (value.type === "AwaitExpression")
@@ -22043,13 +22056,19 @@ var prefer_coded_error_result_default = defineRule({
22043
22056
  }
22044
22057
  function checkProducer(owner, value) {
22045
22058
  if (owner === null) return;
22046
- const rendered = renderedFailure(value, context.sourceCode);
22047
- if (rendered === null || reported.has(rendered.node)) return;
22059
+ const issues = (returnedValues(value) ?? []).flatMap((leaf) => {
22060
+ const issue = renderedFailure(leaf, context.sourceCode);
22061
+ return issue === null ? [] : [issue];
22062
+ });
22063
+ if (issues.length === 0) return;
22048
22064
  const contract = owner.returnType?.typeAnnotation;
22049
22065
  if (contract !== void 0 && outcomeFailures(view(contract), context.sourceCode).length !== 0)
22050
22066
  return;
22051
- reported.add(rendered.node);
22052
- context.report(rendered);
22067
+ for (const issue of issues) {
22068
+ if (reported.has(issue.node)) continue;
22069
+ reported.add(issue.node);
22070
+ context.report(issue);
22071
+ }
22053
22072
  }
22054
22073
  return {
22055
22074
  before() {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  src_default
3
- } from "./chunk-7SYRLUE7.js";
3
+ } from "./chunk-YWEV6GQM.js";
4
4
  export {
5
5
  src_default as default
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarj/eslint-plugin",
3
- "version": "19.12.0",
3
+ "version": "19.14.0",
4
4
  "packageManager": "npm@12.2.1",
5
5
  "description": "Custom Oxlint rules for hypermodern TypeScript / React / Next.js projects",
6
6
  "type": "module",