@rayburst/cli 0.3.8 → 0.4.1
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/{chunk-KOAVTHSN.js → chunk-4YULNVZV.js} +185 -14
- package/dist/index.js +1 -1
- package/dist/vite-plugin.js +1 -1
- package/package.json +1 -1
|
@@ -531,6 +531,33 @@ function analyzeJsxPropsForComponents(jsxElement, propName, projectPath, project
|
|
|
531
531
|
}
|
|
532
532
|
return componentPaths;
|
|
533
533
|
}
|
|
534
|
+
function extractRouterConfigFromJsx(jsxElement, propName) {
|
|
535
|
+
try {
|
|
536
|
+
const jsxAttributes = jsxElement.getChildrenOfKind(SyntaxKind.JsxAttributes)[0];
|
|
537
|
+
if (!jsxAttributes) return null;
|
|
538
|
+
const attributes = jsxAttributes.getChildrenOfKind(SyntaxKind.JsxAttribute);
|
|
539
|
+
for (const attr of attributes) {
|
|
540
|
+
const attrName = attr.getChildrenOfKind(SyntaxKind.Identifier)[0]?.getText();
|
|
541
|
+
if (attrName !== propName) continue;
|
|
542
|
+
const initializer = attr.getChildrenOfKind(SyntaxKind.JsxExpression)[0];
|
|
543
|
+
if (!initializer) continue;
|
|
544
|
+
const identifier = initializer.getChildrenOfKind(SyntaxKind.Identifier)[0];
|
|
545
|
+
if (!identifier) continue;
|
|
546
|
+
const declaration = traceIdentifierToDeclaration(identifier);
|
|
547
|
+
if (!declaration || !isVariableDeclaration(declaration)) continue;
|
|
548
|
+
const dataFlow = traceVariableDataFlow(declaration);
|
|
549
|
+
if (!dataFlow || !isCallExpression(dataFlow)) continue;
|
|
550
|
+
const args = dataFlow.getChildrenOfKind(SyntaxKind.SyntaxList)[0];
|
|
551
|
+
if (!args) continue;
|
|
552
|
+
const configArg = args.getChildrenOfKind(SyntaxKind.ObjectLiteralExpression)[0];
|
|
553
|
+
if (!configArg) continue;
|
|
554
|
+
return extractRouterConfig(configArg);
|
|
555
|
+
}
|
|
556
|
+
} catch (error) {
|
|
557
|
+
console.error("[extractRouterConfigFromJsx] Error:", error);
|
|
558
|
+
}
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
534
561
|
function traceConfigToComponentPaths(configObject, propertyName, projectPath, project) {
|
|
535
562
|
try {
|
|
536
563
|
const propertyNode = traceConfigProperty(configObject, propertyName);
|
|
@@ -667,12 +694,21 @@ function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectP
|
|
|
667
694
|
if (componentPaths.length > 0) {
|
|
668
695
|
if (propName === "router") {
|
|
669
696
|
console.log(`[DEBUG] Creating router decision node for ${componentPaths.length} routes`);
|
|
697
|
+
const routerConfig = extractRouterConfigFromJsx(jsxElement, propName);
|
|
698
|
+
console.log(`[DEBUG] Router config extracted:`, routerConfig);
|
|
699
|
+
if (routerConfig) {
|
|
700
|
+
routerConfig.routeTree = componentPaths.length;
|
|
701
|
+
}
|
|
670
702
|
const relativePath = sourceFile.getFilePath().replace(projectPath + "/", "");
|
|
671
703
|
const routerNode = createRouterDecisionNode(relativePath, gitHash, componentPaths.length);
|
|
672
704
|
nodes.push(routerNode);
|
|
673
705
|
nodeMap.set(routerNode.id, routerNode);
|
|
674
706
|
const routerProviderExternalId = "external::@tanstack/react-router::RouterProvider";
|
|
675
|
-
|
|
707
|
+
let routerProviderNode = externalNodeMap.get(routerProviderExternalId);
|
|
708
|
+
if (routerProviderNode && routerConfig) {
|
|
709
|
+
console.log(`[DEBUG] Updating RouterProvider node with config`);
|
|
710
|
+
routerProviderNode.data.providerItems = formatRouterConfigAsProviderItems(routerConfig);
|
|
711
|
+
}
|
|
676
712
|
if (routerProviderNode) {
|
|
677
713
|
const providerToRouterEdgeId = `e-${routerProviderNode.id}-${routerNode.id}`;
|
|
678
714
|
if (!edges.find((e) => e.id === providerToRouterEdgeId)) {
|
|
@@ -706,16 +742,58 @@ function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectP
|
|
|
706
742
|
totalEdgesCreated++;
|
|
707
743
|
}
|
|
708
744
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
"
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
745
|
+
let decisionNodesCreated = 0;
|
|
746
|
+
let decisionEdgesCreated = 0;
|
|
747
|
+
for (const routeFilePath of componentPaths) {
|
|
748
|
+
const routePath = extractRoutePathFromFile(routeFilePath);
|
|
749
|
+
const isDynamic = routePath.includes(":");
|
|
750
|
+
const decisionNodeId = `${routerNode.id}::decision::${routePath.replace(/[/:]/g, "_")}`;
|
|
751
|
+
const decisionNode = {
|
|
752
|
+
id: decisionNodeId,
|
|
753
|
+
type: "conditional",
|
|
754
|
+
position: { x: 800, y: 400 + decisionNodesCreated * 100 },
|
|
755
|
+
data: {
|
|
756
|
+
label: isDynamic ? `matches "${routePath}"` : `path === "${routePath}"`,
|
|
757
|
+
description: `Route condition for ${routePath}`,
|
|
758
|
+
condition: isDynamic ? `pathname.matches("${routePath}")` : `pathname === "${routePath}"`,
|
|
759
|
+
trueLabel: "render",
|
|
760
|
+
falseLabel: "skip"
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
nodes.push(decisionNode);
|
|
764
|
+
nodeMap.set(decisionNode.id, decisionNode);
|
|
765
|
+
decisionNodesCreated++;
|
|
766
|
+
const routerToDecisionEdgeId = `e-${routerNode.id}-${decisionNode.id}`;
|
|
767
|
+
if (!edges.find((e) => e.id === routerToDecisionEdgeId)) {
|
|
768
|
+
edges.push({
|
|
769
|
+
id: routerToDecisionEdgeId,
|
|
770
|
+
source: routerNode.id,
|
|
771
|
+
target: decisionNode.id,
|
|
772
|
+
type: "floating",
|
|
773
|
+
label: routePath
|
|
774
|
+
});
|
|
775
|
+
decisionEdgesCreated++;
|
|
776
|
+
}
|
|
777
|
+
const targetNodes = findNodesInFile(routeFilePath, nodeMap);
|
|
778
|
+
for (const targetNode of targetNodes) {
|
|
779
|
+
if (targetNode.type !== "component") {
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
const decisionToComponentEdgeId = `e-${decisionNode.id}-${targetNode.id}`;
|
|
783
|
+
if (!edges.find((e) => e.id === decisionToComponentEdgeId)) {
|
|
784
|
+
edges.push({
|
|
785
|
+
id: decisionToComponentEdgeId,
|
|
786
|
+
source: decisionNode.id,
|
|
787
|
+
target: targetNode.id,
|
|
788
|
+
type: "floating",
|
|
789
|
+
label: "true"
|
|
790
|
+
});
|
|
791
|
+
decisionEdgesCreated++;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
console.log(`[ROUTER] Created ${decisionNodesCreated} decision nodes and ${decisionEdgesCreated} edges`);
|
|
796
|
+
totalEdgesCreated += decisionEdgesCreated;
|
|
719
797
|
} else {
|
|
720
798
|
console.log(`[DEBUG] Creating edges for ${componentPaths.length} components`);
|
|
721
799
|
const edgesCreated = createConfigBasedEdges(
|
|
@@ -1312,17 +1390,110 @@ function resolveImportSource(sourceFile, identifierName) {
|
|
|
1312
1390
|
}
|
|
1313
1391
|
return null;
|
|
1314
1392
|
}
|
|
1315
|
-
function
|
|
1393
|
+
function formatRouterConfigAsProviderItems(config) {
|
|
1394
|
+
const items = [];
|
|
1395
|
+
if (config.routeTree !== void 0) {
|
|
1396
|
+
items.push({
|
|
1397
|
+
name: "routeTree",
|
|
1398
|
+
type: typeof config.routeTree === "number" ? `RouteTree (${config.routeTree} routes)` : "RouteTree",
|
|
1399
|
+
icon: "Other",
|
|
1400
|
+
connections: typeof config.routeTree === "number" ? config.routeTree : 0
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
if (config.context !== void 0) {
|
|
1404
|
+
items.push({
|
|
1405
|
+
name: "context",
|
|
1406
|
+
type: typeof config.context === "string" ? config.context : "object",
|
|
1407
|
+
icon: "State",
|
|
1408
|
+
connections: 0
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
if (config.defaultPreload !== void 0) {
|
|
1412
|
+
items.push({
|
|
1413
|
+
name: "defaultPreload",
|
|
1414
|
+
type: `'${config.defaultPreload}'`,
|
|
1415
|
+
icon: "Other",
|
|
1416
|
+
connections: 0
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
if (config.scrollRestoration !== void 0) {
|
|
1420
|
+
items.push({
|
|
1421
|
+
name: "scrollRestoration",
|
|
1422
|
+
type: String(config.scrollRestoration),
|
|
1423
|
+
icon: "Other",
|
|
1424
|
+
connections: 0
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
if (config.defaultStructuralSharing !== void 0) {
|
|
1428
|
+
items.push({
|
|
1429
|
+
name: "defaultStructuralSharing",
|
|
1430
|
+
type: String(config.defaultStructuralSharing),
|
|
1431
|
+
icon: "Other",
|
|
1432
|
+
connections: 0
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
if (config.defaultPreloadStaleTime !== void 0) {
|
|
1436
|
+
items.push({
|
|
1437
|
+
name: "defaultPreloadStaleTime",
|
|
1438
|
+
type: `${config.defaultPreloadStaleTime}ms`,
|
|
1439
|
+
icon: "Other",
|
|
1440
|
+
connections: 0
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
return items;
|
|
1444
|
+
}
|
|
1445
|
+
function extractRouterConfig(configArg) {
|
|
1446
|
+
const config = {};
|
|
1447
|
+
try {
|
|
1448
|
+
if (!Node.isObjectLiteralExpression(configArg)) {
|
|
1449
|
+
return config;
|
|
1450
|
+
}
|
|
1451
|
+
const properties = configArg.getProperties();
|
|
1452
|
+
for (const prop of properties) {
|
|
1453
|
+
if (Node.isPropertyAssignment(prop) || Node.isShorthandPropertyAssignment(prop)) {
|
|
1454
|
+
const name = prop.getName();
|
|
1455
|
+
if (Node.isPropertyAssignment(prop)) {
|
|
1456
|
+
const initializer = prop.getInitializer();
|
|
1457
|
+
if (initializer) {
|
|
1458
|
+
if (Node.isStringLiteral(initializer)) {
|
|
1459
|
+
config[name] = initializer.getLiteralValue();
|
|
1460
|
+
} else if (Node.isNumericLiteral(initializer)) {
|
|
1461
|
+
config[name] = initializer.getLiteralValue();
|
|
1462
|
+
} else if (initializer.getKind() === SyntaxKind.TrueKeyword || initializer.getKind() === SyntaxKind.FalseKeyword) {
|
|
1463
|
+
config[name] = initializer.getText() === "true";
|
|
1464
|
+
} else if (Node.isObjectLiteralExpression(initializer)) {
|
|
1465
|
+
config[name] = "{}";
|
|
1466
|
+
} else {
|
|
1467
|
+
config[name] = initializer.getText();
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
} else if (Node.isShorthandPropertyAssignment(prop)) {
|
|
1471
|
+
config[name] = prop.getName();
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
} catch (error) {
|
|
1476
|
+
console.error("[extractRouterConfig] Error:", error);
|
|
1477
|
+
}
|
|
1478
|
+
return config;
|
|
1479
|
+
}
|
|
1480
|
+
function createExternalComponentNode(componentName, packageName, sourceFilePath, nodes, nodeMap, externalNodeMap, routerConfig) {
|
|
1316
1481
|
const externalId = `external::${packageName}::${componentName}`;
|
|
1317
1482
|
if (externalNodeMap.has(externalId)) {
|
|
1318
1483
|
return externalNodeMap.get(externalId);
|
|
1319
1484
|
}
|
|
1485
|
+
const isRouterProvider = componentName === "RouterProvider" && packageName === "@tanstack/react-router";
|
|
1320
1486
|
const node = {
|
|
1321
1487
|
id: externalId,
|
|
1322
|
-
type: "component",
|
|
1488
|
+
type: isRouterProvider ? "provider" : "component",
|
|
1323
1489
|
position: { x: 1200, y: nodes.length * 150 },
|
|
1324
1490
|
// Position externals to the right
|
|
1325
|
-
data: {
|
|
1491
|
+
data: isRouterProvider ? {
|
|
1492
|
+
providerName: componentName,
|
|
1493
|
+
label: componentName,
|
|
1494
|
+
description: `External: ${packageName}`,
|
|
1495
|
+
providerItems: routerConfig ? formatRouterConfigAsProviderItems(routerConfig) : []
|
|
1496
|
+
} : {
|
|
1326
1497
|
componentName,
|
|
1327
1498
|
props: "external",
|
|
1328
1499
|
label: componentName,
|
package/dist/index.js
CHANGED
package/dist/vite-plugin.js
CHANGED