@suss/extractor 0.8.0 → 0.10.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/index.d.ts CHANGED
@@ -1,246 +1,5 @@
1
1
  import { Effect, MessageBusSemantics, DeployableUnit, Predicate, BehavioralSummary, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, GraphqlDeclaredContract, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
2
2
 
3
- /**
4
- * The language-neutral form the path engine walks: statement kind, condition
5
- * handle, children, and exit kind. Each language's adapter lowers its own AST
6
- * into this, and the path enumeration never touches a language-specific node
7
- * again.
8
- *
9
- * The `Cond` type parameter is the language's own handle for a condition
10
- * expression (a ts-morph Expression for TypeScript, a tree-sitter node for a
11
- * language added later). The engine passes it through untouched for a caller
12
- * to parse afterwards, and never looks inside it.
13
- */
14
- /** Where a condition came from, in terms of what that branch's body does. */
15
- type ConditionSource = "explicit" | "earlyReturn" | "earlyThrow" | "catchBlock";
16
- /** Whether a statement's own subtree leaves the unit by returning or throwing. A throw anywhere beats a return anywhere. Never set for break or continue. */
17
- type ExitKind = "return" | "throw" | null;
18
- /**
19
- * A test the engine passes through without looking inside: its display text
20
- * plus the language's own expression handle. The handle is null for a
21
- * synthetic condition, such as a loop's "some iteration of" marker or a
22
- * switch group's disjunction text.
23
- */
24
- interface ConditionHandle<Cond> {
25
- readonly sourceText: string;
26
- readonly expression: Cond | null;
27
- }
28
- /** One condition attached to a caller-visible transition. */
29
- interface ConditionInfo<Cond> {
30
- readonly sourceText: string;
31
- readonly polarity: "positive" | "negative";
32
- readonly source: ConditionSource;
33
- readonly expression: Cond | null;
34
- }
35
- /** A statement list: an if arm, a loop body, a try/catch/finally block. */
36
- type StatementBlock<Cond> = readonly StructuredStatement<Cond>[];
37
- /**
38
- * One switch or match case group, already merged out of the language's own
39
- * grammar (TypeScript stacks several empty-bodied labels on top of the
40
- * clause that finally has a body, and the lowering step folds that
41
- * into one group with a joined condition). `condition` is null for the
42
- * default or wildcard group. `body` has any language-specific
43
- * statement that ends a fallthrough (a trailing break) already stripped
44
- * out, and `hasTrailingBreak` records whether one was there.
45
- */
46
- interface CaseGroup<Cond> {
47
- readonly condition: ConditionHandle<Cond> | null;
48
- readonly hasTrailingBreak: boolean;
49
- readonly body: StatementBlock<Cond>;
50
- }
51
- /**
52
- * One statement in the unit's control flow, already lowered out of the
53
- * source language. Every variant has the same four things on it:
54
- * `kind` says which construct it is, `condition` (where
55
- * one applies) is the opaque test, the block and group fields are its
56
- * children, and `exitKind` is worked out by the lowering step (a deep
57
- * scan of the statement's own subtree for a return or throw, skipping
58
- * nested function bodies, the same scan every language needs in order to
59
- * tell an early return from an early throw).
60
- */
61
- type StructuredStatement<Cond = unknown> = {
62
- readonly kind: "if";
63
- readonly condition: ConditionHandle<Cond>;
64
- readonly thenBody: StatementBlock<Cond>;
65
- /** null when the source has no else/elif tail at all. */
66
- readonly elseBody: StatementBlock<Cond> | null;
67
- readonly exitKind: ExitKind;
68
- } | {
69
- readonly kind: "switch";
70
- /** Source order; at most one group has a null (default) condition. */
71
- readonly groups: readonly CaseGroup<Cond>[];
72
- readonly exitKind: ExitKind;
73
- } | {
74
- readonly kind: "loop";
75
- /** Display text for the loop header. The engine builds two synthetic conditions out of it: "some iteration of: ..." and "loop exited via ...: ...". */
76
- readonly condition: ConditionHandle<Cond>;
77
- readonly body: StatementBlock<Cond>;
78
- readonly exitKind: ExitKind;
79
- } | {
80
- readonly kind: "try";
81
- readonly tryBody: StatementBlock<Cond>;
82
- readonly catchBody: StatementBlock<Cond> | null;
83
- /** Here only so it can be validated. A finally that exits, or that contains a terminal the caller gave us, is not modeled, and its own conditions are never enumerated. */
84
- readonly finallyBody: StatementBlock<Cond> | null;
85
- readonly exitKind: ExitKind;
86
- } | {
87
- readonly kind: "exit";
88
- readonly exit: "return" | "throw" | "break" | "continue";
89
- readonly exitKind: ExitKind;
90
- } | {
91
- /** Anything else: expression statements, declarations, and any statement the enumeration does not branch on. */
92
- readonly kind: "opaque";
93
- readonly exitKind: ExitKind;
94
- };
95
-
96
- /**
97
- * `Reading<T>`: what a reader found, in the four states a source can leave a
98
- * value in.
99
- *
100
- * A reader that returns `T | null` makes null mean three things at once: the
101
- * source left the value out, the source states it and the reader could not
102
- * evaluate it, or several candidates matched and the reader picked none.
103
- * Each needs something different said about it on the summary, and the type
104
- * does not show which the reader meant, so every new reader decides it again
105
- * and some of them decide wrong.
106
- *
107
- * The rule that turns a reading into a claim, a library default, or a gap
108
- * lives in the summary builder in this package and is not exported.
109
- */
110
- /** Where in a file a value is written, as byte offsets into that file. */
111
- interface SourceRange {
112
- start: number;
113
- end: number;
114
- }
115
- /**
116
- * What a reader found where a value could be. `written` is the only state
117
- * with a value a summary may claim, and the other three each say something
118
- * different about why there is no claim to make.
119
- */
120
- type Reading<T> = {
121
- kind: "written";
122
- value: T;
123
- range: SourceRange;
124
- } | {
125
- kind: "absent";
126
- } | {
127
- kind: "unreadable";
128
- reason: string;
129
- range: SourceRange;
130
- } | {
131
- kind: "ambiguous";
132
- candidates: readonly T[];
133
- reason: string;
134
- range: SourceRange;
135
- };
136
- /** The source gives this value, here, and the reader read it. */
137
- declare function writtenReading<T>(value: T, range: SourceRange): Reading<T>;
138
- /**
139
- * The source says nothing where this value could be. A library that defines
140
- * a default for it may still supply one, and the summary builder applies
141
- * that default only when a pack declares it as data.
142
- */
143
- declare const absentReading: Reading<never>;
144
- /**
145
- * The source gives the value and the reader could not evaluate it. The
146
- * reason is the sentence somebody reading the summary will see, so write it
147
- * about what could not be read rather than about the code.
148
- */
149
- declare function unreadableReading<T>(reason: string, range: SourceRange): Reading<T>;
150
- /**
151
- * Several values could be right and the reader picked none. Keeping the
152
- * candidates leaves what was found available to whoever later teaches the
153
- * reader how to choose, and every step afterwards keeps them too.
154
- *
155
- * The range is where somebody should look to see the ambiguity. An ambiguity
156
- * often spans more than one place (two mounts of one router, in two files),
157
- * so give the site the reading was taken at, the same one an `unreadable`
158
- * reading here would have given.
159
- */
160
- declare function ambiguousReading<T>(candidates: readonly T[], reason: string, range: SourceRange): Reading<T>;
161
- /**
162
- * A reading paired with what the library does when the source says nothing.
163
- * Only a pack may supply that default, so the value a summary claims for an
164
- * unstated field is library-defined and lives in the pack alongside
165
- * everything else the pack already declares.
166
- */
167
- interface DefaultedReading<T> {
168
- /** What the source said. */
169
- reading: Reading<T>;
170
- /**
171
- * The value the library applies when the source gives none, as the pack
172
- * declared it. Leave it out when the library defines no default, and then
173
- * a source that says nothing gets no claim.
174
- */
175
- libraryDefault?: T;
176
- }
177
- /**
178
- * The same reading with its value in another form. A written value goes
179
- * through `f` and keeps its range. An ambiguous reading's candidates go
180
- * through `f` too, so the alternatives end up in the same form as the
181
- * chosen value would. Absent and unreadable readings pass through
182
- * unchanged, since neither one has a value to convert.
183
- */
184
- declare function mapReading<T, U>(reading: Reading<T>, f: (value: T) => U): Reading<U>;
185
- /**
186
- * Read further from what this reading found. `f` runs on a written
187
- * value with the range it was written at, so a step that turns out to
188
- * be unreadable can say so against the same syntax.
189
- *
190
- * `f` runs on each of an ambiguous reading's candidates too, and the ones
191
- * that do read come back as the candidates of an ambiguous reading with the
192
- * same reason. That way the alternatives stay next to the chosen value all
193
- * the way to the summary, instead of being dropped at the first step
194
- * that reads further.
195
- */
196
- declare function andThenReading<T, U>(reading: Reading<T>, f: (value: T, range: SourceRange) => Reading<U>): Reading<U>;
197
- /**
198
- * Which of several readings a claim comes from, for a value a library lets
199
- * a source give in more than one place.
200
- */
201
- interface ChosenReading<T> {
202
- /**
203
- * The reading a claim comes from: the first that was written, or if none
204
- * was, the first that failed to read, or absent when all of them were
205
- * absent.
206
- */
207
- reading: Reading<T>;
208
- /**
209
- * The readings the choice passed over that nobody could resolve. A later
210
- * reading supplying the value does not settle what an earlier one said
211
- * and could not be read, so these still go to the
212
- * builder and their reasons still reach the summary.
213
- */
214
- passedOver: readonly Reading<T>[];
215
- }
216
- /**
217
- * Choose among readings of the same value, taking the first that was
218
- * written. Nothing is thrown away: whatever the choice passed over and
219
- * could not read comes back next to it in `passedOver`, so a
220
- * `response_model` nobody could read still lands as a gap even when the
221
- * return annotation after it supplies the type.
222
- */
223
- declare function firstWrittenReading<T>(readings: readonly Reading<T>[]): ChosenReading<T>;
224
- /**
225
- * What a written reading found, for a reader that has to read further from
226
- * it before anything is claimed. A route's path template gives the
227
- * parameters that decide what each of the handler's parameters is, and
228
- * that has to be settled before there is a summary field to fill in.
229
- *
230
- * This applies no default and gives no reason, so most of what a summary
231
- * says must not be written from it. Hand the reading to the
232
- * builder instead, and the fixed rule gets applied to it once, somewhere
233
- * review can see it.
234
- *
235
- * The identity fields of a boundary binding are the exception, and the path
236
- * this reads is one of them. A binding either says where a unit is or says
237
- * nothing and pairs with nothing, and no pack declares a
238
- * default for what a boundary is called, so the value the builder would
239
- * put there is the value this gives back. Hand the reading over as well and
240
- * the reason still becomes a gap.
241
- */
242
- declare function valueToReadFurtherFrom<T>(reading: Reading<T>): T | null;
243
-
244
3
  /**
245
4
  * The `PatternPack` interface, which is what a framework pack gives a language
246
5
  * adapter. The pack says WHAT to look for (which import, which call, which
@@ -464,10 +223,10 @@ type DiscoveryMatch = {
464
223
  *
465
224
  * The adapter fills in `DiscoveredUnit.resolverInfo` so the binding
466
225
  * comes out as `graphql-resolver(typeName, fieldName)`.
467
- * `typeName` resolves from the class decorator's first argument
468
- * (`@Resolver(() => User)` gives `"User"`), or from
469
- * `methodDecoratorTypeMap` when the class decorator has no
470
- * argument. `fieldName` comes from the method decorator's `{ name }`
226
+ * `typeName` resolves from `methodDecoratorTypeMap` when the
227
+ * method decorator is in it, and otherwise from the class
228
+ * decorator's first argument (`@Resolver(() => User)` gives
229
+ * `"User"`). `fieldName` comes from the method decorator's `{ name }`
471
230
  * option when that is set, and otherwise from the method name.
472
231
  */
473
232
  type: "decoratedMethod";
@@ -489,10 +248,10 @@ type DiscoveryMatch = {
489
248
  classDecorators: string[];
490
249
  methodDecorators: string[];
491
250
  /**
492
- * Maps a method decorator to the type its field belongs to when the
493
- * class decorator does not say. NestJS puts `@Query` on the root
251
+ * Maps a method decorator to the type its field belongs to, for the
252
+ * decorators that settle it. NestJS puts `@Query` on the root
494
253
  * `Query` type and `@Mutation` on `Mutation` no matter what the class
495
- * says, so those two settle it themselves.
254
+ * says, so an entry here wins over the class decorator's argument.
496
255
  *
497
256
  * When the map leaves a decorator out and the class decorator gives no
498
257
  * type either, nothing here works out which type owns the field. The
@@ -1053,6 +812,8 @@ type ResponsePropertyMeaning = {
1053
812
  } | {
1054
813
  type: "headers";
1055
814
  };
815
+ /** Whether a refused request comes back as a response or as an exception. */
816
+ type FailureDelivery = "response" | "exception";
1056
817
  interface ResponsePropertyMapping {
1057
818
  /** Property or method name on the response (e.g. "ok", "status", "json") */
1058
819
  name: string;
@@ -1121,6 +882,14 @@ interface PatternPack {
1121
882
  * `.json()` into a structured IR construct instead of leaving it opaque.
1122
883
  */
1123
884
  responseSemantics?: ResponsePropertyMapping[];
885
+ /**
886
+ * How this client hands back a response the server refused. `fetch`
887
+ * returns one and the caller reads the status off it. axios and ky
888
+ * reject instead, so every non-2xx reaches the caller through a
889
+ * `catch` and there is no status for a guard to read. Defaults to
890
+ * `"response"`.
891
+ */
892
+ failureDelivery?: FailureDelivery;
1124
893
  /**
1125
894
  * Synthesize extra code units out of a parent unit's body, for when one
1126
895
  * construct the user wrote implicitly spawns several units the runtime
@@ -1474,6 +1243,255 @@ interface DiscoveredSubUnit {
1474
1243
  metadata?: Record<string, unknown>;
1475
1244
  }
1476
1245
 
1246
+ /**
1247
+ * The language-neutral form the path engine walks: statement kind, condition
1248
+ * handle, children, and exit kind. Each language's adapter lowers its own AST
1249
+ * into this, and the path enumeration never touches a language-specific node
1250
+ * again.
1251
+ *
1252
+ * The `Cond` type parameter is the language's own handle for a condition
1253
+ * expression (a ts-morph Expression for TypeScript, a tree-sitter node for a
1254
+ * language added later). The engine passes it through untouched for a caller
1255
+ * to parse afterwards, and never looks inside it.
1256
+ */
1257
+ /** Where a condition came from, in terms of what that branch's body does. */
1258
+ type ConditionSource = "explicit" | "earlyReturn" | "earlyThrow" | "catchBlock";
1259
+ /** Whether a statement's own subtree leaves the unit by returning or throwing. A throw anywhere beats a return anywhere. Never set for break or continue. */
1260
+ type ExitKind = "return" | "throw" | null;
1261
+ /**
1262
+ * A test the engine passes through without looking inside: its display text
1263
+ * plus the language's own expression handle. The handle is null for a
1264
+ * synthetic condition, such as a loop's "some iteration of" marker or a
1265
+ * switch group's disjunction text.
1266
+ */
1267
+ interface ConditionHandle<Cond> {
1268
+ readonly sourceText: string;
1269
+ readonly expression: Cond | null;
1270
+ }
1271
+ /** One condition attached to a caller-visible transition. */
1272
+ interface ConditionInfo<Cond> {
1273
+ readonly sourceText: string;
1274
+ readonly polarity: "positive" | "negative";
1275
+ readonly source: ConditionSource;
1276
+ readonly expression: Cond | null;
1277
+ }
1278
+ /** A statement list: an if arm, a loop body, a try/catch/finally block. */
1279
+ type StatementBlock<Cond> = readonly StructuredStatement<Cond>[];
1280
+ /**
1281
+ * One switch or match case group, already merged out of the language's own
1282
+ * grammar (TypeScript stacks several empty-bodied labels on top of the
1283
+ * clause that finally has a body, and the lowering step folds that
1284
+ * into one group with a joined condition). `condition` is null for the
1285
+ * default or wildcard group. `body` has any language-specific
1286
+ * statement that ends a fallthrough (a trailing break) already stripped
1287
+ * out, and `hasTrailingBreak` records whether one was there.
1288
+ */
1289
+ interface CaseGroup<Cond> {
1290
+ readonly condition: ConditionHandle<Cond> | null;
1291
+ readonly hasTrailingBreak: boolean;
1292
+ readonly body: StatementBlock<Cond>;
1293
+ }
1294
+ /**
1295
+ * What every lowered statement has on it, whichever construct it is.
1296
+ *
1297
+ * The lowering works `exitKind` out by scanning the statement's own
1298
+ * subtree for a return or a throw, skipping every nested function body.
1299
+ *
1300
+ * `callbacks` is the bodies of the functions this statement passes to
1301
+ * calls it makes, as far as the language counts those as running for the
1302
+ * enclosing unit. The engine walks them on the same path as the
1303
+ * statement, so their branches are the unit's branches. Their `return`
1304
+ * is not the unit's, so a path that ends inside one continues past the
1305
+ * statement. A lowering that leaves the field out behaves as it did
1306
+ * before there was one.
1307
+ */
1308
+ interface LoweredStatementParts<Cond> {
1309
+ readonly exitKind: ExitKind;
1310
+ readonly callbacks?: readonly StatementBlock<Cond>[];
1311
+ }
1312
+ /**
1313
+ * One statement in the unit's control flow, already lowered out of the
1314
+ * source language. `kind` says which construct it is, `condition` (where
1315
+ * one applies) is the opaque test, and the block and group fields are its
1316
+ * children. `LoweredStatementParts` describes the rest.
1317
+ */
1318
+ type StructuredStatement<Cond = unknown> = (LoweredStatementParts<Cond> & {
1319
+ readonly kind: "if";
1320
+ readonly condition: ConditionHandle<Cond>;
1321
+ readonly thenBody: StatementBlock<Cond>;
1322
+ /** null when the source has no else/elif tail at all. */
1323
+ readonly elseBody: StatementBlock<Cond> | null;
1324
+ }) | (LoweredStatementParts<Cond> & {
1325
+ readonly kind: "switch";
1326
+ /** Source order; at most one group has a null (default) condition. */
1327
+ readonly groups: readonly CaseGroup<Cond>[];
1328
+ }) | (LoweredStatementParts<Cond> & {
1329
+ readonly kind: "loop";
1330
+ /** Display text for the loop header. The engine builds two synthetic conditions out of it: "some iteration of: ..." and "loop exited via ...: ...". */
1331
+ readonly condition: ConditionHandle<Cond>;
1332
+ readonly body: StatementBlock<Cond>;
1333
+ }) | (LoweredStatementParts<Cond> & {
1334
+ readonly kind: "try";
1335
+ readonly tryBody: StatementBlock<Cond>;
1336
+ readonly catchBody: StatementBlock<Cond> | null;
1337
+ /** Here only so it can be validated. A finally that exits, or that contains a terminal the caller gave us, is not modeled, and its own conditions are never enumerated. */
1338
+ readonly finallyBody: StatementBlock<Cond> | null;
1339
+ }) | (LoweredStatementParts<Cond> & {
1340
+ readonly kind: "exit";
1341
+ readonly exit: "return" | "throw" | "break" | "continue";
1342
+ }) | (LoweredStatementParts<Cond> & {
1343
+ /** Anything else: expression statements, declarations, and any statement the enumeration does not branch on. */
1344
+ readonly kind: "opaque";
1345
+ });
1346
+
1347
+ /**
1348
+ * `Reading<T>`: what a reader found, in the four states a source can leave a
1349
+ * value in.
1350
+ *
1351
+ * A reader that returns `T | null` makes null mean three things at once: the
1352
+ * source left the value out, the source states it and the reader could not
1353
+ * evaluate it, or several candidates matched and the reader picked none.
1354
+ * Each needs something different said about it on the summary, and the type
1355
+ * does not show which the reader meant, so every new reader decides it again
1356
+ * and some of them decide wrong.
1357
+ *
1358
+ * The rule that turns a reading into a claim, a library default, or a gap
1359
+ * lives in the summary builder in this package and is not exported.
1360
+ */
1361
+ /** Where in a file a value is written, as byte offsets into that file. */
1362
+ interface SourceRange {
1363
+ start: number;
1364
+ end: number;
1365
+ }
1366
+ /**
1367
+ * What a reader found where a value could be. `written` is the only state
1368
+ * with a value a summary may claim, and the other three each say something
1369
+ * different about why there is no claim to make.
1370
+ */
1371
+ type Reading<T> = {
1372
+ kind: "written";
1373
+ value: T;
1374
+ range: SourceRange;
1375
+ } | {
1376
+ kind: "absent";
1377
+ } | {
1378
+ kind: "unreadable";
1379
+ reason: string;
1380
+ range: SourceRange;
1381
+ } | {
1382
+ kind: "ambiguous";
1383
+ candidates: readonly T[];
1384
+ reason: string;
1385
+ range: SourceRange;
1386
+ };
1387
+ /** The source gives this value, here, and the reader read it. */
1388
+ declare function writtenReading<T>(value: T, range: SourceRange): Reading<T>;
1389
+ /**
1390
+ * The source says nothing where this value could be. A library that defines
1391
+ * a default for it may still supply one, and the summary builder applies
1392
+ * that default only when a pack declares it as data.
1393
+ */
1394
+ declare const absentReading: Reading<never>;
1395
+ /**
1396
+ * The source gives the value and the reader could not evaluate it. The
1397
+ * reason is the sentence somebody reading the summary will see, so write it
1398
+ * about what could not be read rather than about the code.
1399
+ */
1400
+ declare function unreadableReading<T>(reason: string, range: SourceRange): Reading<T>;
1401
+ /**
1402
+ * Several values could be right and the reader picked none. Keeping the
1403
+ * candidates leaves what was found available to whoever later teaches the
1404
+ * reader how to choose, and every step afterwards keeps them too.
1405
+ *
1406
+ * The range is where somebody should look to see the ambiguity. An ambiguity
1407
+ * often spans more than one place (two mounts of one router, in two files),
1408
+ * so give the site the reading was taken at, the same one an `unreadable`
1409
+ * reading here would have given.
1410
+ */
1411
+ declare function ambiguousReading<T>(candidates: readonly T[], reason: string, range: SourceRange): Reading<T>;
1412
+ /**
1413
+ * A reading paired with what the library does when the source says nothing.
1414
+ * Only a pack may supply that default, so the value a summary claims for an
1415
+ * unstated field is library-defined and lives in the pack alongside
1416
+ * everything else the pack already declares.
1417
+ */
1418
+ interface DefaultedReading<T> {
1419
+ /** What the source said. */
1420
+ reading: Reading<T>;
1421
+ /**
1422
+ * The value the library applies when the source gives none, as the pack
1423
+ * declared it. Leave it out when the library defines no default, and then
1424
+ * a source that says nothing gets no claim.
1425
+ */
1426
+ libraryDefault?: T;
1427
+ }
1428
+ /**
1429
+ * The same reading with its value in another form. A written value goes
1430
+ * through `f` and keeps its range. An ambiguous reading's candidates go
1431
+ * through `f` too, so the alternatives end up in the same form as the
1432
+ * chosen value would. Absent and unreadable readings pass through
1433
+ * unchanged, since neither one has a value to convert.
1434
+ */
1435
+ declare function mapReading<T, U>(reading: Reading<T>, f: (value: T) => U): Reading<U>;
1436
+ /**
1437
+ * Read further from what this reading found. `f` runs on a written
1438
+ * value with the range it was written at, so a step that turns out to
1439
+ * be unreadable can say so against the same syntax.
1440
+ *
1441
+ * `f` runs on each of an ambiguous reading's candidates too, and the ones
1442
+ * that do read come back as the candidates of an ambiguous reading with the
1443
+ * same reason. That way the alternatives stay next to the chosen value all
1444
+ * the way to the summary, instead of being dropped at the first step
1445
+ * that reads further.
1446
+ */
1447
+ declare function andThenReading<T, U>(reading: Reading<T>, f: (value: T, range: SourceRange) => Reading<U>): Reading<U>;
1448
+ /**
1449
+ * Which of several readings a claim comes from, for a value a library lets
1450
+ * a source give in more than one place.
1451
+ */
1452
+ interface ChosenReading<T> {
1453
+ /**
1454
+ * The reading a claim comes from: the first that was written, or if none
1455
+ * was, the first that failed to read, or absent when all of them were
1456
+ * absent.
1457
+ */
1458
+ reading: Reading<T>;
1459
+ /**
1460
+ * The readings the choice passed over that nobody could resolve. A later
1461
+ * reading supplying the value does not settle what an earlier one said
1462
+ * and could not be read, so these still go to the
1463
+ * builder and their reasons still reach the summary.
1464
+ */
1465
+ passedOver: readonly Reading<T>[];
1466
+ }
1467
+ /**
1468
+ * Choose among readings of the same value, taking the first that was
1469
+ * written. Nothing is thrown away: whatever the choice passed over and
1470
+ * could not read comes back next to it in `passedOver`, so a
1471
+ * `response_model` nobody could read still lands as a gap even when the
1472
+ * return annotation after it supplies the type.
1473
+ */
1474
+ declare function firstWrittenReading<T>(readings: readonly Reading<T>[]): ChosenReading<T>;
1475
+ /**
1476
+ * What a written reading found, for a reader that has to read further from
1477
+ * it before anything is claimed. A route's path template gives the
1478
+ * parameters that decide what each of the handler's parameters is, and
1479
+ * that has to be settled before there is a summary field to fill in.
1480
+ *
1481
+ * This applies no default and gives no reason, so most of what a summary
1482
+ * says must not be written from it. Hand the reading to the
1483
+ * builder instead, and the fixed rule gets applied to it once, somewhere
1484
+ * review can see it.
1485
+ *
1486
+ * The identity fields of a boundary binding are the exception, and the path
1487
+ * this reads is one of them. A binding either says where a unit is or says
1488
+ * nothing and pairs with nothing, and no pack declares a
1489
+ * default for what a boundary is called, so the value the builder would
1490
+ * put there is the value this gives back. Hand the reading over as well and
1491
+ * the reason still becomes a gap.
1492
+ */
1493
+ declare function valueToReadFurtherFrom<T>(reading: Reading<T>): T | null;
1494
+
1477
1495
  /**
1478
1496
  * Small helpers for pattern packs that are built the same way.
1479
1497
  *
@@ -1865,10 +1883,17 @@ interface RawCodeStructure {
1865
1883
  bodyAccessors?: string[];
1866
1884
  /** The same, for the status: `status` for fetch and for axios. */
1867
1885
  statusAccessors?: string[];
1886
+ /** The same, for the success flag: `ok` for fetch, nothing for axios. */
1887
+ successAccessors?: string[];
1888
+ /** Whether this client's non-2xx arrives as a response or a rejection. */
1889
+ failureDelivery?: FailureDelivery;
1868
1890
  /** Left exactly as written, because the extractor does not depend on
1869
1891
  * graphql-js. The parsing happens at check time. */
1870
1892
  graphqlDocument?: string;
1871
1893
  graphqlSchemaSdl?: string;
1894
+ /** The document this unit was read out of, when something else read out of
1895
+ * the same document states what this one relies on. */
1896
+ sourceDocumentLabel?: string;
1872
1897
  /** The extractor cannot derive this. An adapter that has the SDL and knows
1873
1898
  * which field the resolver serves fills it in. */
1874
1899
  graphqlDeclaredContract?: GraphqlDeclaredContract;
@@ -1917,4 +1942,4 @@ declare function terminalToOutput(terminal: RawTerminal): Output;
1917
1942
  declare function effectToIR(effect: RawEffect): Effect;
1918
1943
  declare function paramToInput(param: RawParameter): Input;
1919
1944
 
1920
- export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
1945
+ export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };