@suss/adapter-typescript 0.22.2 → 0.22.3
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 +270 -247
- package/dist/index.js +266 -243
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -4658,6 +4658,26 @@ function resolveImportedLocalName(sourceFile, importModule, importName) {
|
|
|
4658
4658
|
}
|
|
4659
4659
|
return null;
|
|
4660
4660
|
}
|
|
4661
|
+
function importedReferenceSpellings(sourceFile, importModule, importName) {
|
|
4662
|
+
const spellings = [];
|
|
4663
|
+
const localName = resolveImportedLocalName(
|
|
4664
|
+
sourceFile,
|
|
4665
|
+
importModule,
|
|
4666
|
+
importName
|
|
4667
|
+
);
|
|
4668
|
+
if (localName !== null) {
|
|
4669
|
+
spellings.push(localName);
|
|
4670
|
+
}
|
|
4671
|
+
if (!sourceFile.getFullText().includes(`.${importName}`)) {
|
|
4672
|
+
return spellings;
|
|
4673
|
+
}
|
|
4674
|
+
for (const root of importedRootsOf(sourceFile, [importModule])) {
|
|
4675
|
+
if (root !== importName) {
|
|
4676
|
+
spellings.push(`${root}.${importName}`);
|
|
4677
|
+
}
|
|
4678
|
+
}
|
|
4679
|
+
return spellings;
|
|
4680
|
+
}
|
|
4661
4681
|
|
|
4662
4682
|
// src/discovery/resolveValue.ts
|
|
4663
4683
|
var import_ts_morph19 = require("ts-morph");
|
|
@@ -8081,13 +8101,13 @@ function collectMethodsCalledOnCallResults(sourceFile) {
|
|
|
8081
8101
|
return called;
|
|
8082
8102
|
}
|
|
8083
8103
|
function registrationSubjectsOf(sourceFile, importModule, importName, resolution) {
|
|
8084
|
-
const
|
|
8104
|
+
const spellings = importedReferenceSpellings(
|
|
8085
8105
|
sourceFile,
|
|
8086
8106
|
importModule,
|
|
8087
8107
|
importName
|
|
8088
8108
|
);
|
|
8089
8109
|
const subjects = /* @__PURE__ */ new Map();
|
|
8090
|
-
if (
|
|
8110
|
+
if (spellings.length === 0) {
|
|
8091
8111
|
return subjects;
|
|
8092
8112
|
}
|
|
8093
8113
|
sourceFile.forEachDescendant((node) => {
|
|
@@ -8097,7 +8117,7 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
|
|
|
8097
8117
|
return;
|
|
8098
8118
|
}
|
|
8099
8119
|
const calleeText = import_ts_morph34.Node.isCallExpression(init) || import_ts_morph34.Node.isNewExpression(init) ? init.getExpression().getText() : null;
|
|
8100
|
-
if (calleeText
|
|
8120
|
+
if (calleeText !== null && spellings.includes(calleeText)) {
|
|
8101
8121
|
subjects.set(node.getName(), init);
|
|
8102
8122
|
}
|
|
8103
8123
|
return;
|
|
@@ -8110,7 +8130,9 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
|
|
|
8110
8130
|
return;
|
|
8111
8131
|
}
|
|
8112
8132
|
const typeText = typeNode.getText();
|
|
8113
|
-
if (
|
|
8133
|
+
if (spellings.some(
|
|
8134
|
+
(spelling) => typeText === spelling || typeText.startsWith(`${spelling}<`)
|
|
8135
|
+
)) {
|
|
8114
8136
|
subjects.set(node.getName(), creationSiteBehind(node, resolution));
|
|
8115
8137
|
}
|
|
8116
8138
|
});
|
|
@@ -8154,17 +8176,17 @@ function registrationSubjectIdsOf(sourceFile, matches, resolution) {
|
|
|
8154
8176
|
return ids;
|
|
8155
8177
|
}
|
|
8156
8178
|
function unboundConstructionsOf(sourceFile, importModule, importName) {
|
|
8157
|
-
const
|
|
8179
|
+
const spellings = importedReferenceSpellings(
|
|
8158
8180
|
sourceFile,
|
|
8159
8181
|
importModule,
|
|
8160
8182
|
importName
|
|
8161
8183
|
);
|
|
8162
|
-
if (
|
|
8184
|
+
if (spellings.length === 0) {
|
|
8163
8185
|
return [];
|
|
8164
8186
|
}
|
|
8165
8187
|
const constructions = [];
|
|
8166
8188
|
sourceFile.forEachDescendant((node) => {
|
|
8167
|
-
if ((import_ts_morph34.Node.isCallExpression(node) || import_ts_morph34.Node.isNewExpression(node)) && node.getExpression().getText()
|
|
8189
|
+
if ((import_ts_morph34.Node.isCallExpression(node) || import_ts_morph34.Node.isNewExpression(node)) && spellings.includes(node.getExpression().getText()) && !import_ts_morph34.Node.isVariableDeclaration(node.getParent())) {
|
|
8168
8190
|
constructions.push(node);
|
|
8169
8191
|
}
|
|
8170
8192
|
});
|
|
@@ -10195,199 +10217,12 @@ function tryMatchParameterCall(node, func, pattern, match) {
|
|
|
10195
10217
|
return { node, terminal };
|
|
10196
10218
|
}
|
|
10197
10219
|
|
|
10198
|
-
// src/terminals/
|
|
10199
|
-
var
|
|
10200
|
-
|
|
10201
|
-
let expr;
|
|
10202
|
-
let source;
|
|
10203
|
-
if (import_ts_morph46.Node.isReturnStatement(node)) {
|
|
10204
|
-
expr = node.getExpression();
|
|
10205
|
-
source = node;
|
|
10206
|
-
} else if (import_ts_morph46.Node.isArrowFunction(node)) {
|
|
10207
|
-
const body = node.getBody();
|
|
10208
|
-
if (body !== void 0 && !import_ts_morph46.Node.isBlock(body)) {
|
|
10209
|
-
expr = body;
|
|
10210
|
-
source = body;
|
|
10211
|
-
}
|
|
10212
|
-
}
|
|
10213
|
-
if (expr === void 0 || source === void 0) {
|
|
10214
|
-
return null;
|
|
10215
|
-
}
|
|
10216
|
-
const tree = jsxToRenderNode(expr);
|
|
10217
|
-
if (tree === null) {
|
|
10218
|
-
return null;
|
|
10219
|
-
}
|
|
10220
|
-
const component = tree.type === "element" ? tree.tag : "Fragment";
|
|
10221
|
-
const terminal = {
|
|
10222
|
-
kind: pattern.kind,
|
|
10223
|
-
statusCode: null,
|
|
10224
|
-
body: null,
|
|
10225
|
-
exceptionType: null,
|
|
10226
|
-
message: null,
|
|
10227
|
-
component,
|
|
10228
|
-
delegateTarget: null,
|
|
10229
|
-
emitEvent: null,
|
|
10230
|
-
renderTree: tree,
|
|
10231
|
-
location: {
|
|
10232
|
-
start: startLineOf(node),
|
|
10233
|
-
end: endLineOf(node)
|
|
10234
|
-
}
|
|
10235
|
-
};
|
|
10236
|
-
return { node, source, terminal };
|
|
10237
|
-
}
|
|
10238
|
-
function componentTargetOf(tagNode) {
|
|
10239
|
-
if (!import_ts_morph46.Node.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
|
|
10240
|
-
return null;
|
|
10241
|
-
}
|
|
10242
|
-
const target = functionTargetOf(tagNode);
|
|
10243
|
-
return target === null ? null : { file: target.file, name: target.name };
|
|
10244
|
-
}
|
|
10245
|
-
function jsxToRenderNode(node) {
|
|
10246
|
-
if (import_ts_morph46.Node.isJsxElement(node)) {
|
|
10247
|
-
const opening = node.getOpeningElement();
|
|
10248
|
-
const tag = opening.getTagNameNode().getText();
|
|
10249
|
-
const attrs = collectJsxAttributes(opening);
|
|
10250
|
-
const target = componentTargetOf(opening.getTagNameNode());
|
|
10251
|
-
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
10252
|
-
return {
|
|
10253
|
-
type: "element",
|
|
10254
|
-
tag,
|
|
10255
|
-
children,
|
|
10256
|
-
...attrs !== null ? { attrs } : {},
|
|
10257
|
-
...target !== null ? { target } : {}
|
|
10258
|
-
};
|
|
10259
|
-
}
|
|
10260
|
-
if (import_ts_morph46.Node.isJsxSelfClosingElement(node)) {
|
|
10261
|
-
const tag = node.getTagNameNode().getText();
|
|
10262
|
-
const attrs = collectJsxAttributes(node);
|
|
10263
|
-
const target = componentTargetOf(node.getTagNameNode());
|
|
10264
|
-
return {
|
|
10265
|
-
type: "element",
|
|
10266
|
-
tag,
|
|
10267
|
-
children: [],
|
|
10268
|
-
...attrs !== null ? { attrs } : {},
|
|
10269
|
-
...target !== null ? { target } : {}
|
|
10270
|
-
};
|
|
10271
|
-
}
|
|
10272
|
-
if (import_ts_morph46.Node.isJsxFragment(node)) {
|
|
10273
|
-
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
10274
|
-
return { type: "element", tag: "Fragment", children };
|
|
10275
|
-
}
|
|
10276
|
-
if (import_ts_morph46.Node.isParenthesizedExpression(node)) {
|
|
10277
|
-
return jsxToRenderNode(node.getExpression());
|
|
10278
|
-
}
|
|
10279
|
-
return null;
|
|
10280
|
-
}
|
|
10281
|
-
function collectJsxAttributes(opening) {
|
|
10282
|
-
const entries = {};
|
|
10283
|
-
for (const attr of opening.getAttributes()) {
|
|
10284
|
-
if (import_ts_morph46.Node.isJsxSpreadAttribute(attr)) {
|
|
10285
|
-
const exprText = attr.getExpression().getText();
|
|
10286
|
-
entries[`...${exprText}`] = exprText;
|
|
10287
|
-
continue;
|
|
10288
|
-
}
|
|
10289
|
-
if (!import_ts_morph46.Node.isJsxAttribute(attr)) {
|
|
10290
|
-
continue;
|
|
10291
|
-
}
|
|
10292
|
-
const name = attr.getNameNode().getText();
|
|
10293
|
-
const initializer = attr.getInitializer();
|
|
10294
|
-
if (initializer === void 0) {
|
|
10295
|
-
entries[name] = "";
|
|
10296
|
-
continue;
|
|
10297
|
-
}
|
|
10298
|
-
if (import_ts_morph46.Node.isJsxExpression(initializer)) {
|
|
10299
|
-
const inner = initializer.getExpression();
|
|
10300
|
-
entries[name] = inner !== void 0 ? inner.getText() : "";
|
|
10301
|
-
continue;
|
|
10302
|
-
}
|
|
10303
|
-
entries[name] = initializer.getText();
|
|
10304
|
-
}
|
|
10305
|
-
return Object.keys(entries).length > 0 ? entries : null;
|
|
10306
|
-
}
|
|
10307
|
-
function jsxChildToRenderNode(child) {
|
|
10308
|
-
if (import_ts_morph46.Node.isJsxText(child)) {
|
|
10309
|
-
const text = child.getLiteralText().trim();
|
|
10310
|
-
if (text.length === 0) {
|
|
10311
|
-
return null;
|
|
10312
|
-
}
|
|
10313
|
-
return { type: "text", value: text };
|
|
10314
|
-
}
|
|
10315
|
-
if (import_ts_morph46.Node.isJsxExpression(child)) {
|
|
10316
|
-
const inner = child.getExpression();
|
|
10317
|
-
if (inner === void 0) {
|
|
10318
|
-
return null;
|
|
10319
|
-
}
|
|
10320
|
-
return jsxExpressionToRenderNode(inner);
|
|
10321
|
-
}
|
|
10322
|
-
if (import_ts_morph46.Node.isJsxElement(child) || import_ts_morph46.Node.isJsxSelfClosingElement(child) || import_ts_morph46.Node.isJsxFragment(child)) {
|
|
10323
|
-
return jsxToRenderNode(child);
|
|
10324
|
-
}
|
|
10325
|
-
return null;
|
|
10326
|
-
}
|
|
10327
|
-
function jsxExpressionToRenderNode(expr) {
|
|
10328
|
-
if (import_ts_morph46.Node.isParenthesizedExpression(expr)) {
|
|
10329
|
-
return jsxExpressionToRenderNode(expr.getExpression());
|
|
10330
|
-
}
|
|
10331
|
-
if (import_ts_morph46.Node.isBinaryExpression(expr)) {
|
|
10332
|
-
const op = expr.getOperatorToken().getText();
|
|
10333
|
-
if (op === "&&") {
|
|
10334
|
-
const right = renderAlternative(peelParens(expr.getRight()));
|
|
10335
|
-
if (right.kind === "jsx") {
|
|
10336
|
-
return {
|
|
10337
|
-
type: "conditional",
|
|
10338
|
-
condition: expr.getLeft().getText(),
|
|
10339
|
-
whenTrue: right.node,
|
|
10340
|
-
whenFalse: null
|
|
10341
|
-
};
|
|
10342
|
-
}
|
|
10343
|
-
}
|
|
10344
|
-
}
|
|
10345
|
-
if (import_ts_morph46.Node.isConditionalExpression(expr)) {
|
|
10346
|
-
const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
|
|
10347
|
-
const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
|
|
10348
|
-
if (truthy.kind === "jsx") {
|
|
10349
|
-
return {
|
|
10350
|
-
type: "conditional",
|
|
10351
|
-
condition: expr.getCondition().getText(),
|
|
10352
|
-
whenTrue: truthy.node,
|
|
10353
|
-
whenFalse: falsy.kind === "jsx" ? falsy.node : null
|
|
10354
|
-
};
|
|
10355
|
-
}
|
|
10356
|
-
if (falsy.kind === "jsx") {
|
|
10357
|
-
return {
|
|
10358
|
-
type: "conditional",
|
|
10359
|
-
condition: `!(${expr.getCondition().getText()})`,
|
|
10360
|
-
whenTrue: falsy.node,
|
|
10361
|
-
whenFalse: null
|
|
10362
|
-
};
|
|
10363
|
-
}
|
|
10364
|
-
}
|
|
10365
|
-
return { type: "expression", sourceText: expr.getText() };
|
|
10366
|
-
}
|
|
10367
|
-
function renderAlternative(node) {
|
|
10368
|
-
if (import_ts_morph46.Node.isNullLiteral(node)) {
|
|
10369
|
-
return { kind: "noRender" };
|
|
10370
|
-
}
|
|
10371
|
-
if (import_ts_morph46.Node.isFalseLiteral(node)) {
|
|
10372
|
-
return { kind: "noRender" };
|
|
10373
|
-
}
|
|
10374
|
-
if (import_ts_morph46.Node.isIdentifier(node) && node.getText() === "undefined") {
|
|
10375
|
-
return { kind: "noRender" };
|
|
10376
|
-
}
|
|
10377
|
-
if (import_ts_morph46.Node.isJsxElement(node) || import_ts_morph46.Node.isJsxSelfClosingElement(node) || import_ts_morph46.Node.isJsxFragment(node)) {
|
|
10378
|
-
const tree = jsxToRenderNode(node);
|
|
10379
|
-
if (tree !== null) {
|
|
10380
|
-
return { kind: "jsx", node: tree };
|
|
10381
|
-
}
|
|
10382
|
-
}
|
|
10383
|
-
return { kind: "notStatic" };
|
|
10384
|
-
}
|
|
10385
|
-
|
|
10386
|
-
// src/terminals/returns.ts
|
|
10387
|
-
var import_ts_morph51 = require("ts-morph");
|
|
10220
|
+
// src/terminals/extract.ts
|
|
10221
|
+
var import_ts_morph47 = require("ts-morph");
|
|
10222
|
+
var import_values5 = require("@suss/values");
|
|
10388
10223
|
|
|
10389
10224
|
// src/shapes/shapes.ts
|
|
10390
|
-
var
|
|
10225
|
+
var import_ts_morph46 = require("ts-morph");
|
|
10391
10226
|
|
|
10392
10227
|
// src/shapes/typeShapes.ts
|
|
10393
10228
|
var import_node_crypto = require("crypto");
|
|
@@ -10846,60 +10681,60 @@ function extractShapeWithArguments(node, substitutions) {
|
|
|
10846
10681
|
}
|
|
10847
10682
|
function extractShapeInner(node) {
|
|
10848
10683
|
const unwrapped2 = peelSyntax(node);
|
|
10849
|
-
if (boundArguments !== null &&
|
|
10684
|
+
if (boundArguments !== null && import_ts_morph46.Node.isIdentifier(unwrapped2)) {
|
|
10850
10685
|
const argument = boundArguments.get(unwrapped2.getText());
|
|
10851
10686
|
if (argument !== void 0 && argument !== unwrapped2) {
|
|
10852
10687
|
return extractShape(argument);
|
|
10853
10688
|
}
|
|
10854
10689
|
}
|
|
10855
|
-
if (
|
|
10690
|
+
if (import_ts_morph46.Node.isObjectLiteralExpression(unwrapped2)) {
|
|
10856
10691
|
return shapeFromObjectLiteral(unwrapped2);
|
|
10857
10692
|
}
|
|
10858
|
-
if (
|
|
10693
|
+
if (import_ts_morph46.Node.isArrayLiteralExpression(unwrapped2)) {
|
|
10859
10694
|
return shapeFromArrayLiteral(unwrapped2);
|
|
10860
10695
|
}
|
|
10861
|
-
if (
|
|
10696
|
+
if (import_ts_morph46.Node.isStringLiteral(unwrapped2) || import_ts_morph46.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
|
|
10862
10697
|
return { type: "literal", value: unwrapped2.getLiteralValue() };
|
|
10863
10698
|
}
|
|
10864
|
-
if (
|
|
10699
|
+
if (import_ts_morph46.Node.isTemplateExpression(unwrapped2)) {
|
|
10865
10700
|
return { type: "text" };
|
|
10866
10701
|
}
|
|
10867
|
-
if (
|
|
10702
|
+
if (import_ts_morph46.Node.isNumericLiteral(unwrapped2)) {
|
|
10868
10703
|
return numericLiteralShape(
|
|
10869
10704
|
unwrapped2.getLiteralValue(),
|
|
10870
10705
|
unwrapped2.getText()
|
|
10871
10706
|
);
|
|
10872
10707
|
}
|
|
10873
|
-
if (
|
|
10708
|
+
if (import_ts_morph46.Node.isPrefixUnaryExpression(unwrapped2)) {
|
|
10874
10709
|
const op = unwrapped2.getOperatorToken();
|
|
10875
|
-
if (op ===
|
|
10710
|
+
if (op === import_ts_morph46.SyntaxKind.MinusToken || op === import_ts_morph46.SyntaxKind.PlusToken) {
|
|
10876
10711
|
const inner = unwrapped2.getOperand();
|
|
10877
|
-
if (
|
|
10712
|
+
if (import_ts_morph46.Node.isNumericLiteral(inner)) {
|
|
10878
10713
|
const v3 = inner.getLiteralValue();
|
|
10879
|
-
const signed = op ===
|
|
10714
|
+
const signed = op === import_ts_morph46.SyntaxKind.MinusToken ? -v3 : v3;
|
|
10880
10715
|
const rawBody = inner.getText();
|
|
10881
|
-
const raw = op ===
|
|
10716
|
+
const raw = op === import_ts_morph46.SyntaxKind.MinusToken ? `-${rawBody}` : rawBody;
|
|
10882
10717
|
return numericLiteralShape(signed, raw);
|
|
10883
10718
|
}
|
|
10884
10719
|
}
|
|
10885
10720
|
}
|
|
10886
|
-
if (
|
|
10721
|
+
if (import_ts_morph46.Node.isBigIntLiteral(unwrapped2)) {
|
|
10887
10722
|
return { type: "ref", name: "bigint" };
|
|
10888
10723
|
}
|
|
10889
10724
|
const kind = unwrapped2.getKind();
|
|
10890
|
-
if (kind ===
|
|
10725
|
+
if (kind === import_ts_morph46.SyntaxKind.TrueKeyword) {
|
|
10891
10726
|
return { type: "literal", value: true };
|
|
10892
10727
|
}
|
|
10893
|
-
if (kind ===
|
|
10728
|
+
if (kind === import_ts_morph46.SyntaxKind.FalseKeyword) {
|
|
10894
10729
|
return { type: "literal", value: false };
|
|
10895
10730
|
}
|
|
10896
|
-
if (kind ===
|
|
10731
|
+
if (kind === import_ts_morph46.SyntaxKind.NullKeyword) {
|
|
10897
10732
|
return { type: "null" };
|
|
10898
10733
|
}
|
|
10899
|
-
if (
|
|
10734
|
+
if (import_ts_morph46.Node.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
|
|
10900
10735
|
return { type: "undefined" };
|
|
10901
10736
|
}
|
|
10902
|
-
if (
|
|
10737
|
+
if (import_ts_morph46.Node.isConditionalExpression(unwrapped2)) {
|
|
10903
10738
|
const whenTrue = extractShape(unwrapped2.getWhenTrue());
|
|
10904
10739
|
const whenFalse = extractShape(unwrapped2.getWhenFalse());
|
|
10905
10740
|
const variants = [];
|
|
@@ -10930,7 +10765,7 @@ function shapeFromArrayLiteral(arr) {
|
|
|
10930
10765
|
}
|
|
10931
10766
|
const shapes = [];
|
|
10932
10767
|
for (const el of elements) {
|
|
10933
|
-
if (
|
|
10768
|
+
if (import_ts_morph46.Node.isSpreadElement(el)) {
|
|
10934
10769
|
const inner = el.getExpression();
|
|
10935
10770
|
const innerShape = extractShape(inner);
|
|
10936
10771
|
if (innerShape?.type === "array") {
|
|
@@ -10949,7 +10784,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10949
10784
|
const properties = {};
|
|
10950
10785
|
const unresolvedSpreads = [];
|
|
10951
10786
|
for (const prop of obj.getProperties()) {
|
|
10952
|
-
if (
|
|
10787
|
+
if (import_ts_morph46.Node.isPropertyAssignment(prop)) {
|
|
10953
10788
|
const name = propertyName2(prop);
|
|
10954
10789
|
if (name === null) {
|
|
10955
10790
|
continue;
|
|
@@ -10965,7 +10800,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10965
10800
|
};
|
|
10966
10801
|
continue;
|
|
10967
10802
|
}
|
|
10968
|
-
if (
|
|
10803
|
+
if (import_ts_morph46.Node.isShorthandPropertyAssignment(prop)) {
|
|
10969
10804
|
const name = prop.getName();
|
|
10970
10805
|
const valueExpr = prop.getNameNode();
|
|
10971
10806
|
properties[name] = extractShape(valueExpr) ?? {
|
|
@@ -10974,7 +10809,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10974
10809
|
};
|
|
10975
10810
|
continue;
|
|
10976
10811
|
}
|
|
10977
|
-
if (
|
|
10812
|
+
if (import_ts_morph46.Node.isSpreadAssignment(prop)) {
|
|
10978
10813
|
const expr = prop.getExpression();
|
|
10979
10814
|
const spreadShape = extractShape(expr);
|
|
10980
10815
|
if (spreadShape?.type === "record") {
|
|
@@ -10993,7 +10828,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10993
10828
|
}
|
|
10994
10829
|
function propertyName2(prop) {
|
|
10995
10830
|
const nameNode = prop.getNameNode();
|
|
10996
|
-
if (
|
|
10831
|
+
if (import_ts_morph46.Node.isIdentifier(nameNode) || import_ts_morph46.Node.isStringLiteral(nameNode) || import_ts_morph46.Node.isNoSubstitutionTemplateLiteral(nameNode) || import_ts_morph46.Node.isNumericLiteral(nameNode)) {
|
|
10997
10832
|
return nameNode.getText().replace(/^["']|["']$/g, "");
|
|
10998
10833
|
}
|
|
10999
10834
|
return null;
|
|
@@ -11019,22 +10854,20 @@ function collapseVariants2(shapes) {
|
|
|
11019
10854
|
}
|
|
11020
10855
|
|
|
11021
10856
|
// src/terminals/extract.ts
|
|
11022
|
-
var import_ts_morph48 = require("ts-morph");
|
|
11023
|
-
var import_values5 = require("@suss/values");
|
|
11024
10857
|
function unwrapAs(node) {
|
|
11025
10858
|
return peelSyntax(node);
|
|
11026
10859
|
}
|
|
11027
10860
|
function unwrapJsonStringify(node) {
|
|
11028
10861
|
const outer = unwrapAs(node);
|
|
11029
|
-
if (!
|
|
10862
|
+
if (!import_ts_morph47.Node.isCallExpression(outer)) {
|
|
11030
10863
|
return node;
|
|
11031
10864
|
}
|
|
11032
10865
|
const callee = outer.getExpression();
|
|
11033
|
-
if (!
|
|
10866
|
+
if (!import_ts_morph47.Node.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
|
|
11034
10867
|
return node;
|
|
11035
10868
|
}
|
|
11036
10869
|
const receiver = callee.getExpression();
|
|
11037
|
-
if (!
|
|
10870
|
+
if (!import_ts_morph47.Node.isIdentifier(receiver) || receiver.getText() !== "JSON") {
|
|
11038
10871
|
return node;
|
|
11039
10872
|
}
|
|
11040
10873
|
const args = outer.getArguments();
|
|
@@ -11044,7 +10877,7 @@ function unwrapJsonStringify(node) {
|
|
|
11044
10877
|
return unwrapAs(args[0]);
|
|
11045
10878
|
}
|
|
11046
10879
|
function substituted(value, ctx) {
|
|
11047
|
-
if (ctx.substitutions === void 0 || !
|
|
10880
|
+
if (ctx.substitutions === void 0 || !import_ts_morph47.Node.isIdentifier(value)) {
|
|
11048
10881
|
return value;
|
|
11049
10882
|
}
|
|
11050
10883
|
return ctx.substitutions.get(value.getText()) ?? value;
|
|
@@ -11057,10 +10890,10 @@ function extractStatusCode(ctx) {
|
|
|
11057
10890
|
if (result !== null) {
|
|
11058
10891
|
return result;
|
|
11059
10892
|
}
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
return null;
|
|
10893
|
+
return declaredStatusCode(ctx.extraction);
|
|
10894
|
+
}
|
|
10895
|
+
function declaredStatusCode(extraction) {
|
|
10896
|
+
return extraction.defaultStatusCode !== void 0 ? { type: "literal", value: extraction.defaultStatusCode } : null;
|
|
11064
10897
|
}
|
|
11065
10898
|
function matchConstructorCode(ctorText, codes) {
|
|
11066
10899
|
const fullMatch = codes[ctorText];
|
|
@@ -11088,10 +10921,10 @@ function statusFromProperty(obj, name, ctx) {
|
|
|
11088
10921
|
if (prop === void 0) {
|
|
11089
10922
|
return null;
|
|
11090
10923
|
}
|
|
11091
|
-
if (
|
|
10924
|
+
if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
|
|
11092
10925
|
return { type: "dynamic", sourceText: prop.getName() };
|
|
11093
10926
|
}
|
|
11094
|
-
if (!
|
|
10927
|
+
if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
|
|
11095
10928
|
return null;
|
|
11096
10929
|
}
|
|
11097
10930
|
const value = prop.getInitializer();
|
|
@@ -11114,7 +10947,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11114
10947
|
return null;
|
|
11115
10948
|
}
|
|
11116
10949
|
const first = ctx.throwCallArgs?.[0];
|
|
11117
|
-
if (first !== void 0 &&
|
|
10950
|
+
if (first !== void 0 && import_ts_morph47.Node.isNumericLiteral(first)) {
|
|
11118
10951
|
const value = first.getLiteralValue();
|
|
11119
10952
|
if (value >= 100 && value <= 599) {
|
|
11120
10953
|
return { type: "literal", value };
|
|
@@ -11127,7 +10960,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11127
10960
|
return null;
|
|
11128
10961
|
}
|
|
11129
10962
|
const arg = ctx.throwCallArgs[sc.position];
|
|
11130
|
-
if (arg === void 0 || !
|
|
10963
|
+
if (arg === void 0 || !import_ts_morph47.Node.isNewExpression(arg)) {
|
|
11131
10964
|
return null;
|
|
11132
10965
|
}
|
|
11133
10966
|
const ctorText = arg.getExpression().getText();
|
|
@@ -11136,7 +10969,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11136
10969
|
if (sc.from === "argumentProperty") {
|
|
11137
10970
|
const args = ctx.throwCallArgs ?? ctx.calls?.[0]?.getArguments();
|
|
11138
10971
|
const arg = args?.[sc.position];
|
|
11139
|
-
if (arg === void 0 || !
|
|
10972
|
+
if (arg === void 0 || !import_ts_morph47.Node.isObjectLiteralExpression(arg)) {
|
|
11140
10973
|
return null;
|
|
11141
10974
|
}
|
|
11142
10975
|
return statusFromProperty(arg, sc.name, ctx);
|
|
@@ -11146,8 +10979,8 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11146
10979
|
return null;
|
|
11147
10980
|
}
|
|
11148
10981
|
for (const prop of ctx.returnedObj.getProperties()) {
|
|
11149
|
-
if (!
|
|
11150
|
-
if (
|
|
10982
|
+
if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
|
|
10983
|
+
if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
|
|
11151
10984
|
if (prop.getName() === sc.name) {
|
|
11152
10985
|
const resolved = ctx.substitutions?.get(prop.getName());
|
|
11153
10986
|
if (resolved !== void 0) {
|
|
@@ -11205,8 +11038,8 @@ function extractBody(ctx) {
|
|
|
11205
11038
|
return null;
|
|
11206
11039
|
}
|
|
11207
11040
|
for (const prop of ctx.returnedObj.getProperties()) {
|
|
11208
|
-
if (!
|
|
11209
|
-
if (
|
|
11041
|
+
if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
|
|
11042
|
+
if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
|
|
11210
11043
|
if (prop.getName() === b.name) {
|
|
11211
11044
|
const resolved = ctx.substitutions?.get(prop.getName());
|
|
11212
11045
|
if (resolved !== void 0) {
|
|
@@ -11260,6 +11093,197 @@ function extractBody(ctx) {
|
|
|
11260
11093
|
return null;
|
|
11261
11094
|
}
|
|
11262
11095
|
|
|
11096
|
+
// src/terminals/jsx.ts
|
|
11097
|
+
var import_ts_morph48 = require("ts-morph");
|
|
11098
|
+
function tryMatchJsxReturn(node, pattern) {
|
|
11099
|
+
let expr;
|
|
11100
|
+
let source;
|
|
11101
|
+
if (import_ts_morph48.Node.isReturnStatement(node)) {
|
|
11102
|
+
expr = node.getExpression();
|
|
11103
|
+
source = node;
|
|
11104
|
+
} else if (import_ts_morph48.Node.isArrowFunction(node)) {
|
|
11105
|
+
const body = node.getBody();
|
|
11106
|
+
if (body !== void 0 && !import_ts_morph48.Node.isBlock(body)) {
|
|
11107
|
+
expr = body;
|
|
11108
|
+
source = body;
|
|
11109
|
+
}
|
|
11110
|
+
}
|
|
11111
|
+
if (expr === void 0 || source === void 0) {
|
|
11112
|
+
return null;
|
|
11113
|
+
}
|
|
11114
|
+
const tree = jsxToRenderNode(expr);
|
|
11115
|
+
if (tree === null) {
|
|
11116
|
+
return null;
|
|
11117
|
+
}
|
|
11118
|
+
const component = tree.type === "element" ? tree.tag : "Fragment";
|
|
11119
|
+
const terminal = {
|
|
11120
|
+
kind: pattern.kind,
|
|
11121
|
+
statusCode: null,
|
|
11122
|
+
body: null,
|
|
11123
|
+
exceptionType: null,
|
|
11124
|
+
message: null,
|
|
11125
|
+
component,
|
|
11126
|
+
delegateTarget: null,
|
|
11127
|
+
emitEvent: null,
|
|
11128
|
+
renderTree: tree,
|
|
11129
|
+
location: {
|
|
11130
|
+
start: startLineOf(node),
|
|
11131
|
+
end: endLineOf(node)
|
|
11132
|
+
}
|
|
11133
|
+
};
|
|
11134
|
+
return { node, source, terminal };
|
|
11135
|
+
}
|
|
11136
|
+
function componentTargetOf(tagNode) {
|
|
11137
|
+
if (!import_ts_morph48.Node.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
|
|
11138
|
+
return null;
|
|
11139
|
+
}
|
|
11140
|
+
const target = functionTargetOf(tagNode);
|
|
11141
|
+
return target === null ? null : { file: target.file, name: target.name };
|
|
11142
|
+
}
|
|
11143
|
+
function jsxToRenderNode(node) {
|
|
11144
|
+
if (import_ts_morph48.Node.isJsxElement(node)) {
|
|
11145
|
+
const opening = node.getOpeningElement();
|
|
11146
|
+
const tag = opening.getTagNameNode().getText();
|
|
11147
|
+
const attrs = collectJsxAttributes(opening);
|
|
11148
|
+
const target = componentTargetOf(opening.getTagNameNode());
|
|
11149
|
+
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
11150
|
+
return {
|
|
11151
|
+
type: "element",
|
|
11152
|
+
tag,
|
|
11153
|
+
children,
|
|
11154
|
+
...attrs !== null ? { attrs } : {},
|
|
11155
|
+
...target !== null ? { target } : {}
|
|
11156
|
+
};
|
|
11157
|
+
}
|
|
11158
|
+
if (import_ts_morph48.Node.isJsxSelfClosingElement(node)) {
|
|
11159
|
+
const tag = node.getTagNameNode().getText();
|
|
11160
|
+
const attrs = collectJsxAttributes(node);
|
|
11161
|
+
const target = componentTargetOf(node.getTagNameNode());
|
|
11162
|
+
return {
|
|
11163
|
+
type: "element",
|
|
11164
|
+
tag,
|
|
11165
|
+
children: [],
|
|
11166
|
+
...attrs !== null ? { attrs } : {},
|
|
11167
|
+
...target !== null ? { target } : {}
|
|
11168
|
+
};
|
|
11169
|
+
}
|
|
11170
|
+
if (import_ts_morph48.Node.isJsxFragment(node)) {
|
|
11171
|
+
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
11172
|
+
return { type: "element", tag: "Fragment", children };
|
|
11173
|
+
}
|
|
11174
|
+
if (import_ts_morph48.Node.isParenthesizedExpression(node)) {
|
|
11175
|
+
return jsxToRenderNode(node.getExpression());
|
|
11176
|
+
}
|
|
11177
|
+
return null;
|
|
11178
|
+
}
|
|
11179
|
+
function collectJsxAttributes(opening) {
|
|
11180
|
+
const entries = {};
|
|
11181
|
+
for (const attr of opening.getAttributes()) {
|
|
11182
|
+
if (import_ts_morph48.Node.isJsxSpreadAttribute(attr)) {
|
|
11183
|
+
const exprText = attr.getExpression().getText();
|
|
11184
|
+
entries[`...${exprText}`] = exprText;
|
|
11185
|
+
continue;
|
|
11186
|
+
}
|
|
11187
|
+
if (!import_ts_morph48.Node.isJsxAttribute(attr)) {
|
|
11188
|
+
continue;
|
|
11189
|
+
}
|
|
11190
|
+
const name = attr.getNameNode().getText();
|
|
11191
|
+
const initializer = attr.getInitializer();
|
|
11192
|
+
if (initializer === void 0) {
|
|
11193
|
+
entries[name] = "";
|
|
11194
|
+
continue;
|
|
11195
|
+
}
|
|
11196
|
+
if (import_ts_morph48.Node.isJsxExpression(initializer)) {
|
|
11197
|
+
const inner = initializer.getExpression();
|
|
11198
|
+
entries[name] = inner !== void 0 ? inner.getText() : "";
|
|
11199
|
+
continue;
|
|
11200
|
+
}
|
|
11201
|
+
entries[name] = initializer.getText();
|
|
11202
|
+
}
|
|
11203
|
+
return Object.keys(entries).length > 0 ? entries : null;
|
|
11204
|
+
}
|
|
11205
|
+
function jsxChildToRenderNode(child) {
|
|
11206
|
+
if (import_ts_morph48.Node.isJsxText(child)) {
|
|
11207
|
+
const text = child.getLiteralText().trim();
|
|
11208
|
+
if (text.length === 0) {
|
|
11209
|
+
return null;
|
|
11210
|
+
}
|
|
11211
|
+
return { type: "text", value: text };
|
|
11212
|
+
}
|
|
11213
|
+
if (import_ts_morph48.Node.isJsxExpression(child)) {
|
|
11214
|
+
const inner = child.getExpression();
|
|
11215
|
+
if (inner === void 0) {
|
|
11216
|
+
return null;
|
|
11217
|
+
}
|
|
11218
|
+
return jsxExpressionToRenderNode(inner);
|
|
11219
|
+
}
|
|
11220
|
+
if (import_ts_morph48.Node.isJsxElement(child) || import_ts_morph48.Node.isJsxSelfClosingElement(child) || import_ts_morph48.Node.isJsxFragment(child)) {
|
|
11221
|
+
return jsxToRenderNode(child);
|
|
11222
|
+
}
|
|
11223
|
+
return null;
|
|
11224
|
+
}
|
|
11225
|
+
function jsxExpressionToRenderNode(expr) {
|
|
11226
|
+
if (import_ts_morph48.Node.isParenthesizedExpression(expr)) {
|
|
11227
|
+
return jsxExpressionToRenderNode(expr.getExpression());
|
|
11228
|
+
}
|
|
11229
|
+
if (import_ts_morph48.Node.isBinaryExpression(expr)) {
|
|
11230
|
+
const op = expr.getOperatorToken().getText();
|
|
11231
|
+
if (op === "&&") {
|
|
11232
|
+
const right = renderAlternative(peelParens(expr.getRight()));
|
|
11233
|
+
if (right.kind === "jsx") {
|
|
11234
|
+
return {
|
|
11235
|
+
type: "conditional",
|
|
11236
|
+
condition: expr.getLeft().getText(),
|
|
11237
|
+
whenTrue: right.node,
|
|
11238
|
+
whenFalse: null
|
|
11239
|
+
};
|
|
11240
|
+
}
|
|
11241
|
+
}
|
|
11242
|
+
}
|
|
11243
|
+
if (import_ts_morph48.Node.isConditionalExpression(expr)) {
|
|
11244
|
+
const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
|
|
11245
|
+
const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
|
|
11246
|
+
if (truthy.kind === "jsx") {
|
|
11247
|
+
return {
|
|
11248
|
+
type: "conditional",
|
|
11249
|
+
condition: expr.getCondition().getText(),
|
|
11250
|
+
whenTrue: truthy.node,
|
|
11251
|
+
whenFalse: falsy.kind === "jsx" ? falsy.node : null
|
|
11252
|
+
};
|
|
11253
|
+
}
|
|
11254
|
+
if (falsy.kind === "jsx") {
|
|
11255
|
+
return {
|
|
11256
|
+
type: "conditional",
|
|
11257
|
+
condition: `!(${expr.getCondition().getText()})`,
|
|
11258
|
+
whenTrue: falsy.node,
|
|
11259
|
+
whenFalse: null
|
|
11260
|
+
};
|
|
11261
|
+
}
|
|
11262
|
+
}
|
|
11263
|
+
return { type: "expression", sourceText: expr.getText() };
|
|
11264
|
+
}
|
|
11265
|
+
function renderAlternative(node) {
|
|
11266
|
+
if (import_ts_morph48.Node.isNullLiteral(node)) {
|
|
11267
|
+
return { kind: "noRender" };
|
|
11268
|
+
}
|
|
11269
|
+
if (import_ts_morph48.Node.isFalseLiteral(node)) {
|
|
11270
|
+
return { kind: "noRender" };
|
|
11271
|
+
}
|
|
11272
|
+
if (import_ts_morph48.Node.isIdentifier(node) && node.getText() === "undefined") {
|
|
11273
|
+
return { kind: "noRender" };
|
|
11274
|
+
}
|
|
11275
|
+
if (import_ts_morph48.Node.isJsxElement(node) || import_ts_morph48.Node.isJsxSelfClosingElement(node) || import_ts_morph48.Node.isJsxFragment(node)) {
|
|
11276
|
+
const tree = jsxToRenderNode(node);
|
|
11277
|
+
if (tree !== null) {
|
|
11278
|
+
return { kind: "jsx", node: tree };
|
|
11279
|
+
}
|
|
11280
|
+
}
|
|
11281
|
+
return { kind: "notStatic" };
|
|
11282
|
+
}
|
|
11283
|
+
|
|
11284
|
+
// src/terminals/returns.ts
|
|
11285
|
+
var import_ts_morph51 = require("ts-morph");
|
|
11286
|
+
|
|
11263
11287
|
// src/terminals/helperResolution.ts
|
|
11264
11288
|
var import_ts_morph49 = require("ts-morph");
|
|
11265
11289
|
function resolveHelperReturn(call, resolveCallee2) {
|
|
@@ -11831,10 +11855,9 @@ function tryMatchReturnStatement(node, pattern, func, allPatterns) {
|
|
|
11831
11855
|
return null;
|
|
11832
11856
|
}
|
|
11833
11857
|
function buildReturnTerminal(locationNode, pattern, body) {
|
|
11834
|
-
const statusCode = pattern.extraction.defaultStatusCode !== void 0 ? { type: "literal", value: pattern.extraction.defaultStatusCode } : null;
|
|
11835
11858
|
const terminal = {
|
|
11836
11859
|
kind: pattern.kind,
|
|
11837
|
-
statusCode,
|
|
11860
|
+
statusCode: declaredStatusCode(pattern.extraction),
|
|
11838
11861
|
body,
|
|
11839
11862
|
exceptionType: null,
|
|
11840
11863
|
message: null,
|
|
@@ -12123,15 +12146,15 @@ function functionMayFallThrough(func) {
|
|
|
12123
12146
|
}
|
|
12124
12147
|
return true;
|
|
12125
12148
|
}
|
|
12126
|
-
function makeFallthroughTerminal(func) {
|
|
12149
|
+
function makeFallthroughTerminal(func, pattern) {
|
|
12127
12150
|
const body = func.getBody();
|
|
12128
12151
|
const anchor = body ?? func;
|
|
12129
12152
|
const line = endLineOf(anchor);
|
|
12130
12153
|
return {
|
|
12131
12154
|
node: anchor,
|
|
12132
12155
|
terminal: {
|
|
12133
|
-
kind:
|
|
12134
|
-
statusCode:
|
|
12156
|
+
kind: pattern.kind,
|
|
12157
|
+
statusCode: declaredStatusCode(pattern.extraction),
|
|
12135
12158
|
body: null,
|
|
12136
12159
|
exceptionType: null,
|
|
12137
12160
|
message: null,
|
|
@@ -12251,15 +12274,15 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12251
12274
|
terminals.map(({ node }) => node),
|
|
12252
12275
|
barriers
|
|
12253
12276
|
);
|
|
12254
|
-
const
|
|
12277
|
+
const fallthroughPattern = terminalPatterns.find(
|
|
12255
12278
|
(p) => p.match.type === "functionFallthrough"
|
|
12256
12279
|
);
|
|
12257
|
-
if (
|
|
12280
|
+
if (fallthroughPattern !== void 0 && functionMayFallThrough(func)) {
|
|
12258
12281
|
const hasDefaultTerminal = terminals.some(
|
|
12259
12282
|
({ node }) => (byTerminal.get(node) ?? []).some(isDefaultConditionList)
|
|
12260
12283
|
);
|
|
12261
12284
|
if (!hasDefaultTerminal) {
|
|
12262
|
-
const synthetic = makeFallthroughTerminal(func);
|
|
12285
|
+
const synthetic = makeFallthroughTerminal(func, fallthroughPattern);
|
|
12263
12286
|
terminals.push(synthetic);
|
|
12264
12287
|
const pathResult = computePathConditions(
|
|
12265
12288
|
func,
|