@suss/extractor 0.19.0 → 0.21.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,4 +1,5 @@
1
- import { Effect, MessageBusSemantics, DeployableUnit, Predicate, BehavioralSummary, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, GraphqlDeclaredContract, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
1
+ import { Effect, MessageBusSemantics, DeployableUnit, BehavioralSummary, Predicate, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, WrapperReference, GraphqlDeclaredContract, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
2
+ import { z } from 'zod';
2
3
 
3
4
  /**
4
5
  * What a unit reads out of what it was given.
@@ -21,6 +22,112 @@ interface InputRead {
21
22
  path: string[];
22
23
  }
23
24
 
25
+ /**
26
+ * Reading a function the project wrote in front of a library, before
27
+ * anything is extracted.
28
+ *
29
+ * A service writes `registerCrud(app, "users", handlers)` and puts the
30
+ * library call one hop away, inside a helper of its own, where the path
31
+ * is a parameter. The call site has the literals and no library; the
32
+ * helper body has the library and no literals.
33
+ *
34
+ * A pack asks here for the helper to be read once, over the whole
35
+ * project, before any file is walked. What comes back says what the
36
+ * body does in terms of the helper's own parameters, and the pack turns
37
+ * that into the patterns and recognizers it used to take as config.
38
+ */
39
+
40
+ /**
41
+ * One value inside a helper's body, said in the helper's own terms.
42
+ *
43
+ * Every variant is something a call site can fill in. Anything else is
44
+ * `unread`, which a pack drops rather than guesses at.
45
+ */
46
+ type HelperValue =
47
+ /**
48
+ * A string, with `{N}` standing where parameter N was interpolated.
49
+ * A literal with no interpolation is the literal itself.
50
+ */
51
+ {
52
+ as: "text";
53
+ text: string;
54
+ }
55
+ /** Parameter N, or one named property of it. */
56
+ | {
57
+ as: "parameter";
58
+ position: number;
59
+ property?: string;
60
+ }
61
+ /** An object literal, each property read the same way. */
62
+ | {
63
+ as: "object";
64
+ properties: Record<string, HelperValue>;
65
+ }
66
+ /** A call, so a pack can see through `JSON.stringify(request)`. */
67
+ | {
68
+ as: "call";
69
+ callee: string;
70
+ arguments: HelperValue[];
71
+ }
72
+ /** Something none of the above covers. */
73
+ | {
74
+ as: "unread";
75
+ };
76
+ /** One call a helper's body makes, read in the helper's own terms. */
77
+ interface HelperSink {
78
+ /** The property the call was made through, or null for a bare call. */
79
+ method: string | null;
80
+ /** What the call was made on. */
81
+ receiver: HelperValue;
82
+ arguments: HelperValue[];
83
+ }
84
+ /** A function the project declares, as the index read it. */
85
+ interface ProjectHelper {
86
+ /** What the declaration calls it, which is what a call site writes. */
87
+ name: string;
88
+ /** Absolute path of the file declaring it. */
89
+ file: string;
90
+ /** Its parameters, in order, by name. */
91
+ parameters: string[];
92
+ /**
93
+ * Parameters some caller handed this pack's own value to. Empty when
94
+ * the helper was found by its body rather than by a call site.
95
+ */
96
+ subjectParameters: number[];
97
+ /** Every call its body makes that the search asked about. */
98
+ sinks: HelperSink[];
99
+ }
100
+ /**
101
+ * How the index picks out which of the project's functions to read.
102
+ *
103
+ * `subject` starts at a call site: a function the project hands one of
104
+ * this pack's own values to is a helper of this pack's, whatever the
105
+ * helper's file imports. `text` starts at the body, for a pack whose
106
+ * library is reached over the wire and has no import to look for. Both
107
+ * come from the library itself, which is the bar `requiresImport` meets.
108
+ */
109
+ type HelperSearch = {
110
+ by: "subject";
111
+ } | {
112
+ by: "text";
113
+ contains: string[];
114
+ };
115
+ /** What a pack contributes to a run once its helpers have been read. */
116
+ interface HelperDeclarations {
117
+ discovery?: DiscoveryPattern[];
118
+ invocationRecognizers?: InvocationRecognizer[];
119
+ }
120
+ /** A pack's standing request to have the project's helpers read. */
121
+ interface ProjectHelpers {
122
+ find: HelperSearch;
123
+ /**
124
+ * Turned into patterns and recognizers before the first file is
125
+ * walked. It is handed data, never an AST, so a pack that declares
126
+ * one still runs on any adapter that implements the reading.
127
+ */
128
+ declare(helpers: readonly ProjectHelper[]): HelperDeclarations;
129
+ }
130
+
24
131
  /**
25
132
  * The `PatternPack` interface, which is what a framework pack gives a language
26
133
  * adapter. The pack says WHAT to look for (which import, which call, which
@@ -384,6 +491,16 @@ type DiscoveryMatch = {
384
491
  type: "registrationTemplate";
385
492
  helperName: string;
386
493
  importModule?: string;
494
+ /**
495
+ * Which argument is the routable, so a route the helper writes
496
+ * keys on the same app as one written beside it and the
497
+ * middleware registered there covers it too.
498
+ */
499
+ subject?: {
500
+ argument: number;
501
+ importModule: string;
502
+ importNames: string[];
503
+ };
387
504
  registrations: Array<{
388
505
  method: string;
389
506
  pathTemplate: string;
@@ -637,6 +754,52 @@ interface DiscoveryPattern {
637
754
  /** Argument position of the mounted router/sub-app value. */
638
755
  targetPosition: number;
639
756
  };
757
+ /**
758
+ * How this framework registers a function that runs around a
759
+ * handler rather than as one: middleware, an error handler, a
760
+ * validation hook. Like `mount`, this only means anything when
761
+ * `match.type` is `"registrationCall"`, because wrapper discovery
762
+ * reuses that match's `importModule` and `importName` to work out
763
+ * which variables in a file are the routable being registered on.
764
+ *
765
+ * When set, the registered function becomes a unit of its own and is
766
+ * summarized like any other, and every unit registered on the same
767
+ * routable records a reference to it. A registration whose function
768
+ * the resolution store cannot follow contributes nothing.
769
+ */
770
+ wraps?: {
771
+ /** Method name that registers a wrapper, e.g. "use" or "onError". */
772
+ method: string;
773
+ /** Argument position of the wrapper function. */
774
+ targetPosition: number;
775
+ /**
776
+ * Argument position of a path pattern narrowing which routes the
777
+ * wrapper runs for, when the method takes one. Absent means the
778
+ * wrapper runs for every route on the subject.
779
+ */
780
+ scopePosition?: number;
781
+ /**
782
+ * Parameter position of the continuation inside the wrapper, the one
783
+ * it calls to hand control on. Absent when the wrapper never
784
+ * continues, which is how an error handler that always responds is
785
+ * written.
786
+ */
787
+ continuationParam?: number;
788
+ /**
789
+ * Parameter position that receives what the wrapped unit threw. A
790
+ * wrapper that declares one runs only when the wrapped unit's path
791
+ * ended by throwing, which is a fact about how the framework invokes
792
+ * it rather than anything its body says. Absent means the wrapper
793
+ * runs on the ordinary path.
794
+ */
795
+ throwParam?: number;
796
+ /**
797
+ * Only match a registered function declared with exactly this many
798
+ * parameters. Express tells its error handlers apart from its
799
+ * middleware by arity alone, both being `app.use(fn)`.
800
+ */
801
+ arity?: number;
802
+ };
640
803
  /**
641
804
  * This pattern only runs against files that import one of these module
642
805
  * specifiers, or a sub-path of one. An empty array means no gate at all
@@ -723,6 +886,17 @@ type TerminalMatch = {
723
886
  * `useEffect` bodies, Node `.on(...)` callbacks) should include it.
724
887
  */
725
888
  type: "functionFallthrough";
889
+ } | {
890
+ /**
891
+ * A call to the parameter at this position, `next()` inside a
892
+ * middleware. Nothing declares this in a pack: the adapter builds
893
+ * it from `DiscoveryPattern.wraps.continuationParam`, so a
894
+ * wrapper's path that hands control on ends in a `delegate`
895
+ * output and a path that responds first does not. That is how
896
+ * composition tells the two apart.
897
+ */
898
+ type: "parameterCall";
899
+ parameterPosition: number;
726
900
  };
727
901
  interface TerminalExtraction {
728
902
  statusCode?: {
@@ -757,8 +931,8 @@ interface TerminalExtraction {
757
931
  defaultStatusCode?: number;
758
932
  }
759
933
  interface TerminalPattern {
760
- /** What kind of output this terminal produces: "response", "throw", "return", "render" */
761
- kind: "response" | "throw" | "return" | "render";
934
+ /** What kind of output this terminal produces: "response", "throw", "return", "render", "delegate" */
935
+ kind: "response" | "throw" | "return" | "render" | "delegate";
762
936
  match: TerminalMatch;
763
937
  extraction: TerminalExtraction;
764
938
  /**
@@ -941,6 +1115,19 @@ interface PatternPack {
941
1115
  * will then serve results for code that has since changed.
942
1116
  */
943
1117
  version?: string;
1118
+ /**
1119
+ * Files under the project this pack reads that are not source files,
1120
+ * given the files the run is about to walk. Their content feeds the
1121
+ * same cache key the pack's own config does, so a run made after
1122
+ * somebody edits one reads the project again instead of handing back
1123
+ * the previous answer.
1124
+ *
1125
+ * The aws-lambda pack is the case this exists for: a SAM template
1126
+ * decides which handlers there are and what invokes them, and no
1127
+ * source file changes when that template does. A pack that reads only
1128
+ * the code it is handed leaves this out.
1129
+ */
1130
+ discoveryInputs?: (files: readonly string[]) => string[];
944
1131
  languages: string[];
945
1132
  discovery: DiscoveryPattern[];
946
1133
  terminals: TerminalPattern[];
@@ -1109,6 +1296,13 @@ interface PatternPack {
1109
1296
  * available without importing anything).
1110
1297
  */
1111
1298
  requiresImport?: string[];
1299
+ /**
1300
+ * Functions the project itself wrote in front of this library, read
1301
+ * once across the whole project before any file is walked. What the
1302
+ * pack makes of them joins its own patterns and recognizers for the
1303
+ * rest of the run.
1304
+ */
1305
+ projectHelpers?: ProjectHelpers;
1112
1306
  /**
1113
1307
  * Environment variables the pack's library reads from inside
1114
1308
  * node_modules, where no walk ever looks. Declaring them keeps the
@@ -1292,6 +1486,16 @@ interface DiscoveredCustomUnit {
1292
1486
  kind: string;
1293
1487
  /** Discovered name (e.g. "UserCard"). */
1294
1488
  name: string;
1489
+ /**
1490
+ * The unit's callable identity, when the pack states one: the module
1491
+ * it lives in and the name it goes by there. A server action is the
1492
+ * case, so intent and the keyed pairing pass can refer to it. The
1493
+ * adapter puts both on the unit's function-call binding.
1494
+ */
1495
+ functionCallInfo?: {
1496
+ module: string;
1497
+ exportName: string;
1498
+ };
1295
1499
  /**
1296
1500
  * Terminal patterns to extract from this unit's body. Defaults to
1297
1501
  * the pack-level `terminals` when unset.
@@ -1345,6 +1549,14 @@ interface DiscoveredCustomUnit {
1345
1549
  /** Null when the pack knows the wire but not the channel on it. */
1346
1550
  channel: string | null;
1347
1551
  };
1552
+ /**
1553
+ * The deployed unit this one is, for a unit nothing else routes to.
1554
+ * A Lambda with no event source in its template is reached by being
1555
+ * invoked by name, so its own platform and name are the boundary, and
1556
+ * the adapter builds a `unit-invocation` binding from them. Set it
1557
+ * where a unit would otherwise fall back to a keyless function-call.
1558
+ */
1559
+ invocationInfo?: DeployableUnit;
1348
1560
  /** The thing that gets deployed and runs this unit, when known. */
1349
1561
  deployableUnit?: DeployableUnit;
1350
1562
  /**
@@ -1631,6 +1843,56 @@ declare function firstWrittenReading<T>(readings: readonly Reading<T>[]): Chosen
1631
1843
  */
1632
1844
  declare function valueToReadFurtherFrom<T>(reading: Reading<T>): T | null;
1633
1845
 
1846
+ /**
1847
+ * composeWrappers.ts: what a unit does once the code registered around
1848
+ * it is folded in.
1849
+ *
1850
+ * A wrapper is a meta-function: it takes a unit and returns a unit. Its
1851
+ * summary already says what it does, because the call to its
1852
+ * continuation comes through as a `delegate` transition, so one
1853
+ * application is the wrapper's short circuits plus its pass-throughs
1854
+ * times the wrapped unit's transitions, and a stack is repeated
1855
+ * application. The package README works the example through and says
1856
+ * what composition does not read.
1857
+ */
1858
+
1859
+ /**
1860
+ * Every summary, with the ones that record wrappers replaced by their
1861
+ * composition. A summary with no wrappers, and one whose wrappers this
1862
+ * run has no summaries for, comes back untouched.
1863
+ */
1864
+ declare function composeWrappers(summaries: readonly BehavioralSummary[]): BehavioralSummary[];
1865
+
1866
+ /**
1867
+ * Which branch an effect belongs to.
1868
+ *
1869
+ * An adapter finds the calls a body makes once, then has to say which
1870
+ * of the branches it also found each call runs on. Two facts settle it,
1871
+ * and both are already extracted: the guards the call is written under,
1872
+ * and where the branch's terminal is in the file. Every adapter that
1873
+ * attributes effects to branches reads from here, so they all decide
1874
+ * it the same way.
1875
+ *
1876
+ * Neither test is enough alone, and the README beside this file says
1877
+ * why with the two shapes that go wrong.
1878
+ */
1879
+
1880
+ /**
1881
+ * Whether the branch leaves room for every guard on the effect. A guard
1882
+ * the branch wrote down the other way around rules the effect out. A
1883
+ * guard it says nothing about does not, because a branch out of a loop
1884
+ * or a catch says nothing about what happened inside.
1885
+ */
1886
+ declare function guardsHoldOn(preconditions: readonly RawCondition[] | undefined, conditions: readonly RawCondition[]): boolean;
1887
+ /**
1888
+ * Whether a call on `effectLine` was written by the time the terminal
1889
+ * ending on `terminalEndLine` is reached. The terminal's last line and
1890
+ * not its first, because a call written inside the terminal's own
1891
+ * expression, `return new Promise((resolve) => resolve(read()))`, runs
1892
+ * as part of producing it.
1893
+ */
1894
+ declare function runsBefore(effectLine: number, terminalEndLine: number): boolean;
1895
+
1634
1896
  /**
1635
1897
  * Small helpers for pattern packs that are built the same way.
1636
1898
  *
@@ -1676,15 +1938,39 @@ declare function httpRouteDiscovery(opts: {
1676
1938
  */
1677
1939
  mount?: DiscoveryPattern["mount"];
1678
1940
  }): DiscoveryPattern[];
1941
+ /**
1942
+ * Discovery entries for the functions a framework registers around its
1943
+ * handlers: middleware, error handlers, validation hooks.
1944
+ *
1945
+ * A wrapper becomes a unit of its own, summarized like any other, so
1946
+ * these entries carry no `bindingExtraction` and no registration chain.
1947
+ * Their `match` is there for the import and the imported name, which is
1948
+ * how wrapper discovery works out which variables in a file are the
1949
+ * routable. One entry per (import name, wrapper shape) pair, since a
1950
+ * framework can register more than one kind of wrapper on a routable.
1951
+ */
1952
+ declare function wrapperDiscovery(opts: {
1953
+ importModule: string;
1954
+ importNames: readonly string[];
1955
+ wraps: ReadonlyArray<NonNullable<DiscoveryPattern["wraps"]>>;
1956
+ /** Defaults to "middleware". Override for packs that want another kind. */
1957
+ kind?: string;
1958
+ }): DiscoveryPattern[];
1679
1959
  /**
1680
1960
  * One route a project helper registers when called, spelled with `{N}`
1681
1961
  * placeholders for the call's positional arguments.
1682
1962
  */
1683
1963
  interface RegistrationHelper {
1684
- /** The helper's exported name, as the project's code imports it. */
1964
+ /** What the helper is called, as the project's code writes it. */
1685
1965
  helperName: string;
1686
- /** The module the helper is imported from, to tell two apart. */
1966
+ /** The file declaring it, so a same-named function elsewhere is left alone. */
1687
1967
  importModule?: string;
1968
+ /** Which argument is the app, so middleware on it covers these routes. */
1969
+ subject?: {
1970
+ argument: number;
1971
+ importModule: string;
1972
+ importNames: string[];
1973
+ };
1688
1974
  registrations: Array<{
1689
1975
  method: string;
1690
1976
  pathTemplate: string;
@@ -1694,17 +1980,25 @@ interface RegistrationHelper {
1694
1980
  /**
1695
1981
  * Discovery patterns for a project's own registration helpers.
1696
1982
  *
1697
- * A helper like `registerCrud(app, "users", handlers)` registers
1698
- * routes the call-site never spells out, so registration-call
1699
- * discovery cannot see them. The helper's name belongs to one project,
1700
- * which is why this arrives through per-project pack config rather
1701
- * than shipping inside any framework pack:
1702
- *
1703
- * suss extract -f express=config.json
1704
- *
1705
- * with `{ "registrationHelpers": [...] }` in the file.
1983
+ * A helper like `registerCrud(app, "users", handlers)` registers routes
1984
+ * the call site never spells out. What each one registers comes from
1985
+ * the project helper index, which reads the helper's body before
1986
+ * extraction, so a call site expands per call and a helper called twice
1987
+ * gives two routes rather than none.
1706
1988
  */
1707
1989
  declare function registrationHelperDiscovery(helpers: readonly RegistrationHelper[], kind?: string): DiscoveryPattern[];
1990
+ /**
1991
+ * The standing request an HTTP pack makes to have the project's own
1992
+ * route helpers read, so what each one registers is a fact about the
1993
+ * code rather than something the project restates in config.
1994
+ */
1995
+ declare function routeHelperIndex(opts: {
1996
+ importModule: string;
1997
+ importNames: readonly string[];
1998
+ methods: readonly string[];
1999
+ /** Defaults to "handler", to match `httpRouteDiscovery`. */
2000
+ kind?: string;
2001
+ }): ProjectHelpers;
1708
2002
  /**
1709
2003
  * The payload behind a `JSON.stringify(...)` call, or the argument
1710
2004
  * unchanged when it is anything else. A producer serializes its message
@@ -1713,6 +2007,52 @@ declare function registrationHelperDiscovery(helpers: readonly RegistrationHelpe
1713
2007
  */
1714
2008
  declare function unwrapJsonStringify(body: EffectArg | null): EffectArg | null;
1715
2009
 
2010
+ /**
2011
+ * Option declarations more than one pack takes.
2012
+ *
2013
+ * A pack exports `optionsSchema` beside its factory, and the CLI parses
2014
+ * a `-f pack=config.json` file against it before the factory runs, so a
2015
+ * key nobody declared is refused by name instead of read as nothing.
2016
+ *
2017
+ * Four packs accept `storageSystem` and three accept `scope`. A copy
2018
+ * per pack is how one of them ends up allowing a value the others
2019
+ * reject, which is what happened when two doc comments named
2020
+ * `"postgres"` and the union allowed only `"postgresql"`.
2021
+ */
2022
+
2023
+ /**
2024
+ * Which database is behind the connection, spelled the way the
2025
+ * provider summaries spell it. Both sides build a pairing key from
2026
+ * this, so a value only one side would write stops the two pairing
2027
+ * with nothing said about why.
2028
+ */
2029
+ declare const storageSystemOption: z.ZodEnum<{
2030
+ postgresql: "postgresql";
2031
+ mysql: "mysql";
2032
+ sqlite: "sqlite";
2033
+ }>;
2034
+ /**
2035
+ * Which of a project's connections an access belongs to, matched
2036
+ * against the scope the provider summaries carry. Packs default it to
2037
+ * `"default"`, so a project with one connection never sets it.
2038
+ */
2039
+ declare const scopeOption: z.ZodString;
2040
+ /**
2041
+ * A call the project has declared to be its own dispatcher, which both
2042
+ * message-bus packs take under `producers`.
2043
+ *
2044
+ * `receiver` is the type rather than the variable: a service keeps its
2045
+ * dispatcher in a field, a closure or a constructor parameter, and the
2046
+ * type is the only thing stable across all three.
2047
+ */
2048
+ declare const configuredCallOption: z.ZodObject<{
2049
+ module: z.ZodString;
2050
+ receiver: z.ZodString;
2051
+ method: z.ZodString;
2052
+ subjectArg: z.ZodNumber;
2053
+ bodyArg: z.ZodOptional<z.ZodNumber>;
2054
+ }, z.core.$strict>;
2055
+
1716
2056
  /**
1717
2057
  * The path engine, written against `StructuredStatement` rather than any one
1718
2058
  * language. Every control-flow path from entry to a terminal contributes its
@@ -1728,6 +2068,8 @@ declare function unwrapJsonStringify(body: EffectArg | null): EffectArg | null;
1728
2068
  * enclosure conditions plus an opaque conjunct instead of guessing.
1729
2069
  */
1730
2070
 
2071
+ /** The cap on how many paths to enumerate. Past it the caller falls back to degraded conditions. */
2072
+ declare const MAX_PATHS = 256;
1731
2073
  /** A construct the lowering step will not model safely, such as switch and case rules the enumeration does not cover. Callers catch this and degrade. */
1732
2074
  declare class UnmodeledFlow extends Error {
1733
2075
  }
@@ -1810,6 +2152,40 @@ declare class IdMap<T extends Identified, V> implements Iterable<[T, V]> {
1810
2152
  [Symbol.iterator](): Iterator<[T, V]>;
1811
2153
  }
1812
2154
 
2155
+ /**
2156
+ * nodeWalk.ts: the one recursion the adapters use to read a declaration
2157
+ * wherever the language allows it to be written.
2158
+ *
2159
+ * A declaration goes where a statement goes, and every language has more
2160
+ * places for a statement than a reader remembers to list. So an adapter
2161
+ * does not list the containers it descends into. It walks every named
2162
+ * child and says only which nodes keep their own body, because that set
2163
+ * is short and a grammar's own vocabulary already names it.
2164
+ */
2165
+ /** A parse tree, however a grammar spells one. */
2166
+ interface WalkableNode<T> {
2167
+ readonly namedChildren: ReadonlyArray<T | null>;
2168
+ }
2169
+ /**
2170
+ * Returned by `into` for a node whose children the walk should leave
2171
+ * unread, such as one whose body belongs to what it declares. A symbol,
2172
+ * so it cannot collide with whatever a caller carries.
2173
+ */
2174
+ declare const SKIP_CHILDREN: unique symbol;
2175
+ /** What a walk does at each node it reaches. */
2176
+ interface NodeVisitor<T, C> {
2177
+ /** Called once per node, in source order, before its own children. */
2178
+ at(node: T, carried: C): void;
2179
+ /** What to carry into this node's children, or `SKIP_CHILDREN` to leave them unread. */
2180
+ into(node: T, carried: C): C | typeof SKIP_CHILDREN;
2181
+ }
2182
+ /**
2183
+ * Every named node under `root`, depth first and in source order, with a
2184
+ * value the visitor updates as the walk descends. `root` itself is not
2185
+ * visited, because a caller starts from the body it is reading.
2186
+ */
2187
+ declare function walkDescendants<T extends WalkableNode<T>, C>(root: T, carried: C, visitor: NodeVisitor<T, C>): void;
2188
+
1813
2189
  /**
1814
2190
  * The small surface every language adapter implements, whatever that
1815
2191
  * language's own tooling looks like underneath.
@@ -2017,6 +2393,20 @@ interface CallOps {
2017
2393
  * `model("User", schema)` call it was declared as says everything.
2018
2394
  */
2019
2395
  callee(): CallOps | null;
2396
+ /**
2397
+ * Whether the call goes to a name the program bound, rather than to
2398
+ * an expression written in place. `useAppStore(...)` does;
2399
+ * `create()(...)` does not, even though both are bare calls.
2400
+ */
2401
+ namedCallee?(): boolean;
2402
+ /**
2403
+ * The properties the function argument in this position reads off
2404
+ * its first parameter, one per distinct first segment: `(s) =>
2405
+ * s.bears.count` reads `bears`, and a parameter used whole reads
2406
+ * `*`. Null when the argument is not a function of one plain
2407
+ * parameter.
2408
+ */
2409
+ parameterReadsAt?(index: number): readonly string[] | null;
2020
2410
  /**
2021
2411
  * What a named property of the object an argument states says. A
2022
2412
  * property bag is not a call, so nothing else here reaches into one.
@@ -2029,6 +2419,15 @@ interface CallOps {
2029
2419
  * for a pack whose rule has to walk it.
2030
2420
  */
2031
2421
  valueAt(index: number): ValueOps | null;
2422
+ /**
2423
+ * The one call behind the receiver the origin accepts, however many
2424
+ * name, construction, or query hops separate them. Mongoose's
2425
+ * `model(...)` behind a document is the picture. Null when nothing
2426
+ * behind the receiver matches, when two distinct calls do (picking
2427
+ * one would depend on the order facts arrived), and for an origin
2428
+ * kind with no construction to hand back.
2429
+ */
2430
+ anchorCall?(origin: ReceiverOrigin): CallOps | null;
2032
2431
  }
2033
2432
  /**
2034
2433
  * The property an adapter puts its ops on, in the context it hands a
@@ -2251,6 +2650,11 @@ interface RawCodeStructure {
2251
2650
  start: number;
2252
2651
  end: number;
2253
2652
  };
2653
+ /** Character offsets of the unit, when a source position backs it. */
2654
+ span?: {
2655
+ start: number;
2656
+ end: number;
2657
+ };
2254
2658
  exportName: string | null;
2255
2659
  exportPath: string[] | null;
2256
2660
  };
@@ -2292,6 +2696,13 @@ interface RawCodeStructure {
2292
2696
  /** The document this unit was read out of, when something else read out of
2293
2697
  * the same document states what this one relies on. */
2294
2698
  sourceDocumentLabel?: string;
2699
+ /** Set when several mounts serve the declaration and this unit is one of them. */
2700
+ mount?: {
2701
+ siblings: number;
2702
+ prefix: string;
2703
+ };
2704
+ /** The wrappers registered around this unit: middleware, error handlers. */
2705
+ wrappers?: WrapperReference[];
2295
2706
  /** The extractor cannot derive this. An adapter that has the SDL and knows
2296
2707
  * which field the resolver serves fills it in. */
2297
2708
  graphqlDeclaredContract?: GraphqlDeclaredContract;
@@ -2340,7 +2751,10 @@ declare function assembleSummary(raw: RawCodeStructure, options?: ExtractorOptio
2340
2751
  declare function detectGaps(raw: RawCodeStructure, transitions: Transition[], options: ExtractorOptions): Gap[];
2341
2752
  declare function assessConfidence(raw: RawCodeStructure): ConfidenceInfo;
2342
2753
  declare function terminalToOutput(terminal: RawTerminal): Output;
2754
+ /** A condition the adapter left unstructured becomes an opaque predicate
2755
+ * rather than being dropped, so the branch keeps its guard. */
2756
+ declare function rawConditionToPredicate(c: RawCondition): Predicate;
2343
2757
  declare function effectToIR(effect: RawEffect): Effect;
2344
2758
  declare function paramToInput(param: RawParameter): Input;
2345
2759
 
2346
- export { type AccessRecognizer, type AstCapableOps, type BindingExtraction, type BodyContent, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, 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 InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, type OpsCarrier, type PackDeclarations, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, registrationHelperDiscovery, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
2760
+ export { type AccessRecognizer, type AstCapableOps, type BindingExtraction, type BodyContent, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, MAX_PATHS, type NodeVisitor, type OpsCarrier, type PackDeclarations, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, SKIP_CHILDREN, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type WalkableNode, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, composeWrappers, configuredCallOption, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, guardsHoldOn, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, rawConditionToPredicate, registrationHelperDiscovery, routeHelperIndex, runsBefore, scopeOption, sharedGatingConditions, storageSystemOption, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };