@rayburst/cli 0.2.7 → 0.2.9

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.
@@ -334,27 +334,43 @@ function createConfigBasedEdges(sourceNode, targetFilePaths, nodeMap, edges, edg
334
334
  function analyzeJsxPropsForComponents(jsxElement, propName, projectPath) {
335
335
  const componentPaths = [];
336
336
  try {
337
- const attributes = jsxElement.getChildrenOfKind(SyntaxKind.JsxAttribute);
337
+ const jsxAttributes = jsxElement.getChildrenOfKind(SyntaxKind.JsxAttributes)[0];
338
+ if (!jsxAttributes) {
339
+ console.log(`[DEBUG analyzeJsxProps] No JsxAttributes container found`);
340
+ return componentPaths;
341
+ }
342
+ const attributes = jsxAttributes.getChildrenOfKind(SyntaxKind.JsxAttribute);
343
+ console.log(`[DEBUG analyzeJsxProps] Attributes found: ${attributes.length}, looking for: ${propName}`);
338
344
  for (const attr of attributes) {
339
345
  const attrName = attr.getChildrenOfKind(SyntaxKind.Identifier)[0]?.getText();
346
+ console.log(`[DEBUG analyzeJsxProps] Attribute name: ${attrName}`);
340
347
  if (attrName !== propName) {
341
348
  continue;
342
349
  }
350
+ console.log(`[DEBUG analyzeJsxProps] Found matching prop: ${propName}`);
343
351
  const initializer = attr.getChildrenOfKind(SyntaxKind.JsxExpression)[0];
352
+ console.log(`[DEBUG analyzeJsxProps] Initializer exists: ${!!initializer}`);
344
353
  if (!initializer) continue;
345
354
  const identifier = initializer.getChildrenOfKind(SyntaxKind.Identifier)[0];
355
+ console.log(`[DEBUG analyzeJsxProps] Identifier: ${identifier?.getText()}`);
346
356
  if (!identifier) continue;
347
357
  const declaration = traceIdentifierToDeclaration(identifier);
358
+ console.log(`[DEBUG analyzeJsxProps] Declaration found: ${!!declaration}, is VariableDeclaration: ${declaration ? isVariableDeclaration(declaration) : false}`);
348
359
  if (!declaration || !isVariableDeclaration(declaration)) continue;
349
360
  const dataFlow = traceVariableDataFlow(declaration);
361
+ console.log(`[DEBUG analyzeJsxProps] DataFlow found: ${!!dataFlow}, is CallExpression: ${dataFlow ? isCallExpression(dataFlow) : false}`);
350
362
  if (!dataFlow || !isCallExpression(dataFlow)) continue;
351
363
  const args = dataFlow.getChildrenOfKind(SyntaxKind.SyntaxList)[0];
364
+ console.log(`[DEBUG analyzeJsxProps] Args found: ${!!args}`);
352
365
  if (!args) continue;
353
366
  const configArg = args.getChildrenOfKind(SyntaxKind.ObjectLiteralExpression)[0];
367
+ console.log(`[DEBUG analyzeJsxProps] ConfigArg found: ${!!configArg}`);
354
368
  if (!configArg) continue;
355
369
  const commonPropNames = ["routeTree", "routes", "children", "components"];
356
370
  for (const commonPropName of commonPropNames) {
371
+ console.log(`[DEBUG analyzeJsxProps] Checking config property: ${commonPropName}`);
357
372
  const paths = traceConfigToComponentPaths(configArg, commonPropName, projectPath);
373
+ console.log(`[DEBUG analyzeJsxProps] Paths found for ${commonPropName}: ${paths.length}`);
358
374
  if (paths.length > 0) {
359
375
  return paths;
360
376
  }
@@ -403,20 +419,45 @@ function detectConfigBasedComponents(sourceFile, nodeMap, edges, projectPath) {
403
419
  let totalEdgesCreated = 0;
404
420
  try {
405
421
  const jsxElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement);
422
+ console.log(`[DEBUG] File: ${sourceFile.getFilePath()}, JSX elements: ${jsxElements.length}`);
406
423
  for (const jsxElement of jsxElements) {
424
+ console.log(`[DEBUG] Processing JSX element: ${jsxElement.getText().substring(0, 50)}...`);
407
425
  const containingFunc = jsxElement.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) || jsxElement.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
408
- if (!containingFunc) continue;
409
- const parentName = containingFunc.getName?.() || containingFunc.getParent()?.asKind(SyntaxKind.VariableDeclaration)?.getName() || null;
410
- if (!parentName) continue;
426
+ if (!containingFunc) {
427
+ console.log("[DEBUG] No containing function found, skipping");
428
+ continue;
429
+ }
430
+ console.log(`[DEBUG] Containing function kind: ${containingFunc.getKindName()}`);
431
+ let parentName = null;
432
+ if (containingFunc.getKind() === SyntaxKind.FunctionDeclaration) {
433
+ parentName = containingFunc.getName?.();
434
+ } else if (containingFunc.getKind() === SyntaxKind.ArrowFunction) {
435
+ const varDecl = containingFunc.getParent();
436
+ if (varDecl && varDecl.getKind() === SyntaxKind.VariableDeclaration) {
437
+ parentName = varDecl.getName?.();
438
+ }
439
+ }
440
+ console.log(`[DEBUG] Parent name: ${parentName}`);
441
+ if (!parentName) {
442
+ console.log("[DEBUG] No parent name found, skipping");
443
+ continue;
444
+ }
411
445
  const sourceNode = Array.from(nodeMap.values()).find((node) => {
412
446
  const nodeName = node.id.split("::")[1];
413
447
  return nodeName === parentName;
414
448
  });
415
- if (!sourceNode) continue;
449
+ console.log(`[DEBUG] Source node found: ${sourceNode ? sourceNode.id : "NO"}`);
450
+ if (!sourceNode) {
451
+ console.log("[DEBUG] No source node in nodeMap, skipping");
452
+ continue;
453
+ }
416
454
  const commonPropNames = ["router", "config", "routes", "navigation"];
417
455
  for (const propName of commonPropNames) {
456
+ console.log(`[DEBUG] Checking prop: ${propName}`);
418
457
  const componentPaths = analyzeJsxPropsForComponents(jsxElement, propName, projectPath);
458
+ console.log(`[DEBUG] Component paths found: ${componentPaths.length}`);
419
459
  if (componentPaths.length > 0) {
460
+ console.log(`[DEBUG] Creating edges for ${componentPaths.length} components`);
420
461
  const edgesCreated = createConfigBasedEdges(
421
462
  sourceNode,
422
463
  componentPaths,
@@ -424,6 +465,7 @@ function detectConfigBasedComponents(sourceFile, nodeMap, edges, projectPath) {
424
465
  edges,
425
466
  `config:${propName}`
426
467
  );
468
+ console.log(`[DEBUG] Edges created: ${edgesCreated}`);
427
469
  totalEdgesCreated += edgesCreated;
428
470
  }
429
471
  }
@@ -461,6 +503,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
461
503
  const nodes = [];
462
504
  const edges = [];
463
505
  const nodeMap = /* @__PURE__ */ new Map();
506
+ const externalNodeMap = /* @__PURE__ */ new Map();
464
507
  const usedIds = /* @__PURE__ */ new Set();
465
508
  const idCounters = /* @__PURE__ */ new Map();
466
509
  let fileIndex = 0;
@@ -491,7 +534,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
491
534
  }
492
535
  log(` Extracted ${nodes.length} nodes`);
493
536
  for (const sourceFile of sourceFiles) {
494
- generateEdges(sourceFile, nodeMap, edges);
537
+ generateEdges(sourceFile, nodeMap, edges, nodes, externalNodeMap);
495
538
  }
496
539
  log(` Generated ${edges.length} edges (syntactic analysis)`);
497
540
  log(` Analyzing config-based components...`);
@@ -978,25 +1021,86 @@ function extractState(sourceFile, relativePath, gitHash, baseX, startY, nodes, n
978
1021
  });
979
1022
  return count;
980
1023
  }
981
- function generateEdges(sourceFile, nodeMap, edges) {
1024
+ function resolveImportSource(sourceFile, identifierName) {
1025
+ const importDecls = sourceFile.getImportDeclarations();
1026
+ for (const importDecl of importDecls) {
1027
+ const namedImports = importDecl.getNamedImports();
1028
+ const defaultImport = importDecl.getDefaultImport();
1029
+ const namespaceImport = importDecl.getNamespaceImport();
1030
+ if (namedImports.some((ni) => ni.getName() === identifierName)) {
1031
+ return importDecl.getModuleSpecifierValue();
1032
+ }
1033
+ if (defaultImport?.getText() === identifierName) {
1034
+ return importDecl.getModuleSpecifierValue();
1035
+ }
1036
+ if (namespaceImport && identifierName.startsWith(namespaceImport.getText() + ".")) {
1037
+ return importDecl.getModuleSpecifierValue();
1038
+ }
1039
+ }
1040
+ return null;
1041
+ }
1042
+ function createExternalComponentNode(componentName, packageName, sourceFilePath, nodes, nodeMap, externalNodeMap) {
1043
+ const externalId = `external::${packageName}::${componentName}`;
1044
+ if (externalNodeMap.has(externalId)) {
1045
+ return externalNodeMap.get(externalId);
1046
+ }
1047
+ const node = {
1048
+ id: externalId,
1049
+ type: "component",
1050
+ position: { x: 1200, y: nodes.length * 150 },
1051
+ // Position externals to the right
1052
+ data: {
1053
+ componentName,
1054
+ props: "external",
1055
+ label: componentName,
1056
+ description: `External: ${packageName}`,
1057
+ returnValueSummary: `<${componentName} />`,
1058
+ returnDescription: `External component from ${packageName}`,
1059
+ hasJsxReturn: true,
1060
+ hasNullReturn: false,
1061
+ primaryReturnType: "jsx"
1062
+ }
1063
+ };
1064
+ externalNodeMap.set(externalId, node);
1065
+ nodeMap.set(componentName, node);
1066
+ nodes.push(node);
1067
+ return node;
1068
+ }
1069
+ function generateEdges(sourceFile, nodeMap, edges, nodes, externalNodeMap) {
982
1070
  sourceFile.getDescendantsOfKind(SyntaxKind.JsxElement).forEach((jsxElement) => {
983
1071
  const openingElement = jsxElement.getOpeningElement();
984
1072
  const tagName = openingElement.getTagNameNode().getText();
985
1073
  const containingFunc = jsxElement.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) || jsxElement.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
986
1074
  if (containingFunc) {
987
1075
  const parentName = containingFunc.getName?.() || containingFunc.getParent()?.asKind(SyntaxKind.VariableDeclaration)?.getName() || null;
988
- if (parentName && nodeMap.has(parentName) && nodeMap.has(tagName)) {
989
- const sourceNode = nodeMap.get(parentName);
990
- const targetNode = nodeMap.get(tagName);
991
- if (sourceNode && targetNode) {
992
- const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
993
- if (!edges.find((e) => e.id === edgeId)) {
994
- edges.push({
995
- id: edgeId,
996
- source: sourceNode.id,
997
- target: targetNode.id,
998
- type: "floating"
999
- });
1076
+ if (parentName && nodeMap.has(parentName)) {
1077
+ let targetNode = nodeMap.get(tagName);
1078
+ if (!targetNode) {
1079
+ const importSource = resolveImportSource(sourceFile, tagName);
1080
+ if (importSource && !importSource.startsWith(".") && !importSource.startsWith("/")) {
1081
+ const sourceFilePath = sourceFile.getFilePath();
1082
+ targetNode = createExternalComponentNode(
1083
+ tagName,
1084
+ importSource,
1085
+ sourceFilePath,
1086
+ nodes,
1087
+ nodeMap,
1088
+ externalNodeMap
1089
+ );
1090
+ }
1091
+ }
1092
+ if (targetNode) {
1093
+ const sourceNode = nodeMap.get(parentName);
1094
+ if (sourceNode) {
1095
+ const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
1096
+ if (!edges.find((e) => e.id === edgeId)) {
1097
+ edges.push({
1098
+ id: edgeId,
1099
+ source: sourceNode.id,
1100
+ target: targetNode.id,
1101
+ type: "floating"
1102
+ });
1103
+ }
1000
1104
  }
1001
1105
  }
1002
1106
  }
@@ -1007,18 +1111,34 @@ function generateEdges(sourceFile, nodeMap, edges) {
1007
1111
  const containingFunc = jsxElement.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) || jsxElement.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
1008
1112
  if (containingFunc) {
1009
1113
  const parentName = containingFunc.getName?.() || containingFunc.getParent()?.asKind(SyntaxKind.VariableDeclaration)?.getName() || null;
1010
- if (parentName && nodeMap.has(parentName) && nodeMap.has(tagName)) {
1011
- const sourceNode = nodeMap.get(parentName);
1012
- const targetNode = nodeMap.get(tagName);
1013
- if (sourceNode && targetNode) {
1014
- const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
1015
- if (!edges.find((e) => e.id === edgeId)) {
1016
- edges.push({
1017
- id: edgeId,
1018
- source: sourceNode.id,
1019
- target: targetNode.id,
1020
- type: "floating"
1021
- });
1114
+ if (parentName && nodeMap.has(parentName)) {
1115
+ let targetNode = nodeMap.get(tagName);
1116
+ if (!targetNode) {
1117
+ const importSource = resolveImportSource(sourceFile, tagName);
1118
+ if (importSource && !importSource.startsWith(".") && !importSource.startsWith("/")) {
1119
+ const sourceFilePath = sourceFile.getFilePath();
1120
+ targetNode = createExternalComponentNode(
1121
+ tagName,
1122
+ importSource,
1123
+ sourceFilePath,
1124
+ nodes,
1125
+ nodeMap,
1126
+ externalNodeMap
1127
+ );
1128
+ }
1129
+ }
1130
+ if (targetNode) {
1131
+ const sourceNode = nodeMap.get(parentName);
1132
+ if (sourceNode) {
1133
+ const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
1134
+ if (!edges.find((e) => e.id === edgeId)) {
1135
+ edges.push({
1136
+ id: edgeId,
1137
+ source: sourceNode.id,
1138
+ target: targetNode.id,
1139
+ type: "floating"
1140
+ });
1141
+ }
1022
1142
  }
1023
1143
  }
1024
1144
  }
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  readLocalMeta,
10
10
  writeLocalAnalysis,
11
11
  writeLocalMeta
12
- } from "./chunk-JMVBDG54.js";
12
+ } from "./chunk-7HEX7KJS.js";
13
13
  export {
14
14
  addGitignoreEntry,
15
15
  analyzeProject,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rayburstPlugin
3
- } from "./chunk-JMVBDG54.js";
3
+ } from "./chunk-7HEX7KJS.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.7",
3
+ "version": "0.2.9",
4
4
  "description": "Rayburst - Automatic code analysis for TypeScript/JavaScript projects via Vite plugin",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",