carrick 0.3.104 → 0.3.105

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.
@@ -21,6 +21,7 @@ import * as path from 'node:path';
21
21
  import { Node, SyntaxKind, ts, } from 'ts-morph';
22
22
  import { validateInferRequestItem } from './validators.js';
23
23
  import { externalImportsOf, isExternalOrigin } from './origin.js';
24
+ import { reachedOnlyOnFailure } from './failure-path.js';
24
25
  import { addedDiagnostics, applyInsertions, fileDiagnostics, literalInsertions, mapBack, mapForward, normalise, pathOf, } from './unwidened.js';
25
26
  import { expandTypeStructural, } from './type-structural-expander.js';
26
27
  /**
@@ -1813,6 +1814,16 @@ export class TypeInferrer {
1813
1814
  for (const expr of candidates) {
1814
1815
  if (expr.getStart() <= startPos)
1815
1816
  continue;
1817
+ // carrick#1796: what the source does with the response once it has
1818
+ // FAILED describes the failure, not the payload. `if (res.ok) {
1819
+ // return ... } const errorText = await res.text()` published the error
1820
+ // text as the response contract because the walk keeps the LAST whole
1821
+ // read, and the failure path's read comes after the success path's
1822
+ // return. A read there is neither the payload nor a part of it.
1823
+ if (this.usesTrackedNames(expr, currentNames) &&
1824
+ reachedOnlyOnFailure(expr, func, (node) => this.isIdentifierUsage(node, currentNames))) {
1825
+ continue;
1826
+ }
1816
1827
  // carrick#1017: a comparison is `boolean` by construction, so it is
1817
1828
  // never the payload a call yields. `const res = await fetch(url); if
1818
1829
  // (res.status === 404) return null; return await res.json() as Entry`
@@ -2361,6 +2372,12 @@ export class TypeInferrer {
2361
2372
  const identifiers = expr.getDescendantsOfKind(SyntaxKind.Identifier);
2362
2373
  return identifiers.some((id) => this.isIdentifierUsage(id, names));
2363
2374
  }
2375
+ /** `expr` is a use of a tracked name, or contains one. */
2376
+ usesTrackedNames(expr, names) {
2377
+ return Node.isIdentifier(expr)
2378
+ ? this.isIdentifierUsage(expr, names)
2379
+ : this.expressionUsesNames(expr, names);
2380
+ }
2364
2381
  isIdentifierUsage(id, names) {
2365
2382
  if (!Node.isIdentifier(id)) {
2366
2383
  return false;