Skip to content

Commit 104783b

Browse files
committed
no tree brnahc isolation, run splitting on the whole tree
1 parent 9916bec commit 104783b

File tree

13 files changed

+875
-171
lines changed

13 files changed

+875
-171
lines changed

packages/app/src/components/MethodBadge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default function MethodBadge(props: { method: string }) {
55
const [color, setColor] = useState<BadgeProps["color"]>("gray");
66

77
useEffect(() => {
8-
switch (props.method.toLocaleLowerCase()) {
8+
switch (props.method.toLowerCase()) {
99
case "get":
1010
setColor("green");
1111
break;

packages/cli/src/api/split.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,38 @@ import { z } from "zod";
1212
import { GroupMap } from "../helper/types";
1313

1414
export function split(payload: z.infer<typeof splitSchema>) {
15-
let groupIndex = 0;
15+
console.time("split command");
1616
const groupMap: GroupMap = {};
1717

1818
// Get the dependency tree
1919
const tree = getDependencyTree(payload.entrypointPath);
2020

21-
payload.outputDir = payload.outputDir || path.dirname(payload.entrypointPath);
21+
const outputDir = payload.outputDir || path.dirname(payload.entrypointPath);
2222

2323
// Clean up and prepare the output directory
24-
cleanupOutputDir(payload.outputDir);
25-
createOutputDir(payload.outputDir);
24+
cleanupOutputDir(outputDir);
25+
createOutputDir(outputDir);
2626

2727
// Iterate over the tree and get endpoints
2828
const endpoints = getEndpontsFromTree(tree);
2929

3030
// Get groups from the endpoints
3131
const groups = getGroupsFromEndpoints(endpoints);
3232

33-
// Process each endpoint for splitting
34-
for (const group of groups) {
35-
createSplit(
36-
group,
37-
payload.outputDir,
38-
payload.entrypointPath,
39-
groupMap,
40-
groupIndex,
41-
);
42-
groupIndex++;
43-
}
33+
// Process each group for splitting
34+
groups.forEach((group, index) => {
35+
// Clone the tree to avoid mutation of the original tree
36+
const treeClone = structuredClone(tree);
37+
createSplit(treeClone, group, outputDir, payload.entrypointPath, index);
38+
});
4439

4540
// Store the processed annotations in the output directory
46-
const annotationFilePath = path.join(payload.outputDir, "annotations.json");
41+
groups.forEach((group, index) => {
42+
groupMap[index] = group;
43+
});
44+
const annotationFilePath = path.join(outputDir, "annotations.json");
4745
fs.writeFileSync(annotationFilePath, JSON.stringify(groupMap, null, 2));
4846

47+
console.timeEnd("split command");
4948
return { groups, success: true };
5049
}

packages/cli/src/api/sync.ts

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { z } from "zod";
22
import { syncSchema } from "./helpers/validation";
33
import fs from "fs";
44
import {
5-
getNanoApiAnnotationFromCommentValue,
6-
replaceCommentFromAnnotation,
5+
parseNanoApiAnnotation,
6+
updateCommentFromAnnotation,
77
} from "../helper/annotations";
88
import {
99
getDependencyTree,
@@ -12,6 +12,7 @@ import {
1212
import Parser from "tree-sitter";
1313
import { getParserLanguageFromFile } from "../helper/treeSitter";
1414
import { replaceIndexesFromSourceCode } from "../helper/cleanup";
15+
import { getAnnotationNodes } from "../helper/languages/javascript/annotations";
1516

1617
export function sync(payload: z.infer<typeof syncSchema>) {
1718
const tree = getDependencyTree(payload.entrypointPath);
@@ -48,35 +49,26 @@ export function sync(payload: z.infer<typeof syncSchema>) {
4849
text: string;
4950
}[] = [];
5051

51-
function traverse(node: Parser.SyntaxNode) {
52-
if (node.type === "comment") {
53-
const comment = node.text;
54-
55-
const annotation = getNanoApiAnnotationFromCommentValue(comment);
56-
57-
if (annotation) {
58-
if (
59-
annotation.path === endpoint.path &&
60-
annotation.method === endpoint.method
61-
) {
62-
annotation.group = endpoint.group;
63-
const updatedComment = replaceCommentFromAnnotation(
64-
comment,
65-
annotation,
66-
);
67-
68-
indexesToReplace.push({
69-
startIndex: node.startIndex,
70-
endIndex: node.endIndex,
71-
text: updatedComment,
72-
});
73-
}
74-
}
52+
const annotationNodes = getAnnotationNodes(parser, tree.rootNode);
53+
annotationNodes.forEach((node) => {
54+
const annotation = parseNanoApiAnnotation(node.text);
55+
if (
56+
annotation.path === endpoint.path &&
57+
annotation.method === endpoint.method
58+
) {
59+
annotation.group = endpoint.group;
60+
const updatedComment = updateCommentFromAnnotation(
61+
node.text,
62+
annotation,
63+
);
64+
65+
indexesToReplace.push({
66+
startIndex: node.startIndex,
67+
endIndex: node.endIndex,
68+
text: updatedComment,
69+
});
7570
}
76-
node.children.forEach((child) => traverse(child));
77-
}
78-
79-
traverse(tree.rootNode);
71+
});
8072

8173
sourceCode = replaceIndexesFromSourceCode(sourceCode, indexesToReplace);
8274

packages/cli/src/commands/split.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export default function splitCommandHandler(
1313
entrypointPath: string, // Path to the entrypoint file
1414
outputDir: string, // Path to the output directory
1515
) {
16-
let groupIndex = 0;
1716
const groupMap: GroupMap = {};
1817

1918
const tree = getDependencyTree(entrypointPath);
@@ -27,13 +26,17 @@ export default function splitCommandHandler(
2726
// Get groups from the endpoints
2827
const groups = getGroupsFromEndpoints(endpoints);
2928

30-
// Process each endpoint for splitting
31-
for (const group of groups) {
32-
createSplit(group, outputDir, entrypointPath, groupMap, groupIndex);
33-
groupIndex++;
34-
}
29+
// Process each group for splitting
30+
groups.forEach((group, index) => {
31+
// Clone the tree to avoid mutation of the original tree
32+
const treeClone = structuredClone(tree);
33+
createSplit(treeClone, group, outputDir, entrypointPath, index);
34+
});
3535

3636
// Store the processed annotations in the output directory
37+
groups.forEach((group, index) => {
38+
groupMap[index] = group;
39+
});
3740
const annotationFilePath = path.join(outputDir, "annotations.json");
3841
fs.writeFileSync(annotationFilePath, JSON.stringify(groupMap, null, 2));
3942
}

packages/cli/src/helper/annotations.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { NanoAPIAnnotation } from "./types";
1+
import { Group, NanoAPIAnnotation } from "./types";
22

3-
export function getNanoApiAnnotationFromCommentValue(comment: string) {
3+
export function parseNanoApiAnnotation(value: string) {
44
const nanoapiRegex = /@nanoapi|((method|path|group):([^ ]+))/g;
5-
const matches = comment.match(nanoapiRegex);
5+
const matches = value.match(nanoapiRegex);
66
// remove first match, which is the @nanoapi identifier
77
matches?.shift();
88

@@ -16,10 +16,41 @@ export function getNanoApiAnnotationFromCommentValue(comment: string) {
1616
}, {} as NanoAPIAnnotation);
1717
}
1818

19-
return null;
19+
throw new Error("Could not parse annotation");
2020
}
2121

22-
export function replaceCommentFromAnnotation(
22+
export function isAnnotationInGroup(
23+
group: Group,
24+
annotation: NanoAPIAnnotation,
25+
) {
26+
// check if annotation has a method (actual endpoint)
27+
if (annotation.method) {
28+
const endpoint = group.endpoints.find(
29+
(endpoint) =>
30+
endpoint.method === annotation.method &&
31+
endpoint.path === annotation.path,
32+
);
33+
34+
if (endpoint) {
35+
return true;
36+
}
37+
38+
return false;
39+
}
40+
41+
// if annotation has no method, we treat it as a module that contains other endpoints
42+
const endpoints = group.endpoints.filter((endpoint) =>
43+
endpoint.path.startsWith(annotation.path),
44+
);
45+
46+
if (endpoints.length > 0) {
47+
return true;
48+
}
49+
50+
return false;
51+
}
52+
53+
export function updateCommentFromAnnotation(
2354
comment: string,
2455
annotation: NanoAPIAnnotation,
2556
) {

0 commit comments

Comments
 (0)