@rayburst/cli 0.2.8 → 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,9 +419,15 @@ 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;
426
+ if (!containingFunc) {
427
+ console.log("[DEBUG] No containing function found, skipping");
428
+ continue;
429
+ }
430
+ console.log(`[DEBUG] Containing function kind: ${containingFunc.getKindName()}`);
409
431
  let parentName = null;
410
432
  if (containingFunc.getKind() === SyntaxKind.FunctionDeclaration) {
411
433
  parentName = containingFunc.getName?.();
@@ -415,16 +437,27 @@ function detectConfigBasedComponents(sourceFile, nodeMap, edges, projectPath) {
415
437
  parentName = varDecl.getName?.();
416
438
  }
417
439
  }
418
- if (!parentName) continue;
440
+ console.log(`[DEBUG] Parent name: ${parentName}`);
441
+ if (!parentName) {
442
+ console.log("[DEBUG] No parent name found, skipping");
443
+ continue;
444
+ }
419
445
  const sourceNode = Array.from(nodeMap.values()).find((node) => {
420
446
  const nodeName = node.id.split("::")[1];
421
447
  return nodeName === parentName;
422
448
  });
423
- 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
+ }
424
454
  const commonPropNames = ["router", "config", "routes", "navigation"];
425
455
  for (const propName of commonPropNames) {
456
+ console.log(`[DEBUG] Checking prop: ${propName}`);
426
457
  const componentPaths = analyzeJsxPropsForComponents(jsxElement, propName, projectPath);
458
+ console.log(`[DEBUG] Component paths found: ${componentPaths.length}`);
427
459
  if (componentPaths.length > 0) {
460
+ console.log(`[DEBUG] Creating edges for ${componentPaths.length} components`);
428
461
  const edgesCreated = createConfigBasedEdges(
429
462
  sourceNode,
430
463
  componentPaths,
@@ -432,6 +465,7 @@ function detectConfigBasedComponents(sourceFile, nodeMap, edges, projectPath) {
432
465
  edges,
433
466
  `config:${propName}`
434
467
  );
468
+ console.log(`[DEBUG] Edges created: ${edgesCreated}`);
435
469
  totalEdgesCreated += edgesCreated;
436
470
  }
437
471
  }
@@ -469,6 +503,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
469
503
  const nodes = [];
470
504
  const edges = [];
471
505
  const nodeMap = /* @__PURE__ */ new Map();
506
+ const externalNodeMap = /* @__PURE__ */ new Map();
472
507
  const usedIds = /* @__PURE__ */ new Set();
473
508
  const idCounters = /* @__PURE__ */ new Map();
474
509
  let fileIndex = 0;
@@ -499,7 +534,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
499
534
  }
500
535
  log(` Extracted ${nodes.length} nodes`);
501
536
  for (const sourceFile of sourceFiles) {
502
- generateEdges(sourceFile, nodeMap, edges);
537
+ generateEdges(sourceFile, nodeMap, edges, nodes, externalNodeMap);
503
538
  }
504
539
  log(` Generated ${edges.length} edges (syntactic analysis)`);
505
540
  log(` Analyzing config-based components...`);
@@ -986,25 +1021,86 @@ function extractState(sourceFile, relativePath, gitHash, baseX, startY, nodes, n
986
1021
  });
987
1022
  return count;
988
1023
  }
989
- 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) {
990
1070
  sourceFile.getDescendantsOfKind(SyntaxKind.JsxElement).forEach((jsxElement) => {
991
1071
  const openingElement = jsxElement.getOpeningElement();
992
1072
  const tagName = openingElement.getTagNameNode().getText();
993
1073
  const containingFunc = jsxElement.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) || jsxElement.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
994
1074
  if (containingFunc) {
995
1075
  const parentName = containingFunc.getName?.() || containingFunc.getParent()?.asKind(SyntaxKind.VariableDeclaration)?.getName() || null;
996
- if (parentName && nodeMap.has(parentName) && nodeMap.has(tagName)) {
997
- const sourceNode = nodeMap.get(parentName);
998
- const targetNode = nodeMap.get(tagName);
999
- if (sourceNode && targetNode) {
1000
- const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
1001
- if (!edges.find((e) => e.id === edgeId)) {
1002
- edges.push({
1003
- id: edgeId,
1004
- source: sourceNode.id,
1005
- target: targetNode.id,
1006
- type: "floating"
1007
- });
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
+ }
1008
1104
  }
1009
1105
  }
1010
1106
  }
@@ -1015,18 +1111,34 @@ function generateEdges(sourceFile, nodeMap, edges) {
1015
1111
  const containingFunc = jsxElement.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) || jsxElement.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
1016
1112
  if (containingFunc) {
1017
1113
  const parentName = containingFunc.getName?.() || containingFunc.getParent()?.asKind(SyntaxKind.VariableDeclaration)?.getName() || null;
1018
- if (parentName && nodeMap.has(parentName) && nodeMap.has(tagName)) {
1019
- const sourceNode = nodeMap.get(parentName);
1020
- const targetNode = nodeMap.get(tagName);
1021
- if (sourceNode && targetNode) {
1022
- const edgeId = `e-${sourceNode.id}-${targetNode.id}`;
1023
- if (!edges.find((e) => e.id === edgeId)) {
1024
- edges.push({
1025
- id: edgeId,
1026
- source: sourceNode.id,
1027
- target: targetNode.id,
1028
- type: "floating"
1029
- });
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
+ }
1030
1142
  }
1031
1143
  }
1032
1144
  }
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  readLocalMeta,
10
10
  writeLocalAnalysis,
11
11
  writeLocalMeta
12
- } from "./chunk-K4NZXXX4.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-K4NZXXX4.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.8",
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",