@stupidloud/codegraph 0.7.20 → 0.9.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.
- package/README.md +127 -106
- package/dist/bin/codegraph.d.ts +4 -0
- package/dist/bin/codegraph.d.ts.map +1 -1
- package/dist/bin/codegraph.js +327 -8
- package/dist/bin/codegraph.js.map +1 -1
- package/dist/bin/node-version-check.d.ts +17 -0
- package/dist/bin/node-version-check.d.ts.map +1 -1
- package/dist/bin/node-version-check.js +37 -0
- package/dist/bin/node-version-check.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -11
- package/dist/config.js.map +1 -1
- package/dist/db/index.d.ts +30 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +75 -25
- package/dist/db/index.js.map +1 -1
- package/dist/db/queries.d.ts +16 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +80 -27
- package/dist/db/queries.js.map +1 -1
- package/dist/db/sqlite-adapter.d.ts +17 -23
- package/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.js +51 -174
- package/dist/db/sqlite-adapter.js.map +1 -1
- package/dist/extraction/grammars.d.ts +7 -1
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +42 -2
- package/dist/extraction/grammars.js.map +1 -1
- package/dist/extraction/index.d.ts +9 -14
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +131 -124
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/index.d.ts.map +1 -1
- package/dist/extraction/languages/index.js +4 -0
- package/dist/extraction/languages/index.js.map +1 -1
- package/dist/extraction/languages/lua.d.ts +3 -0
- package/dist/extraction/languages/lua.d.ts.map +1 -0
- package/dist/extraction/languages/lua.js +150 -0
- package/dist/extraction/languages/lua.js.map +1 -0
- package/dist/extraction/languages/luau.d.ts +3 -0
- package/dist/extraction/languages/luau.d.ts.map +1 -0
- package/dist/extraction/languages/luau.js +37 -0
- package/dist/extraction/languages/luau.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +38 -0
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -0
- package/dist/extraction/wasm-runtime-flags.js +105 -0
- package/dist/extraction/wasm-runtime-flags.js.map +1 -0
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +71 -36
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -18
- package/dist/index.js.map +1 -1
- package/dist/installer/config-writer.d.ts.map +1 -1
- package/dist/installer/config-writer.js +3 -1
- package/dist/installer/config-writer.js.map +1 -1
- package/dist/installer/index.d.ts +66 -2
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +195 -5
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/instructions-template.d.ts +2 -2
- package/dist/installer/instructions-template.d.ts.map +1 -1
- package/dist/installer/instructions-template.js +4 -2
- package/dist/installer/instructions-template.js.map +1 -1
- package/dist/installer/targets/claude.d.ts +26 -6
- package/dist/installer/targets/claude.d.ts.map +1 -1
- package/dist/installer/targets/claude.js +165 -10
- package/dist/installer/targets/claude.js.map +1 -1
- package/dist/installer/targets/cursor.d.ts.map +1 -1
- package/dist/installer/targets/cursor.js +57 -3
- package/dist/installer/targets/cursor.js.map +1 -1
- package/dist/installer/targets/hermes.d.ts +18 -0
- package/dist/installer/targets/hermes.d.ts.map +1 -0
- package/dist/installer/targets/hermes.js +305 -0
- package/dist/installer/targets/hermes.js.map +1 -0
- package/dist/installer/targets/registry.d.ts.map +1 -1
- package/dist/installer/targets/registry.js +2 -0
- package/dist/installer/targets/registry.js.map +1 -1
- package/dist/installer/targets/types.d.ts +1 -1
- package/dist/installer/targets/types.d.ts.map +1 -1
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +213 -18
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +15 -0
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +25 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +221 -30
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/transport.d.ts +17 -0
- package/dist/mcp/transport.d.ts.map +1 -1
- package/dist/mcp/transport.js +63 -0
- package/dist/mcp/transport.js.map +1 -1
- package/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/dist/resolution/frameworks/drupal.d.ts.map +1 -0
- package/dist/resolution/frameworks/drupal.js +335 -0
- package/dist/resolution/frameworks/drupal.js.map +1 -0
- package/dist/resolution/frameworks/index.d.ts +2 -0
- package/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/dist/resolution/frameworks/index.js +9 -1
- package/dist/resolution/frameworks/index.js.map +1 -1
- package/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/dist/resolution/frameworks/nestjs.d.ts.map +1 -0
- package/dist/resolution/frameworks/nestjs.js +374 -0
- package/dist/resolution/frameworks/nestjs.js.map +1 -0
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +40 -7
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/lru-cache.d.ts +24 -0
- package/dist/resolution/lru-cache.d.ts.map +1 -0
- package/dist/resolution/lru-cache.js +62 -0
- package/dist/resolution/lru-cache.js.map +1 -0
- package/dist/sync/git-hooks.d.ts +45 -0
- package/dist/sync/git-hooks.d.ts.map +1 -0
- package/dist/sync/git-hooks.js +223 -0
- package/dist/sync/git-hooks.js.map +1 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +12 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/watch-policy.d.ts +48 -0
- package/dist/sync/watch-policy.d.ts.map +1 -0
- package/dist/sync/watch-policy.js +124 -0
- package/dist/sync/watch-policy.js.map +1 -0
- package/dist/sync/watcher.d.ts +2 -4
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +14 -6
- package/dist/sync/watcher.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.js +1 -1
- package/package.json +4 -4
- package/scripts/add-lang/bench.sh +60 -0
- package/scripts/add-lang/check-grammar.mjs +75 -0
- package/scripts/add-lang/dump-ast.mjs +103 -0
- package/scripts/add-lang/verify-extraction.mjs +70 -0
- package/scripts/agent-eval/audit.sh +68 -0
- package/scripts/agent-eval/itrun.sh +1 -1
- package/scripts/agent-eval/run-all.sh +67 -0
- package/scripts/build-bundle.sh +118 -0
- package/scripts/npm-shim.js +246 -0
- package/scripts/pack-npm.sh +95 -0
- package/scripts/patch-tree-sitter-dart.js +0 -112
- package/scripts/release.sh +0 -68
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Drupal Framework Resolver
|
|
4
|
+
*
|
|
5
|
+
* Supports Drupal 8/9/10/11 (Composer-based projects). Drupal 7 is not supported.
|
|
6
|
+
*
|
|
7
|
+
* ## What this resolver does
|
|
8
|
+
*
|
|
9
|
+
* 1. **Detection** — reads composer.json and checks for any `drupal/*` dependency in
|
|
10
|
+
* `require` or `require-dev`.
|
|
11
|
+
*
|
|
12
|
+
* 2. **Route extraction** — parses `*.routing.yml` files and emits `route` nodes for each
|
|
13
|
+
* Drupal route, with `references` edges to the `_controller`, `_form`, or entity handler
|
|
14
|
+
* class/method.
|
|
15
|
+
*
|
|
16
|
+
* 3. **Hook detection** — scans `.module`, `.install`, `.theme`, and `.inc` files for Drupal
|
|
17
|
+
* hook implementations. Two strategies are used:
|
|
18
|
+
* a. Docblock: `@Implements hook_X()` → precise, no false positives.
|
|
19
|
+
* b. Name pattern: function `{moduleName}_{hookSuffix}()` → catches hooks without
|
|
20
|
+
* docblocks but may produce false positives on helper functions.
|
|
21
|
+
* Detected hooks emit an `UnresolvedRef` from the implementing function node to the
|
|
22
|
+
* canonical `hook_X` name, linking implementations to the hook when `codegraph_callers`
|
|
23
|
+
* is invoked.
|
|
24
|
+
*
|
|
25
|
+
* ## Design decisions (review in future iterations)
|
|
26
|
+
*
|
|
27
|
+
* - Hook graph resolution (v1): hook references are stored as UnresolvedRef pointing to the
|
|
28
|
+
* canonical `hook_X` name. If Drupal core is indexed, these will resolve to core hook
|
|
29
|
+
* definitions. Without core, they remain unresolved but are still searchable via
|
|
30
|
+
* `codegraph_search("form_alter")`. Full hook-node creation (virtual nodes for every hook)
|
|
31
|
+
* is deferred to a future iteration.
|
|
32
|
+
*
|
|
33
|
+
* - Services / plugins (out of scope for v1): `*.services.yml` service definitions and plugin
|
|
34
|
+
* annotations (`@Block`, `@FormElement`, etc.) are not extracted. Add a TODO below when
|
|
35
|
+
* ready to implement.
|
|
36
|
+
*
|
|
37
|
+
* - Twig templates (out of scope for v1): `.twig` files are tracked as file nodes but no
|
|
38
|
+
* symbol extraction is performed (no tree-sitter Twig grammar). Implement when a Twig
|
|
39
|
+
* grammar WASM is available.
|
|
40
|
+
*
|
|
41
|
+
* ## TODOs for future iterations
|
|
42
|
+
*
|
|
43
|
+
* - TODO: Extract service definitions from `*.services.yml` files (class → service-id edges).
|
|
44
|
+
* - TODO: Extract plugin annotations (`@Block`, `@FormElement`, `@Field`, etc.) from PHP
|
|
45
|
+
* docblocks and emit plugin nodes with references to the annotated class.
|
|
46
|
+
* - TODO: Add Twig symbol extraction when a tree-sitter Twig grammar becomes available.
|
|
47
|
+
* - TODO: Improve hook resolution: create virtual `hook_*` nodes so `codegraph_callers`
|
|
48
|
+
* returns all implementations even when Drupal core is not indexed.
|
|
49
|
+
*/
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.drupalResolver = void 0;
|
|
52
|
+
const tree_sitter_helpers_1 = require("../../extraction/tree-sitter-helpers");
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Helpers
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* Parse the last PHP namespace segment from a FQCN like `\Drupal\mymodule\Controller\Foo`.
|
|
58
|
+
* Returns `null` for strings that don't look like a FQCN.
|
|
59
|
+
*/
|
|
60
|
+
function lastSegment(fqcn) {
|
|
61
|
+
const clean = fqcn.replace(/^\\+/, '').trim();
|
|
62
|
+
if (!clean.includes('\\'))
|
|
63
|
+
return null;
|
|
64
|
+
const parts = clean.split('\\');
|
|
65
|
+
return parts[parts.length - 1] ?? null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Derive the Drupal module name from a file path.
|
|
69
|
+
* e.g. `web/modules/custom/my_module/my_module.module` → `my_module`
|
|
70
|
+
*/
|
|
71
|
+
function moduleNameFromPath(filePath) {
|
|
72
|
+
const match = filePath.match(/\/([^/]+)\.[^./]+$/);
|
|
73
|
+
return match ? match[1] : null;
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Route extraction helpers
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
/**
|
|
79
|
+
* Extract route nodes and handler references from a Drupal `*.routing.yml` file.
|
|
80
|
+
*
|
|
81
|
+
* Drupal routing YAML format:
|
|
82
|
+
*
|
|
83
|
+
* route.name:
|
|
84
|
+
* path: '/some/path'
|
|
85
|
+
* defaults:
|
|
86
|
+
* _controller: '\Drupal\module\Controller\MyController::method'
|
|
87
|
+
* _form: '\Drupal\module\Form\MyForm'
|
|
88
|
+
* _title: 'Page title'
|
|
89
|
+
* requirements:
|
|
90
|
+
* _permission: 'access content'
|
|
91
|
+
* methods: [GET, POST] # optional
|
|
92
|
+
*/
|
|
93
|
+
function extractDrupalRoutes(filePath, content) {
|
|
94
|
+
const nodes = [];
|
|
95
|
+
const references = [];
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const lines = content.split('\n');
|
|
98
|
+
let pending = null;
|
|
99
|
+
let currentPath = null;
|
|
100
|
+
let handlerRefs = [];
|
|
101
|
+
let methods = [];
|
|
102
|
+
const flushRoute = () => {
|
|
103
|
+
if (!pending || !currentPath)
|
|
104
|
+
return;
|
|
105
|
+
const methodTag = methods.length > 0 ? ` [${methods.join(',')}]` : '';
|
|
106
|
+
const routeNode = {
|
|
107
|
+
id: `route:${filePath}:${pending.lineNum}:${currentPath}`,
|
|
108
|
+
kind: 'route',
|
|
109
|
+
name: `${currentPath}${methodTag}`,
|
|
110
|
+
qualifiedName: `${filePath}::${pending.name}`,
|
|
111
|
+
filePath,
|
|
112
|
+
startLine: pending.lineNum,
|
|
113
|
+
endLine: pending.lineNum,
|
|
114
|
+
startColumn: 0,
|
|
115
|
+
endColumn: 0,
|
|
116
|
+
language: 'yaml',
|
|
117
|
+
updatedAt: now,
|
|
118
|
+
};
|
|
119
|
+
nodes.push(routeNode);
|
|
120
|
+
for (const handler of handlerRefs) {
|
|
121
|
+
references.push({
|
|
122
|
+
fromNodeId: routeNode.id,
|
|
123
|
+
referenceName: handler,
|
|
124
|
+
referenceKind: 'references',
|
|
125
|
+
line: pending.lineNum,
|
|
126
|
+
column: 0,
|
|
127
|
+
filePath,
|
|
128
|
+
language: 'yaml',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
for (let i = 0; i < lines.length; i++) {
|
|
133
|
+
const line = lines[i];
|
|
134
|
+
const trimmed = line.trim();
|
|
135
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
136
|
+
continue;
|
|
137
|
+
// Top-level route name: no leading whitespace, ends with a colon (no value after)
|
|
138
|
+
if (/^\S.*:\s*$/.test(line) && !/^\s/.test(line)) {
|
|
139
|
+
flushRoute();
|
|
140
|
+
pending = { name: trimmed.slice(0, -1).trim(), lineNum: i + 1 };
|
|
141
|
+
currentPath = null;
|
|
142
|
+
handlerRefs = [];
|
|
143
|
+
methods = [];
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// path: '/some/path'
|
|
147
|
+
const pathMatch = trimmed.match(/^path:\s*['"]?([^'"#\n]+?)['"]?\s*(?:#.*)?$/);
|
|
148
|
+
if (pathMatch) {
|
|
149
|
+
currentPath = pathMatch[1].trim();
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// _controller: '\Drupal\...\Class::method'
|
|
153
|
+
const controllerMatch = trimmed.match(/^_controller:\s*['"]?([^'"#\n]+?)['"]?\s*(?:#.*)?$/);
|
|
154
|
+
if (controllerMatch) {
|
|
155
|
+
handlerRefs.push(controllerMatch[1].trim());
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// _form: '\Drupal\...\Form\MyForm'
|
|
159
|
+
const formMatch = trimmed.match(/^_form:\s*['"]?([^'"#\n]+?)['"]?\s*(?:#.*)?$/);
|
|
160
|
+
if (formMatch) {
|
|
161
|
+
handlerRefs.push(formMatch[1].trim());
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// _entity_form / _entity_list / _entity_view: entity.type
|
|
165
|
+
const entityMatch = trimmed.match(/^_(entity_form|entity_list|entity_view):\s*['"]?([^'"#\n]+?)['"]?\s*(?:#.*)?$/);
|
|
166
|
+
if (entityMatch) {
|
|
167
|
+
handlerRefs.push(entityMatch[2].trim());
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// methods: [GET, POST] or methods: [GET]
|
|
171
|
+
const methodsMatch = trimmed.match(/^methods:\s*\[([^\]]+)\]/);
|
|
172
|
+
if (methodsMatch) {
|
|
173
|
+
methods = methodsMatch[1].split(',').map((m) => m.trim().toUpperCase()).filter(Boolean);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
flushRoute();
|
|
178
|
+
return { nodes, references };
|
|
179
|
+
}
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// Hook detection helpers
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
const HOOK_FILE_EXTENSIONS = ['.module', '.install', '.theme', '.inc'];
|
|
184
|
+
function isDrupalHookFile(filePath) {
|
|
185
|
+
return HOOK_FILE_EXTENSIONS.some((ext) => filePath.endsWith(ext));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Extract hook implementation references from a Drupal PHP file.
|
|
189
|
+
*
|
|
190
|
+
* Strategy A (primary): look for docblocks containing `Implements hook_X().`
|
|
191
|
+
* followed immediately by the function definition. This is the Drupal coding
|
|
192
|
+
* standard and is precise.
|
|
193
|
+
*
|
|
194
|
+
* Strategy B (fallback): for functions whose name starts with `{moduleName}_`,
|
|
195
|
+
* treat the suffix as the hook name. Catches hooks without docblocks but may
|
|
196
|
+
* produce false positives on non-hook helper functions.
|
|
197
|
+
*
|
|
198
|
+
* Each detected hook emits an UnresolvedRef from the implementing function node
|
|
199
|
+
* (identified by computing the same ID tree-sitter would generate) to the
|
|
200
|
+
* canonical hook name, e.g. `hook_form_alter`.
|
|
201
|
+
*/
|
|
202
|
+
function extractDrupalHooks(filePath, content) {
|
|
203
|
+
const references = [];
|
|
204
|
+
// Build a map of function name → 1-indexed line number for all top-level functions.
|
|
205
|
+
// This mirrors tree-sitter's line numbering so we can reconstruct node IDs.
|
|
206
|
+
const funcLineMap = new Map();
|
|
207
|
+
const funcDef = /^function\s+(\w+)\s*\(/gm;
|
|
208
|
+
let fm;
|
|
209
|
+
while ((fm = funcDef.exec(content)) !== null) {
|
|
210
|
+
const name = fm[1];
|
|
211
|
+
if (!funcLineMap.has(name)) {
|
|
212
|
+
// line = number of newlines before match start + 1
|
|
213
|
+
funcLineMap.set(name, content.slice(0, fm.index).split('\n').length);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const emitHookRef = (hookName, funcName) => {
|
|
217
|
+
const lineNum = funcLineMap.get(funcName);
|
|
218
|
+
if (lineNum === undefined)
|
|
219
|
+
return;
|
|
220
|
+
const nodeId = (0, tree_sitter_helpers_1.generateNodeId)(filePath, 'function', funcName, lineNum);
|
|
221
|
+
references.push({
|
|
222
|
+
fromNodeId: nodeId,
|
|
223
|
+
referenceName: hookName,
|
|
224
|
+
referenceKind: 'references',
|
|
225
|
+
line: lineNum,
|
|
226
|
+
column: 0,
|
|
227
|
+
filePath,
|
|
228
|
+
language: 'php',
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
// Strategy A: docblock `Implements hook_X().` followed by function definition.
|
|
232
|
+
// The docblock and function may be separated by blank lines.
|
|
233
|
+
const docblockPattern = /\/\*\*[\s\S]*?(?:@|\*\s+)Implements\s+(hook_\w+)\s*\(\)[\s\S]*?\*\/\s*\n(?:\s*\n)*function\s+(\w+)\s*\(/g;
|
|
234
|
+
const docblockMatched = new Set();
|
|
235
|
+
let match;
|
|
236
|
+
while ((match = docblockPattern.exec(content)) !== null) {
|
|
237
|
+
const [, hookName, funcName] = match;
|
|
238
|
+
emitHookRef(hookName, funcName);
|
|
239
|
+
docblockMatched.add(funcName);
|
|
240
|
+
}
|
|
241
|
+
// Strategy B: fallback name-pattern matching for functions without docblocks.
|
|
242
|
+
// Only applies to functions whose name starts with {moduleName}_ and that were
|
|
243
|
+
// not already matched by Strategy A.
|
|
244
|
+
const moduleName = moduleNameFromPath(filePath);
|
|
245
|
+
if (moduleName) {
|
|
246
|
+
const prefix = moduleName + '_';
|
|
247
|
+
for (const [funcName] of funcLineMap) {
|
|
248
|
+
if (docblockMatched.has(funcName))
|
|
249
|
+
continue;
|
|
250
|
+
if (!funcName.startsWith(prefix))
|
|
251
|
+
continue;
|
|
252
|
+
const hookSuffix = funcName.slice(prefix.length);
|
|
253
|
+
if (!hookSuffix)
|
|
254
|
+
continue;
|
|
255
|
+
// Emit a reference to hook_{suffix} — the resolver will link it if the
|
|
256
|
+
// hook is defined somewhere in the indexed graph (e.g. Drupal core).
|
|
257
|
+
emitHookRef(`hook_${hookSuffix}`, funcName);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return { nodes: [], references };
|
|
261
|
+
}
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
// Resolver
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
exports.drupalResolver = {
|
|
266
|
+
name: 'drupal',
|
|
267
|
+
languages: ['php', 'yaml'],
|
|
268
|
+
detect(context) {
|
|
269
|
+
const composer = context.readFile('composer.json');
|
|
270
|
+
if (!composer)
|
|
271
|
+
return false;
|
|
272
|
+
try {
|
|
273
|
+
const json = JSON.parse(composer);
|
|
274
|
+
const deps = { ...json.require, ...(json['require-dev'] ?? {}) };
|
|
275
|
+
return Object.keys(deps).some((k) => k.startsWith('drupal/'));
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
resolve(ref, context) {
|
|
282
|
+
const name = ref.referenceName;
|
|
283
|
+
// _controller: '\Drupal\module\...\ClassName::methodName'
|
|
284
|
+
const controllerMatch = name.match(/^\\?(?:Drupal\\[^:]+\\)?([^\\:]+)::(\w+)$/);
|
|
285
|
+
if (controllerMatch) {
|
|
286
|
+
const [, className, methodName] = controllerMatch;
|
|
287
|
+
const classNodes = context.getNodesByName(className);
|
|
288
|
+
for (const cls of classNodes) {
|
|
289
|
+
if (cls.kind !== 'class')
|
|
290
|
+
continue;
|
|
291
|
+
const fileNodes = context.getNodesInFile(cls.filePath);
|
|
292
|
+
const method = fileNodes.find((n) => n.kind === 'method' && n.name === methodName);
|
|
293
|
+
if (method) {
|
|
294
|
+
return { original: ref, targetNodeId: method.id, confidence: 0.9, resolvedBy: 'framework' };
|
|
295
|
+
}
|
|
296
|
+
return { original: ref, targetNodeId: cls.id, confidence: 0.7, resolvedBy: 'framework' };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// _form / _entity_form: '\Drupal\module\...\ClassName' (no ::method)
|
|
300
|
+
if (name.includes('\\') && !name.includes('::')) {
|
|
301
|
+
const className = lastSegment(name);
|
|
302
|
+
if (className) {
|
|
303
|
+
const classNodes = context.getNodesByName(className);
|
|
304
|
+
const cls = classNodes.find((n) => n.kind === 'class');
|
|
305
|
+
if (cls) {
|
|
306
|
+
return { original: ref, targetNodeId: cls.id, confidence: 0.85, resolvedBy: 'framework' };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// hook_X — find any function whose name ends in _{hookSuffix} in a hook file
|
|
311
|
+
if (name.startsWith('hook_')) {
|
|
312
|
+
const hookSuffix = name.slice(5); // strip 'hook_'
|
|
313
|
+
const candidates = context.getNodesByKind('function').filter((n) => n.name.endsWith(`_${hookSuffix}`) && isDrupalHookFile(n.filePath));
|
|
314
|
+
if (candidates.length > 0) {
|
|
315
|
+
return {
|
|
316
|
+
original: ref,
|
|
317
|
+
targetNodeId: candidates[0].id,
|
|
318
|
+
confidence: 0.75,
|
|
319
|
+
resolvedBy: 'framework',
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
},
|
|
325
|
+
extract(filePath, content) {
|
|
326
|
+
if (filePath.endsWith('.routing.yml')) {
|
|
327
|
+
return extractDrupalRoutes(filePath, content);
|
|
328
|
+
}
|
|
329
|
+
if (isDrupalHookFile(filePath) || filePath.endsWith('.php')) {
|
|
330
|
+
return extractDrupalHooks(filePath, content);
|
|
331
|
+
}
|
|
332
|
+
return { nodes: [], references: [] };
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
//# sourceMappingURL=drupal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drupal.js","sourceRoot":"","sources":["../../../src/resolution/frameworks/drupal.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,8 +26,10 @@ export declare function getApplicableFrameworks(detected: FrameworkResolver[], l
|
|
|
26
26
|
* Register a custom framework resolver
|
|
27
27
|
*/
|
|
28
28
|
export declare function registerFrameworkResolver(resolver: FrameworkResolver): void;
|
|
29
|
+
export { drupalResolver } from './drupal';
|
|
29
30
|
export { laravelResolver, FACADE_MAPPINGS } from './laravel';
|
|
30
31
|
export { expressResolver } from './express';
|
|
32
|
+
export { nestjsResolver } from './nestjs';
|
|
31
33
|
export { reactResolver } from './react';
|
|
32
34
|
export { svelteResolver } from './svelte';
|
|
33
35
|
export { vueResolver } from './vue';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resolution/frameworks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resolution/frameworks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiD5C;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,iBAAiB,EAAE,CAE9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEhF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAQhF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,QAAQ,EAAE,QAAQ,GACjB,iBAAiB,EAAE,CAIrB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAO3E;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -5,14 +5,16 @@
|
|
|
5
5
|
* Manages framework-specific resolvers.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.vaporResolver = exports.uikitResolver = exports.swiftUIResolver = exports.aspnetResolver = exports.rustResolver = exports.goResolver = exports.springResolver = exports.railsResolver = exports.fastapiResolver = exports.flaskResolver = exports.djangoResolver = exports.vueResolver = exports.svelteResolver = exports.reactResolver = exports.expressResolver = exports.FACADE_MAPPINGS = exports.laravelResolver = void 0;
|
|
8
|
+
exports.vaporResolver = exports.uikitResolver = exports.swiftUIResolver = exports.aspnetResolver = exports.rustResolver = exports.goResolver = exports.springResolver = exports.railsResolver = exports.fastapiResolver = exports.flaskResolver = exports.djangoResolver = exports.vueResolver = exports.svelteResolver = exports.reactResolver = exports.nestjsResolver = exports.expressResolver = exports.FACADE_MAPPINGS = exports.laravelResolver = exports.drupalResolver = void 0;
|
|
9
9
|
exports.getAllFrameworkResolvers = getAllFrameworkResolvers;
|
|
10
10
|
exports.getFrameworkResolver = getFrameworkResolver;
|
|
11
11
|
exports.detectFrameworks = detectFrameworks;
|
|
12
12
|
exports.getApplicableFrameworks = getApplicableFrameworks;
|
|
13
13
|
exports.registerFrameworkResolver = registerFrameworkResolver;
|
|
14
|
+
const drupal_1 = require("./drupal");
|
|
14
15
|
const laravel_1 = require("./laravel");
|
|
15
16
|
const express_1 = require("./express");
|
|
17
|
+
const nestjs_1 = require("./nestjs");
|
|
16
18
|
const react_1 = require("./react");
|
|
17
19
|
const svelte_1 = require("./svelte");
|
|
18
20
|
const vue_1 = require("./vue");
|
|
@@ -29,8 +31,10 @@ const swift_1 = require("./swift");
|
|
|
29
31
|
const FRAMEWORK_RESOLVERS = [
|
|
30
32
|
// PHP
|
|
31
33
|
laravel_1.laravelResolver,
|
|
34
|
+
drupal_1.drupalResolver,
|
|
32
35
|
// JavaScript/TypeScript
|
|
33
36
|
express_1.expressResolver,
|
|
37
|
+
nestjs_1.nestjsResolver,
|
|
34
38
|
react_1.reactResolver,
|
|
35
39
|
svelte_1.svelteResolver,
|
|
36
40
|
vue_1.vueResolver,
|
|
@@ -97,11 +101,15 @@ function registerFrameworkResolver(resolver) {
|
|
|
97
101
|
FRAMEWORK_RESOLVERS.push(resolver);
|
|
98
102
|
}
|
|
99
103
|
// Re-export framework resolvers
|
|
104
|
+
var drupal_2 = require("./drupal");
|
|
105
|
+
Object.defineProperty(exports, "drupalResolver", { enumerable: true, get: function () { return drupal_2.drupalResolver; } });
|
|
100
106
|
var laravel_2 = require("./laravel");
|
|
101
107
|
Object.defineProperty(exports, "laravelResolver", { enumerable: true, get: function () { return laravel_2.laravelResolver; } });
|
|
102
108
|
Object.defineProperty(exports, "FACADE_MAPPINGS", { enumerable: true, get: function () { return laravel_2.FACADE_MAPPINGS; } });
|
|
103
109
|
var express_2 = require("./express");
|
|
104
110
|
Object.defineProperty(exports, "expressResolver", { enumerable: true, get: function () { return express_2.expressResolver; } });
|
|
111
|
+
var nestjs_2 = require("./nestjs");
|
|
112
|
+
Object.defineProperty(exports, "nestjsResolver", { enumerable: true, get: function () { return nestjs_2.nestjsResolver; } });
|
|
105
113
|
var react_2 = require("./react");
|
|
106
114
|
Object.defineProperty(exports, "reactResolver", { enumerable: true, get: function () { return react_2.reactResolver; } });
|
|
107
115
|
var svelte_2 = require("./svelte");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/resolution/frameworks/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/resolution/frameworks/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NestJS Framework Resolver
|
|
3
|
+
*
|
|
4
|
+
* Handles NestJS decorator-based routing across its transport layers:
|
|
5
|
+
* - HTTP: @Controller(prefix) + @Get/@Post/@Put/@Patch/@Delete/@Head/@Options/@All
|
|
6
|
+
* - GraphQL: @Resolver + @Query/@Mutation/@Subscription
|
|
7
|
+
* - Microservices: @MessagePattern / @EventPattern
|
|
8
|
+
* - WebSockets: @WebSocketGateway(namespace) + @SubscribeMessage(event)
|
|
9
|
+
*
|
|
10
|
+
* Like the other framework extractors this is regex-over-source (comment-
|
|
11
|
+
* stripped), not AST traversal. NestJS differs from Spring/ASP.NET in two ways
|
|
12
|
+
* that this resolver has to account for:
|
|
13
|
+
*
|
|
14
|
+
* 1. An HTTP route's path is split across TWO decorators — the class-level
|
|
15
|
+
* `@Controller` prefix and the method-level `@Get`/`@Post` path — and both
|
|
16
|
+
* are frequently empty (`@Controller()`, `@Get()`). We pair each method
|
|
17
|
+
* decorator with its enclosing class and join the two paths.
|
|
18
|
+
*
|
|
19
|
+
* 2. `@Query()` is overloaded: it's a GraphQL *method* decorator (from
|
|
20
|
+
* `@nestjs/graphql`) AND a REST *parameter* decorator (from
|
|
21
|
+
* `@nestjs/common`). We only treat it as GraphQL when it sits inside an
|
|
22
|
+
* `@Resolver` class, which is what disambiguates the two.
|
|
23
|
+
*/
|
|
24
|
+
import { FrameworkResolver } from '../types';
|
|
25
|
+
export declare const nestjsResolver: FrameworkResolver;
|
|
26
|
+
//# sourceMappingURL=nestjs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../../src/resolution/frameworks/nestjs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EACL,iBAAiB,EAIlB,MAAM,UAAU,CAAC;AAQlB,eAAO,MAAM,cAAc,EAAE,iBAqJ5B,CAAC"}
|