@suss/adapter-typescript 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +507 -117
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +507 -117
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -67,7 +67,7 @@ __export(index_exports, {
|
|
|
67
67
|
module.exports = __toCommonJS(index_exports);
|
|
68
68
|
|
|
69
69
|
// src/adapter.ts
|
|
70
|
-
var
|
|
70
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
71
71
|
var import_ts_morph60 = require("ts-morph");
|
|
72
72
|
var import_behavioral_ir8 = require("@suss/behavioral-ir");
|
|
73
73
|
var import_datalog6 = require("@suss/datalog");
|
|
@@ -1864,8 +1864,8 @@ function loadImportGraphsDepthFirstFromPaths(project, rootPaths) {
|
|
|
1864
1864
|
stack.pop();
|
|
1865
1865
|
loadOrder.push(top.path);
|
|
1866
1866
|
let deepest = 0;
|
|
1867
|
-
for (const
|
|
1868
|
-
deepest = Math.max(deepest, chainDepth.get(
|
|
1867
|
+
for (const path13 of top.deps) {
|
|
1868
|
+
deepest = Math.max(deepest, chainDepth.get(path13) ?? 0);
|
|
1869
1869
|
}
|
|
1870
1870
|
chainDepth.set(top.path, deepest + 1);
|
|
1871
1871
|
}
|
|
@@ -2210,11 +2210,11 @@ function walkAndWarm(root, reach) {
|
|
|
2210
2210
|
if (warmedFiles.get(target) !== void 0) {
|
|
2211
2211
|
continue;
|
|
2212
2212
|
}
|
|
2213
|
-
const
|
|
2214
|
-
if (visited.has(
|
|
2213
|
+
const path13 = target.getFilePath();
|
|
2214
|
+
if (visited.has(path13)) {
|
|
2215
2215
|
continue;
|
|
2216
2216
|
}
|
|
2217
|
-
visited.add(
|
|
2217
|
+
visited.add(path13);
|
|
2218
2218
|
stack.push(frameOf(target, reach));
|
|
2219
2219
|
continue;
|
|
2220
2220
|
}
|
|
@@ -2231,7 +2231,7 @@ function sitsOnWarmChains(file) {
|
|
|
2231
2231
|
return false;
|
|
2232
2232
|
}
|
|
2233
2233
|
const imported = importedFilePathsOf(project, file.getFilePath());
|
|
2234
|
-
return imported.length > 0 && imported.every((
|
|
2234
|
+
return imported.length > 0 && imported.every((path13) => warmed.has(path13));
|
|
2235
2235
|
}
|
|
2236
2236
|
function markWarmed(file) {
|
|
2237
2237
|
warmedFiles.set(file, true);
|
|
@@ -2688,7 +2688,7 @@ var ORIGIN = {
|
|
|
2688
2688
|
declaredBy: (origin, receiver) => receiver.callee !== null && origin.importedFrom.some(
|
|
2689
2689
|
(module2) => methodDeclaredIn(receiver.callee, module2, receiver.resolve)
|
|
2690
2690
|
),
|
|
2691
|
-
constructed: (origin, receiver) => madeFromNamed(origin,
|
|
2691
|
+
constructed: (origin, receiver) => madeFromNamed(origin, madeExpression(receiver)) && origin.importedFrom.some(
|
|
2692
2692
|
(module2) => isImportedFrom(madeBy(receiver), module2)
|
|
2693
2693
|
)
|
|
2694
2694
|
};
|
|
@@ -2696,14 +2696,15 @@ function madeFromNamed(origin, made) {
|
|
|
2696
2696
|
if (origin.origin !== "constructed" || origin.named === void 0) {
|
|
2697
2697
|
return true;
|
|
2698
2698
|
}
|
|
2699
|
-
return origin.named.includes(made
|
|
2699
|
+
return origin.named.includes(constructorName(made));
|
|
2700
|
+
}
|
|
2701
|
+
function constructorName(made) {
|
|
2702
|
+
const expression = import_ts_morph14.Node.isNewExpression(made) || import_ts_morph14.Node.isCallExpression(made) ? made.getExpression() : made;
|
|
2703
|
+
return import_ts_morph14.Node.isPropertyAccessExpression(expression) ? expression.getName() : expression.getText();
|
|
2700
2704
|
}
|
|
2701
2705
|
var CALL_ORIGIN = {
|
|
2702
2706
|
declaredBy: ORIGIN.declaredBy,
|
|
2703
|
-
constructed: (origin, receiver) => madeFromNamed(
|
|
2704
|
-
origin,
|
|
2705
|
-
rootIdentifier(receiver.expression) ?? receiver.expression
|
|
2706
|
-
) && origin.importedFrom.some(
|
|
2707
|
+
constructed: (origin, receiver) => madeFromNamed(origin, receiver.expression) && origin.importedFrom.some(
|
|
2707
2708
|
(module2) => isImportedFrom(
|
|
2708
2709
|
rootIdentifier(receiver.expression) ?? receiver.expression,
|
|
2709
2710
|
module2
|
|
@@ -2711,14 +2712,19 @@ var CALL_ORIGIN = {
|
|
|
2711
2712
|
)
|
|
2712
2713
|
};
|
|
2713
2714
|
function madeBy(receiver) {
|
|
2715
|
+
const made = madeExpression(receiver);
|
|
2716
|
+
const expression = import_ts_morph14.Node.isNewExpression(made) || import_ts_morph14.Node.isCallExpression(made) ? made.getExpression() : made;
|
|
2717
|
+
return rootIdentifier(expression) ?? expression;
|
|
2718
|
+
}
|
|
2719
|
+
function madeExpression(receiver) {
|
|
2714
2720
|
if (receiver.callee === null) {
|
|
2715
|
-
return
|
|
2721
|
+
return receiver.expression;
|
|
2716
2722
|
}
|
|
2717
2723
|
const written = receiver.resolve(receiver.callee.getExpression());
|
|
2718
2724
|
if (written === null || !import_ts_morph14.Node.isNewExpression(written) && !import_ts_morph14.Node.isCallExpression(written)) {
|
|
2719
2725
|
return receiver.callee;
|
|
2720
2726
|
}
|
|
2721
|
-
return
|
|
2727
|
+
return written;
|
|
2722
2728
|
}
|
|
2723
2729
|
function callOpsFor(call, resolveWrittenValue) {
|
|
2724
2730
|
const resolve2 = resolveWrittenValue ?? (() => null);
|
|
@@ -2759,6 +2765,7 @@ function valueOpsFor(value, resolve2) {
|
|
|
2759
2765
|
flag: () => literalFlag(written()),
|
|
2760
2766
|
entries: (unsettled) => entriesOf(written(), unsettled, resolve2),
|
|
2761
2767
|
items: () => itemsOf(written(), resolve2),
|
|
2768
|
+
asArg: () => effectArgOf(written()),
|
|
2762
2769
|
property: (name) => {
|
|
2763
2770
|
const object = written();
|
|
2764
2771
|
const inside = import_ts_morph14.Node.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
|
|
@@ -3246,6 +3253,9 @@ var MAX_ARG_DEPTH = 8;
|
|
|
3246
3253
|
function extractArgs(call) {
|
|
3247
3254
|
return call.getArguments().map((arg) => extractArg(arg, MAX_ARG_DEPTH));
|
|
3248
3255
|
}
|
|
3256
|
+
function effectArgOf(node) {
|
|
3257
|
+
return extractArg(node, MAX_ARG_DEPTH);
|
|
3258
|
+
}
|
|
3249
3259
|
function extractArg(node, depth) {
|
|
3250
3260
|
if (import_ts_morph15.Node.isAsExpression(node) || import_ts_morph15.Node.isTypeAssertion(node) || import_ts_morph15.Node.isSatisfiesExpression(node) || import_ts_morph15.Node.isNonNullExpression(node)) {
|
|
3251
3261
|
return extractArg(node.getExpression(), depth);
|
|
@@ -5838,9 +5848,9 @@ function createSourceFileLookup(project) {
|
|
|
5838
5848
|
if (sf === null) {
|
|
5839
5849
|
return null;
|
|
5840
5850
|
}
|
|
5841
|
-
const
|
|
5842
|
-
const index = functionsByFile.get(
|
|
5843
|
-
functionsByFile.set(
|
|
5851
|
+
const path13 = sf.getFilePath();
|
|
5852
|
+
const index = functionsByFile.get(path13) ?? indexFunctions(sf);
|
|
5853
|
+
functionsByFile.set(path13, index);
|
|
5844
5854
|
return index.get(rangeKey(location.range)) ?? null;
|
|
5845
5855
|
}
|
|
5846
5856
|
};
|
|
@@ -6367,7 +6377,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
6367
6377
|
}
|
|
6368
6378
|
const responses = [];
|
|
6369
6379
|
let method;
|
|
6370
|
-
let
|
|
6380
|
+
let path13;
|
|
6371
6381
|
for (const prop of endpointNode.getProperties()) {
|
|
6372
6382
|
if (!import_ts_morph28.Node.isPropertyAssignment(prop)) {
|
|
6373
6383
|
continue;
|
|
@@ -6382,7 +6392,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
6382
6392
|
if (propName === pattern.pathProperty) {
|
|
6383
6393
|
const val = prop.getInitializer();
|
|
6384
6394
|
if (val !== void 0 && import_ts_morph28.Node.isStringLiteral(val)) {
|
|
6385
|
-
|
|
6395
|
+
path13 = val.getLiteralValue();
|
|
6386
6396
|
}
|
|
6387
6397
|
}
|
|
6388
6398
|
if (propName === pattern.responseExtraction.property) {
|
|
@@ -6406,10 +6416,10 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
6406
6416
|
if (responses.length === 0) {
|
|
6407
6417
|
return null;
|
|
6408
6418
|
}
|
|
6409
|
-
const boundaryBinding = method !== void 0 ||
|
|
6419
|
+
const boundaryBinding = method !== void 0 || path13 !== void 0 ? (0, import_behavioral_ir2.restBinding)({
|
|
6410
6420
|
transport: "http",
|
|
6411
6421
|
method: method ?? null,
|
|
6412
|
-
path:
|
|
6422
|
+
path: path13 ?? null,
|
|
6413
6423
|
recognition: framework
|
|
6414
6424
|
}) : null;
|
|
6415
6425
|
return {
|
|
@@ -7871,6 +7881,31 @@ function constructionRef(node, localNames, resolution) {
|
|
|
7871
7881
|
// src/discovery/clientCall.ts
|
|
7872
7882
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
7873
7883
|
var import_ts_morph34 = require("ts-morph");
|
|
7884
|
+
|
|
7885
|
+
// src/discovery/resolveImport.ts
|
|
7886
|
+
function resolveImportedLocalName(sourceFile, importModule, importName) {
|
|
7887
|
+
for (const importDecl of sourceFile.getImportDeclarations()) {
|
|
7888
|
+
if (importDecl.getModuleSpecifierValue() !== importModule) {
|
|
7889
|
+
continue;
|
|
7890
|
+
}
|
|
7891
|
+
for (const named2 of importDecl.getNamedImports()) {
|
|
7892
|
+
if (named2.getName() === importName || named2.getAliasNode()?.getText() === importName) {
|
|
7893
|
+
return named2.getAliasNode()?.getText() ?? named2.getName();
|
|
7894
|
+
}
|
|
7895
|
+
}
|
|
7896
|
+
const defaultImport = importDecl.getDefaultImport();
|
|
7897
|
+
if (defaultImport !== void 0 && defaultImport.getText() === importName) {
|
|
7898
|
+
return defaultImport.getText();
|
|
7899
|
+
}
|
|
7900
|
+
const namespaceImport = importDecl.getNamespaceImport();
|
|
7901
|
+
if (namespaceImport !== void 0 && namespaceImport.getText() === importName) {
|
|
7902
|
+
return namespaceImport.getText();
|
|
7903
|
+
}
|
|
7904
|
+
}
|
|
7905
|
+
return null;
|
|
7906
|
+
}
|
|
7907
|
+
|
|
7908
|
+
// src/discovery/clientCall.ts
|
|
7874
7909
|
function discoverClientCalls(sourceFile, match, kind, resolution) {
|
|
7875
7910
|
const results = [];
|
|
7876
7911
|
const isGlobal = match.importModule === "global";
|
|
@@ -7889,7 +7924,7 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
|
|
|
7889
7924
|
if (!isGlobal && importedLocalName !== null) {
|
|
7890
7925
|
for (const varDecl of sourceFile.getVariableDeclarations()) {
|
|
7891
7926
|
const init = varDecl.getInitializer();
|
|
7892
|
-
if (init !== void 0 && import_ts_morph34.Node.isCallExpression(init) && isInstanceCreationCall(init, importedLocalName, match.factoryMethods)) {
|
|
7927
|
+
if (init !== void 0 && (import_ts_morph34.Node.isCallExpression(init) || import_ts_morph34.Node.isNewExpression(init)) && isInstanceCreationCall(init, importedLocalName, match.factoryMethods)) {
|
|
7893
7928
|
clientVarNames.add(varDecl.getName());
|
|
7894
7929
|
}
|
|
7895
7930
|
}
|
|
@@ -7934,12 +7969,50 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
|
|
|
7934
7969
|
});
|
|
7935
7970
|
return results;
|
|
7936
7971
|
}
|
|
7972
|
+
function clientReceiverCheckFor(sourceFile, match, resolution) {
|
|
7973
|
+
const localName = resolveImportedLocalName(
|
|
7974
|
+
sourceFile,
|
|
7975
|
+
match.importModule,
|
|
7976
|
+
match.importName
|
|
7977
|
+
);
|
|
7978
|
+
const constructedHere = /* @__PURE__ */ new Set();
|
|
7979
|
+
if (localName !== null) {
|
|
7980
|
+
sourceFile.forEachDescendant((node) => {
|
|
7981
|
+
if (import_ts_morph34.Node.isVariableDeclaration(node)) {
|
|
7982
|
+
const init = node.getInitializer();
|
|
7983
|
+
if (init !== void 0 && (import_ts_morph34.Node.isCallExpression(init) || import_ts_morph34.Node.isNewExpression(init)) && isInstanceCreationCall(init, localName, match.factoryMethods) || typedAsClient(node.getTypeNode(), localName)) {
|
|
7984
|
+
constructedHere.add(node.getName());
|
|
7985
|
+
}
|
|
7986
|
+
return;
|
|
7987
|
+
}
|
|
7988
|
+
if (import_ts_morph34.Node.isParameterDeclaration(node) && typedAsClient(node.getTypeNode(), localName)) {
|
|
7989
|
+
const written = node.getNameNode();
|
|
7990
|
+
if (import_ts_morph34.Node.isIdentifier(written)) {
|
|
7991
|
+
constructedHere.add(written.getText());
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
});
|
|
7995
|
+
}
|
|
7996
|
+
const full = {
|
|
7997
|
+
type: "clientCall",
|
|
7998
|
+
importModule: match.importModule,
|
|
7999
|
+
importName: match.importName,
|
|
8000
|
+
...match.factoryMethods === void 0 ? {} : { factoryMethods: match.factoryMethods }
|
|
8001
|
+
};
|
|
8002
|
+
return (subject) => localName !== null && import_ts_morph34.Node.isIdentifier(subject) && subject.getText() === localName || import_ts_morph34.Node.isIdentifier(subject) && constructedHere.has(subject.getText()) || resolvesToKnownInstance(subject, full, resolution);
|
|
8003
|
+
}
|
|
8004
|
+
function typedAsClient(typeNode, localName) {
|
|
8005
|
+
if (typeNode === void 0 || !import_ts_morph34.Node.isTypeReference(typeNode)) {
|
|
8006
|
+
return false;
|
|
8007
|
+
}
|
|
8008
|
+
return typeNode.getTypeName().getText() === localName;
|
|
8009
|
+
}
|
|
7937
8010
|
function resolvesToKnownInstance(subject, match, resolution) {
|
|
7938
8011
|
if (resolution === void 0 || match.importModule === "global") {
|
|
7939
8012
|
return false;
|
|
7940
8013
|
}
|
|
7941
8014
|
const written = writtenNodeOf(subject, resolution);
|
|
7942
|
-
if (written === null || !import_ts_morph34.Node.isCallExpression(written)) {
|
|
8015
|
+
if (written === null || !import_ts_morph34.Node.isCallExpression(written) && !import_ts_morph34.Node.isNewExpression(written)) {
|
|
7943
8016
|
return false;
|
|
7944
8017
|
}
|
|
7945
8018
|
const writtenLocalName = resolvedImportLocalName(
|
|
@@ -8261,7 +8334,34 @@ function joinRoutePath(prefix, suffix) {
|
|
|
8261
8334
|
}
|
|
8262
8335
|
return `/${segments.join("/")}`;
|
|
8263
8336
|
}
|
|
8264
|
-
function
|
|
8337
|
+
function declaredChannelOf(source, decorator, resolution) {
|
|
8338
|
+
if (source.from === "literal") {
|
|
8339
|
+
return source.value;
|
|
8340
|
+
}
|
|
8341
|
+
if (source.from === "unstated") {
|
|
8342
|
+
return null;
|
|
8343
|
+
}
|
|
8344
|
+
if (!import_ts_morph38.Node.isDecorator(decorator)) {
|
|
8345
|
+
return null;
|
|
8346
|
+
}
|
|
8347
|
+
const arg = decorator.getArguments()[source.position];
|
|
8348
|
+
if (arg === void 0) {
|
|
8349
|
+
return null;
|
|
8350
|
+
}
|
|
8351
|
+
const text = literalStringOf(arg, resolution);
|
|
8352
|
+
return text === null || text === "" ? null : text;
|
|
8353
|
+
}
|
|
8354
|
+
function literalStringOf(node, resolution) {
|
|
8355
|
+
if (import_ts_morph38.Node.isStringLiteral(node) || import_ts_morph38.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
8356
|
+
return node.getLiteralValue();
|
|
8357
|
+
}
|
|
8358
|
+
const written = resolution?.resolveWrittenValue(node) ?? null;
|
|
8359
|
+
if (written === null || written === node) {
|
|
8360
|
+
return null;
|
|
8361
|
+
}
|
|
8362
|
+
return literalStringOf(written, resolution);
|
|
8363
|
+
}
|
|
8364
|
+
function discoverDecoratedRoutes(sourceFile, match, kind, resolution, binding) {
|
|
8265
8365
|
const acceptedModules = Array.isArray(match.importModule) ? match.importModule : [match.importModule];
|
|
8266
8366
|
const routeDecoratorNames = Object.keys(match.methodDecoratorRouteMap);
|
|
8267
8367
|
const importedRouteDecorators = /* @__PURE__ */ new Set();
|
|
@@ -8293,6 +8393,22 @@ function discoverDecoratedRoutes(sourceFile, match, kind, resolution) {
|
|
|
8293
8393
|
const pathPrefix = routePathOf(marker.args, resolution);
|
|
8294
8394
|
const className = cls.getName() ?? "<anon-class>";
|
|
8295
8395
|
for (const handler of decoratedCallablesOf(cls, routeDecoratorNames)) {
|
|
8396
|
+
if (binding !== void 0) {
|
|
8397
|
+
results.push({
|
|
8398
|
+
func: handler.func,
|
|
8399
|
+
kind,
|
|
8400
|
+
name: `${className}.${handler.name}`,
|
|
8401
|
+
channelInfo: {
|
|
8402
|
+
messageBus: binding.messageBus,
|
|
8403
|
+
channel: declaredChannelOf(
|
|
8404
|
+
binding.channel,
|
|
8405
|
+
handler.decorator,
|
|
8406
|
+
resolution
|
|
8407
|
+
)
|
|
8408
|
+
}
|
|
8409
|
+
});
|
|
8410
|
+
continue;
|
|
8411
|
+
}
|
|
8296
8412
|
const httpMethod = match.methodDecoratorRouteMap[handler.standsFor];
|
|
8297
8413
|
const pathSuffix = resolveRoutePathArg(handler.decorator, resolution);
|
|
8298
8414
|
const routePath = joinRoutePath(pathPrefix, pathSuffix);
|
|
@@ -9134,40 +9250,8 @@ function discoverGraphqlHookCalls(sourceFile, match, kind, resolution) {
|
|
|
9134
9250
|
|
|
9135
9251
|
// src/discovery/graphqlImperativeCall.ts
|
|
9136
9252
|
var import_ts_morph42 = require("ts-morph");
|
|
9137
|
-
|
|
9138
|
-
// src/discovery/resolveImport.ts
|
|
9139
|
-
function resolveImportedLocalName(sourceFile, importModule, importName) {
|
|
9140
|
-
for (const importDecl of sourceFile.getImportDeclarations()) {
|
|
9141
|
-
if (importDecl.getModuleSpecifierValue() !== importModule) {
|
|
9142
|
-
continue;
|
|
9143
|
-
}
|
|
9144
|
-
for (const named2 of importDecl.getNamedImports()) {
|
|
9145
|
-
if (named2.getName() === importName || named2.getAliasNode()?.getText() === importName) {
|
|
9146
|
-
return named2.getAliasNode()?.getText() ?? named2.getName();
|
|
9147
|
-
}
|
|
9148
|
-
}
|
|
9149
|
-
const defaultImport = importDecl.getDefaultImport();
|
|
9150
|
-
if (defaultImport !== void 0 && defaultImport.getText() === importName) {
|
|
9151
|
-
return defaultImport.getText();
|
|
9152
|
-
}
|
|
9153
|
-
const namespaceImport = importDecl.getNamespaceImport();
|
|
9154
|
-
if (namespaceImport !== void 0 && namespaceImport.getText() === importName) {
|
|
9155
|
-
return namespaceImport.getText();
|
|
9156
|
-
}
|
|
9157
|
-
}
|
|
9158
|
-
return null;
|
|
9159
|
-
}
|
|
9160
|
-
|
|
9161
|
-
// src/discovery/graphqlImperativeCall.ts
|
|
9162
9253
|
function discoverGraphqlImperativeCalls(sourceFile, match, kind, resolution) {
|
|
9163
|
-
const
|
|
9164
|
-
sourceFile,
|
|
9165
|
-
match.importModule,
|
|
9166
|
-
match.importName
|
|
9167
|
-
);
|
|
9168
|
-
if (localName === null) {
|
|
9169
|
-
return [];
|
|
9170
|
-
}
|
|
9254
|
+
const isTheClient = clientReceiverCheckFor(sourceFile, match, resolution);
|
|
9171
9255
|
const methodSpec = /* @__PURE__ */ new Map();
|
|
9172
9256
|
for (const method of match.methods) {
|
|
9173
9257
|
methodSpec.set(method.methodName, {
|
|
@@ -9189,6 +9273,9 @@ function discoverGraphqlImperativeCalls(sourceFile, match, kind, resolution) {
|
|
|
9189
9273
|
if (spec === void 0) {
|
|
9190
9274
|
return;
|
|
9191
9275
|
}
|
|
9276
|
+
if (!isTheClient(callee.getExpression())) {
|
|
9277
|
+
return;
|
|
9278
|
+
}
|
|
9192
9279
|
const args = node.getArguments();
|
|
9193
9280
|
if (args.length === 0 || !import_ts_morph42.Node.isObjectLiteralExpression(args[0])) {
|
|
9194
9281
|
return;
|
|
@@ -9335,7 +9422,7 @@ function attributeValueOf(node, name) {
|
|
|
9335
9422
|
}
|
|
9336
9423
|
return null;
|
|
9337
9424
|
}
|
|
9338
|
-
function
|
|
9425
|
+
function literalStringOf2(value) {
|
|
9339
9426
|
const unwrapped2 = import_ts_morph43.Node.isJsxExpression(value) ? value.getExpression() ?? value : value;
|
|
9340
9427
|
if (import_ts_morph43.Node.isStringLiteral(unwrapped2) || import_ts_morph43.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
|
|
9341
9428
|
return unwrapped2.getLiteralValue();
|
|
@@ -9345,7 +9432,7 @@ function literalStringOf(value) {
|
|
|
9345
9432
|
function ownPathOfJsx(node, match) {
|
|
9346
9433
|
const pathValue = attributeValueOf(node, match.pathAttribute);
|
|
9347
9434
|
if (pathValue !== null) {
|
|
9348
|
-
const literal =
|
|
9435
|
+
const literal = literalStringOf2(pathValue);
|
|
9349
9436
|
return literal !== null ? { kind: "literal", value: literal } : { kind: "unreadable" };
|
|
9350
9437
|
}
|
|
9351
9438
|
if (match.indexAttribute !== void 0 && attributeValueOf(node, match.indexAttribute) !== null) {
|
|
@@ -9436,14 +9523,14 @@ function unitForJsxRoute(node, match, routeNames, kind, resolution) {
|
|
|
9436
9523
|
}
|
|
9437
9524
|
return routeUnit(node, kind, match.method, resolved.path, target, resolution);
|
|
9438
9525
|
}
|
|
9439
|
-
function routeUnit(at, kind, method,
|
|
9440
|
-
const routeInfo = { method, path:
|
|
9526
|
+
function routeUnit(at, kind, method, path13, target, resolution) {
|
|
9527
|
+
const routeInfo = { method, path: path13 };
|
|
9441
9528
|
if (target.kind === "unreadable") {
|
|
9442
9529
|
return {
|
|
9443
9530
|
func: null,
|
|
9444
9531
|
announcedAt: at,
|
|
9445
9532
|
kind,
|
|
9446
|
-
name:
|
|
9533
|
+
name: path13,
|
|
9447
9534
|
nameKind: "label",
|
|
9448
9535
|
routeInfo
|
|
9449
9536
|
};
|
|
@@ -9613,7 +9700,7 @@ function unitsUnderRouteObject(object, match, kind, resolution, prefix, ancestry
|
|
|
9613
9700
|
function ownPathOfObject(object, match) {
|
|
9614
9701
|
const pathValue = routePropertyOf(object, match.pathAttribute);
|
|
9615
9702
|
if (pathValue !== null) {
|
|
9616
|
-
const literal =
|
|
9703
|
+
const literal = literalStringOf2(pathValue);
|
|
9617
9704
|
return literal !== null ? { kind: "literal", value: literal } : { kind: "unreadable" };
|
|
9618
9705
|
}
|
|
9619
9706
|
if (match.indexAttribute !== void 0) {
|
|
@@ -9873,6 +9960,9 @@ function resolvePackageExportsCached(packageJsonPath) {
|
|
|
9873
9960
|
return fresh;
|
|
9874
9961
|
}
|
|
9875
9962
|
function discoverPackageExports(sourceFile, match, kind) {
|
|
9963
|
+
if (match.packageJsonPath === void 0) {
|
|
9964
|
+
return [];
|
|
9965
|
+
}
|
|
9876
9966
|
const { entries } = resolvePackageExportsCached(match.packageJsonPath);
|
|
9877
9967
|
const filePath = sourceFile.getFilePath();
|
|
9878
9968
|
const matching = [];
|
|
@@ -10260,12 +10350,12 @@ function originEndOf(flattened) {
|
|
|
10260
10350
|
const slash = flattened.indexOf("/", opener[0].length);
|
|
10261
10351
|
return slash === -1 ? flattened.length : slash;
|
|
10262
10352
|
}
|
|
10263
|
-
function appendPathText(
|
|
10353
|
+
function appendPathText(path13, text) {
|
|
10264
10354
|
const idx = text.search(/[?#]/);
|
|
10265
10355
|
if (idx === -1) {
|
|
10266
|
-
return { path:
|
|
10356
|
+
return { path: path13 + text, stop: false };
|
|
10267
10357
|
}
|
|
10268
|
-
return { path:
|
|
10358
|
+
return { path: path13 + text.slice(0, idx), stop: true };
|
|
10269
10359
|
}
|
|
10270
10360
|
function parseAbsoluteUrl(text) {
|
|
10271
10361
|
try {
|
|
@@ -10289,8 +10379,8 @@ function pathnameOfAbsoluteLiteral(text) {
|
|
|
10289
10379
|
return stripQueryAndFragment(stripOriginManually(text));
|
|
10290
10380
|
}
|
|
10291
10381
|
function pathFromLiteralUrl(text) {
|
|
10292
|
-
const
|
|
10293
|
-
return
|
|
10382
|
+
const path13 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
|
|
10383
|
+
return path13 === "" ? void 0 : path13;
|
|
10294
10384
|
}
|
|
10295
10385
|
function pathFromTemplateUrl(arg, resolution) {
|
|
10296
10386
|
const headText = arg.getHead().getLiteralText();
|
|
@@ -10298,7 +10388,7 @@ function pathFromTemplateUrl(arg, resolution) {
|
|
|
10298
10388
|
const tails = spans.map((span) => span.getLiteral().getLiteralText());
|
|
10299
10389
|
const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
|
|
10300
10390
|
const head = appendPathText("", headText.slice(originEnd));
|
|
10301
|
-
let
|
|
10391
|
+
let path13 = head.path;
|
|
10302
10392
|
let stop = head.stop;
|
|
10303
10393
|
let at = headText.length;
|
|
10304
10394
|
for (let i = 0; i < spans.length && !stop; i++) {
|
|
@@ -10308,18 +10398,18 @@ function pathFromTemplateUrl(arg, resolution) {
|
|
|
10308
10398
|
continue;
|
|
10309
10399
|
}
|
|
10310
10400
|
if (at >= originEnd) {
|
|
10311
|
-
|
|
10401
|
+
path13 += holeText(span.getExpression(), resolution);
|
|
10312
10402
|
}
|
|
10313
10403
|
at += SUBSTITUTION.length;
|
|
10314
10404
|
const appended = appendPathText(
|
|
10315
|
-
|
|
10405
|
+
path13,
|
|
10316
10406
|
tailText.slice(Math.max(0, originEnd - at))
|
|
10317
10407
|
);
|
|
10318
|
-
|
|
10408
|
+
path13 = appended.path;
|
|
10319
10409
|
stop = appended.stop;
|
|
10320
10410
|
at += tailText.length;
|
|
10321
10411
|
}
|
|
10322
|
-
return
|
|
10412
|
+
return path13 === "" ? void 0 : path13;
|
|
10323
10413
|
}
|
|
10324
10414
|
function pathFromUrlNode(node, resolution) {
|
|
10325
10415
|
if (import_ts_morph48.Node.isStringLiteral(node)) {
|
|
@@ -10331,8 +10421,24 @@ function pathFromUrlNode(node, resolution) {
|
|
|
10331
10421
|
if (import_ts_morph48.Node.isTemplateExpression(node)) {
|
|
10332
10422
|
return pathFromTemplateUrl(node, resolution);
|
|
10333
10423
|
}
|
|
10424
|
+
if (import_ts_morph48.Node.isBinaryExpression(node)) {
|
|
10425
|
+
const joined = joinedStringOf(node, resolution);
|
|
10426
|
+
return joined === void 0 ? void 0 : pathFromLiteralUrl(joined);
|
|
10427
|
+
}
|
|
10334
10428
|
return void 0;
|
|
10335
10429
|
}
|
|
10430
|
+
function joinedStringOf(node, resolution) {
|
|
10431
|
+
if (import_ts_morph48.Node.isStringLiteral(node) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
10432
|
+
return node.getLiteralValue();
|
|
10433
|
+
}
|
|
10434
|
+
if (import_ts_morph48.Node.isBinaryExpression(node) && node.getOperatorToken().getText() === "+") {
|
|
10435
|
+
const left = joinedStringOf(node.getLeft(), resolution);
|
|
10436
|
+
const right = joinedStringOf(node.getRight(), resolution);
|
|
10437
|
+
return left === void 0 || right === void 0 ? void 0 : left + right;
|
|
10438
|
+
}
|
|
10439
|
+
const written = resolution?.resolveWrittenValue(node) ?? null;
|
|
10440
|
+
return written === null || written === node ? void 0 : joinedStringOf(written, resolution);
|
|
10441
|
+
}
|
|
10336
10442
|
function placeholderName(expr) {
|
|
10337
10443
|
if (import_ts_morph48.Node.isIdentifier(expr)) {
|
|
10338
10444
|
return expr.getText();
|
|
@@ -10470,9 +10576,9 @@ function withMountPrefix(routeInfo, subjectNode, mountPrefixes) {
|
|
|
10470
10576
|
const prefix = mountPrefixes.effectivePrefixFor(subjectNode);
|
|
10471
10577
|
return prefix === "" ? routeInfo : { ...routeInfo, path: joinMountedPath(prefix, routeInfo.path) };
|
|
10472
10578
|
}
|
|
10473
|
-
function joinMountedPath(prefix,
|
|
10579
|
+
function joinMountedPath(prefix, path13) {
|
|
10474
10580
|
const trimmed = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
10475
|
-
return trimmed === "" ?
|
|
10581
|
+
return trimmed === "" ? path13 : trimmed + path13;
|
|
10476
10582
|
}
|
|
10477
10583
|
function registrationSubjectsOf(sourceFile, importModule, importName) {
|
|
10478
10584
|
let importedLocalName = null;
|
|
@@ -10636,11 +10742,11 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
|
|
|
10636
10742
|
return null;
|
|
10637
10743
|
}
|
|
10638
10744
|
const method2 = stringProperty(routeObject, binding.method.property);
|
|
10639
|
-
const
|
|
10640
|
-
if (method2 === null ||
|
|
10745
|
+
const path14 = stringProperty(routeObject, binding.path.property);
|
|
10746
|
+
if (method2 === null || path14 === null) {
|
|
10641
10747
|
return null;
|
|
10642
10748
|
}
|
|
10643
|
-
return { method: method2.toUpperCase(), path:
|
|
10749
|
+
return { method: method2.toUpperCase(), path: path14 };
|
|
10644
10750
|
}
|
|
10645
10751
|
if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromArgument") {
|
|
10646
10752
|
return null;
|
|
@@ -10657,26 +10763,46 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
|
|
|
10657
10763
|
method = arg.getLiteralValue().toUpperCase();
|
|
10658
10764
|
}
|
|
10659
10765
|
const pathArg = call.getArguments()[binding.path.position];
|
|
10660
|
-
const
|
|
10661
|
-
return
|
|
10766
|
+
const path13 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
|
|
10767
|
+
return path13 === void 0 ? null : { method, path: path13 };
|
|
10662
10768
|
}
|
|
10663
10769
|
|
|
10664
10770
|
// src/discovery/registrationLoop.ts
|
|
10665
10771
|
var import_ts_morph50 = require("ts-morph");
|
|
10666
10772
|
function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
|
|
10667
10773
|
const results = [];
|
|
10774
|
+
const routables = routableNames(sourceFile, match);
|
|
10775
|
+
if (routables !== null && routables.size === 0) {
|
|
10776
|
+
return results;
|
|
10777
|
+
}
|
|
10668
10778
|
sourceFile.forEachDescendant((node) => {
|
|
10669
10779
|
if (!import_ts_morph50.Node.isForOfStatement(node)) {
|
|
10670
10780
|
return;
|
|
10671
10781
|
}
|
|
10672
|
-
const expanded = tryExpandLoop(node, match, kind, resolution);
|
|
10782
|
+
const expanded = tryExpandLoop(node, match, kind, resolution, routables);
|
|
10673
10783
|
if (expanded !== null) {
|
|
10674
10784
|
results.push(...expanded);
|
|
10675
10785
|
}
|
|
10676
10786
|
});
|
|
10677
10787
|
return results;
|
|
10678
10788
|
}
|
|
10679
|
-
function
|
|
10789
|
+
function routableNames(sourceFile, match) {
|
|
10790
|
+
if (match.receiver === void 0) {
|
|
10791
|
+
return null;
|
|
10792
|
+
}
|
|
10793
|
+
const names = /* @__PURE__ */ new Set();
|
|
10794
|
+
for (const importName of match.receiver.importNames) {
|
|
10795
|
+
for (const name of registrationSubjectsOf(
|
|
10796
|
+
sourceFile,
|
|
10797
|
+
match.receiver.importModule,
|
|
10798
|
+
importName
|
|
10799
|
+
).keys()) {
|
|
10800
|
+
names.add(name);
|
|
10801
|
+
}
|
|
10802
|
+
}
|
|
10803
|
+
return names;
|
|
10804
|
+
}
|
|
10805
|
+
function tryExpandLoop(loop, match, kind, resolution, routables) {
|
|
10680
10806
|
const loopVar = loopVariableName(loop);
|
|
10681
10807
|
if (loopVar === null) {
|
|
10682
10808
|
return null;
|
|
@@ -10684,6 +10810,9 @@ function tryExpandLoop(loop, match, kind, resolution) {
|
|
|
10684
10810
|
if (!bodyReferencesLoopVar(loop, loopVar)) {
|
|
10685
10811
|
return null;
|
|
10686
10812
|
}
|
|
10813
|
+
if (routables !== null && !bodyCallsOn(loop, routables)) {
|
|
10814
|
+
return null;
|
|
10815
|
+
}
|
|
10687
10816
|
const arrayLit = arrayLiteralOf(loop.getExpression(), resolution);
|
|
10688
10817
|
if (arrayLit === null) {
|
|
10689
10818
|
return null;
|
|
@@ -10742,9 +10871,23 @@ function bodyReferencesLoopVar(loop, name) {
|
|
|
10742
10871
|
});
|
|
10743
10872
|
return referenced;
|
|
10744
10873
|
}
|
|
10874
|
+
function bodyCallsOn(loop, routables) {
|
|
10875
|
+
let found = false;
|
|
10876
|
+
loop.getStatement().forEachDescendant((node) => {
|
|
10877
|
+
if (found || !import_ts_morph50.Node.isCallExpression(node)) {
|
|
10878
|
+
return;
|
|
10879
|
+
}
|
|
10880
|
+
const callee = node.getExpression();
|
|
10881
|
+
const subject = import_ts_morph50.Node.isPropertyAccessExpression(callee) || import_ts_morph50.Node.isElementAccessExpression(callee) ? callee.getExpression() : null;
|
|
10882
|
+
if (subject !== null && import_ts_morph50.Node.isIdentifier(subject) && routables.has(subject.getText())) {
|
|
10883
|
+
found = true;
|
|
10884
|
+
}
|
|
10885
|
+
});
|
|
10886
|
+
return found;
|
|
10887
|
+
}
|
|
10745
10888
|
function readRouteSpec(element, shape, resolution) {
|
|
10746
10889
|
let method = null;
|
|
10747
|
-
let
|
|
10890
|
+
let path13 = null;
|
|
10748
10891
|
let handler = null;
|
|
10749
10892
|
for (const prop of element.getProperties()) {
|
|
10750
10893
|
if (import_ts_morph50.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
|
|
@@ -10762,16 +10905,16 @@ function readRouteSpec(element, shape, resolution) {
|
|
|
10762
10905
|
if (name === shape.methodKey) {
|
|
10763
10906
|
method = readStringLiteralValue(init);
|
|
10764
10907
|
} else if (name === shape.pathKey) {
|
|
10765
|
-
|
|
10908
|
+
path13 = readStringLiteralValue(init);
|
|
10766
10909
|
} else if (name === shape.handlerKey) {
|
|
10767
10910
|
const func = functionValueOf(init, resolution);
|
|
10768
10911
|
handler = func === null ? null : { func, name: handlerName(init) };
|
|
10769
10912
|
}
|
|
10770
10913
|
}
|
|
10771
|
-
if (method === null ||
|
|
10914
|
+
if (method === null || path13 === null || handler === null) {
|
|
10772
10915
|
return null;
|
|
10773
10916
|
}
|
|
10774
|
-
return { method, path:
|
|
10917
|
+
return { method, path: path13, handler: handler.func, handlerName: handler.name };
|
|
10775
10918
|
}
|
|
10776
10919
|
function readStringLiteralValue(node) {
|
|
10777
10920
|
if (import_ts_morph50.Node.isStringLiteral(node) || import_ts_morph50.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
@@ -10800,8 +10943,8 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
|
|
|
10800
10943
|
}
|
|
10801
10944
|
const args = node.getArguments();
|
|
10802
10945
|
for (const reg of match.registrations) {
|
|
10803
|
-
const
|
|
10804
|
-
if (
|
|
10946
|
+
const path13 = substitutePath(reg.pathTemplate, args);
|
|
10947
|
+
if (path13 === null) {
|
|
10805
10948
|
continue;
|
|
10806
10949
|
}
|
|
10807
10950
|
const handler = resolveHandler(reg.handlerArg, args, resolution);
|
|
@@ -10814,7 +10957,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
|
|
|
10814
10957
|
name: handler.name,
|
|
10815
10958
|
routeInfo: {
|
|
10816
10959
|
method: reg.method.toUpperCase(),
|
|
10817
|
-
path:
|
|
10960
|
+
path: path13
|
|
10818
10961
|
}
|
|
10819
10962
|
});
|
|
10820
10963
|
}
|
|
@@ -11140,7 +11283,8 @@ function runPattern(sourceFile, pattern, resolution, mountPrefixes) {
|
|
|
11140
11283
|
sourceFile,
|
|
11141
11284
|
pattern.match,
|
|
11142
11285
|
pattern.kind,
|
|
11143
|
-
resolution
|
|
11286
|
+
resolution,
|
|
11287
|
+
pattern.binding
|
|
11144
11288
|
);
|
|
11145
11289
|
}
|
|
11146
11290
|
if (pattern.match.type === "jsxElementRoute") {
|
|
@@ -12405,7 +12549,38 @@ var REACHABLE_RULES = [
|
|
|
12405
12549
|
)
|
|
12406
12550
|
];
|
|
12407
12551
|
var NO_RECOGNIZERS = { invocation: [], access: [] };
|
|
12408
|
-
function
|
|
12552
|
+
function recognizerOnlyRoots(packsByFile) {
|
|
12553
|
+
const roots = [];
|
|
12554
|
+
for (const [sourceFile, packs] of packsByFile) {
|
|
12555
|
+
const recognizerOnly = packs.some(
|
|
12556
|
+
(pack) => pack.discovery.length === 0 && pack.discoverUnits === void 0 && ((pack.invocationRecognizers?.length ?? 0) > 0 || (pack.accessRecognizers?.length ?? 0) > 0)
|
|
12557
|
+
);
|
|
12558
|
+
if (!recognizerOnly) {
|
|
12559
|
+
continue;
|
|
12560
|
+
}
|
|
12561
|
+
for (const declaration of sourceFile.getFunctions()) {
|
|
12562
|
+
if (declaration.isExported() && hasBody(declaration)) {
|
|
12563
|
+
roots.push({
|
|
12564
|
+
func: declaration,
|
|
12565
|
+
name: declaration.getName() ?? "<anon>"
|
|
12566
|
+
});
|
|
12567
|
+
}
|
|
12568
|
+
}
|
|
12569
|
+
for (const variableStatement of sourceFile.getVariableStatements()) {
|
|
12570
|
+
if (!variableStatement.isExported()) {
|
|
12571
|
+
continue;
|
|
12572
|
+
}
|
|
12573
|
+
for (const declaration of variableStatement.getDeclarations()) {
|
|
12574
|
+
const init = declaration.getInitializer();
|
|
12575
|
+
if (init !== void 0 && (import_ts_morph56.Node.isArrowFunction(init) || import_ts_morph56.Node.isFunctionExpression(init)) && hasBody(init)) {
|
|
12576
|
+
roots.push({ func: init, name: declaration.getName() });
|
|
12577
|
+
}
|
|
12578
|
+
}
|
|
12579
|
+
}
|
|
12580
|
+
}
|
|
12581
|
+
return roots;
|
|
12582
|
+
}
|
|
12583
|
+
function expandReachableClosure(seeds, project, options, projectFileSet, facts, recognizers = NO_RECOGNIZERS, alreadySummarized = [], extraRoots = []) {
|
|
12409
12584
|
const lookup = createSourceFileLookup(project);
|
|
12410
12585
|
const db = facts?.db ?? new import_datalog4.Database();
|
|
12411
12586
|
const functionByKey = /* @__PURE__ */ new Map();
|
|
@@ -12425,6 +12600,13 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
12425
12600
|
db.add("entry", [key]);
|
|
12426
12601
|
}
|
|
12427
12602
|
}
|
|
12603
|
+
for (const root of extraRoots) {
|
|
12604
|
+
const key = nodeKey2(root.func);
|
|
12605
|
+
if (!functionByKey.has(key)) {
|
|
12606
|
+
functionByKey.set(key, root);
|
|
12607
|
+
}
|
|
12608
|
+
db.add("entry", [key]);
|
|
12609
|
+
}
|
|
12428
12610
|
const knownKeys = /* @__PURE__ */ new Set();
|
|
12429
12611
|
for (const summary of alreadySummarized) {
|
|
12430
12612
|
const func = lookup.functionAt(summary.location);
|
|
@@ -13486,6 +13668,185 @@ function computeAdapterPacksDigest(packVersions) {
|
|
|
13486
13668
|
return `${adapterStamp}|${sortedPacks.join(",")}`;
|
|
13487
13669
|
}
|
|
13488
13670
|
|
|
13671
|
+
// src/workspacePatterns.ts
|
|
13672
|
+
var import_node_crypto4 = require("crypto");
|
|
13673
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
13674
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
13675
|
+
function readJson(filePath) {
|
|
13676
|
+
try {
|
|
13677
|
+
return JSON.parse(import_node_fs6.default.readFileSync(filePath, "utf8"));
|
|
13678
|
+
} catch {
|
|
13679
|
+
return void 0;
|
|
13680
|
+
}
|
|
13681
|
+
}
|
|
13682
|
+
function pnpmWorkspaceGlobs(yamlText) {
|
|
13683
|
+
const globs = [];
|
|
13684
|
+
let inPackages = false;
|
|
13685
|
+
for (const line of yamlText.split("\n")) {
|
|
13686
|
+
if (/^packages\s*:/.test(line)) {
|
|
13687
|
+
inPackages = true;
|
|
13688
|
+
continue;
|
|
13689
|
+
}
|
|
13690
|
+
if (inPackages) {
|
|
13691
|
+
const item = line.match(/^\s+-\s+["']?([^"'#\s]+)["']?/);
|
|
13692
|
+
if (item !== null) {
|
|
13693
|
+
globs.push(item[1]);
|
|
13694
|
+
continue;
|
|
13695
|
+
}
|
|
13696
|
+
if (/^\S/.test(line)) {
|
|
13697
|
+
inPackages = false;
|
|
13698
|
+
}
|
|
13699
|
+
}
|
|
13700
|
+
}
|
|
13701
|
+
return globs;
|
|
13702
|
+
}
|
|
13703
|
+
function workspaceGlobsAt(dir) {
|
|
13704
|
+
const pkg = readJson(import_node_path9.default.join(dir, "package.json"));
|
|
13705
|
+
if (typeof pkg === "object" && pkg !== null && "workspaces" in pkg) {
|
|
13706
|
+
const ws = pkg.workspaces;
|
|
13707
|
+
if (Array.isArray(ws)) {
|
|
13708
|
+
return ws.filter((g) => typeof g === "string");
|
|
13709
|
+
}
|
|
13710
|
+
if (typeof ws === "object" && ws !== null && Array.isArray(ws.packages)) {
|
|
13711
|
+
return ws.packages.filter(
|
|
13712
|
+
(g) => typeof g === "string"
|
|
13713
|
+
);
|
|
13714
|
+
}
|
|
13715
|
+
}
|
|
13716
|
+
const pnpmPath = import_node_path9.default.join(dir, "pnpm-workspace.yaml");
|
|
13717
|
+
if (import_node_fs6.default.existsSync(pnpmPath)) {
|
|
13718
|
+
try {
|
|
13719
|
+
return pnpmWorkspaceGlobs(import_node_fs6.default.readFileSync(pnpmPath, "utf8"));
|
|
13720
|
+
} catch {
|
|
13721
|
+
return null;
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
return null;
|
|
13725
|
+
}
|
|
13726
|
+
function isDirectory(candidate) {
|
|
13727
|
+
try {
|
|
13728
|
+
return import_node_fs6.default.statSync(candidate).isDirectory();
|
|
13729
|
+
} catch {
|
|
13730
|
+
return false;
|
|
13731
|
+
}
|
|
13732
|
+
}
|
|
13733
|
+
function subdirectoriesOf(dir) {
|
|
13734
|
+
try {
|
|
13735
|
+
return import_node_fs6.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
13736
|
+
} catch {
|
|
13737
|
+
return [];
|
|
13738
|
+
}
|
|
13739
|
+
}
|
|
13740
|
+
function segmentToRegExp(segment) {
|
|
13741
|
+
const escaped = segment.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
13742
|
+
return new RegExp(`^${escaped.replace(/\*/g, "[^/]*")}$`);
|
|
13743
|
+
}
|
|
13744
|
+
function directoriesMatchingGlob(root, glob) {
|
|
13745
|
+
let current2 = [root];
|
|
13746
|
+
for (const segment of glob.split("/").filter((s) => s.length > 0)) {
|
|
13747
|
+
const next = [];
|
|
13748
|
+
if (segment.includes("*")) {
|
|
13749
|
+
const pattern = segmentToRegExp(segment);
|
|
13750
|
+
for (const dir of current2) {
|
|
13751
|
+
for (const entry of subdirectoriesOf(dir)) {
|
|
13752
|
+
if (pattern.test(entry)) {
|
|
13753
|
+
next.push(import_node_path9.default.join(dir, entry));
|
|
13754
|
+
}
|
|
13755
|
+
}
|
|
13756
|
+
}
|
|
13757
|
+
} else {
|
|
13758
|
+
for (const dir of current2) {
|
|
13759
|
+
next.push(import_node_path9.default.join(dir, segment));
|
|
13760
|
+
}
|
|
13761
|
+
}
|
|
13762
|
+
current2 = next.filter(isDirectory);
|
|
13763
|
+
}
|
|
13764
|
+
return current2;
|
|
13765
|
+
}
|
|
13766
|
+
function packageAt(dir) {
|
|
13767
|
+
const packageJsonPath = import_node_path9.default.join(dir, "package.json");
|
|
13768
|
+
const pkg = readJson(packageJsonPath);
|
|
13769
|
+
if (typeof pkg === "object" && pkg !== null && typeof pkg.name === "string") {
|
|
13770
|
+
return { name: pkg.name, packageJsonPath };
|
|
13771
|
+
}
|
|
13772
|
+
return null;
|
|
13773
|
+
}
|
|
13774
|
+
function workspacePackagesFrom(anchor) {
|
|
13775
|
+
let dir = import_node_path9.default.resolve(anchor);
|
|
13776
|
+
for (; ; ) {
|
|
13777
|
+
const globs = workspaceGlobsAt(dir);
|
|
13778
|
+
if (globs !== null) {
|
|
13779
|
+
const found = /* @__PURE__ */ new Map();
|
|
13780
|
+
for (const glob of globs) {
|
|
13781
|
+
if (glob.startsWith("!")) {
|
|
13782
|
+
continue;
|
|
13783
|
+
}
|
|
13784
|
+
for (const match of directoriesMatchingGlob(dir, glob)) {
|
|
13785
|
+
const pkg = packageAt(match);
|
|
13786
|
+
if (pkg !== null) {
|
|
13787
|
+
found.set(pkg.packageJsonPath, pkg);
|
|
13788
|
+
}
|
|
13789
|
+
}
|
|
13790
|
+
}
|
|
13791
|
+
return [...found.values()].sort(
|
|
13792
|
+
(a, b) => a.packageJsonPath.localeCompare(b.packageJsonPath)
|
|
13793
|
+
);
|
|
13794
|
+
}
|
|
13795
|
+
const parent = import_node_path9.default.dirname(dir);
|
|
13796
|
+
if (parent === dir) {
|
|
13797
|
+
return [];
|
|
13798
|
+
}
|
|
13799
|
+
dir = parent;
|
|
13800
|
+
}
|
|
13801
|
+
}
|
|
13802
|
+
function isWorkspaceMarked(pattern) {
|
|
13803
|
+
const match = pattern.match;
|
|
13804
|
+
return (match.type === "packageExports" || match.type === "packageImport") && match.workspaces === true;
|
|
13805
|
+
}
|
|
13806
|
+
function expandPattern(pattern, packages) {
|
|
13807
|
+
const match = pattern.match;
|
|
13808
|
+
if (match.type === "packageExports" && match.workspaces === true) {
|
|
13809
|
+
const { workspaces: _workspaces, ...rest } = match;
|
|
13810
|
+
return packages.map((pkg) => ({
|
|
13811
|
+
...pattern,
|
|
13812
|
+
match: { ...rest, packageJsonPath: pkg.packageJsonPath }
|
|
13813
|
+
}));
|
|
13814
|
+
}
|
|
13815
|
+
if (match.type === "packageImport" && match.workspaces === true) {
|
|
13816
|
+
const listed = match.packages ?? [];
|
|
13817
|
+
const names = [.../* @__PURE__ */ new Set([...listed, ...packages.map((p) => p.name)])];
|
|
13818
|
+
if (names.length === 0) {
|
|
13819
|
+
return [];
|
|
13820
|
+
}
|
|
13821
|
+
return [{ ...pattern, match: { type: "packageImport", packages: names } }];
|
|
13822
|
+
}
|
|
13823
|
+
return [pattern];
|
|
13824
|
+
}
|
|
13825
|
+
function workspaceExpansionStamp(frameworks) {
|
|
13826
|
+
const paths = frameworks.flatMap((pack) => pack.discovery).flatMap(
|
|
13827
|
+
(pattern) => pattern.match.type === "packageExports" && pattern.match.packageJsonPath !== void 0 ? [pattern.match.packageJsonPath] : []
|
|
13828
|
+
).sort();
|
|
13829
|
+
if (paths.length === 0) {
|
|
13830
|
+
return "none";
|
|
13831
|
+
}
|
|
13832
|
+
return (0, import_node_crypto4.createHash)("sha256").update(paths.join("\n")).digest("hex").slice(0, 12);
|
|
13833
|
+
}
|
|
13834
|
+
function expandWorkspacePatterns(frameworks, anchor) {
|
|
13835
|
+
const marked = frameworks.some(
|
|
13836
|
+
(pack) => pack.discovery.some(isWorkspaceMarked)
|
|
13837
|
+
);
|
|
13838
|
+
if (!marked) {
|
|
13839
|
+
return frameworks;
|
|
13840
|
+
}
|
|
13841
|
+
const packages = anchor !== void 0 ? workspacePackagesFrom(anchor) : [];
|
|
13842
|
+
return frameworks.map((pack) => ({
|
|
13843
|
+
...pack,
|
|
13844
|
+
discovery: pack.discovery.flatMap(
|
|
13845
|
+
(pattern) => expandPattern(pattern, packages)
|
|
13846
|
+
)
|
|
13847
|
+
}));
|
|
13848
|
+
}
|
|
13849
|
+
|
|
13489
13850
|
// src/adapter.ts
|
|
13490
13851
|
var raise = (msg) => {
|
|
13491
13852
|
throw new Error(msg);
|
|
@@ -13896,11 +14257,11 @@ function extractConsumerBinding(unit, pattern, pack, resolution) {
|
|
|
13896
14257
|
return null;
|
|
13897
14258
|
}
|
|
13898
14259
|
const method = extractBindingMethod(binding, callSite, pack, resolution);
|
|
13899
|
-
const
|
|
14260
|
+
const path13 = extractBindingPath(binding, callSite, pack, resolution);
|
|
13900
14261
|
return (0, import_behavioral_ir8.restBinding)({
|
|
13901
14262
|
transport: pack.protocol,
|
|
13902
14263
|
method: method ?? null,
|
|
13903
|
-
path:
|
|
14264
|
+
path: path13 ?? null,
|
|
13904
14265
|
recognition: pack.name
|
|
13905
14266
|
});
|
|
13906
14267
|
}
|
|
@@ -14512,8 +14873,8 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
|
|
|
14512
14873
|
if (pathArg === void 0) {
|
|
14513
14874
|
continue;
|
|
14514
14875
|
}
|
|
14515
|
-
const
|
|
14516
|
-
if (
|
|
14876
|
+
const path13 = pathFromArgument(pathArg, resolution);
|
|
14877
|
+
if (path13 === void 0) {
|
|
14517
14878
|
continue;
|
|
14518
14879
|
}
|
|
14519
14880
|
const callerFunc = enclosingFunction(callExpr);
|
|
@@ -14525,7 +14886,7 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
|
|
|
14525
14886
|
continue;
|
|
14526
14887
|
}
|
|
14527
14888
|
seen.add(dedupKey);
|
|
14528
|
-
out.push(buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
14889
|
+
out.push(buildCallerSummary(wrapper, callerFunc, callExpr, path13, options));
|
|
14529
14890
|
}
|
|
14530
14891
|
return out;
|
|
14531
14892
|
}
|
|
@@ -14582,7 +14943,7 @@ function callerName(func) {
|
|
|
14582
14943
|
}
|
|
14583
14944
|
return "anonymous";
|
|
14584
14945
|
}
|
|
14585
|
-
function buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
14946
|
+
function buildCallerSummary(wrapper, callerFunc, callExpr, path13, options) {
|
|
14586
14947
|
const wrapperBinding = wrapper.summary.identity.boundaryBinding;
|
|
14587
14948
|
const wrapperRest = wrapperBinding?.semantics.name === "rest" ? wrapperBinding.semantics : null;
|
|
14588
14949
|
const syntheticPack = {
|
|
@@ -14614,7 +14975,7 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path12, options) {
|
|
|
14614
14975
|
raw.boundaryBinding = (0, import_behavioral_ir8.restBinding)({
|
|
14615
14976
|
transport: wrapperBinding?.transport ?? "http",
|
|
14616
14977
|
method: wrapperRest?.method ?? null,
|
|
14617
|
-
path:
|
|
14978
|
+
path: path13,
|
|
14618
14979
|
recognition: wrapperBinding?.recognition ?? "unknown"
|
|
14619
14980
|
});
|
|
14620
14981
|
const summary = (0, import_extractor5.assembleSummary)(raw, options);
|
|
@@ -14680,25 +15041,32 @@ function loadRunFiles(project, candidatePaths, timer) {
|
|
|
14680
15041
|
);
|
|
14681
15042
|
return { sourceFiles, deep };
|
|
14682
15043
|
}
|
|
14683
|
-
function createTypeScriptAdapter(
|
|
15044
|
+
function createTypeScriptAdapter(suppliedConfig) {
|
|
15045
|
+
const config = {
|
|
15046
|
+
...suppliedConfig,
|
|
15047
|
+
frameworks: expandWorkspacePatterns(
|
|
15048
|
+
suppliedConfig.frameworks,
|
|
15049
|
+
suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ? import_node_path10.default.dirname(suppliedConfig.tsConfigFilePath) : void 0)
|
|
15050
|
+
)
|
|
15051
|
+
};
|
|
14684
15052
|
const project = config.project ?? new import_ts_morph60.Project(
|
|
14685
15053
|
config.tsConfigFilePath !== void 0 ? {
|
|
14686
15054
|
tsConfigFilePath: config.tsConfigFilePath,
|
|
14687
15055
|
skipAddingFilesFromTsConfig: true
|
|
14688
15056
|
} : { skipAddingFilesFromTsConfig: true }
|
|
14689
15057
|
);
|
|
14690
|
-
const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(
|
|
15058
|
+
const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(import_node_path10.default.dirname(config.tsConfigFilePath)) : void 0);
|
|
14691
15059
|
let lazyBootstrapped = false;
|
|
14692
15060
|
let projectFileSet;
|
|
14693
15061
|
const cacheDir = declineWhenRunFromSource(
|
|
14694
|
-
config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ?
|
|
15062
|
+
config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ? import_node_path10.default.join(import_node_path10.default.dirname(config.tsConfigFilePath), ".suss", "cache") : null)
|
|
14695
15063
|
);
|
|
14696
15064
|
const cache = createCacheLayer(cacheDir);
|
|
14697
15065
|
const adapterPacksDigest = `${computeAdapterPacksDigest(
|
|
14698
15066
|
config.frameworks.map(
|
|
14699
15067
|
(p) => p.version !== void 0 ? { name: p.name, version: p.version } : { name: p.name }
|
|
14700
15068
|
)
|
|
14701
|
-
)}|${extractionConfigStamp(config)}`;
|
|
15069
|
+
)}|${extractionConfigStamp(config)}|ws:${workspaceExpansionStamp(config.frameworks)}`;
|
|
14702
15070
|
const packWrappers = config.frameworks.flatMap(
|
|
14703
15071
|
(pack) => pack.transparentWrappers ?? []
|
|
14704
15072
|
);
|
|
@@ -14934,7 +15302,12 @@ function createTypeScriptAdapter(config) {
|
|
|
14934
15302
|
},
|
|
14935
15303
|
// Reached units the cache already serves emit nothing,
|
|
14936
15304
|
// the way a cold run's seeds do not.
|
|
14937
|
-
reused?.summaries ?? []
|
|
15305
|
+
reused?.summaries ?? [],
|
|
15306
|
+
// A recognizer-only pack's effects need a function to
|
|
15307
|
+
// live on even when nothing discovers units in its
|
|
15308
|
+
// files, so those files' exports join the walk as
|
|
15309
|
+
// roots.
|
|
15310
|
+
recognizerOnlyRoots(packsByFile)
|
|
14938
15311
|
)
|
|
14939
15312
|
) : withSubUnits;
|
|
14940
15313
|
const closureOwnership = caching && config.includeReachable !== false ? timer.time(
|
|
@@ -15331,8 +15704,8 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
|
|
|
15331
15704
|
}
|
|
15332
15705
|
|
|
15333
15706
|
// src/bootstrap/noTsconfigProject.ts
|
|
15334
|
-
var
|
|
15335
|
-
var
|
|
15707
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
15708
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
15336
15709
|
var import_ts_morph61 = require("ts-morph");
|
|
15337
15710
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
15338
15711
|
".ts",
|
|
@@ -15363,7 +15736,7 @@ function findSourceFiles(rootDir, depth = 0) {
|
|
|
15363
15736
|
const found = [];
|
|
15364
15737
|
let entries;
|
|
15365
15738
|
try {
|
|
15366
|
-
entries =
|
|
15739
|
+
entries = import_node_fs7.default.readdirSync(rootDir, { withFileTypes: true });
|
|
15367
15740
|
} catch {
|
|
15368
15741
|
return [];
|
|
15369
15742
|
}
|
|
@@ -15371,10 +15744,10 @@ function findSourceFiles(rootDir, depth = 0) {
|
|
|
15371
15744
|
if (entry.name.startsWith(".") || SKIP_DIRECTORIES.has(entry.name)) {
|
|
15372
15745
|
continue;
|
|
15373
15746
|
}
|
|
15374
|
-
const full =
|
|
15747
|
+
const full = import_node_path11.default.join(rootDir, entry.name);
|
|
15375
15748
|
if (entry.isDirectory()) {
|
|
15376
15749
|
found.push(...findSourceFiles(full, depth + 1));
|
|
15377
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
15750
|
+
} else if (SOURCE_EXTENSIONS.has(import_node_path11.default.extname(entry.name)) && !entry.name.endsWith(".d.ts")) {
|
|
15378
15751
|
found.push(full);
|
|
15379
15752
|
}
|
|
15380
15753
|
}
|
|
@@ -15409,15 +15782,15 @@ function createProjectWithoutTsconfig(rootDir) {
|
|
|
15409
15782
|
return { project, files };
|
|
15410
15783
|
}
|
|
15411
15784
|
function findNearestTsconfig(startDir) {
|
|
15412
|
-
let dir =
|
|
15785
|
+
let dir = import_node_path11.default.resolve(startDir);
|
|
15413
15786
|
while (true) {
|
|
15414
15787
|
for (const name of ["tsconfig.json", "jsconfig.json"]) {
|
|
15415
|
-
const candidate =
|
|
15416
|
-
if (
|
|
15788
|
+
const candidate = import_node_path11.default.join(dir, name);
|
|
15789
|
+
if (import_node_fs7.default.existsSync(candidate)) {
|
|
15417
15790
|
return candidate;
|
|
15418
15791
|
}
|
|
15419
15792
|
}
|
|
15420
|
-
const parent =
|
|
15793
|
+
const parent = import_node_path11.default.dirname(dir);
|
|
15421
15794
|
if (parent === dir) {
|
|
15422
15795
|
return null;
|
|
15423
15796
|
}
|
|
@@ -15426,7 +15799,7 @@ function findNearestTsconfig(startDir) {
|
|
|
15426
15799
|
}
|
|
15427
15800
|
|
|
15428
15801
|
// src/facts/why.ts
|
|
15429
|
-
var
|
|
15802
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
15430
15803
|
var import_ts_morph62 = require("ts-morph");
|
|
15431
15804
|
var import_resolution2 = require("@suss/resolution");
|
|
15432
15805
|
var JS_PHRASES = {
|
|
@@ -15439,7 +15812,7 @@ var WhySession = class {
|
|
|
15439
15812
|
store;
|
|
15440
15813
|
root;
|
|
15441
15814
|
constructor(options) {
|
|
15442
|
-
this.root =
|
|
15815
|
+
this.root = import_node_path12.default.resolve(options.dir);
|
|
15443
15816
|
const tsconfig = findNearestTsconfig(this.root);
|
|
15444
15817
|
this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph62.Project({ tsConfigFilePath: tsconfig });
|
|
15445
15818
|
this.store = new ResolutionStore();
|
|
@@ -15528,7 +15901,7 @@ var WhySession = class {
|
|
|
15528
15901
|
};
|
|
15529
15902
|
}
|
|
15530
15903
|
sourceFileAt(file) {
|
|
15531
|
-
const absolute =
|
|
15904
|
+
const absolute = import_node_path12.default.resolve(this.root, file);
|
|
15532
15905
|
const loaded = this.project.getSourceFile(absolute);
|
|
15533
15906
|
if (loaded !== void 0) {
|
|
15534
15907
|
return loaded;
|
|
@@ -15542,7 +15915,7 @@ var WhySession = class {
|
|
|
15542
15915
|
/** A module key: a file path said relative to the root, or a package name. */
|
|
15543
15916
|
displayPath(key) {
|
|
15544
15917
|
if (key.startsWith(this.root)) {
|
|
15545
|
-
return
|
|
15918
|
+
return import_node_path12.default.relative(this.root, key);
|
|
15546
15919
|
}
|
|
15547
15920
|
return key;
|
|
15548
15921
|
}
|
|
@@ -15613,6 +15986,17 @@ function funnelDrops(packs) {
|
|
|
15613
15986
|
}
|
|
15614
15987
|
return violations;
|
|
15615
15988
|
}
|
|
15989
|
+
function recognizersWithNoUnits(packs) {
|
|
15990
|
+
return packs.filter(
|
|
15991
|
+
(funnel) => funnel.recognizes && !funnel.discovers && funnel.gates.length > 0 && funnel.unresolvedGates.length === 0 && funnel.candidateFiles > 0 && funnel.unitsInGatedFiles === 0 && // The closure walks a recognizer-only pack's gated exports as
|
|
15992
|
+
// roots, so effects recognized there mean the run worked and
|
|
15993
|
+
// the missing framework pack costs attribution, not existence.
|
|
15994
|
+
funnel.effectsRecognized === 0
|
|
15995
|
+
).map((funnel) => ({
|
|
15996
|
+
label: funnel.pack,
|
|
15997
|
+
detail: `${funnel.candidateFiles} gated files, and no pack in this run discovered a unit in them. ${funnel.pack} reads calls inside units another pack finds, so add the pack that finds this project's handlers (-f express, -f fastify, ...), or run suss init to work out which.`
|
|
15998
|
+
}));
|
|
15999
|
+
}
|
|
15616
16000
|
function unversionedPacks(packs) {
|
|
15617
16001
|
return packs.filter((funnel) => funnel.version === null).map((funnel) => ({
|
|
15618
16002
|
label: funnel.pack,
|
|
@@ -15707,6 +16091,12 @@ function evaluatePackHealth(report) {
|
|
|
15707
16091
|
audience: "run",
|
|
15708
16092
|
violations: selfCollisions(report.packs)
|
|
15709
16093
|
},
|
|
16094
|
+
{
|
|
16095
|
+
name: "every recognizer had units to look inside",
|
|
16096
|
+
code: "no-units",
|
|
16097
|
+
audience: "run",
|
|
16098
|
+
violations: recognizersWithNoUnits(report.packs)
|
|
16099
|
+
},
|
|
15710
16100
|
{
|
|
15711
16101
|
name: "every pack declares a version",
|
|
15712
16102
|
code: "no-version",
|