@suss/adapter-typescript 0.29.0 → 0.31.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 { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, Project, ImportDeclaration, Symbol, Expression, NewExpression, Identifier } from 'ts-morph';
1
+ import { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, Project, ImportDeclaration, ArrayLiteralExpression, ObjectLiteralExpression, ObjectLiteralElementLike, Symbol, Expression, NewExpression, Identifier } from 'ts-morph';
2
2
  import { TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, TimingReport, CacheDiagnostic, ExtractionReport, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
3
3
  export { EmptyStage, ExtractionReport, PackFunnel, Timer, TimingReport, computeContentHash } from '@suss/extractor';
4
4
  import { MessageBusSemantics, DeployableUnit, UnfollowedCall, WrapperReference, BehavioralSummary, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
@@ -14,18 +14,17 @@ interface FileSetQuery {
14
14
  }
15
15
 
16
16
  /**
17
- * The resolution store, and the three questions callers ask it.
17
+ * The resolution store, and the questions callers ask it.
18
18
  *
19
19
  * `resolveCallable` says which function a value comes down to, through
20
20
  * any depth of aliasing, imports, re-export barrels, wrapper factories
21
21
  * and `.bind`. `resolveWrittenValue` says which expression a value is
22
22
  * written as, for callers chasing something that is neither a function
23
- * nor an object. `filesImportingTransitively` says which of a set of
24
- * files reach any of a set of packages, which a per-file import check
25
- * misses whenever a local barrel re-exports the SDK.
26
- *
27
- * A query extracts the modules the rules ask for while answering it,
28
- * so the files a question reads do not depend on what was asked before.
23
+ * nor an object. `argumentsPassedTo` and `callsPassing` go from a
24
+ * parameter to the calls that filled it, or the ones it hands to.
25
+ * `filesImportingTransitively` says which of a set of files reach any
26
+ * of a set of packages, which a per-file import check misses whenever a
27
+ * local barrel re-exports the SDK.
29
28
  */
30
29
 
31
30
  interface ExplainCallableOptions {
@@ -42,6 +41,11 @@ interface ExplainedResolution {
42
41
  nodeFor: (atom: Atom) => Node | undefined;
43
42
  stats: ExplainStats;
44
43
  }
44
+ /** One call of a function, and what it wrote at one parameter. */
45
+ interface PassedArgument {
46
+ call: Node;
47
+ argument: Node;
48
+ }
45
49
  declare class ResolutionStore {
46
50
  private readonly db;
47
51
  private readonly table;
@@ -57,10 +61,16 @@ declare class ResolutionStore {
57
61
  * extraction elsewhere cannot change an entry.
58
62
  */
59
63
  private readonly exportTables;
64
+ /** Keyed by value and site both, since one value differs per site. */
65
+ private readonly writtenUnderSite;
66
+ private readonly constructionSites;
60
67
  /** Files the most recent query read, for the memo to keep. */
61
68
  private lastQueryWalked;
62
69
  private readonly declarations;
63
70
  private readonly graph;
71
+ /** See `notePossibleCallers`. */
72
+ private readonly possibleCallers;
73
+ private readonly callerFilesRead;
64
74
  private stale;
65
75
  constructor(wrappers?: TransparentWrapper[]);
66
76
  /**
@@ -101,6 +111,54 @@ declare class ResolutionStore {
101
111
  * GraphQL document kept in a constant in another file.
102
112
  */
103
113
  resolveWrittenValue(value: Node): Node | null;
114
+ /**
115
+ * The same question under one construction site: what the value is
116
+ * when the receiver behind it is the instance that site made. A field
117
+ * two constructions fill differently settles here and not context
118
+ * free, where two answers are ambiguity.
119
+ */
120
+ resolveWrittenValueUnder(value: Node, site: string): Node | null;
121
+ /**
122
+ * Every construction of this class the run can see, as fact keys, for
123
+ * a caller about to ask a value question under each. A class nothing
124
+ * constructs has none.
125
+ */
126
+ constructionSitesOf(cls: Node): string[];
127
+ /**
128
+ * Every call of the function this parameter belongs to, with the
129
+ * argument that call wrote at it, as the caller wrote it. The reading
130
+ * is left to the asker, who knows what kind of value it is after.
131
+ *
132
+ * The callers are in files that import the parameter's own, so they
133
+ * are read into the store first; no query starting at the parameter
134
+ * arrives at them.
135
+ */
136
+ argumentsPassedTo(parameter: Node): PassedArgument[];
137
+ /**
138
+ * The other direction from `argumentsPassedTo`: every call in this
139
+ * parameter's own function, or a closure nested inside it, that hands
140
+ * the parameter to something else. `callArg` keeps the argument as a
141
+ * bare reference, so the join is against `binds` rather than the
142
+ * parameter's own key; a reference only binds to a parameter in scope
143
+ * where it is written, which already keeps the answer inside the
144
+ * parameter's own function with no join against `bodyCalls` needed.
145
+ */
146
+ callsPassing(parameter: Node): PassedArgument[];
147
+ /**
148
+ * Whether running this function hands back that call: returned
149
+ * outright, written into a name and returned, or a shorthand body.
150
+ * A call whose own callee the rules cannot follow is not, which is
151
+ * what keeps a wrapper's own result apart from the library's.
152
+ */
153
+ returnsCall(func: Node, call: Node): boolean;
154
+ /**
155
+ * Files a later question about a parameter may find a caller in.
156
+ * Without this the search falls back to every file the project has
157
+ * loaded, which reads more of the import graph than a run needs.
158
+ */
159
+ notePossibleCallers(sourceFiles: Iterable<SourceFile>): void;
160
+ private readPossibleCallersOf;
161
+ private callerCandidates;
104
162
  /**
105
163
  * The construction behind a registration subject: the call or `new`
106
164
  * this value is written as, kept only when its callee comes from
@@ -285,6 +343,12 @@ interface ClientCallSite {
285
343
  callExpression: CallExpression;
286
344
  /** Method name on the client object (e.g. "getUser"), null for bare calls like fetch() */
287
345
  methodName: string | null;
346
+ /**
347
+ * The construction of the surrounding class to read the request
348
+ * under, for a call whose path or method a constructor argument
349
+ * states. Absent for a call that says what it reaches on its own.
350
+ */
351
+ under?: string;
288
352
  }
289
353
  interface DiscoveredUnit {
290
354
  /**
@@ -388,6 +452,8 @@ interface DiscoveredUnit {
388
452
  rootFields: string[];
389
453
  /** Spreads in `document` with no definition in it: read partially. */
390
454
  unresolvedFragments?: string[];
455
+ /** Spreads the project defines more than once, with different bodies. */
456
+ ambiguousFragments?: string[];
391
457
  unresolved?: {
392
458
  reference: string;
393
459
  reason: string;
@@ -482,6 +548,8 @@ interface DiscoveredUnit {
482
548
  */
483
549
  routeUnfollowed?: UnfollowedCall[];
484
550
  }
551
+ /** Walk to the nearest enclosing function-shaped node, or null if none. */
552
+ declare function findEnclosingFunction(node: Node): FunctionRoot | null;
485
553
 
486
554
  /**
487
555
  * What a route's path should be composed with once mount discovery has
@@ -564,6 +632,12 @@ interface TsAccessRecognizerContext {
564
632
  * and the recognizer's own pattern match runs on the raw node.
565
633
  */
566
634
  resolveWrittenValue: (value: Node) => Node | null;
635
+ /**
636
+ * The run's store, for a recognizer reading a value through the
637
+ * adapter's shared resolvers rather than one hop at a time.
638
+ * Undefined when the run has no store.
639
+ */
640
+ resolution?: ResolutionStore;
567
641
  /**
568
642
  * What a declared pack asks about this node, when the node is a call
569
643
  * or a tagged template. This walk visits property accesses as well,
@@ -617,6 +691,12 @@ interface TsInvocationRecognizerContext {
617
691
  * binding is correct.
618
692
  */
619
693
  resolveWrittenValue(value: Node): Node | null;
694
+ /**
695
+ * The run's store, for a recognizer reading a value through the
696
+ * adapter's shared resolvers rather than one hop at a time.
697
+ * Undefined when the run has no store.
698
+ */
699
+ resolution?: ResolutionStore;
620
700
  /**
621
701
  * What a declared pack asks about this call, in the vocabulary
622
702
  * `@suss/extractor` defines. A pack written as a chain of data links
@@ -631,7 +711,7 @@ interface TsInvocationRecognizerContext {
631
711
  * A pack's tests build it here too, so a pack that passes them has run
632
712
  * against the context extraction gives it.
633
713
  */
634
- declare function invocationContextFor(call: CallExpression, resolveWrittenValue?: (value: Node) => Node | null, originatesFrom?: OriginatesFrom, anchorCallsOf?: AnchorCallsOf): TsInvocationRecognizerContext;
714
+ declare function invocationContextFor(call: CallExpression, resolution?: ResolutionStore, originatesFrom?: OriginatesFrom, anchorCallsOf?: AnchorCallsOf): TsInvocationRecognizerContext;
635
715
  /**
636
716
  * Whether a value's chain reaches the module, asked of the store. The
637
717
  * adapter binds it; a context built bare falls back to the checker's
@@ -664,7 +744,7 @@ type Accessed = PropertyAccessExpression | CallExpression | TaggedTemplateExpres
664
744
  * A pack's tests build it here too, so a pack that passes them has run
665
745
  * against the context extraction gives it.
666
746
  */
667
- declare function accessContextFor(node: Accessed, sourceFile: SourceFile, resolveWrittenValue?: (value: Node) => Node | null, originatesFrom?: OriginatesFrom, anchorCallsOf?: AnchorCallsOf): TsAccessRecognizerContext;
747
+ declare function accessContextFor(node: Accessed, sourceFile: SourceFile, resolution?: ResolutionStore, originatesFrom?: OriginatesFrom, anchorCallsOf?: AnchorCallsOf): TsAccessRecognizerContext;
668
748
 
669
749
  /** Resolves a helper callee to its declaration; the adapter binds the store's ask. */
670
750
  type ResolveCallee = (callee: Node) => Node | null;
@@ -979,7 +1059,104 @@ declare function importedRootsOf(sourceFile: SourceFile, modules: readonly strin
979
1059
  /** Every import declaration in the file that names one of `modules`. */
980
1060
  declare function importDeclarationsOf(sourceFile: SourceFile, modules: readonly string[], options?: ImportScanOptions): ImportDeclaration[];
981
1061
 
1062
+ /**
1063
+ * What a value at a discovery site turns out to be, whether it was
1064
+ * written out there or referred to by name.
1065
+ *
1066
+ * A recognizer reading an argument, a property or a loop's iterable is
1067
+ * asking one of two things: which function is this, and which object is
1068
+ * this. The resolution store settles both over the fact layer, which
1069
+ * follows a name through a property read, an array element, an alias, an
1070
+ * import and a barrel. A recognizer that reads the syntax at the
1071
+ * position instead sees an identifier and gets no further.
1072
+ */
1073
+
1074
+ /**
1075
+ * Whether a value is a name rather than something written out where it
1076
+ * is used. A route's path argument is a string, and asking the fact
1077
+ * layer about that pulls in the file's import closure to produce a null
1078
+ * that was never in doubt.
1079
+ */
1080
+ declare function couldNameAValue(value: Node): boolean;
1081
+ /**
1082
+ * The expression a property of an object literal is set to, when it has
1083
+ * one. A shorthand property is set to whatever its name refers to, so
1084
+ * the name node is the expression.
1085
+ */
1086
+ declare function propertyValueOf(property: Node): Node | null;
1087
+ /**
1088
+ * The function this value is, whether it was written out here or
1089
+ * referred to by name.
1090
+ *
1091
+ * A value the rules can reach two different functions from returns null,
1092
+ * because picking one would report a boundary's behaviour from a
1093
+ * function that may not be the one that runs. So does a handler that
1094
+ * arrives as a parameter, which nothing here can follow.
1095
+ */
1096
+ declare function functionValueOf(value: Node, resolution: ResolutionStore | undefined): FunctionRoot | null;
1097
+ /**
1098
+ * The name a property of an object literal is written under, or null
1099
+ * for a spread, which has none.
1100
+ */
1101
+ declare function propertyNameOf(property: Node): string | null;
1102
+ /**
1103
+ * The function a property of an object literal is set to. A method
1104
+ * written into the literal is that function; a property set to a name
1105
+ * or a call is followed the way `functionValueOf` follows any value.
1106
+ */
1107
+ declare function propertyFunctionOf(property: Node, resolution: ResolutionStore | undefined): FunctionRoot | null;
1108
+ /** The object literal this value is, written out here or named. */
1109
+ declare function objectLiteralOf(value: Node, resolution: ResolutionStore | undefined): ObjectLiteralExpression | null;
1110
+ /**
1111
+ * The properties of an object literal, with a spread replaced by the
1112
+ * properties of whatever it spreads.
1113
+ *
1114
+ * A spread is a name in property position, so it is the same question
1115
+ * `objectLiteralOf` settles. A spread of something the rules cannot
1116
+ * reach an object from contributes nothing, the same as a property whose
1117
+ * value nothing resolves. An object that spreads its way back to itself
1118
+ * is walked once.
1119
+ */
1120
+ declare function propertiesOf(object: ObjectLiteralExpression, resolution: ResolutionStore | undefined): ObjectLiteralElementLike[];
1121
+ /**
1122
+ * What an object sets one named property to, with a spread walked and
1123
+ * a shorthand giving back the name it forwards. Null when nothing in
1124
+ * the object sets that name.
1125
+ */
1126
+ declare function propertyOf(object: ObjectLiteralExpression, name: string, resolution: ResolutionStore | undefined): Node | null;
1127
+ /**
1128
+ * The expression `value` comes down to, whatever kind of expression that
1129
+ * turns out to be, whether it was a name or written out where it is
1130
+ * used. A mount call's target argument is sometimes a call or `new`
1131
+ * expression right there (`app.use("/x", Router())`) and sometimes a
1132
+ * name imported from wherever the sub-router is declared. A caller
1133
+ * comparing that against another value's creation site does not care
1134
+ * which.
1135
+ */
1136
+ declare function writtenNodeOf(value: Node, resolution: ResolutionStore | undefined): Node | null;
1137
+ /**
1138
+ * The string this value comes to, with every name the evaluator can
1139
+ * follow folded in. Null rather than the empty string when the value
1140
+ * does not settle to one string, so a caller can tell "stated as
1141
+ * empty" from "could not read" (#123).
1142
+ */
1143
+ declare function stringValueOf(value: Node, resolution: ResolutionStore | undefined): string | null;
1144
+ /**
1145
+ * The string a named property of an object is set to, with the object
1146
+ * and the value each read through whatever name they were given.
1147
+ * `fetch(url, { method })`, `fetch(url, opts)` and `{ ...base, method }`
1148
+ * are all read here. Null when the property is absent or not a string.
1149
+ */
1150
+ declare function stringPropertyOf(object: Node, name: string, resolution: ResolutionStore | undefined, site?: string): string | null;
1151
+ /** The array literal this value is, written out here or named. */
1152
+ declare function arrayLiteralOf(value: Node, resolution: ResolutionStore | undefined): ArrayLiteralExpression | null;
1153
+
982
1154
  interface TsDiscoveryContext {
1155
+ /**
1156
+ * The run's store, for a pack reading a value through the adapter's
1157
+ * shared resolvers rather than the syntax at the position.
1158
+ */
1159
+ resolution: ResolutionStore;
983
1160
  /** Full filesystem path of the source file. Useful for excluding
984
1161
  * test / story files via the pack's own regex. */
985
1162
  getFilePath(sourceFile: SourceFile): string;
@@ -1126,6 +1303,12 @@ declare function callOpsFor(call: Called, resolveWrittenValue?: Resolve, origina
1126
1303
  * closure takes `resolveDecl` for the function root itself.
1127
1304
  */
1128
1305
 
1306
+ /**
1307
+ * The symbol a reference resolves to. A shorthand property
1308
+ * (`{ roomId }`) gives its identifier the property's symbol, and the
1309
+ * local binding it reads is behind `getValueSymbol`.
1310
+ */
1311
+ declare function symbolBehind(node: Identifier): Symbol | undefined;
1129
1312
  /**
1130
1313
  * The function an identifier refers to, as its declaration's file and
1131
1314
  * name, for joins that never walk the body. Null when the reference
@@ -1354,4 +1537,46 @@ declare function computeAdapterPacksDigest(packVersions: ReadonlyArray<{
1354
1537
  version?: string;
1355
1538
  }>): string;
1356
1539
 
1357
- export { ADAPTER_VERSION, type Accessed, type CallAccountingEntry, type CallAccountingOutcome, type ClientCallSite, type ConfiguredCallContext, type ConfiguredCallRead, type ConfiguredCallSpec, type ContractReadResult, type DescentBarriers, type DiscoveredUnit, type ExplainCallableOptions, type ExplainedResolution, type FoundTerminal, type FunctionRoot, GENERIC_TERMINALS, type ImportScanOptions, NO_BARRIERS, type ObservedStubCall, type RawBranchResult, type ReadNameOptions, ResolutionStore, type StubCallEvidence, type StubEvidenceOptions, TSCONFIG_NAMES, type TsDiscoveryContext, type TsInvocationRecognizerContext, type TsJsxAttributeLocation, type TsSubUnitContext, type TypeScriptAdapter, type TypeScriptAdapterConfig, TypeScriptWhySession, type WhySessionOptions, accessContextFor, buildProjectHelperIndex, callOpsFor, collectAncestorBranches, collectClientFieldAccesses, computeAdapterPacksDigest, createProjectWithoutTsconfig, createTsDiscoveryContext, createTsSubUnitContext, createTypeScriptAdapter, discoverUnits, exportedDeclarationsOf, extractCodeStructure, extractRawBranches, findNearestTsconfig, findTerminals, functionTargetOf, hasBody, importDeclarationsOf, importedNamesOf, importedRootsOf, invocationContextFor, isImportedFrom, methodDeclaredIn, namedImportsOf, parseConditionExpression, readConfiguredCall, readContract, readContractForClientCall, readName, resolveAliasedSymbol, resolveSubject, rootIdentifier, startsItsOwnScope, stubEvidence, stubEvidenceIn, workspaceRootFor };
1540
+ /**
1541
+ * defaulted.ts: whether a read has something behind it.
1542
+ *
1543
+ * `??` and `||` are ECMAScript, not anything a pack defines, so the
1544
+ * packs that record a read ask here instead of each spelling the
1545
+ * operators out. This is a separate file from unwrap.ts because that
1546
+ * one is about wrappers, and a fallback is not one.
1547
+ */
1548
+
1549
+ /**
1550
+ * Whether something else supplies a value when this read comes back
1551
+ * empty. `env.X ?? "default"` and `env.X || other` both do, and so does
1552
+ * the middle of a chain: in `env.A || env.B || undefined`, B's fallback
1553
+ * is the chain's tail. The climb stops when the read is the final
1554
+ * operand (`getDefault() ?? env.X`), where the read is itself the
1555
+ * fallback and its absence propagates.
1556
+ */
1557
+ declare function isDefaultedAt(node: Node): boolean;
1558
+
1559
+ /**
1560
+ * The expression inside any type-level wrappers: `as` and
1561
+ * angle-bracket assertions, parentheses, non-null `!`, and `satisfies`.
1562
+ * The `await` is left in place, so the caller can still ask TypeScript
1563
+ * for the awaited type.
1564
+ */
1565
+ declare function peelSyntax(node: Node): Node;
1566
+ /**
1567
+ * The outermost node wrapping this one through the same type-level
1568
+ * wrappers `peelSyntax` sees through, or the node itself when nothing
1569
+ * wraps it. Ask the result for its parent to get the node that consumes
1570
+ * the value, and compare the result against that parent's operands to
1571
+ * find out which operand this was.
1572
+ */
1573
+ declare function climbSyntax(node: Node): Node;
1574
+ /**
1575
+ * The expression inside every value-preserving wrapper, `await`
1576
+ * included, for a pass asking "what value flows here". A pass reading
1577
+ * types off the checker wants `peelSyntax` instead, so the await stays
1578
+ * where TypeScript reports the resolved type.
1579
+ */
1580
+ declare function peelValue(node: Node): Node;
1581
+
1582
+ export { ADAPTER_VERSION, type Accessed, type CallAccountingEntry, type CallAccountingOutcome, type ClientCallSite, type ConfiguredCallContext, type ConfiguredCallRead, type ConfiguredCallSpec, type ContractReadResult, type DescentBarriers, type DiscoveredUnit, type ExplainCallableOptions, type ExplainedResolution, type FoundTerminal, type FunctionRoot, GENERIC_TERMINALS, type ImportScanOptions, NO_BARRIERS, type ObservedStubCall, type RawBranchResult, type ReadNameOptions, ResolutionStore, type StubCallEvidence, type StubEvidenceOptions, TSCONFIG_NAMES, type TsDiscoveryContext, type TsInvocationRecognizerContext, type TsJsxAttributeLocation, type TsSubUnitContext, type TypeScriptAdapter, type TypeScriptAdapterConfig, TypeScriptWhySession, type WhySessionOptions, accessContextFor, arrayLiteralOf, buildProjectHelperIndex, callOpsFor, climbSyntax, collectAncestorBranches, collectClientFieldAccesses, computeAdapterPacksDigest, couldNameAValue, createProjectWithoutTsconfig, createTsDiscoveryContext, createTsSubUnitContext, createTypeScriptAdapter, discoverUnits, exportedDeclarationsOf, extractCodeStructure, extractRawBranches, findEnclosingFunction, findNearestTsconfig, findTerminals, functionTargetOf, functionValueOf, hasBody, importDeclarationsOf, importedNamesOf, importedRootsOf, invocationContextFor, isDefaultedAt, isImportedFrom, methodDeclaredIn, namedImportsOf, objectLiteralOf, parseConditionExpression, peelSyntax, peelValue, propertiesOf, propertyFunctionOf, propertyNameOf, propertyOf, propertyValueOf, readConfiguredCall, readContract, readContractForClientCall, readName, resolveAliasedSymbol, resolveSubject, rootIdentifier, startsItsOwnScope, stringPropertyOf, stringValueOf, stubEvidence, stubEvidenceIn, symbolBehind, workspaceRootFor, writtenNodeOf };