Navegador

navegador / navegador / enrichment / express.py
Blame History Raw 110 lines
1
"""
2
Express.js framework enricher.
3
4
Promotes generic Function/Class nodes to semantic Express types:
5
- Route — app.get / app.post / app.put / app.delete / app.patch calls
6
- Middleware — app.use calls
7
- Controller — functions/classes defined in a controllers/ directory
8
- Router — Router() instantiations / express.Router()
9
"""
10
11
from navegador.enrichment.base import EnrichmentResult, FrameworkEnricher
12
13
# HTTP method prefixes that indicate a route definition
14
_ROUTE_PREFIXES = (
15
"app.get",
16
"app.post",
17
"app.put",
18
"app.delete",
19
"app.patch",
20
"router.get",
21
"router.post",
22
"router.put",
23
"router.delete",
24
"router.patch",
25
)
26
27
28
class ExpressEnricher(FrameworkEnricher):
29
"""Enricher for Express.js codebases."""
30
31
@property
32
def framework_name(self) -> str:
33
return "express"
34
35
@property
36
def detection_patterns(self) -> list[str]:
37
return ["express"]
38
39
def enrich(self) -> EnrichmentResult:
40
result = EnrichmentResult()
41
42
# ── Routes: app.<method> or router.<method> patterns ─────────────────
43
route_rows = (
44
self.store.query(
45
"MATCH (n) WHERE (n.name STARTS WITH 'app.get' "
46
"OR n.name STARTS WITH 'app.post' "
47
"OR n.name STARTS WITH 'app.put' "
48
"OR n.name STARTS WITH 'app.delete' "
49
"OR n.name STARTS WITH 'app.patch' "
50
"OR n.name STARTS WITH 'router.get' "
51
"OR n.name STARTS WITH 'router.post' "
52
"OR n.name STARTS WITH 'router.put' "
53
"OR n.name STARTS WITH 'router.delete' "
54
"OR n.name STARTS WITH 'router.patch') "
55
"AND n.file_path IS NOT NULL "
56
"RETURN n.name, n.file_path",
57
).result_set
58
or []
59
)
60
for name, file_path in route_rows:
61
self._promote_node(name, file_path, "ExpressRoute")
62
result.promoted += 1
63
result.patterns_found["routes"] = len(route_rows)
64
65
# ── Middleware: app.use calls ─────────────────────────────────────────
66
middleware_rows = (
67
self.store.query(
68
"MATCH (n) WHERE (n.name STARTS WITH 'app.use' "
69
"OR n.name STARTS WITH 'router.use') "
70
"AND n.file_path IS NOT NULL "
71
"RETURN n.name, n.file_path",
72
).result_set
73
or []
74
)
75
for name, file_path in middleware_rows:
76
self._promote_node(name, file_path, "ExpressMiddleware")
77
result.promoted += 1
78
result.patterns_found["middleware"] = len(middleware_rows)
79
80
# ── Controllers: nodes whose file_path contains /controllers/ ─────────
81
controller_rows = (
82
self.store.query(
83
"MATCH (n) WHERE n.file_path CONTAINS '/controllers/' "
84
"AND n.name IS NOT NULL "
85
"RETURN n.name, n.file_path",
86
).result_set
87
or []
88
)
89
for name, file_path in controller_rows:
90
self._promote_node(name, file_path, "ExpressController")
91
result.promoted += 1
92
result.patterns_found["controllers"] = len(controller_rows)
93
94
# ── Routers: Router() / express.Router() instantiations ──────────────
95
router_rows = (
96
self.store.query(
97
"MATCH (n) WHERE (n.name = 'Router' OR n.name CONTAINS 'Router()' "
98
"OR n.name CONTAINS 'express.Router') "
99
"AND n.file_path IS NOT NULL "
100
"RETURN n.name, n.file_path",
101
).result_set
102
or []
103
)
104
for name, file_path in router_rows:
105
self._promote_node(name, file_path, "ExpressRouter")
106
result.promoted += 1
107
result.patterns_found["routers"] = len(router_rows)
108
109
return result
110

Keyboard Shortcuts

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