Navegador

navegador / navegador / enrichment / react.py
Blame History Raw 107 lines
1
"""
2
React / Next.js framework enricher.
3
4
Promotes generic Function/Class nodes to semantic React types:
5
- Component — JSX files or PascalCase functions in .jsx/.tsx
6
- Page — files under pages/ directory
7
- ApiRoute — files under pages/api/ or app/api/ directory
8
- Hook — functions whose name starts with "use"
9
- Store — functions/classes matching createStore or useStore patterns
10
"""
11
12
from navegador.enrichment.base import EnrichmentResult, FrameworkEnricher
13
14
15
class ReactEnricher(FrameworkEnricher):
16
"""Enricher for React and Next.js codebases."""
17
18
@property
19
def framework_name(self) -> str:
20
return "react"
21
22
@property
23
def detection_patterns(self) -> list[str]:
24
return ["react", "react-dom", "next"]
25
26
@property
27
def detection_files(self) -> list[str]:
28
return ["next.config.js", "next.config.ts", "next.config.mjs"]
29
30
def enrich(self) -> EnrichmentResult:
31
result = EnrichmentResult()
32
33
# ── Components: functions/classes defined in .jsx or .tsx files ──────
34
component_rows = (
35
self.store.query(
36
"MATCH (n) WHERE (n.file_path CONTAINS '.jsx' OR n.file_path CONTAINS '.tsx') "
37
"AND n.name IS NOT NULL "
38
"RETURN n.name, n.file_path",
39
).result_set
40
or []
41
)
42
for name, file_path in component_rows:
43
self._promote_node(name, file_path, "ReactComponent")
44
result.promoted += 1
45
result.patterns_found["components"] = len(component_rows)
46
47
# ── Pages: nodes whose file_path contains /pages/ ────────────────────
48
page_rows = (
49
self.store.query(
50
"MATCH (n) WHERE n.file_path CONTAINS '/pages/' "
51
"AND NOT n.file_path CONTAINS '/pages/api/' "
52
"AND n.name IS NOT NULL "
53
"RETURN n.name, n.file_path",
54
).result_set
55
or []
56
)
57
for name, file_path in page_rows:
58
self._promote_node(name, file_path, "NextPage")
59
result.promoted += 1
60
result.patterns_found["pages"] = len(page_rows)
61
62
# ── API Routes: nodes under pages/api/ or app/api/ ───────────────────
63
api_rows = (
64
self.store.query(
65
"MATCH (n) WHERE (n.file_path CONTAINS '/pages/api/' "
66
"OR n.file_path CONTAINS '/app/api/') "
67
"AND n.name IS NOT NULL "
68
"RETURN n.name, n.file_path",
69
).result_set
70
or []
71
)
72
for name, file_path in api_rows:
73
self._promote_node(name, file_path, "NextApiRoute")
74
result.promoted += 1
75
result.patterns_found["api_routes"] = len(api_rows)
76
77
# ── Hooks: functions whose name starts with "use" ────────────────────
78
hook_rows = (
79
self.store.query(
80
"MATCH (n) WHERE n.name STARTS WITH 'use' "
81
"AND n.name <> 'use' "
82
"AND n.file_path IS NOT NULL "
83
"RETURN n.name, n.file_path",
84
).result_set
85
or []
86
)
87
for name, file_path in hook_rows:
88
self._promote_node(name, file_path, "ReactHook")
89
result.promoted += 1
90
result.patterns_found["hooks"] = len(hook_rows)
91
92
# ── Stores: createStore / useStore patterns ───────────────────────────
93
store_rows = (
94
self.store.query(
95
"MATCH (n) WHERE (n.name CONTAINS 'createStore' OR n.name CONTAINS 'useStore') "
96
"AND n.file_path IS NOT NULL "
97
"RETURN n.name, n.file_path",
98
).result_set
99
or []
100
)
101
for name, file_path in store_rows:
102
self._promote_node(name, file_path, "ReactStore")
103
result.promoted += 1
104
result.patterns_found["stores"] = len(store_rows)
105
106
return result
107

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button