@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.cjs +68 -24
- package/dist/index.d.cts +274 -249
- package/dist/index.d.ts +274 -249
- package/dist/index.js +66 -21
- package/package.json +2 -2
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
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
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
|
|
493
|
-
*
|
|
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
|
|
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 };
|