@suss/extractor 0.35.1 → 0.37.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,4 @@
1
- import { Effect, MessageBusSemantics, DeployableUnit, CodeUnitKind, RequestSpellingMetadata, BehavioralSummary, TypeShape, Predicate, ValueRef, RenderNode, ProvenanceSlot, BoundaryBinding, WrapperReference, TestMetadata, GraphqlDeclaredContract, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
1
+ import { BehavioralSummary, Effect, MessageBusSemantics, DeployableUnit, CodeUnitKind, RequestSpellingMetadata, TypeShape, Predicate, ValueRef, BoundaryBinding, RenderNode, ProvenanceSlot, WrapperReference, TestMetadata, GraphqlDeclaredContract, GraphqlMetadata, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -22,6 +22,26 @@ interface InputRead {
22
22
  path: string[];
23
23
  }
24
24
 
25
+ /**
26
+ * Environment variables a library reads from its own installed code,
27
+ * where no walk over the project goes. Without them the checker would
28
+ * call a variable in a template unused when the library reads it on
29
+ * every invocation. An adapter writes one marker summary per declared
30
+ * library that some project file imports, and runtime-config pairing
31
+ * checks the markers before it reports a variable as unused.
32
+ */
33
+
34
+ interface LibraryEnvVars {
35
+ /** What the library's import starts with: `@aws-lambda-powertools/`, `aws_lambda_powertools`. */
36
+ module: string;
37
+ /** Prefixes of the variables the library reads, such as `POWERTOOLS_`. */
38
+ prefixes?: string[];
39
+ /** Exact names of the variables the library reads. */
40
+ names?: string[];
41
+ }
42
+ /** The marker for one library, placed at the first project file found importing it. */
43
+ declare function libraryEnvReadMarker(recognition: string, declared: LibraryEnvVars, importer: string): BehavioralSummary;
44
+
25
45
  /**
26
46
  * Reading a function the project wrote in front of a library, before
27
47
  * anything is extracted.
@@ -240,6 +260,11 @@ type DiscoveryMatch = {
240
260
  hookName: string;
241
261
  operationType: "query" | "mutation" | "subscription";
242
262
  }>;
263
+ /** Where a call passes a client of its own instead of the app's: the options argument and the option. */
264
+ clientOption?: {
265
+ argument: number;
266
+ property: string;
267
+ };
243
268
  } | {
244
269
  /**
245
270
  * An imperative Apollo Client call: `client.query({ query })`,
@@ -565,7 +590,26 @@ type DiscoveryMatch = {
565
590
  * side of the package-export boundary, whichever two they are.
566
591
  */
567
592
  workspaces?: true;
568
- } | TestCaseMatch;
593
+ } | CallbackArgumentMatch | TestCaseMatch;
594
+ /**
595
+ * A function handed to a call or construction of a library export, which
596
+ * the library then calls with work of its own. BullMQ's
597
+ * `new Worker("emails", async (job) => {...})` is the case it was written
598
+ * for: the processor becomes a unit, and a binding the pattern declares
599
+ * can read its channel off the same call with `callArgument`.
600
+ *
601
+ * `new X(...)` and `x(...)` both match. The function is followed the way
602
+ * any value is, so a processor written in another module and passed by
603
+ * name is found too. A function the run cannot settle to one body, such
604
+ * as a parameter or a file path the library loads itself, gives no unit.
605
+ */
606
+ interface CallbackArgumentMatch {
607
+ type: "callbackArgument";
608
+ importModule: string;
609
+ importName: string;
610
+ /** Which argument is the function. */
611
+ callbackPosition: number;
612
+ }
569
613
  /**
570
614
  * Test cases written as nested calls, the way vitest, jest and mocha
571
615
  * write them: `describe("orders", () => { it("cancels", () => ...) })`.
@@ -710,13 +754,18 @@ type BindingExtraction = {
710
754
  *
711
755
  * `decoratorArgument` reads the argument off the same decorator the
712
756
  * match selected the handler by, so `@EventPattern("order.placed")`
713
- * gives "order.placed". `literal` is for a wire whose channel the
714
- * library fixes. `unstated` means the wire is known and the channel is
715
- * not, and it pairs the same as a null channel.
757
+ * gives "order.placed". `callArgument` reads an argument of the call a
758
+ * `callbackArgument` match found the function in, so
759
+ * `new Worker("emails", fn)` gives "emails". `literal` is for a wire
760
+ * whose channel the library fixes. `unstated` means the wire is known
761
+ * and the channel is not, and it pairs the same as a null channel.
716
762
  */
717
763
  type ChannelSource = {
718
764
  from: "decoratorArgument";
719
765
  position: number;
766
+ } | {
767
+ from: "callArgument";
768
+ position: number;
720
769
  } | {
721
770
  from: "literal";
722
771
  value: string;
@@ -1422,14 +1471,7 @@ interface PatternPack {
1422
1471
  * before reporting. `module` matches as a prefix, so one entry covers a
1423
1472
  * family like `@aws-lambda-powertools/`.
1424
1473
  */
1425
- libraryEnvVars?: Array<{
1426
- /** Module-specifier prefix the library's imports start with. */
1427
- module: string;
1428
- /** Env-var name prefixes the library reads, e.g. "POWERTOOLS_". */
1429
- prefixes?: string[];
1430
- /** Exact env-var names the library reads. */
1431
- names?: string[];
1432
- }>;
1474
+ libraryEnvVars?: LibraryEnvVars[];
1433
1475
  /**
1434
1476
  * Library wrappers that return the function they were handed. A call to
1435
1477
  * the `name` that `module` exports resolves to its `argument`-th
@@ -1479,13 +1521,14 @@ interface PatternPack {
1479
1521
  * `uriProperty` the option key whose value is the endpoint. The
1480
1522
  * adapter reads every construction in the project and stamps the
1481
1523
  * client on each operation summary when exactly one distinct client
1482
- * exists; two or more distinct clients abstain, since a hook call
1483
- * does not say which one it goes through.
1524
+ * exists; two or more abstain, unless a call passes its own client.
1484
1525
  */
1485
1526
  graphqlClients?: Array<{
1486
1527
  importModule: string;
1487
1528
  importName: string;
1488
1529
  uriProperty: string;
1530
+ /** On a client a call can pass, the option its transport goes in. */
1531
+ linkProperty?: string;
1489
1532
  /**
1490
1533
  * How this constructor's cache option installs a fragment
1491
1534
  * registry, for the library whose client can supply fragment
@@ -1510,8 +1553,9 @@ interface PatternPack {
1510
1553
  * Which service a client talks to, keyed by the endpoint the
1511
1554
  * construction was read with: the uri literal, or the written
1512
1555
  * expression when the value is computed. The value is the provider
1513
- * workspace name. This is deployment knowledge, so it comes from the
1514
- * pack's own per-project config rather than from the library.
1556
+ * workspace name, or the schema file the provider was read from.
1557
+ * This is deployment knowledge, so it comes from the pack's own
1558
+ * per-project config rather than from the library.
1515
1559
  */
1516
1560
  graphqlClientBindings?: Record<string, string>;
1517
1561
  /**
@@ -1525,6 +1569,14 @@ interface PatternPack {
1525
1569
  files: string[];
1526
1570
  workspace: string;
1527
1571
  }>;
1572
+ /**
1573
+ * What happens to an operation whose client no binding or scope ties
1574
+ * to a service, in a project with clients for more than one endpoint.
1575
+ * `unchecked`, the default, lists it as not checked. `pairWithAll`
1576
+ * pairs it with every resolver that serves its fields, and warns that
1577
+ * the match is ambiguous.
1578
+ */
1579
+ graphqlUnboundClients?: "unchecked" | "pairWithAll";
1528
1580
  /**
1529
1581
  * Per-access recognizers, the counterpart to `invocationRecognizers` for
1530
1582
  * values read without a call, such as `process.env.X`. A recognizer is
@@ -1759,6 +1811,8 @@ interface CaseGroup<Cond> {
1759
1811
  *
1760
1812
  * The lowering works `exitKind` out by scanning the statement's own
1761
1813
  * subtree for a return or a throw, skipping every nested function body.
1814
+ * The engine reads `lines` only to say which loop or try each terminal
1815
+ * is written in.
1762
1816
  *
1763
1817
  * `callbacks` is the bodies of the functions this statement passes to
1764
1818
  * calls it makes, when the language treats those as running for the
@@ -1771,6 +1825,15 @@ interface CaseGroup<Cond> {
1771
1825
  interface LoweredStatementParts<Cond> {
1772
1826
  readonly exitKind: ExitKind;
1773
1827
  readonly callbacks?: readonly StatementBlock<Cond>[];
1828
+ /**
1829
+ * The lines a loop or a try is written on, from its first line to the
1830
+ * end of its body. Without them, a branch cannot say which calls in a
1831
+ * loop may have run before its terminal.
1832
+ */
1833
+ readonly lines?: {
1834
+ readonly start: number;
1835
+ readonly end: number;
1836
+ };
1774
1837
  }
1775
1838
  /**
1776
1839
  * One statement in the unit's control flow, already lowered out of the
@@ -1950,6 +2013,31 @@ declare function firstWrittenReading<T>(readings: readonly Reading<T>[]): Chosen
1950
2013
  */
1951
2014
  declare function valueToReadFurtherFrom<T>(reading: Reading<T>): T | null;
1952
2015
 
2016
+ /**
2017
+ * The `groupId` an effect has, which says which call site in its unit
2018
+ * produced it.
2019
+ *
2020
+ * The id says what the effect is and never where its call is written:
2021
+ * the callee, then a hash of everything else the effect records, such as
2022
+ * its class and the shape of what the call passed. Code that moves or is
2023
+ * reformatted keeps its ids, so `inspect --diff` and `check --base` do
2024
+ * not report it as changed. Two call sites in one unit with the same
2025
+ * effect get the same key, so the ones after the first, in source order,
2026
+ * take `#2`, `#3` and so on. The lines stay in the effect's `location`,
2027
+ * which the key leaves out.
2028
+ */
2029
+
2030
+ /** The key for an effect, which has no `groupId` yet. */
2031
+ declare function callSiteKey(effect: Effect): string;
2032
+ /**
2033
+ * The effects of one unit's call sites, given in source order with one
2034
+ * list per site, with each `groupId` a later site repeats numbered. An
2035
+ * entry keeps whatever else an adapter records beside its effect.
2036
+ */
2037
+ declare function numberRepeatedCallSites<T extends {
2038
+ effect: Effect;
2039
+ }>(sites: readonly (readonly T[])[]): T[][];
2040
+
1953
2041
  /**
1954
2042
  * Folds the code registered around a unit, such as middleware, into what
1955
2043
  * the unit does.
@@ -2033,16 +2121,46 @@ declare function stampModules(summaries: readonly BehavioralSummary[], modules:
2033
2121
  * Which branch an effect belongs to.
2034
2122
  *
2035
2123
  * An adapter finds the calls a body makes once, then has to say which
2036
- * of the branches it also found each call runs on. Two facts settle it,
2037
- * and both are already extracted: the guards the call is written under,
2038
- * and where the branch's terminal is in the file. Every adapter that
2039
- * attributes effects to branches reads from here, so they all decide
2040
- * it the same way.
2124
+ * of the branches it also found each call runs on. `firesOn` settles it
2125
+ * from what is already extracted: the guards the call is written under,
2126
+ * the line it is written on, and where the branch's terminal is. Every
2127
+ * adapter attributes effects to branches through it, so they all decide
2128
+ * it the same way, for a plain call and for one a pack recognized.
2041
2129
  *
2042
- * Neither test is enough alone. This package's DESIGN.md shows the two
2043
- * cases where one test on its own gets the branch wrong.
2130
+ * This package's DESIGN.md shows why each test is there, with the cases
2131
+ * where leaving one out puts an effect on the wrong branch.
2044
2132
  */
2045
2133
 
2134
+ /** Where the call or read behind an effect is written. */
2135
+ interface EffectSite {
2136
+ /** The line the statement the call is written in starts on. */
2137
+ line: number;
2138
+ /** The guards the call is written under, spelled the way a branch records its conditions. */
2139
+ preconditions?: readonly RawCondition[] | undefined;
2140
+ /**
2141
+ * For a call in a `finally` or `ensure` body, the first line of the
2142
+ * try it cleans up after. The call runs on every path that entered
2143
+ * that try, including one that returned or threw before reaching it.
2144
+ */
2145
+ cleansUpFrom?: number | undefined;
2146
+ }
2147
+ /** An effect, and where it was written. */
2148
+ interface PlacedEffect<E> {
2149
+ effect: E;
2150
+ site: EffectSite;
2151
+ }
2152
+ /** What the branch test reads off a branch. */
2153
+ type BranchEnding = Pick<RawBranch, "conditions" | "terminal" | "loopAround">;
2154
+ /**
2155
+ * Whether the effect written at `site` can run before `branch` reaches its
2156
+ * terminal. A call in the loop around the terminal may have run on an
2157
+ * earlier pass, whatever its guards say about the last one, so it stays.
2158
+ * Anything else needs a branch that does not contradict its guards, and
2159
+ * has to be written no later than the terminal ends.
2160
+ */
2161
+ declare function firesOn(site: EffectSite, branch: BranchEnding): boolean;
2162
+ /** The effects that can run before the branch reaches its terminal, in the order given. */
2163
+ declare function effectsFiringOn<E>(placed: readonly PlacedEffect<E>[], branch: BranchEnding): E[];
2046
2164
  /**
2047
2165
  * Whether the branch leaves room for every guard on the effect. A guard
2048
2166
  * the branch wrote down the other way around rules the effect out. A
@@ -2111,20 +2229,19 @@ declare function throughHelper(branch: RawBranch, at: {
2111
2229
  * records of field names a branch's `expectedInput` lists.
2112
2230
  */
2113
2231
  declare function mergeReadShapes(a: TypeShape | null, b: TypeShape | null): TypeShape | null;
2114
- /** One call in a caller's body that hands a helper the response, in source order. */
2115
- interface HandOffSite {
2232
+ /**
2233
+ * One call in a caller's body that hands a helper the response, in
2234
+ * source order. A branch reaches it when an effect written there would
2235
+ * fire on the branch.
2236
+ */
2237
+ interface HandOffSite extends EffectSite {
2116
2238
  /** The helper's paths, in the caller's terms. */
2117
2239
  helper: readonly RawBranch[];
2118
- preconditions?: readonly RawCondition[] | undefined;
2119
- /** The line the statement holding the call starts on, which decides whether a branch reaches it. */
2120
- line: number;
2121
2240
  /** The lines the call is written on. */
2122
2241
  at: {
2123
2242
  start: number;
2124
2243
  end: number;
2125
2244
  };
2126
- /** A call in a `finally` runs on every path, even one that left before it. */
2127
- alwaysRuns?: boolean;
2128
2245
  }
2129
2246
  /**
2130
2247
  * The branch split at each hand-off on it, in source order. A path that
@@ -2392,7 +2509,32 @@ interface StructuredPathConditionsResult<Cond, Terminal> {
2392
2509
  byTerminal: Map<Terminal, ConditionInfo<Cond>[][]>;
2393
2510
  /** Condition lists for paths that fall through the end of the body. */
2394
2511
  fallthrough: ConditionInfo<Cond>[][];
2512
+ /** Where each terminal is written, for the terminals inside a loop or a cleanup body. */
2513
+ placement: Map<Terminal, TerminalPlacement>;
2514
+ }
2515
+ /** Which loop and which try a terminal is written in, as effect placement reads them. */
2516
+ interface TerminalPlacement {
2517
+ /**
2518
+ * The lines of the outermost loop the terminal is in. Anything else
2519
+ * written in those lines may have run on an earlier pass.
2520
+ */
2521
+ loopAround?: {
2522
+ start: number;
2523
+ end: number;
2524
+ };
2525
+ /**
2526
+ * For a terminal in a `finally` or `ensure` body, the first line of the
2527
+ * outermost try it cleans up after. It runs on every path that got
2528
+ * that far, including one that left the try early.
2529
+ */
2530
+ cleansUpFrom?: number;
2395
2531
  }
2532
+ type ParentMap<Cond> = ReadonlyMap<StructuredStatement<Cond>, StructuredStatement<Cond> | null>;
2533
+ /**
2534
+ * Which loop and which try each terminal is written in. A lowering that
2535
+ * gave its loops and tries no `lines` gets no placement for them.
2536
+ */
2537
+ declare function placeTerminals<Cond, Terminal>(input: Pick<StructuredPathConditionsInput<Cond, Terminal>, "statements" | "terminalsByStmt">, parentOf?: ParentMap<Cond>): Map<Terminal, TerminalPlacement>;
2396
2538
  /**
2397
2539
  * Work out the conditions on each path, for every StructuredStatement
2398
2540
  * reachable from `input.statements`. Throws `PathBudgetExceeded` when the
@@ -2518,6 +2660,36 @@ type ChildrenOf<T> = (node: T) => readonly T[];
2518
2660
  */
2519
2661
  declare function walkDescendants<T, C>(root: T, carried: C, childrenOf: ChildrenOf<T>, visitor: NodeVisitor<T, C>): void;
2520
2662
 
2663
+ /**
2664
+ * Where each of a body's calls is written, in the terms the branch test
2665
+ * reads: the paths to the statement the call is in, the line that
2666
+ * statement starts on, and the try whose cleanup body it is in.
2667
+ *
2668
+ * The Python and the Ruby adapter ask here once per body. The statements
2669
+ * stand in as the engine's terminals, so one enumeration covers every
2670
+ * call in the body. tree-sitter hands back a new wrapper for a node each
2671
+ * time one is read, so statements are matched by id.
2672
+ */
2673
+
2674
+ /** What an adapter says about its own language for `statementSites`. */
2675
+ interface StatementReading<N extends Identified, Cond> {
2676
+ /** The statement a node is written in, which is what the lowering keys a path on. */
2677
+ statementOf: (node: N) => N | null;
2678
+ /** The body lowered with these statements as its terminals. */
2679
+ lower: (statements: readonly N[]) => Pick<StructuredPathConditionsInput<Cond, N>, "statements" | "terminalsByStmt">;
2680
+ /** The one-based line a node starts on. */
2681
+ firstLine: (node: N) => number;
2682
+ }
2683
+ /** The paths to each node's statement, and the site an effect at the node has. */
2684
+ interface StatementSites<N, Cond> {
2685
+ pathsTo: (node: N) => readonly ConditionInfo<Cond>[][] | undefined;
2686
+ /** The site for an effect at the node, with the guards the caller read for it. */
2687
+ siteOf: (node: N, preconditions: readonly RawCondition[]) => EffectSite;
2688
+ /** The site for an effect at the node, with the guards every path to its statement passes. */
2689
+ plainSiteOf: (node: N) => EffectSite;
2690
+ }
2691
+ declare function statementSites<N extends Identified, Cond>(nodes: readonly N[], reading: StatementReading<N, Cond>): StatementSites<N, Cond>;
2692
+
2521
2693
  /**
2522
2694
  * The project root when nothing declares one.
2523
2695
  *
@@ -2591,6 +2763,39 @@ interface SourceSpelling<L extends WalkEnd> {
2591
2763
  /** Every place a value's walk ended, as distinct value references. */
2592
2764
  declare function sourceRefsOf<L extends WalkEnd>(leaves: readonly L[], spelling: SourceSpelling<L>): ValueRef[];
2593
2765
 
2766
+ /**
2767
+ * Functions a deploy manifest says the platform calls, as a pack finds
2768
+ * them for one source file. A Lambda's `Handler` is one: the template
2769
+ * says which file and which function, and nothing in the code calls it.
2770
+ *
2771
+ * The pack reads the manifest, which is the library's business, and
2772
+ * decides which units the function gets. The adapter finds the
2773
+ * definition by `name`, which is a language rule, and builds each unit
2774
+ * on it, so the call walk starts there. Python and Ruby take packs as
2775
+ * data and use this shape; a TypeScript pack has `discoverUnits` and
2776
+ * finds the function itself.
2777
+ */
2778
+
2779
+ interface DeclaredEntryPoint {
2780
+ /**
2781
+ * The function as the manifest writes it, in the language's own
2782
+ * spelling: `handler` for a function at the top of the file, or
2783
+ * `Billing::Handler.process` for a Ruby class method.
2784
+ */
2785
+ name: string;
2786
+ /** The units to build on that function. One function can be several deployed units. */
2787
+ units: DeclaredEntryUnit[];
2788
+ }
2789
+ interface DeclaredEntryUnit {
2790
+ kind: CodeUnitKind;
2791
+ /** The summary's name. */
2792
+ name: string;
2793
+ binding: BoundaryBinding;
2794
+ deployableUnit: DeployableUnit;
2795
+ /** Merged onto the summary's `metadata`. */
2796
+ metadata?: Record<string, unknown>;
2797
+ }
2798
+
2594
2799
  /**
2595
2800
  * The small surface every language adapter implements, whatever that
2596
2801
  * language's own tooling looks like underneath.
@@ -2951,6 +3156,11 @@ declare const CACHE_DIR_ENV = "SUSS_CACHE_DIR";
2951
3156
  declare function chosenCacheRoot(): string | null;
2952
3157
  /** The extraction cache for the files read under `projectDir`. */
2953
3158
  declare function extractionCacheDirFor(projectDir: string): string;
3159
+ /**
3160
+ * The folder `suss map` writes its page and the summaries behind it to:
3161
+ * `.suss` in the project, or a folder of its own under the chosen root.
3162
+ */
3163
+ declare function mapFolderFor(projectDir: string): string;
2954
3164
  /** The file where the server for `projectDir` says how to reach it. */
2955
3165
  declare function liveRecordFor(projectDir: string): string;
2956
3166
 
@@ -3297,6 +3507,35 @@ interface PackConfigNeed {
3297
3507
  * since it never ran, so the caller passes these in.
3298
3508
  */
3299
3509
  declare function packConfigCheck(needs: ReadonlyArray<PackConfigNeed>): HealthCheck;
3510
+ /**
3511
+ * A path in a pack's config file where nothing exists. `resolved` is the
3512
+ * path the pack was given. `inProject` is the same value read against the
3513
+ * project instead, set only when something exists there, since that is
3514
+ * the path the user most likely meant.
3515
+ */
3516
+ interface PackPathMissing {
3517
+ pack: string;
3518
+ option: string;
3519
+ /** The value as the config file wrote it, or one entry of a list. */
3520
+ value: string;
3521
+ configFile: string;
3522
+ resolved: string;
3523
+ inProject?: string;
3524
+ }
3525
+ /**
3526
+ * What went wrong with a path option and what to do about it, worded
3527
+ * once for the health block and for the run finding `check` reports.
3528
+ */
3529
+ declare function describeMissingPath(missing: PackPathMissing): {
3530
+ problem: string;
3531
+ fix: string;
3532
+ };
3533
+ /**
3534
+ * Path options in a config file that point at nothing. The pack still
3535
+ * runs, and every lookup under such a path comes back empty, so the
3536
+ * summaries look like a project with less in it.
3537
+ */
3538
+ declare function packPathCheck(missing: ReadonlyArray<PackPathMissing>): HealthCheck;
3300
3539
  /**
3301
3540
  * Run every health check over one extraction report and return what
3302
3541
  * fired, grouped by which check caught it.
@@ -3708,6 +3947,8 @@ interface RawTerminal {
3708
3947
  * An invocation argument as the adapter read it. An argument that fits none of
3709
3948
  * these variants, arithmetic for instance, comes through as null instead of
3710
3949
  * being dropped, so a reader still knows how many arguments the call had.
3950
+ * JSON null therefore means the adapter could not read the argument, and a
3951
+ * caller that wrote `null` gets `{ kind: "null" }` instead.
3711
3952
  */
3712
3953
  type EffectArg = {
3713
3954
  kind: "string";
@@ -3718,6 +3959,14 @@ type EffectArg = {
3718
3959
  } | {
3719
3960
  kind: "boolean";
3720
3961
  value: boolean;
3962
+ }
3963
+ /** A literal `null`, Python's `None` or Ruby's `nil`, which a caller passed on purpose. */
3964
+ | {
3965
+ kind: "null";
3966
+ }
3967
+ /** JavaScript's `undefined`, kept apart from `null` because a parameter default replaces only this one. */
3968
+ | {
3969
+ kind: "undefined";
3721
3970
  } | {
3722
3971
  kind: "object";
3723
3972
  fields: Record<string, EffectArg>;
@@ -3749,6 +3998,11 @@ type EffectArg = {
3749
3998
  args: EffectArg[];
3750
3999
  } | null;
3751
4000
  type RawEffect = {
4001
+ location?: {
4002
+ start: number;
4003
+ end: number;
4004
+ };
4005
+ } & ({
3752
4006
  type: "mutation";
3753
4007
  target: string;
3754
4008
  operation: "create" | "update" | "delete";
@@ -3765,7 +4019,7 @@ type RawEffect = {
3765
4019
  } | {
3766
4020
  type: "stateChange";
3767
4021
  variable: string;
3768
- };
4022
+ });
3769
4023
  interface RawBranch {
3770
4024
  conditions: RawCondition[];
3771
4025
  terminal: RawTerminal;
@@ -3781,6 +4035,15 @@ interface RawBranch {
3781
4035
  start: number;
3782
4036
  end: number;
3783
4037
  };
4038
+ /**
4039
+ * The lines of the outermost loop the terminal is written in, when it
4040
+ * is in one. A call anywhere in those lines may have run on an earlier
4041
+ * pass before this path reached the terminal.
4042
+ */
4043
+ loopAround?: {
4044
+ start: number;
4045
+ end: number;
4046
+ };
3784
4047
  isDefault: boolean;
3785
4048
  /** The fields a consumer reads off a response inside this branch. */
3786
4049
  expectedInput?: TypeShape | null;
@@ -3925,6 +4188,8 @@ interface RawCodeStructure {
3925
4188
  requestSpelling?: RequestSpellingMetadata;
3926
4189
  /** What a test pack found about a `test` unit: whether it is skipped, and what it replaces with a mock. */
3927
4190
  test?: TestMetadata;
4191
+ /** A pack's own metadata namespaces, merged onto the summary's `metadata` as given. */
4192
+ packMetadata?: Record<string, unknown>;
3928
4193
  /** The extractor cannot derive this. An adapter that has the SDL and knows
3929
4194
  * which field the resolver serves fills it in. */
3930
4195
  graphqlDeclaredContract?: GraphqlDeclaredContract;
@@ -3940,6 +4205,13 @@ interface RawCodeStructure {
3940
4205
  reference: string;
3941
4206
  reason: string;
3942
4207
  };
4208
+ /** The client the operation's own call passes, when one settled. */
4209
+ graphqlClient?: GraphqlMetadata["client"];
4210
+ /** Why the client the operation's call passes could not be settled. */
4211
+ graphqlUnresolvedClient?: {
4212
+ reference: string;
4213
+ reason: string;
4214
+ };
3943
4215
  /**
3944
4216
  * Which part of the boundary the source does not state, and why. The binding
3945
4217
  * still goes out with that part empty, so the unit pairs with nothing rather
@@ -3989,4 +4261,4 @@ declare function rawConditionToPredicate(c: RawCondition): Predicate;
3989
4261
  declare function effectToIR(effect: RawEffect): Effect;
3990
4262
  declare function paramToInput(param: RawParameter): Input;
3991
4263
 
3992
- export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type ArgumentParser, type AstCapableOps, type BindingExtraction, type BodyContent, CACHE_DIR_ENV, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CaseGroup, type ChannelSource, type ChildrenOf, type ChosenReading, type ClassOps, type CodeHasher, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DeclaredModule, type DeclaredStatusDecorators, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EmptyStage, EnclosingNodes, type ExitKind, type ExtractionConfig, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type GlobalPrefixCall, type HandOffSite, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type KeepsArms, KeptParses, type LanguageAdapter, type LoweredStatementParts, MAX_ENTRIES, MAX_HELPER_PATHS, MAX_PATHS, MODULE_SURFACE_RECOGNITION, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackConfigNeed, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackTally, type ParameterSupplier, type ParsedNode, type PartialPlan, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawProvenance, type RawTerminal, type Reading, type ReceiverOrigin, type RedirectDelivery, type RedirectOption, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, type RouteVersioning, SKIP_CHILDREN, type SettledModule, type SourceRange, type SourceSpelling, type StatedSlot, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TestCaseMatch, type Timer, type TimingReport, type TransparentWrapper, type UnitRecord, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type VersionPlacement, type WalkEnd, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, chosenCacheRoot, commonDirectoryOf, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createCodeHasher, createPackTallies, createTimer, detectGaps, effectToIR, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, extractionCacheDirFor, extractionConfigStamp, firstWrittenReading, formatPackHealth, guardsHoldOn, helperPathsOnVariables, httpRouteDiscovery, isListedTestFile, liveRecordFor, makeIgnoredDirectory, makeTransitionId, mapReading, markReturnsAsExitCode, matchesTestFileName, mergeReadShapes, moduleInitStructure, moduleOfFile, noopTimer, ownersWhereWritten, packConfigCheck, packGradients, paramToInput, processCodeHasher, projectFileStamp, rawConditionToPredicate, recordPackFailure, redirectDeliveryWhenSet, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, settleModules, sharedGatingConditions, sourceRefsOf, splitAtHandOffs, stampMayMissAWrite, stampModuleImports, stampModules, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, throughHelper, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };
4264
+ export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type ArgumentParser, type AstCapableOps, type BindingExtraction, type BodyContent, type BranchEnding, CACHE_DIR_ENV, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CallbackArgumentMatch, type CaseGroup, type ChannelSource, type ChildrenOf, type ChosenReading, type ClassOps, type CodeHasher, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredEntryPoint, type DeclaredEntryUnit, type DeclaredMatch, type DeclaredModule, type DeclaredStatusDecorators, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EffectSite, type EmptyStage, EnclosingNodes, type ExitKind, type ExtractionConfig, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type GlobalPrefixCall, type HandOffSite, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type KeepsArms, KeptParses, type LanguageAdapter, type LibraryEnvVars, type LoweredStatementParts, MAX_ENTRIES, MAX_HELPER_PATHS, MAX_PATHS, MODULE_SURFACE_RECOGNITION, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackConfigNeed, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackPathMissing, type PackTally, type ParameterSupplier, type ParsedNode, type PartialPlan, PathBudgetExceeded, type PatternPack, type PlacedEffect, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawProvenance, type RawTerminal, type Reading, type ReceiverOrigin, type RedirectDelivery, type RedirectOption, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, type RouteVersioning, SKIP_CHILDREN, type SettledModule, type SourceRange, type SourceSpelling, type StatedSlot, type StatementBlock, type StatementReading, type StatementSites, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TerminalPlacement, type TestCaseMatch, type Timer, type TimingReport, type TransparentWrapper, type UnitRecord, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type VersionPlacement, type WalkEnd, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, callSiteKey, chosenCacheRoot, commonDirectoryOf, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createCodeHasher, createPackTallies, createTimer, describeMissingPath, detectGaps, effectToIR, effectsFiringOn, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, extractionCacheDirFor, extractionConfigStamp, firesOn, firstWrittenReading, formatPackHealth, guardsHoldOn, helperPathsOnVariables, httpRouteDiscovery, isListedTestFile, libraryEnvReadMarker, liveRecordFor, makeIgnoredDirectory, makeTransitionId, mapFolderFor, mapReading, markReturnsAsExitCode, matchesTestFileName, mergeReadShapes, moduleInitStructure, moduleOfFile, noopTimer, numberRepeatedCallSites, ownersWhereWritten, packConfigCheck, packGradients, packPathCheck, paramToInput, placeTerminals, processCodeHasher, projectFileStamp, rawConditionToPredicate, recordPackFailure, redirectDeliveryWhenSet, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, settleModules, sharedGatingConditions, sourceRefsOf, splitAtHandOffs, stampMayMissAWrite, stampModuleImports, stampModules, statementSites, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, throughHelper, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };