@suss/adapter-typescript 0.22.3 → 0.22.4
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 +317 -82
- package/dist/index.d.cts +65 -3
- package/dist/index.d.ts +65 -3
- package/dist/index.js +313 -82
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -3716,6 +3716,18 @@ var ResolutionStore = class {
|
|
|
3716
3716
|
const target = factKeyOf(value);
|
|
3717
3717
|
return this.askAbout(target, "wanted", () => this.lookupObject(target));
|
|
3718
3718
|
}
|
|
3719
|
+
/**
|
|
3720
|
+
* The function a call returns: `app.use(requireCaller(config))`
|
|
3721
|
+
* registers what the factory gives back. A separate question from
|
|
3722
|
+
* `resolveCallable`, which keeps a call unresolved on purpose so an
|
|
3723
|
+
* unwrapping answer wins; this one is asked only after that has
|
|
3724
|
+
* declined. Two returned functions give null, like every other
|
|
3725
|
+
* single-answer question here.
|
|
3726
|
+
*/
|
|
3727
|
+
resolveReturnedCallable(call) {
|
|
3728
|
+
const target = factKeyOf(call);
|
|
3729
|
+
return this.askAbout(target, "wanted", () => this.lookupReturned(target));
|
|
3730
|
+
}
|
|
3719
3731
|
/**
|
|
3720
3732
|
* For a value that is neither a function nor an object, such as a
|
|
3721
3733
|
* GraphQL document kept in a constant in another file.
|
|
@@ -4159,6 +4171,21 @@ var ResolutionStore = class {
|
|
|
4159
4171
|
}
|
|
4160
4172
|
return [...candidates][0];
|
|
4161
4173
|
}
|
|
4174
|
+
lookupReturned(call) {
|
|
4175
|
+
this.derive();
|
|
4176
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
4177
|
+
for (const target of this.answersFor("wantedGivesBack", nodeId(call))) {
|
|
4178
|
+
const node = this.table.byId.get(target);
|
|
4179
|
+
if (node === void 0 || !isFunctionRoot(node)) {
|
|
4180
|
+
continue;
|
|
4181
|
+
}
|
|
4182
|
+
candidates.add(node);
|
|
4183
|
+
}
|
|
4184
|
+
if (candidates.size !== 1) {
|
|
4185
|
+
return null;
|
|
4186
|
+
}
|
|
4187
|
+
return [...candidates][0];
|
|
4188
|
+
}
|
|
4162
4189
|
/**
|
|
4163
4190
|
* Two candidates give null, since ambiguity is nothing. The value
|
|
4164
4191
|
* itself is never a result either, or an identifier whose chain went
|
|
@@ -5286,7 +5313,27 @@ function functionValueOf(value, resolution) {
|
|
|
5286
5313
|
return null;
|
|
5287
5314
|
}
|
|
5288
5315
|
const resolved = resolution.resolveCallable(written);
|
|
5289
|
-
|
|
5316
|
+
if (resolved !== null) {
|
|
5317
|
+
return toFunctionRoot(resolved);
|
|
5318
|
+
}
|
|
5319
|
+
if (!Node17.isCallExpression(written)) {
|
|
5320
|
+
return null;
|
|
5321
|
+
}
|
|
5322
|
+
const returned = resolution.resolveReturnedCallable(written);
|
|
5323
|
+
return returned === null ? null : toFunctionRoot(returned);
|
|
5324
|
+
}
|
|
5325
|
+
function propertyNameOf(property) {
|
|
5326
|
+
if (Node17.isPropertyAssignment(property) || Node17.isShorthandPropertyAssignment(property) || Node17.isMethodDeclaration(property)) {
|
|
5327
|
+
return property.getName();
|
|
5328
|
+
}
|
|
5329
|
+
return null;
|
|
5330
|
+
}
|
|
5331
|
+
function propertyFunctionOf(property, resolution) {
|
|
5332
|
+
if (Node17.isMethodDeclaration(property)) {
|
|
5333
|
+
return property;
|
|
5334
|
+
}
|
|
5335
|
+
const held = propertyValueOf(property);
|
|
5336
|
+
return held === null ? null : functionValueOf(held, resolution);
|
|
5290
5337
|
}
|
|
5291
5338
|
function objectLiteralOf(value, resolution) {
|
|
5292
5339
|
return literalValueOf(
|
|
@@ -8760,7 +8807,7 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
|
|
|
8760
8807
|
}
|
|
8761
8808
|
const schemaSdl = extractTypeDefsSdl(config, store);
|
|
8762
8809
|
for (const typeProp of propertiesOf(resolversObj, store)) {
|
|
8763
|
-
const typeName =
|
|
8810
|
+
const typeName = propertyNameOf(typeProp);
|
|
8764
8811
|
if (typeName === null || excludeTypes.has(typeName)) {
|
|
8765
8812
|
continue;
|
|
8766
8813
|
}
|
|
@@ -8769,11 +8816,11 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
|
|
|
8769
8816
|
continue;
|
|
8770
8817
|
}
|
|
8771
8818
|
for (const fieldProp of propertiesOf(typeObj, store)) {
|
|
8772
|
-
const fieldName =
|
|
8819
|
+
const fieldName = propertyNameOf(fieldProp);
|
|
8773
8820
|
if (fieldName === null) {
|
|
8774
8821
|
continue;
|
|
8775
8822
|
}
|
|
8776
|
-
const fn =
|
|
8823
|
+
const fn = propertyFunctionOf(fieldProp, store);
|
|
8777
8824
|
if (fn === null) {
|
|
8778
8825
|
continue;
|
|
8779
8826
|
}
|
|
@@ -8837,22 +8884,6 @@ function writtenSdl(expr) {
|
|
|
8837
8884
|
}
|
|
8838
8885
|
return null;
|
|
8839
8886
|
}
|
|
8840
|
-
function resolverPropertyName(prop) {
|
|
8841
|
-
if (Node36.isPropertyAssignment(prop) || Node36.isMethodDeclaration(prop)) {
|
|
8842
|
-
return prop.getName();
|
|
8843
|
-
}
|
|
8844
|
-
if (Node36.isShorthandPropertyAssignment(prop)) {
|
|
8845
|
-
return prop.getName();
|
|
8846
|
-
}
|
|
8847
|
-
return null;
|
|
8848
|
-
}
|
|
8849
|
-
function resolverPropertyFunction(prop, resolution) {
|
|
8850
|
-
if (Node36.isMethodDeclaration(prop)) {
|
|
8851
|
-
return prop;
|
|
8852
|
-
}
|
|
8853
|
-
const held = propertyValueOf(prop);
|
|
8854
|
-
return held === null ? null : functionValueOf(held, resolution);
|
|
8855
|
-
}
|
|
8856
8887
|
|
|
8857
8888
|
// src/discovery/index.ts
|
|
8858
8889
|
function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere) {
|
|
@@ -12265,7 +12296,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
|
|
|
12265
12296
|
});
|
|
12266
12297
|
return unmatched;
|
|
12267
12298
|
}
|
|
12268
|
-
function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2) {
|
|
12299
|
+
function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2, collectCallAccounting = false) {
|
|
12269
12300
|
const terminals = findTerminals(
|
|
12270
12301
|
func,
|
|
12271
12302
|
terminalPatterns,
|
|
@@ -12353,8 +12384,8 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12353
12384
|
seenBranches.add(key);
|
|
12354
12385
|
return true;
|
|
12355
12386
|
});
|
|
12387
|
+
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
12356
12388
|
if (invocations.length > 0) {
|
|
12357
|
-
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
12358
12389
|
const sideEffects = invocations.filter(
|
|
12359
12390
|
(i) => !writesTerminal(i.node, terminalNodes)
|
|
12360
12391
|
);
|
|
@@ -12370,7 +12401,39 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12370
12401
|
branch.extraEffects = [...branch.extraEffects ?? [], ...extra];
|
|
12371
12402
|
}
|
|
12372
12403
|
}
|
|
12373
|
-
return {
|
|
12404
|
+
return {
|
|
12405
|
+
branches: distinctBranches,
|
|
12406
|
+
terminals,
|
|
12407
|
+
...collectCallAccounting ? {
|
|
12408
|
+
callAccounting: invocations.map(
|
|
12409
|
+
(site) => accountFor(site, terminalNodes, distinctBranches)
|
|
12410
|
+
)
|
|
12411
|
+
} : {}
|
|
12412
|
+
};
|
|
12413
|
+
}
|
|
12414
|
+
function accountFor(site, terminalNodes, branches) {
|
|
12415
|
+
const { node, line } = site;
|
|
12416
|
+
const callee = node.getExpression().getText();
|
|
12417
|
+
if (writesTerminal(node, terminalNodes)) {
|
|
12418
|
+
return { node, callee, line, outcome: "terminal" };
|
|
12419
|
+
}
|
|
12420
|
+
const call = {
|
|
12421
|
+
line,
|
|
12422
|
+
alwaysRuns: site.alwaysRuns,
|
|
12423
|
+
preconditions: preconditionsOf(site.effect)
|
|
12424
|
+
};
|
|
12425
|
+
if (branches.some((branch) => firesOn(call, branch))) {
|
|
12426
|
+
return { node, callee, line, outcome: "invocation" };
|
|
12427
|
+
}
|
|
12428
|
+
const reachable = branches.some(
|
|
12429
|
+
(branch) => site.alwaysRuns || runsBefore(line, branch.terminal.location.end)
|
|
12430
|
+
);
|
|
12431
|
+
return {
|
|
12432
|
+
node,
|
|
12433
|
+
callee,
|
|
12434
|
+
line,
|
|
12435
|
+
outcome: reachable ? "unrecorded" : "unreachable"
|
|
12436
|
+
};
|
|
12374
12437
|
}
|
|
12375
12438
|
|
|
12376
12439
|
// src/bootstrap/sourceFileLookup.ts
|
|
@@ -12585,7 +12648,7 @@ function unwrapContractInit(init) {
|
|
|
12585
12648
|
}
|
|
12586
12649
|
return null;
|
|
12587
12650
|
}
|
|
12588
|
-
function extractEndpointContract(endpointNode, pattern, framework) {
|
|
12651
|
+
function extractEndpointContract(endpointNode, pattern, framework, resolution) {
|
|
12589
12652
|
if (!Node54.isObjectLiteralExpression(endpointNode)) {
|
|
12590
12653
|
return null;
|
|
12591
12654
|
}
|
|
@@ -12610,9 +12673,10 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
12610
12673
|
}
|
|
12611
12674
|
}
|
|
12612
12675
|
if (propName === pattern.responseExtraction.property) {
|
|
12613
|
-
const
|
|
12614
|
-
|
|
12615
|
-
|
|
12676
|
+
const written = prop.getInitializer();
|
|
12677
|
+
const val = written === void 0 ? null : objectLiteralOf(written, resolution);
|
|
12678
|
+
if (val !== null) {
|
|
12679
|
+
for (const respProp of propertiesOf(val, resolution)) {
|
|
12616
12680
|
if (!Node54.isPropertyAssignment(respProp)) {
|
|
12617
12681
|
continue;
|
|
12618
12682
|
}
|
|
@@ -12651,7 +12715,12 @@ function readContract(unit, pattern, framework, resolution) {
|
|
|
12651
12715
|
if (endpointNode === null) {
|
|
12652
12716
|
return null;
|
|
12653
12717
|
}
|
|
12654
|
-
return extractEndpointContract(
|
|
12718
|
+
return extractEndpointContract(
|
|
12719
|
+
endpointNode,
|
|
12720
|
+
pattern,
|
|
12721
|
+
framework,
|
|
12722
|
+
resolution
|
|
12723
|
+
);
|
|
12655
12724
|
}
|
|
12656
12725
|
const routerInfo = findRouterCall(unit);
|
|
12657
12726
|
if (routerInfo === null) {
|
|
@@ -12672,7 +12741,12 @@ function readContract(unit, pattern, framework, resolution) {
|
|
|
12672
12741
|
if (endpointInit === void 0) {
|
|
12673
12742
|
continue;
|
|
12674
12743
|
}
|
|
12675
|
-
return extractEndpointContract(
|
|
12744
|
+
return extractEndpointContract(
|
|
12745
|
+
endpointInit,
|
|
12746
|
+
pattern,
|
|
12747
|
+
framework,
|
|
12748
|
+
resolution
|
|
12749
|
+
);
|
|
12676
12750
|
}
|
|
12677
12751
|
return null;
|
|
12678
12752
|
}
|
|
@@ -12749,7 +12823,12 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
|
|
|
12749
12823
|
if (endpointInit === void 0) {
|
|
12750
12824
|
continue;
|
|
12751
12825
|
}
|
|
12752
|
-
return extractEndpointContract(
|
|
12826
|
+
return extractEndpointContract(
|
|
12827
|
+
endpointInit,
|
|
12828
|
+
pattern,
|
|
12829
|
+
framework,
|
|
12830
|
+
resolution
|
|
12831
|
+
);
|
|
12753
12832
|
}
|
|
12754
12833
|
return null;
|
|
12755
12834
|
}
|
|
@@ -13509,7 +13588,11 @@ function recordEdge(edgesByChild, candidate) {
|
|
|
13509
13588
|
// src/discovery/wrapperIndex.ts
|
|
13510
13589
|
import { Node as Node58 } from "ts-morph";
|
|
13511
13590
|
import { joinMountedPath as joinMountedPath3 } from "@suss/resolution";
|
|
13512
|
-
var NO_WRAPPERS = {
|
|
13591
|
+
var NO_WRAPPERS = {
|
|
13592
|
+
wrappersFor: () => [],
|
|
13593
|
+
unfollowedFor: () => [],
|
|
13594
|
+
unitsIn: () => []
|
|
13595
|
+
};
|
|
13513
13596
|
var ANONYMOUS = "<anon>";
|
|
13514
13597
|
function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
13515
13598
|
const workByPack = /* @__PURE__ */ new Map();
|
|
@@ -13535,21 +13618,32 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
|
13535
13618
|
}
|
|
13536
13619
|
}
|
|
13537
13620
|
const bySubject = /* @__PURE__ */ new Map();
|
|
13621
|
+
const unfollowedBySubject = /* @__PURE__ */ new Map();
|
|
13538
13622
|
const unitsByFile = /* @__PURE__ */ new Map();
|
|
13623
|
+
const stopsSeen = /* @__PURE__ */ new Set();
|
|
13539
13624
|
let found = false;
|
|
13540
13625
|
for (const [packName, work] of workByPack) {
|
|
13541
13626
|
const candidates = [];
|
|
13542
13627
|
for (const { sourceFile, pattern, match, wraps } of work) {
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
mountPrefixes
|
|
13551
|
-
)
|
|
13628
|
+
const scan = discoverWrapperRegistrations(
|
|
13629
|
+
sourceFile,
|
|
13630
|
+
pattern,
|
|
13631
|
+
match,
|
|
13632
|
+
wraps,
|
|
13633
|
+
resolution,
|
|
13634
|
+
mountPrefixes
|
|
13552
13635
|
);
|
|
13636
|
+
candidates.push(...scan.candidates);
|
|
13637
|
+
for (const { subjectId, callId, stop } of scan.unresolved) {
|
|
13638
|
+
if (stopsSeen.has(callId)) {
|
|
13639
|
+
continue;
|
|
13640
|
+
}
|
|
13641
|
+
stopsSeen.add(callId);
|
|
13642
|
+
found = true;
|
|
13643
|
+
const stops = unfollowedBySubject.get(subjectId) ?? [];
|
|
13644
|
+
stops.push(stop);
|
|
13645
|
+
unfollowedBySubject.set(subjectId, stops);
|
|
13646
|
+
}
|
|
13553
13647
|
}
|
|
13554
13648
|
for (const candidate of mostSpecific(candidates)) {
|
|
13555
13649
|
found = true;
|
|
@@ -13567,6 +13661,7 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
|
13567
13661
|
}
|
|
13568
13662
|
return {
|
|
13569
13663
|
wrappersFor: (subjectId) => bySubject.get(subjectId) ?? [],
|
|
13664
|
+
unfollowedFor: (subjectId) => unfollowedBySubject.get(subjectId) ?? [],
|
|
13570
13665
|
unitsIn: (file, pack) => unitsByFile.get(unitKey(file, pack)) ?? []
|
|
13571
13666
|
};
|
|
13572
13667
|
}
|
|
@@ -13600,10 +13695,20 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13600
13695
|
match.importName,
|
|
13601
13696
|
resolution
|
|
13602
13697
|
);
|
|
13698
|
+
if ("constructorOption" in wraps) {
|
|
13699
|
+
return discoverConstructorOptions(
|
|
13700
|
+
sourceFile,
|
|
13701
|
+
pattern,
|
|
13702
|
+
wraps,
|
|
13703
|
+
subjects,
|
|
13704
|
+
resolution
|
|
13705
|
+
);
|
|
13706
|
+
}
|
|
13603
13707
|
if (subjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution)) {
|
|
13604
|
-
return [];
|
|
13708
|
+
return { candidates: [], unresolved: [] };
|
|
13605
13709
|
}
|
|
13606
13710
|
const candidates = [];
|
|
13711
|
+
const unresolved = [];
|
|
13607
13712
|
sourceFile.forEachDescendant((node) => {
|
|
13608
13713
|
if (!Node58.isCallExpression(node)) {
|
|
13609
13714
|
return;
|
|
@@ -13626,8 +13731,13 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13626
13731
|
if (targetArg === void 0) {
|
|
13627
13732
|
return;
|
|
13628
13733
|
}
|
|
13734
|
+
const subjectId = nodeId(subjectNode);
|
|
13629
13735
|
const target = functionValueOf(targetArg, resolution);
|
|
13630
13736
|
if (target === null) {
|
|
13737
|
+
const stop = factoryStopOf(targetArg);
|
|
13738
|
+
if (stop !== null) {
|
|
13739
|
+
unresolved.push({ subjectId, callId: nodeId(node), stop });
|
|
13740
|
+
}
|
|
13631
13741
|
return;
|
|
13632
13742
|
}
|
|
13633
13743
|
if (wraps.arity !== void 0 && target.getParameters().length !== wraps.arity) {
|
|
@@ -13637,29 +13747,136 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13637
13747
|
if (scope === null) {
|
|
13638
13748
|
return;
|
|
13639
13749
|
}
|
|
13640
|
-
const subjectId = nodeId(subjectNode);
|
|
13641
13750
|
const mountedScope = scope === void 0 ? void 0 : mountedAt(subjectId, mountPrefixes, scope);
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
...wraps.throwParam === void 0 ? {} : { onThrow: true },
|
|
13658
|
-
...mountedScope === void 0 ? {} : { scope: mountedScope }
|
|
13659
|
-
}
|
|
13660
|
-
});
|
|
13751
|
+
candidates.push(
|
|
13752
|
+
candidateOf(
|
|
13753
|
+
{
|
|
13754
|
+
subjectId,
|
|
13755
|
+
callId: nodeId(node),
|
|
13756
|
+
target,
|
|
13757
|
+
label: labelFor(targetArg, wraps),
|
|
13758
|
+
byArity: wraps.arity !== void 0,
|
|
13759
|
+
onThrow: wraps.throwParam !== void 0,
|
|
13760
|
+
scope: mountedScope
|
|
13761
|
+
},
|
|
13762
|
+
pattern,
|
|
13763
|
+
sourceFile
|
|
13764
|
+
)
|
|
13765
|
+
);
|
|
13661
13766
|
});
|
|
13662
|
-
return candidates;
|
|
13767
|
+
return { candidates, unresolved };
|
|
13768
|
+
}
|
|
13769
|
+
function discoverConstructorOptions(sourceFile, pattern, wraps, subjects, resolution) {
|
|
13770
|
+
const candidates = [];
|
|
13771
|
+
const unresolved = [];
|
|
13772
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13773
|
+
for (const construction of subjects.values()) {
|
|
13774
|
+
const subjectId = nodeId(construction);
|
|
13775
|
+
if (seen.has(subjectId) || construction.getSourceFile() !== sourceFile) {
|
|
13776
|
+
continue;
|
|
13777
|
+
}
|
|
13778
|
+
seen.add(subjectId);
|
|
13779
|
+
const option = constructorOptionOf(construction, wraps, resolution);
|
|
13780
|
+
if (option === void 0) {
|
|
13781
|
+
continue;
|
|
13782
|
+
}
|
|
13783
|
+
const callId = nodeId(option);
|
|
13784
|
+
const written = propertyValueOf(option);
|
|
13785
|
+
const target = propertyFunctionOf(option, resolution);
|
|
13786
|
+
if (target === null) {
|
|
13787
|
+
const stop = written === null ? null : factoryStopOf(written);
|
|
13788
|
+
if (stop !== null) {
|
|
13789
|
+
unresolved.push({ subjectId, callId, stop });
|
|
13790
|
+
}
|
|
13791
|
+
continue;
|
|
13792
|
+
}
|
|
13793
|
+
candidates.push(
|
|
13794
|
+
candidateOf(
|
|
13795
|
+
{
|
|
13796
|
+
subjectId,
|
|
13797
|
+
callId,
|
|
13798
|
+
target,
|
|
13799
|
+
label: (written === null ? void 0 : factoryNameOf(written)) ?? wraps.constructorOption,
|
|
13800
|
+
byArity: false,
|
|
13801
|
+
onThrow: wraps.throwParam !== void 0,
|
|
13802
|
+
scope: void 0
|
|
13803
|
+
},
|
|
13804
|
+
pattern,
|
|
13805
|
+
sourceFile
|
|
13806
|
+
)
|
|
13807
|
+
);
|
|
13808
|
+
}
|
|
13809
|
+
return { candidates, unresolved };
|
|
13810
|
+
}
|
|
13811
|
+
function constructorOptionOf(construction, wraps, resolution) {
|
|
13812
|
+
if (!(Node58.isNewExpression(construction) || Node58.isCallExpression(construction))) {
|
|
13813
|
+
return void 0;
|
|
13814
|
+
}
|
|
13815
|
+
const optionsArg = construction.getArguments()[wraps.targetPosition];
|
|
13816
|
+
if (optionsArg === void 0) {
|
|
13817
|
+
return void 0;
|
|
13818
|
+
}
|
|
13819
|
+
const options = objectLiteralOf(optionsArg, resolution);
|
|
13820
|
+
if (options === null) {
|
|
13821
|
+
return void 0;
|
|
13822
|
+
}
|
|
13823
|
+
return propertiesOf(options, resolution).find(
|
|
13824
|
+
(property) => propertyNameOf(property) === wraps.constructorOption
|
|
13825
|
+
);
|
|
13826
|
+
}
|
|
13827
|
+
function candidateOf(registration, pattern, sourceFile) {
|
|
13828
|
+
const { target, label, onThrow, scope } = registration;
|
|
13829
|
+
const named2 = functionNameOrAnon(target) !== ANONYMOUS;
|
|
13830
|
+
return {
|
|
13831
|
+
subjectId: registration.subjectId,
|
|
13832
|
+
callId: registration.callId,
|
|
13833
|
+
targetId: nodeId(target),
|
|
13834
|
+
byArity: registration.byArity,
|
|
13835
|
+
target,
|
|
13836
|
+
pattern,
|
|
13837
|
+
registeredIn: sourceFile.getFilePath(),
|
|
13838
|
+
named: named2,
|
|
13839
|
+
reference: {
|
|
13840
|
+
file: target.getSourceFile().getFilePath(),
|
|
13841
|
+
name: named2 ? functionNameOrAnon(target) : label,
|
|
13842
|
+
...onThrow ? { onThrow: true } : {},
|
|
13843
|
+
...scope === void 0 ? {} : { scope }
|
|
13844
|
+
}
|
|
13845
|
+
};
|
|
13846
|
+
}
|
|
13847
|
+
function labelFor(targetArg, wraps) {
|
|
13848
|
+
return factoryNameOf(targetArg) ?? wraps.method;
|
|
13849
|
+
}
|
|
13850
|
+
function factoryNameOf(targetArg) {
|
|
13851
|
+
const written = factKeyOf(targetArg);
|
|
13852
|
+
if (!Node58.isCallExpression(written)) {
|
|
13853
|
+
return void 0;
|
|
13854
|
+
}
|
|
13855
|
+
const callee = written.getExpression();
|
|
13856
|
+
if (Node58.isIdentifier(callee)) {
|
|
13857
|
+
return callee.getText();
|
|
13858
|
+
}
|
|
13859
|
+
if (Node58.isPropertyAccessExpression(callee)) {
|
|
13860
|
+
return callee.getName();
|
|
13861
|
+
}
|
|
13862
|
+
return void 0;
|
|
13863
|
+
}
|
|
13864
|
+
function factoryStopOf(targetArg) {
|
|
13865
|
+
const written = factKeyOf(targetArg);
|
|
13866
|
+
if (!Node58.isCallExpression(written)) {
|
|
13867
|
+
return null;
|
|
13868
|
+
}
|
|
13869
|
+
const callee = factoryNameOf(targetArg);
|
|
13870
|
+
if (callee === void 0) {
|
|
13871
|
+
return null;
|
|
13872
|
+
}
|
|
13873
|
+
const reason = classifyStop(
|
|
13874
|
+
declarationsBehind(written.getExpression().getSymbol())
|
|
13875
|
+
);
|
|
13876
|
+
if (!worthRecording(reason)) {
|
|
13877
|
+
return null;
|
|
13878
|
+
}
|
|
13879
|
+
return { callee, reason: "unresolvedWrapper" };
|
|
13663
13880
|
}
|
|
13664
13881
|
function mountedAt(subjectId, mountPrefixes, scope) {
|
|
13665
13882
|
const prefix = mountPrefixes?.prefixForId?.(subjectId) ?? "";
|
|
@@ -14034,22 +14251,23 @@ import { Node as Node60 } from "ts-morph";
|
|
|
14034
14251
|
import { functionCallBinding, TargetPlacements } from "@suss/behavioral-ir";
|
|
14035
14252
|
import { Database as Database3, evaluate as evaluate4, lit as lit4, rule as rule4, variable as variable2 } from "@suss/datalog";
|
|
14036
14253
|
import { assembleSummary as assembleSummary2 } from "@suss/extractor";
|
|
14254
|
+
var GENERIC_TERMINALS = [
|
|
14255
|
+
{ kind: "return", match: { type: "returnStatement" }, extraction: {} },
|
|
14256
|
+
{ kind: "throw", match: { type: "throwExpression" }, extraction: {} },
|
|
14257
|
+
{
|
|
14258
|
+
// Implicit fall-through at the end of a function body: covers
|
|
14259
|
+
// void-returning orchestrators that never write `return`.
|
|
14260
|
+
kind: "return",
|
|
14261
|
+
match: { type: "functionFallthrough" },
|
|
14262
|
+
extraction: {}
|
|
14263
|
+
}
|
|
14264
|
+
];
|
|
14037
14265
|
var reachablePack = {
|
|
14038
14266
|
name: "reachable",
|
|
14039
14267
|
languages: ["typescript"],
|
|
14040
14268
|
protocol: "in-process",
|
|
14041
14269
|
discovery: [],
|
|
14042
|
-
terminals:
|
|
14043
|
-
{ kind: "return", match: { type: "returnStatement" }, extraction: {} },
|
|
14044
|
-
{ kind: "throw", match: { type: "throwExpression" }, extraction: {} },
|
|
14045
|
-
{
|
|
14046
|
-
// Implicit fall-through at the end of a function body: covers
|
|
14047
|
-
// void-returning orchestrators that never write `return`.
|
|
14048
|
-
kind: "return",
|
|
14049
|
-
match: { type: "functionFallthrough" },
|
|
14050
|
-
extraction: {}
|
|
14051
|
-
}
|
|
14052
|
-
],
|
|
14270
|
+
terminals: GENERIC_TERMINALS,
|
|
14053
14271
|
inputMapping: { type: "allPositional" }
|
|
14054
14272
|
};
|
|
14055
14273
|
function nodeKey(func) {
|
|
@@ -15854,10 +16072,10 @@ var FUNCTION_FALLTHROUGH_TERMINAL = {
|
|
|
15854
16072
|
match: { type: "functionFallthrough" },
|
|
15855
16073
|
extraction: {}
|
|
15856
16074
|
};
|
|
15857
|
-
function
|
|
15858
|
-
return unit.pattern?.wraps?.throwParam;
|
|
16075
|
+
function frameworkValueAt(unit) {
|
|
16076
|
+
return unit.pattern?.wraps?.throwParam ?? unit.pattern?.wraps?.resultParam;
|
|
15859
16077
|
}
|
|
15860
|
-
function
|
|
16078
|
+
function pastFrameworkValue(terminals, at) {
|
|
15861
16079
|
if (at === void 0) {
|
|
15862
16080
|
return terminals;
|
|
15863
16081
|
}
|
|
@@ -15871,7 +16089,7 @@ function pastThrownValue(terminals, at) {
|
|
|
15871
16089
|
} : pattern
|
|
15872
16090
|
);
|
|
15873
16091
|
}
|
|
15874
|
-
function
|
|
16092
|
+
function rolesPastFrameworkValue(mapping, at) {
|
|
15875
16093
|
if (at === void 0 || mapping.type !== "positionalParams") {
|
|
15876
16094
|
return mapping;
|
|
15877
16095
|
}
|
|
@@ -15897,7 +16115,7 @@ function continuationTerminal(unit) {
|
|
|
15897
16115
|
}
|
|
15898
16116
|
function terminalsFor(unit, pack) {
|
|
15899
16117
|
const declared = [
|
|
15900
|
-
...unit.terminals ??
|
|
16118
|
+
...unit.terminals ?? pastFrameworkValue(pack.terminals, frameworkValueAt(unit)),
|
|
15901
16119
|
...continuationTerminal(unit)
|
|
15902
16120
|
];
|
|
15903
16121
|
if (unit.callSite === void 0) {
|
|
@@ -15915,7 +16133,7 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
|
|
|
15915
16133
|
}
|
|
15916
16134
|
const params = extractParameters(
|
|
15917
16135
|
func,
|
|
15918
|
-
unit.inputMapping ??
|
|
16136
|
+
unit.inputMapping ?? rolesPastFrameworkValue(pack.inputMapping, frameworkValueAt(unit))
|
|
15919
16137
|
);
|
|
15920
16138
|
const extracted = extractRawBranches(
|
|
15921
16139
|
func,
|
|
@@ -16417,8 +16635,10 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16417
16635
|
}
|
|
16418
16636
|
}
|
|
16419
16637
|
const summary = assembleSummary3(raw, options);
|
|
16420
|
-
if (
|
|
16421
|
-
|
|
16638
|
+
if (options?.gapHandling !== "silent") {
|
|
16639
|
+
for (const stop of unfollowedStopsOf(unit, wrappers)) {
|
|
16640
|
+
summary.gaps.push(unfollowedCallGap(stop));
|
|
16641
|
+
}
|
|
16422
16642
|
}
|
|
16423
16643
|
if (unit.metadata !== void 0 && Object.keys(unit.metadata).length > 0) {
|
|
16424
16644
|
summary.metadata = {
|
|
@@ -16471,6 +16691,13 @@ function stampWrappers(raw, unit, wrappers) {
|
|
|
16471
16691
|
recordFileDependency(wrapper.file);
|
|
16472
16692
|
}
|
|
16473
16693
|
}
|
|
16694
|
+
function unfollowedStopsOf(unit, wrappers) {
|
|
16695
|
+
const stops = unit.unfollowed === void 0 ? [] : [unit.unfollowed];
|
|
16696
|
+
if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
|
|
16697
|
+
return stops;
|
|
16698
|
+
}
|
|
16699
|
+
return [...stops, ...wrappers.unfollowedFor(unit.registrationSubjectId)];
|
|
16700
|
+
}
|
|
16474
16701
|
function emitLibraryEnvReadMarkers(summaries, project, frameworks) {
|
|
16475
16702
|
for (const pack of frameworks) {
|
|
16476
16703
|
for (const declared of pack.libraryEnvVars ?? []) {
|
|
@@ -17185,7 +17412,7 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
17185
17412
|
});
|
|
17186
17413
|
const composed = timer.time(
|
|
17187
17414
|
"composeWrappers",
|
|
17188
|
-
() => composeWrappers(enriched)
|
|
17415
|
+
() => composeWrappers(enriched, config.extractorOptions ?? {})
|
|
17189
17416
|
);
|
|
17190
17417
|
if (config.onTiming !== void 0) {
|
|
17191
17418
|
config.onTiming(timer.report());
|
|
@@ -17809,6 +18036,8 @@ function stubEvidence(options) {
|
|
|
17809
18036
|
}
|
|
17810
18037
|
export {
|
|
17811
18038
|
ADAPTER_VERSION,
|
|
18039
|
+
GENERIC_TERMINALS,
|
|
18040
|
+
NO_BARRIERS,
|
|
17812
18041
|
ResolutionStore,
|
|
17813
18042
|
TypeScriptWhySession,
|
|
17814
18043
|
accessContextFor,
|
|
@@ -17829,6 +18058,7 @@ export {
|
|
|
17829
18058
|
findNearestTsconfig,
|
|
17830
18059
|
findTerminals,
|
|
17831
18060
|
functionTargetOf,
|
|
18061
|
+
hasBody,
|
|
17832
18062
|
importDeclarationsOf,
|
|
17833
18063
|
importedNamesOf,
|
|
17834
18064
|
importedRootsOf,
|
|
@@ -17844,6 +18074,7 @@ export {
|
|
|
17844
18074
|
resolveAliasedSymbol,
|
|
17845
18075
|
resolveSubject,
|
|
17846
18076
|
rootIdentifier,
|
|
18077
|
+
startsItsOwnScope,
|
|
17847
18078
|
stubEvidence,
|
|
17848
18079
|
stubEvidenceIn,
|
|
17849
18080
|
workspaceRootFor
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-typescript",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.4",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "TypeScript
|
|
5
|
+
"description": "Read a TypeScript or JavaScript codebase with suss and check what each handler returns against every caller, spec and template it can see.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"suss",
|
|
8
|
-
"behavioral-summary",
|
|
9
8
|
"static-analysis",
|
|
10
9
|
"typescript",
|
|
10
|
+
"javascript",
|
|
11
11
|
"ts-morph",
|
|
12
|
-
"
|
|
12
|
+
"api-contract",
|
|
13
|
+
"api-drift",
|
|
14
|
+
"code-review"
|
|
13
15
|
],
|
|
14
16
|
"license": "Apache-2.0",
|
|
15
17
|
"author": "Nimbus Cloud AI LLC",
|
|
@@ -46,11 +48,11 @@
|
|
|
46
48
|
"typecheck": "tsc --noEmit"
|
|
47
49
|
},
|
|
48
50
|
"dependencies": {
|
|
49
|
-
"@suss/behavioral-ir": "0.22.
|
|
50
|
-
"@suss/datalog": "0.22.
|
|
51
|
-
"@suss/extractor": "0.22.
|
|
52
|
-
"@suss/resolution": "0.22.
|
|
53
|
-
"@suss/values": "0.22.
|
|
51
|
+
"@suss/behavioral-ir": "0.22.4",
|
|
52
|
+
"@suss/datalog": "0.22.4",
|
|
53
|
+
"@suss/extractor": "0.22.4",
|
|
54
|
+
"@suss/resolution": "0.22.4",
|
|
55
|
+
"@suss/values": "0.22.4",
|
|
54
56
|
"graphql": "^16.8.0",
|
|
55
57
|
"picomatch": "^4.0.4",
|
|
56
58
|
"ts-morph": "^23.0.0",
|