@rayburst/cli 0.4.4 → 0.4.5
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.
|
@@ -434,15 +434,15 @@ function createRouterDecisionNode(sourceFilePath, gitHash, routeCount) {
|
|
|
434
434
|
};
|
|
435
435
|
}
|
|
436
436
|
function extractRoutePathFromFile(routeFilePath) {
|
|
437
|
-
let
|
|
438
|
-
if (
|
|
437
|
+
let path6 = routeFilePath.replace(/^src\/routes\//, "/").replace(/\.(tsx?|jsx?)$/, "").replace(/\/route$/, "").replace(/\/index$/, "");
|
|
438
|
+
if (path6 === "/__root") {
|
|
439
439
|
return "/";
|
|
440
440
|
}
|
|
441
|
-
|
|
442
|
-
if (
|
|
441
|
+
path6 = path6.replace(/\/\$([^/]+)/g, (_, param) => `/:${param}`);
|
|
442
|
+
if (path6 === "" || path6 === "/") {
|
|
443
443
|
return "/";
|
|
444
444
|
}
|
|
445
|
-
return
|
|
445
|
+
return path6;
|
|
446
446
|
}
|
|
447
447
|
function createConfigBasedEdges(sourceNode, targetFilePaths, nodeMap, edges, edgeType = "config", useRoutePathLabels = false) {
|
|
448
448
|
let edgesCreated = 0;
|
|
@@ -650,7 +650,7 @@ function traceConfigToComponentPaths(configObject, propertyName, projectPath, pr
|
|
|
650
650
|
}
|
|
651
651
|
return [];
|
|
652
652
|
}
|
|
653
|
-
function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap) {
|
|
653
|
+
function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap, usedIds, idCounters) {
|
|
654
654
|
let totalEdgesCreated = 0;
|
|
655
655
|
try {
|
|
656
656
|
const jsxElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement);
|
|
@@ -747,7 +747,18 @@ function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectP
|
|
|
747
747
|
for (const routeFilePath of componentPaths) {
|
|
748
748
|
const routePath = extractRoutePathFromFile(routeFilePath);
|
|
749
749
|
const isDynamic = routePath.includes(":");
|
|
750
|
-
const
|
|
750
|
+
const routePathNormalized = routePath.replace(/[/:]/g, "_");
|
|
751
|
+
const decisionNodeName = `RouterDecision::decision::${routePathNormalized}`;
|
|
752
|
+
const routerIdParts = routerNode.id.split("::");
|
|
753
|
+
const sourceFilePath = routerIdParts[0];
|
|
754
|
+
const gitHash2 = routerIdParts[2];
|
|
755
|
+
const decisionNodeId = getUniqueNodeId(
|
|
756
|
+
sourceFilePath,
|
|
757
|
+
decisionNodeName,
|
|
758
|
+
gitHash2,
|
|
759
|
+
usedIds,
|
|
760
|
+
idCounters
|
|
761
|
+
);
|
|
751
762
|
const decisionNode = {
|
|
752
763
|
id: decisionNodeId,
|
|
753
764
|
type: "conditional",
|
|
@@ -879,7 +890,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
|
|
|
879
890
|
log(` Analyzing config-based components...`);
|
|
880
891
|
let totalConfigEdges = 0;
|
|
881
892
|
for (const sourceFile of sourceFiles) {
|
|
882
|
-
const configEdges = detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap);
|
|
893
|
+
const configEdges = detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap, usedIds, idCounters);
|
|
883
894
|
totalConfigEdges += configEdges;
|
|
884
895
|
}
|
|
885
896
|
if (totalConfigEdges > 0) {
|
|
@@ -935,6 +946,19 @@ async function analyzeProject(projectPath, projectId, onLog) {
|
|
|
935
946
|
log(" Checking for changed files vs remote...");
|
|
936
947
|
const changedFiles = getChangedFilesVsRemote(projectPath);
|
|
937
948
|
log(` Found ${changedFiles.length} changed files`);
|
|
949
|
+
const changedFilesMetadata = [];
|
|
950
|
+
for (const filePath of changedFiles) {
|
|
951
|
+
try {
|
|
952
|
+
const stats = fs.statSync(filePath);
|
|
953
|
+
changedFilesMetadata.push({
|
|
954
|
+
filePath,
|
|
955
|
+
lastModified: stats.mtimeMs
|
|
956
|
+
// Unix timestamp in milliseconds
|
|
957
|
+
});
|
|
958
|
+
} catch (error) {
|
|
959
|
+
log(` Warning: Could not get stats for ${filePath}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
938
962
|
const result = {
|
|
939
963
|
project: projectMetadata,
|
|
940
964
|
branches: [branchMetadata],
|
|
@@ -945,6 +969,9 @@ async function analyzeProject(projectPath, projectId, onLog) {
|
|
|
945
969
|
logs,
|
|
946
970
|
changedFilesVsRemote: changedFiles.length > 0 ? {
|
|
947
971
|
[branchId]: changedFiles
|
|
972
|
+
} : void 0,
|
|
973
|
+
changedFilesMetadata: changedFilesMetadata.length > 0 ? {
|
|
974
|
+
[branchId]: changedFilesMetadata
|
|
948
975
|
} : void 0
|
|
949
976
|
};
|
|
950
977
|
return result;
|
|
@@ -1893,6 +1920,8 @@ function getEdgeChanges(oldEdge, newEdge) {
|
|
|
1893
1920
|
|
|
1894
1921
|
// src/vite-plugin.ts
|
|
1895
1922
|
import chalk2 from "chalk";
|
|
1923
|
+
import * as fs3 from "fs";
|
|
1924
|
+
import * as path5 from "path";
|
|
1896
1925
|
function rayburstPlugin(options = {}) {
|
|
1897
1926
|
const {
|
|
1898
1927
|
enabled = process.env.CI !== "true",
|
|
@@ -1902,6 +1931,41 @@ function rayburstPlugin(options = {}) {
|
|
|
1902
1931
|
let config;
|
|
1903
1932
|
let debounceTimer = null;
|
|
1904
1933
|
let isAnalyzing = false;
|
|
1934
|
+
let lastGitState = null;
|
|
1935
|
+
let gitPollInterval = null;
|
|
1936
|
+
const checkGitState = (projectPath) => {
|
|
1937
|
+
try {
|
|
1938
|
+
const gitDir = path5.join(projectPath, ".git");
|
|
1939
|
+
if (!fs3.existsSync(gitDir)) {
|
|
1940
|
+
return false;
|
|
1941
|
+
}
|
|
1942
|
+
const headPath = path5.join(gitDir, "HEAD");
|
|
1943
|
+
if (!fs3.existsSync(headPath)) {
|
|
1944
|
+
return false;
|
|
1945
|
+
}
|
|
1946
|
+
const headContent = fs3.readFileSync(headPath, "utf-8").trim();
|
|
1947
|
+
let gitState = headContent;
|
|
1948
|
+
if (headContent.startsWith("ref: ")) {
|
|
1949
|
+
const refPath = headContent.substring(5);
|
|
1950
|
+
const fullRefPath = path5.join(gitDir, refPath);
|
|
1951
|
+
if (fs3.existsSync(fullRefPath)) {
|
|
1952
|
+
const refContent = fs3.readFileSync(fullRefPath, "utf-8").trim();
|
|
1953
|
+
gitState = `${headContent}:${refContent}`;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
if (lastGitState === null) {
|
|
1957
|
+
lastGitState = gitState;
|
|
1958
|
+
return false;
|
|
1959
|
+
}
|
|
1960
|
+
if (lastGitState !== gitState) {
|
|
1961
|
+
lastGitState = gitState;
|
|
1962
|
+
return true;
|
|
1963
|
+
}
|
|
1964
|
+
return false;
|
|
1965
|
+
} catch (error) {
|
|
1966
|
+
return false;
|
|
1967
|
+
}
|
|
1968
|
+
};
|
|
1905
1969
|
const runAnalysis = async (triggerFile) => {
|
|
1906
1970
|
if (isAnalyzing) return;
|
|
1907
1971
|
isAnalyzing = true;
|
|
@@ -1980,6 +2044,24 @@ function rayburstPlugin(options = {}) {
|
|
|
1980
2044
|
server.watcher.on("change", handleFileChange);
|
|
1981
2045
|
server.watcher.on("add", handleFileChange);
|
|
1982
2046
|
server.watcher.on("unlink", handleFileChange);
|
|
2047
|
+
const gitHeadPath = path5.join(config.root, ".git", "HEAD");
|
|
2048
|
+
if (fs3.existsSync(gitHeadPath)) {
|
|
2049
|
+
server.watcher.add(gitHeadPath);
|
|
2050
|
+
const handleGitChange = (changedPath) => {
|
|
2051
|
+
if (changedPath === gitHeadPath || changedPath.includes(".git/refs/heads/")) {
|
|
2052
|
+
console.log(chalk2.dim("[Rayburst] Git state changed, re-analyzing..."));
|
|
2053
|
+
runAnalysis("git-event");
|
|
2054
|
+
}
|
|
2055
|
+
};
|
|
2056
|
+
server.watcher.on("change", handleGitChange);
|
|
2057
|
+
checkGitState(config.root);
|
|
2058
|
+
gitPollInterval = setInterval(() => {
|
|
2059
|
+
if (checkGitState(config.root)) {
|
|
2060
|
+
console.log(chalk2.dim("[Rayburst] Git state changed (poll), re-analyzing..."));
|
|
2061
|
+
runAnalysis("git-poll");
|
|
2062
|
+
}
|
|
2063
|
+
}, 5e3);
|
|
2064
|
+
}
|
|
1983
2065
|
return () => {
|
|
1984
2066
|
server.watcher.off("change", handleFileChange);
|
|
1985
2067
|
server.watcher.off("add", handleFileChange);
|
|
@@ -1987,6 +2069,9 @@ function rayburstPlugin(options = {}) {
|
|
|
1987
2069
|
if (debounceTimer) {
|
|
1988
2070
|
clearTimeout(debounceTimer);
|
|
1989
2071
|
}
|
|
2072
|
+
if (gitPollInterval) {
|
|
2073
|
+
clearInterval(gitPollInterval);
|
|
2074
|
+
}
|
|
1990
2075
|
};
|
|
1991
2076
|
}
|
|
1992
2077
|
};
|
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.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Rayburst - Automatic code analysis for TypeScript/JavaScript projects via Vite plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"zod": "^4.2.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@rayburst/types": "^0.1.
|
|
50
|
+
"@rayburst/types": "^0.1.8",
|
|
51
51
|
"@types/node": "^25.0.2",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
53
|
"typescript": "^5.9.3",
|