@rayburst/cli 0.2.3 → 0.2.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.
|
@@ -309,10 +309,119 @@ function getUniqueNodeId(filePath, nodeName, gitHash, usedIds, idCounters) {
|
|
|
309
309
|
return id;
|
|
310
310
|
}
|
|
311
311
|
function isReactComponent(func) {
|
|
312
|
+
const name = func.getName() || func.getParent()?.asKind?.(SyntaxKind.VariableDeclaration)?.getName?.();
|
|
313
|
+
const hasComponentName = name && /^[A-Z]/.test(name);
|
|
314
|
+
const returnType = func.getReturnType().getText();
|
|
315
|
+
const hasJsxReturnType = returnType.includes("JSX.Element") || returnType.includes("React.ReactElement") || returnType.includes("ReactElement") || returnType.includes("React.ReactNode") || returnType.includes("ReactNode");
|
|
312
316
|
const body = func.getBody();
|
|
313
317
|
if (!body) return false;
|
|
314
|
-
const
|
|
315
|
-
|
|
318
|
+
const hasJsxElements = body.getDescendantsOfKind(SyntaxKind.JsxElement).length > 0 || body.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement).length > 0 || body.getDescendantsOfKind(SyntaxKind.JsxFragment).length > 0;
|
|
319
|
+
const hasHooks = body.getDescendantsOfKind(SyntaxKind.CallExpression).some((call) => {
|
|
320
|
+
const expr = call.getExpression().getText();
|
|
321
|
+
return expr.startsWith("use") && /^use[A-Z]/.test(expr);
|
|
322
|
+
});
|
|
323
|
+
if (hasJsxElements) return true;
|
|
324
|
+
if (hasJsxReturnType) return true;
|
|
325
|
+
if (hasComponentName && hasHooks) return true;
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
function analyzeReturnStatements(func) {
|
|
329
|
+
const body = func.getBody();
|
|
330
|
+
if (!body) {
|
|
331
|
+
return {
|
|
332
|
+
hasJsxReturn: false,
|
|
333
|
+
hasNullReturn: false,
|
|
334
|
+
hasUndefinedReturn: false,
|
|
335
|
+
returnValueSummary: "void",
|
|
336
|
+
primaryReturnType: "undefined"
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
const returnStatements = body.getDescendantsOfKind(SyntaxKind.ReturnStatement);
|
|
340
|
+
let hasJsxReturn = false;
|
|
341
|
+
let hasNullReturn = false;
|
|
342
|
+
let hasUndefinedReturn = false;
|
|
343
|
+
const returnTypes = [];
|
|
344
|
+
for (const returnStmt of returnStatements) {
|
|
345
|
+
const expr = returnStmt.getExpression();
|
|
346
|
+
if (!expr) {
|
|
347
|
+
hasUndefinedReturn = true;
|
|
348
|
+
returnTypes.push("undefined");
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (Node.isJsxElement(expr) || Node.isJsxSelfClosingElement(expr) || Node.isJsxFragment(expr)) {
|
|
352
|
+
hasJsxReturn = true;
|
|
353
|
+
let jsxName = "JSX";
|
|
354
|
+
if (Node.isJsxElement(expr)) {
|
|
355
|
+
jsxName = expr.getOpeningElement().getTagNameNode().getText();
|
|
356
|
+
} else if (Node.isJsxSelfClosingElement(expr)) {
|
|
357
|
+
jsxName = expr.getTagNameNode().getText();
|
|
358
|
+
} else {
|
|
359
|
+
jsxName = "<>";
|
|
360
|
+
}
|
|
361
|
+
returnTypes.push(`<${jsxName}>`);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (expr.getKind() === SyntaxKind.NullKeyword) {
|
|
365
|
+
hasNullReturn = true;
|
|
366
|
+
returnTypes.push("null");
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (expr.getKind() === SyntaxKind.Identifier && expr.getText() === "undefined") {
|
|
370
|
+
hasUndefinedReturn = true;
|
|
371
|
+
returnTypes.push("undefined");
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (Node.isConditionalExpression(expr)) {
|
|
375
|
+
const whenTrue = expr.getWhenTrue();
|
|
376
|
+
const whenFalse = expr.getWhenFalse();
|
|
377
|
+
const trueIsJsx = Node.isJsxElement(whenTrue) || Node.isJsxSelfClosingElement(whenTrue);
|
|
378
|
+
const falseIsJsx = Node.isJsxElement(whenFalse) || Node.isJsxSelfClosingElement(whenFalse);
|
|
379
|
+
if (trueIsJsx || falseIsJsx) hasJsxReturn = true;
|
|
380
|
+
if (whenTrue.getText() === "null") hasNullReturn = true;
|
|
381
|
+
if (whenFalse.getText() === "null") hasNullReturn = true;
|
|
382
|
+
const trueText = whenTrue.getText().length > 20 ? whenTrue.getText().substring(0, 17) + "..." : whenTrue.getText();
|
|
383
|
+
const falseText = whenFalse.getText().length > 20 ? whenFalse.getText().substring(0, 17) + "..." : whenFalse.getText();
|
|
384
|
+
returnTypes.push(`${trueText} : ${falseText}`);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const exprText = expr.getText();
|
|
388
|
+
const truncated = exprText.length > 50 ? exprText.substring(0, 47) + "..." : exprText;
|
|
389
|
+
returnTypes.push(truncated);
|
|
390
|
+
}
|
|
391
|
+
let primaryReturnType = "mixed";
|
|
392
|
+
if (hasJsxReturn && !hasNullReturn && !hasUndefinedReturn) {
|
|
393
|
+
primaryReturnType = "jsx";
|
|
394
|
+
} else if (hasNullReturn && !hasJsxReturn && !hasUndefinedReturn) {
|
|
395
|
+
primaryReturnType = "null";
|
|
396
|
+
} else if (hasUndefinedReturn && !hasJsxReturn && !hasNullReturn) {
|
|
397
|
+
primaryReturnType = "undefined";
|
|
398
|
+
} else if (returnTypes.length === 1) {
|
|
399
|
+
primaryReturnType = "primitive";
|
|
400
|
+
}
|
|
401
|
+
const uniqueReturns = Array.from(new Set(returnTypes));
|
|
402
|
+
const returnValueSummary = uniqueReturns.join(" | ") || "void";
|
|
403
|
+
return {
|
|
404
|
+
hasJsxReturn,
|
|
405
|
+
hasNullReturn,
|
|
406
|
+
hasUndefinedReturn,
|
|
407
|
+
returnValueSummary,
|
|
408
|
+
primaryReturnType
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
function getReturnDescription(returnAnalysis) {
|
|
412
|
+
if (returnAnalysis.hasJsxReturn && returnAnalysis.hasNullReturn) {
|
|
413
|
+
return "Returns JSX or null";
|
|
414
|
+
}
|
|
415
|
+
if (returnAnalysis.hasJsxReturn) {
|
|
416
|
+
return "Returns JSX";
|
|
417
|
+
}
|
|
418
|
+
if (returnAnalysis.hasNullReturn) {
|
|
419
|
+
return "Returns null";
|
|
420
|
+
}
|
|
421
|
+
if (returnAnalysis.hasUndefinedReturn) {
|
|
422
|
+
return "Returns void";
|
|
423
|
+
}
|
|
424
|
+
return "Returns value";
|
|
316
425
|
}
|
|
317
426
|
function extractComponents(sourceFile, relativePath, gitHash, baseX, startY, nodes, nodeMap, usedIds, idCounters) {
|
|
318
427
|
let count = 0;
|
|
@@ -325,6 +434,7 @@ function extractComponents(sourceFile, relativePath, gitHash, baseX, startY, nod
|
|
|
325
434
|
const params = func.getParameters();
|
|
326
435
|
const propsParam = params[0];
|
|
327
436
|
const propsType = propsParam ? propsParam.getType().getText() : "any";
|
|
437
|
+
const returnAnalysis = analyzeReturnStatements(func);
|
|
328
438
|
const node = {
|
|
329
439
|
id,
|
|
330
440
|
type: "component",
|
|
@@ -333,7 +443,12 @@ function extractComponents(sourceFile, relativePath, gitHash, baseX, startY, nod
|
|
|
333
443
|
componentName: name,
|
|
334
444
|
props: propsType,
|
|
335
445
|
label: name,
|
|
336
|
-
description: `Component in ${relativePath}
|
|
446
|
+
description: `Component in ${relativePath}`,
|
|
447
|
+
returnValueSummary: returnAnalysis.returnValueSummary,
|
|
448
|
+
returnDescription: getReturnDescription(returnAnalysis),
|
|
449
|
+
hasJsxReturn: returnAnalysis.hasJsxReturn,
|
|
450
|
+
hasNullReturn: returnAnalysis.hasNullReturn,
|
|
451
|
+
primaryReturnType: returnAnalysis.primaryReturnType
|
|
337
452
|
}
|
|
338
453
|
};
|
|
339
454
|
nodes.push(node);
|
|
@@ -353,6 +468,7 @@ function extractComponents(sourceFile, relativePath, gitHash, baseX, startY, nod
|
|
|
353
468
|
const params = init.getParameters();
|
|
354
469
|
const propsParam = params[0];
|
|
355
470
|
const propsType = propsParam ? propsParam.getType().getText() : "any";
|
|
471
|
+
const returnAnalysis = analyzeReturnStatements(init);
|
|
356
472
|
const node = {
|
|
357
473
|
id,
|
|
358
474
|
type: "component",
|
|
@@ -361,7 +477,12 @@ function extractComponents(sourceFile, relativePath, gitHash, baseX, startY, nod
|
|
|
361
477
|
componentName: name,
|
|
362
478
|
props: propsType,
|
|
363
479
|
label: name,
|
|
364
|
-
description: `Component in ${relativePath}
|
|
480
|
+
description: `Component in ${relativePath}`,
|
|
481
|
+
returnValueSummary: returnAnalysis.returnValueSummary,
|
|
482
|
+
returnDescription: getReturnDescription(returnAnalysis),
|
|
483
|
+
hasJsxReturn: returnAnalysis.hasJsxReturn,
|
|
484
|
+
hasNullReturn: returnAnalysis.hasNullReturn,
|
|
485
|
+
primaryReturnType: returnAnalysis.primaryReturnType
|
|
365
486
|
}
|
|
366
487
|
};
|
|
367
488
|
nodes.push(node);
|
|
@@ -389,6 +510,7 @@ function extractFunctions(sourceFile, relativePath, gitHash, baseX, startY, node
|
|
|
389
510
|
return `${paramName}: ${paramType}`;
|
|
390
511
|
}).join(", ");
|
|
391
512
|
const returnType = func.getReturnType().getText();
|
|
513
|
+
const returnAnalysis = analyzeReturnStatements(func);
|
|
392
514
|
const node = {
|
|
393
515
|
id,
|
|
394
516
|
type: "function",
|
|
@@ -398,7 +520,12 @@ function extractFunctions(sourceFile, relativePath, gitHash, baseX, startY, node
|
|
|
398
520
|
parameters: params,
|
|
399
521
|
returnType,
|
|
400
522
|
label: name,
|
|
401
|
-
description: `Function in ${relativePath}
|
|
523
|
+
description: `Function in ${relativePath}`,
|
|
524
|
+
returnValueSummary: returnAnalysis.returnValueSummary,
|
|
525
|
+
returnDescription: getReturnDescription(returnAnalysis),
|
|
526
|
+
hasJsxReturn: returnAnalysis.hasJsxReturn,
|
|
527
|
+
hasNullReturn: returnAnalysis.hasNullReturn,
|
|
528
|
+
primaryReturnType: returnAnalysis.primaryReturnType
|
|
402
529
|
}
|
|
403
530
|
};
|
|
404
531
|
nodes.push(node);
|
package/dist/index.js
CHANGED
package/dist/vite-plugin.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rayburst/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Rayburst - Automatic code analysis for TypeScript/JavaScript projects via Vite plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@rayburst/types": "^0.1.3",
|
|
46
45
|
"chalk": "^5.3.0",
|
|
47
46
|
"ts-morph": "^21.0.1",
|
|
48
47
|
"zod": "^4.2.0"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
50
|
+
"@rayburst/types": "^0.1.4",
|
|
51
51
|
"@types/node": "^25.0.2",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
53
|
"typescript": "^5.9.3",
|