@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 text = body.getText();
315
- return text.includes("return") && (text.includes("</") || text.includes("<>") || text.includes("jsx"));
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
@@ -9,7 +9,7 @@ import {
9
9
  readLocalMeta,
10
10
  writeLocalAnalysis,
11
11
  writeLocalMeta
12
- } from "./chunk-2VW2AH2U.js";
12
+ } from "./chunk-74JMCHWV.js";
13
13
  export {
14
14
  addGitignoreEntry,
15
15
  analyzeProject,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rayburstPlugin
3
- } from "./chunk-2VW2AH2U.js";
3
+ } from "./chunk-74JMCHWV.js";
4
4
  export {
5
5
  rayburstPlugin
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayburst/cli",
3
- "version": "0.2.3",
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",