@mgamil/mapx 0.2.4

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.
Files changed (203) hide show
  1. package/LICENSE +194 -0
  2. package/README.md +488 -0
  3. package/VERSION +1 -0
  4. package/dist/agents/generator.d.ts +74 -0
  5. package/dist/agents/generator.js +375 -0
  6. package/dist/agents/templates.d.ts +29 -0
  7. package/dist/agents/templates.js +459 -0
  8. package/dist/cli.d.ts +16 -0
  9. package/dist/cli.js +1835 -0
  10. package/dist/core/cluster-engine.d.ts +32 -0
  11. package/dist/core/cluster-engine.js +314 -0
  12. package/dist/core/config.d.ts +29 -0
  13. package/dist/core/config.js +178 -0
  14. package/dist/core/context-builder.d.ts +61 -0
  15. package/dist/core/context-builder.js +252 -0
  16. package/dist/core/flow-tracer.d.ts +63 -0
  17. package/dist/core/flow-tracer.js +366 -0
  18. package/dist/core/git-tracker.d.ts +20 -0
  19. package/dist/core/git-tracker.js +159 -0
  20. package/dist/core/graph.d.ts +42 -0
  21. package/dist/core/graph.js +186 -0
  22. package/dist/core/metrics.d.ts +24 -0
  23. package/dist/core/metrics.js +87 -0
  24. package/dist/core/scanner.d.ts +53 -0
  25. package/dist/core/scanner.js +949 -0
  26. package/dist/core/store-bun.d.ts +13 -0
  27. package/dist/core/store-bun.js +34 -0
  28. package/dist/core/store-interface.d.ts +15 -0
  29. package/dist/core/store-interface.js +7 -0
  30. package/dist/core/store-node.d.ts +13 -0
  31. package/dist/core/store-node.js +35 -0
  32. package/dist/core/store.d.ts +132 -0
  33. package/dist/core/store.js +614 -0
  34. package/dist/core/workspace-manager.d.ts +9 -0
  35. package/dist/core/workspace-manager.js +64 -0
  36. package/dist/exporters/dot-exporter.d.ts +16 -0
  37. package/dist/exporters/dot-exporter.js +179 -0
  38. package/dist/exporters/graph-exporter.d.ts +14 -0
  39. package/dist/exporters/graph-exporter.js +85 -0
  40. package/dist/exporters/index.d.ts +9 -0
  41. package/dist/exporters/index.js +12 -0
  42. package/dist/exporters/llm-exporter.d.ts +18 -0
  43. package/dist/exporters/llm-exporter.js +224 -0
  44. package/dist/exporters/svg-exporter.d.ts +19 -0
  45. package/dist/exporters/svg-exporter.js +319 -0
  46. package/dist/exporters/toon-exporter.d.ts +16 -0
  47. package/dist/exporters/toon-exporter.js +246 -0
  48. package/dist/frameworks/detectors/aspnet.d.ts +11 -0
  49. package/dist/frameworks/detectors/aspnet.js +52 -0
  50. package/dist/frameworks/detectors/django.d.ts +14 -0
  51. package/dist/frameworks/detectors/django.js +135 -0
  52. package/dist/frameworks/detectors/drupal.d.ts +13 -0
  53. package/dist/frameworks/detectors/drupal.js +94 -0
  54. package/dist/frameworks/detectors/express.d.ts +12 -0
  55. package/dist/frameworks/detectors/express.js +234 -0
  56. package/dist/frameworks/detectors/fastapi.d.ts +12 -0
  57. package/dist/frameworks/detectors/fastapi.js +203 -0
  58. package/dist/frameworks/detectors/flask.d.ts +12 -0
  59. package/dist/frameworks/detectors/flask.js +244 -0
  60. package/dist/frameworks/detectors/go.d.ts +11 -0
  61. package/dist/frameworks/detectors/go.js +75 -0
  62. package/dist/frameworks/detectors/laravel.d.ts +11 -0
  63. package/dist/frameworks/detectors/laravel.js +462 -0
  64. package/dist/frameworks/detectors/nestjs.d.ts +12 -0
  65. package/dist/frameworks/detectors/nestjs.js +155 -0
  66. package/dist/frameworks/detectors/nextjs.d.ts +11 -0
  67. package/dist/frameworks/detectors/nextjs.js +118 -0
  68. package/dist/frameworks/detectors/rails.d.ts +12 -0
  69. package/dist/frameworks/detectors/rails.js +76 -0
  70. package/dist/frameworks/detectors/react-router.d.ts +11 -0
  71. package/dist/frameworks/detectors/react-router.js +115 -0
  72. package/dist/frameworks/detectors/rust.d.ts +11 -0
  73. package/dist/frameworks/detectors/rust.js +59 -0
  74. package/dist/frameworks/detectors/spring.d.ts +11 -0
  75. package/dist/frameworks/detectors/spring.js +56 -0
  76. package/dist/frameworks/detectors/sveltekit.d.ts +11 -0
  77. package/dist/frameworks/detectors/sveltekit.js +154 -0
  78. package/dist/frameworks/detectors/symfony.d.ts +13 -0
  79. package/dist/frameworks/detectors/symfony.js +175 -0
  80. package/dist/frameworks/detectors/tanstack-router.d.ts +12 -0
  81. package/dist/frameworks/detectors/tanstack-router.js +80 -0
  82. package/dist/frameworks/detectors/vapor.d.ts +11 -0
  83. package/dist/frameworks/detectors/vapor.js +52 -0
  84. package/dist/frameworks/detectors/vue-router.d.ts +12 -0
  85. package/dist/frameworks/detectors/vue-router.js +237 -0
  86. package/dist/frameworks/detectors/wordpress.d.ts +13 -0
  87. package/dist/frameworks/detectors/wordpress.js +141 -0
  88. package/dist/frameworks/detectors/yii.d.ts +11 -0
  89. package/dist/frameworks/detectors/yii.js +131 -0
  90. package/dist/frameworks/framework-registry.d.ts +13 -0
  91. package/dist/frameworks/framework-registry.js +77 -0
  92. package/dist/frameworks/route-registry.d.ts +26 -0
  93. package/dist/frameworks/route-registry.js +102 -0
  94. package/dist/index.d.ts +19 -0
  95. package/dist/index.js +30 -0
  96. package/dist/languages/index.d.ts +2 -0
  97. package/dist/languages/index.js +7 -0
  98. package/dist/languages/installer.d.ts +13 -0
  99. package/dist/languages/installer.js +103 -0
  100. package/dist/languages/registry.d.ts +19 -0
  101. package/dist/languages/registry.js +427 -0
  102. package/dist/main.d.ts +2 -0
  103. package/dist/main.js +20 -0
  104. package/dist/mcp.d.ts +11 -0
  105. package/dist/mcp.js +1699 -0
  106. package/dist/parsers/common-methods.d.ts +3 -0
  107. package/dist/parsers/common-methods.js +33 -0
  108. package/dist/parsers/fallback-parser.d.ts +10 -0
  109. package/dist/parsers/fallback-parser.js +18 -0
  110. package/dist/parsers/generic-wasm-parser.d.ts +23 -0
  111. package/dist/parsers/generic-wasm-parser.js +168 -0
  112. package/dist/parsers/ignored-symbols.d.ts +26 -0
  113. package/dist/parsers/ignored-symbols.js +77 -0
  114. package/dist/parsers/index.d.ts +9 -0
  115. package/dist/parsers/index.js +13 -0
  116. package/dist/parsers/languages/javascript.d.ts +11 -0
  117. package/dist/parsers/languages/javascript.js +28 -0
  118. package/dist/parsers/languages/php.d.ts +15 -0
  119. package/dist/parsers/languages/php.js +648 -0
  120. package/dist/parsers/languages/typescript.d.ts +10 -0
  121. package/dist/parsers/languages/typescript.js +9 -0
  122. package/dist/parsers/languages/vue.d.ts +13 -0
  123. package/dist/parsers/languages/vue.js +63 -0
  124. package/dist/parsers/parse-worker.d.ts +2 -0
  125. package/dist/parsers/parse-worker.js +185 -0
  126. package/dist/parsers/parser-interface.d.ts +9 -0
  127. package/dist/parsers/parser-interface.js +0 -0
  128. package/dist/parsers/parser-registry.d.ts +8 -0
  129. package/dist/parsers/parser-registry.js +52 -0
  130. package/dist/parsers/wasm-parser.d.ts +16 -0
  131. package/dist/parsers/wasm-parser.js +110 -0
  132. package/dist/types.d.ts +172 -0
  133. package/dist/types.js +0 -0
  134. package/dist/ui/index.html +270 -0
  135. package/dist/ui/main.js +581 -0
  136. package/dist/ui/main.js.map +7 -0
  137. package/dist/ui/styles.css +573 -0
  138. package/dist/ui-events.d.ts +36 -0
  139. package/dist/ui-events.js +61 -0
  140. package/dist/ui-server.d.ts +12 -0
  141. package/dist/ui-server.js +504 -0
  142. package/package.json +179 -0
  143. package/queries/bash/references.scm +22 -0
  144. package/queries/bash/symbols.scm +15 -0
  145. package/queries/c/references.scm +14 -0
  146. package/queries/c/symbols.scm +30 -0
  147. package/queries/c-sharp/references.scm +26 -0
  148. package/queries/c-sharp/symbols.scm +57 -0
  149. package/queries/cpp/references.scm +21 -0
  150. package/queries/cpp/symbols.scm +44 -0
  151. package/queries/dart/references.scm +33 -0
  152. package/queries/dart/symbols.scm +38 -0
  153. package/queries/elixir/references.scm +45 -0
  154. package/queries/elixir/symbols.scm +41 -0
  155. package/queries/go/references.scm +22 -0
  156. package/queries/go/symbols.scm +53 -0
  157. package/queries/java/references.scm +32 -0
  158. package/queries/java/symbols.scm +41 -0
  159. package/queries/javascript/references.scm +14 -0
  160. package/queries/javascript/symbols.scm +23 -0
  161. package/queries/kotlin/references.scm +31 -0
  162. package/queries/kotlin/symbols.scm +24 -0
  163. package/queries/lua/references.scm +19 -0
  164. package/queries/lua/symbols.scm +29 -0
  165. package/queries/pascal/references.scm +29 -0
  166. package/queries/pascal/symbols.scm +45 -0
  167. package/queries/php/references.scm +109 -0
  168. package/queries/php/symbols.scm +33 -0
  169. package/queries/python/references.scm +50 -0
  170. package/queries/python/symbols.scm +21 -0
  171. package/queries/ruby/references.scm +48 -0
  172. package/queries/ruby/symbols.scm +24 -0
  173. package/queries/rust/references.scm +31 -0
  174. package/queries/rust/symbols.scm +35 -0
  175. package/queries/scala/references.scm +30 -0
  176. package/queries/scala/symbols.scm +35 -0
  177. package/queries/svelte/references.scm +20 -0
  178. package/queries/svelte/symbols.scm +30 -0
  179. package/queries/swift/references.scm +22 -0
  180. package/queries/swift/symbols.scm +37 -0
  181. package/queries/typescript/references.scm +25 -0
  182. package/queries/typescript/symbols.scm +35 -0
  183. package/queries/vue/references.scm +20 -0
  184. package/queries/vue/symbols.scm +28 -0
  185. package/queries/zig/references.scm +20 -0
  186. package/queries/zig/symbols.scm +22 -0
  187. package/wasm/tree-sitter-c.wasm +0 -0
  188. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  189. package/wasm/tree-sitter-cpp.wasm +0 -0
  190. package/wasm/tree-sitter-dart.wasm +0 -0
  191. package/wasm/tree-sitter-go.wasm +0 -0
  192. package/wasm/tree-sitter-java.wasm +0 -0
  193. package/wasm/tree-sitter-javascript.wasm +0 -0
  194. package/wasm/tree-sitter-kotlin.wasm +0 -0
  195. package/wasm/tree-sitter-php.wasm +0 -0
  196. package/wasm/tree-sitter-python.wasm +0 -0
  197. package/wasm/tree-sitter-ruby.wasm +0 -0
  198. package/wasm/tree-sitter-rust.wasm +0 -0
  199. package/wasm/tree-sitter-scala.wasm +0 -0
  200. package/wasm/tree-sitter-swift.wasm +0 -0
  201. package/wasm/tree-sitter-tsx.wasm +0 -0
  202. package/wasm/tree-sitter-typescript.wasm +0 -0
  203. package/wasm/tree-sitter-vue.wasm +0 -0
@@ -0,0 +1,648 @@
1
+ import { parseWithQueries } from "../wasm-parser.js";
2
+ import { COMMON_FRAMEWORK_METHODS } from "../common-methods.js";
3
+ import { GenericWasmParser } from "../generic-wasm-parser.js";
4
+ const LARAVEL_FACADE_MAP = {
5
+ App: "Illuminate\\Foundation\\Application",
6
+ Auth: "Illuminate\\Auth\\AuthManager",
7
+ Bus: "Illuminate\\Contracts\\Bus\\Dispatcher",
8
+ Cache: "Illuminate\\Cache\\CacheManager",
9
+ Config: "Illuminate\\Config\\Repository",
10
+ Cookie: "Illuminate\\Cookie\\CookieJar",
11
+ Crypt: "Illuminate\\Encryption\\Encrypter",
12
+ DB: "Illuminate\\Database\\DatabaseManager",
13
+ Event: "Illuminate\\Events\\Dispatcher",
14
+ File: "Illuminate\\Filesystem\\Filesystem",
15
+ Gate: "Illuminate\\Auth\\Access\\Gate",
16
+ Hash: "Illuminate\\Hashing\\HashManager",
17
+ Http: "Illuminate\\Http\\Client\\Factory",
18
+ Lang: "Illuminate\\Translation\\Translator",
19
+ Log: "Illuminate\\Log\\LogManager",
20
+ Mail: "Illuminate\\Mail\\Mailer",
21
+ Notification: "Illuminate\\Notifications\\ChannelManager",
22
+ Password: "Illuminate\\Auth\\Passwords\\PasswordBrokerManager",
23
+ Queue: "Illuminate\\Queue\\QueueManager",
24
+ RateLimiter: "Illuminate\\Cache\\RateLimiter",
25
+ Redirect: "Illuminate\\Routing\\Redirector",
26
+ Request: "Illuminate\\Http\\Request",
27
+ Response: "Illuminate\\Routing\\ResponseFactory",
28
+ Route: "Illuminate\\Routing\\Router",
29
+ Schema: "Illuminate\\Database\\Schema\\Builder",
30
+ Session: "Illuminate\\Session\\SessionManager",
31
+ Storage: "Illuminate\\Filesystem\\FilesystemManager",
32
+ URL: "Illuminate\\Routing\\UrlGenerator",
33
+ Validator: "Illuminate\\Validation\\Factory",
34
+ View: "Illuminate\\View\\Factory"
35
+ };
36
+ class PhpParser extends GenericWasmParser {
37
+ constructor(langDef) {
38
+ super(langDef);
39
+ }
40
+ async parse(filePath, source, options) {
41
+ if (filePath.includes("bootstrap/cache/") || filePath.endsWith(".blade.php")) {
42
+ return { symbols: [], references: [], errors: [] };
43
+ }
44
+ await this.ensureLoaded();
45
+ const errors = [];
46
+ const symbols = [];
47
+ const references = [];
48
+ let fileMetadata = void 0;
49
+ try {
50
+ const { symbols: symCaptures, references: refCaptures, nameByNodeId } = await parseWithQueries(
51
+ source,
52
+ this.language,
53
+ this.symbolsQuery,
54
+ this.referencesQuery
55
+ );
56
+ let currentClass = null;
57
+ for (const [captureName, captures] of symCaptures) {
58
+ if (captureName.startsWith("symbol.kind_")) {
59
+ const kind = captureName.replace("symbol.kind_", "");
60
+ for (const capture of captures) {
61
+ const name = nameByNodeId.get(capture.node.id) || capture.node.text;
62
+ const startLine = capture.node.startPosition.row + 1;
63
+ const endLine = capture.node.endPosition.row + 1;
64
+ if (kind === "namespace") {
65
+ if (!fileMetadata) fileMetadata = {};
66
+ fileMetadata.namespace = name;
67
+ continue;
68
+ }
69
+ if (kind === "class" || kind === "interface" || kind === "trait" || kind === "enum") {
70
+ currentClass = name;
71
+ }
72
+ let signature = name;
73
+ const parentNode = capture.node.parent;
74
+ if (parentNode) {
75
+ signature = this.extractSignature(source, parentNode, name, kind, startLine);
76
+ }
77
+ symbols.push({
78
+ name,
79
+ kind,
80
+ scope: kind === "method" || kind === "property" || kind === "constant" ? currentClass : null,
81
+ signature,
82
+ startLine,
83
+ endLine,
84
+ metadata: {}
85
+ });
86
+ }
87
+ }
88
+ }
89
+ const useTable = /* @__PURE__ */ new Map();
90
+ const useClauses = refCaptures.get("ref.target_use_clause") || [];
91
+ for (const capture of useClauses) {
92
+ const node = capture.node;
93
+ const parent = node.parent;
94
+ let prefix = "";
95
+ if (parent && parent.type === "namespace_use_group") {
96
+ const grandParent = parent.parent;
97
+ if (grandParent) {
98
+ const prefixNode = grandParent.namedChildren.find((c) => c.type === "namespace_name");
99
+ if (prefixNode) {
100
+ prefix = prefixNode.text;
101
+ }
102
+ }
103
+ }
104
+ const targetNode = (node.namedChildCount > 0 ? node.namedChild(0) : null) || node;
105
+ const targetText = targetNode.text;
106
+ const fullTarget = prefix ? `${prefix}\\${targetText}` : targetText;
107
+ const startLine = node.startPosition.row + 1;
108
+ let aliasText = "";
109
+ if (node.namedChildCount > 1) {
110
+ const secondChild = node.namedChild(1);
111
+ if (secondChild && secondChild.type === "name") {
112
+ aliasText = secondChild.text;
113
+ }
114
+ }
115
+ const shortName = targetText.includes("\\") ? targetText.substring(targetText.lastIndexOf("\\") + 1) : targetText;
116
+ const importName = aliasText || shortName;
117
+ useTable.set(importName, fullTarget);
118
+ references.push({
119
+ sourceSymbol: null,
120
+ targetName: fullTarget,
121
+ referenceType: "import",
122
+ startLine,
123
+ verifiability: "verified"
124
+ });
125
+ }
126
+ const ELOQUENT_RELATIONSHIP_METHODS = /* @__PURE__ */ new Set([
127
+ "hasOne",
128
+ "hasMany",
129
+ "hasOneThrough",
130
+ "hasManyThrough",
131
+ "belongsTo",
132
+ "belongsToMany",
133
+ "morphTo",
134
+ "morphOne",
135
+ "morphMany",
136
+ "morphToMany",
137
+ "morphedByMany",
138
+ "hasOneOfMany"
139
+ ]);
140
+ const resolveToFqn = (name) => {
141
+ if (name.startsWith("\\")) {
142
+ return name.substring(1);
143
+ }
144
+ if (name.includes("\\")) {
145
+ return name;
146
+ }
147
+ return useTable.get(name) ?? name;
148
+ };
149
+ for (const [captureName, captures] of refCaptures) {
150
+ if (captureName === "ref.target_use_clause") continue;
151
+ if (captureName === "ref.target_param" || captureName === "ref.target_return_type" || captureName === "ref.target_property" || captureName === "ref.target_dispatch" || captureName === "ref.target_dispatch_static" || captureName === "ref.target_notify") {
152
+ continue;
153
+ }
154
+ if (captureName.startsWith("ref.target_")) {
155
+ const refType = captureName.replace("ref.target_", "");
156
+ for (const capture of captures) {
157
+ const targetName = capture.node.text;
158
+ if (!targetName || typeof targetName !== "string") continue;
159
+ const startLine = capture.node.startPosition.row + 1;
160
+ const cleaned = this.cleanTargetName(targetName, refType);
161
+ const referenceType = this.mapRefType(refType);
162
+ let verifiability = "verified";
163
+ if (referenceType === "call") {
164
+ const parent = capture.node.parent;
165
+ if (parent?.type === "member_call_expression" && parent.child(0)?.text === "$this" && ELOQUENT_RELATIONSHIP_METHODS.has(cleaned)) {
166
+ continue;
167
+ }
168
+ const parentType = parent?.type;
169
+ if (parentType === "member_call_expression" || COMMON_FRAMEWORK_METHODS.has(cleaned)) {
170
+ verifiability = "inferred";
171
+ }
172
+ }
173
+ let resolvedTarget = cleaned;
174
+ if (referenceType === "extends" || referenceType === "implements" || referenceType === "instantiation" || referenceType === "call" && capture.node.parent?.type === "scoped_call_expression") {
175
+ resolvedTarget = resolveToFqn(cleaned);
176
+ }
177
+ references.push({
178
+ sourceSymbol: null,
179
+ targetName: resolvedTarget,
180
+ referenceType,
181
+ startLine,
182
+ verifiability
183
+ });
184
+ }
185
+ }
186
+ }
187
+ const findNamedTypes = (node) => {
188
+ const results = [];
189
+ if (node.type === "named_type") {
190
+ results.push(node);
191
+ }
192
+ for (let i = 0; i < node.namedChildCount; i++) {
193
+ results.push(...findNamedTypes(node.namedChild(i)));
194
+ }
195
+ return results;
196
+ };
197
+ const getEnclosingScope = (node) => {
198
+ let className = null;
199
+ let methodName = null;
200
+ let curr = node.parent;
201
+ while (curr) {
202
+ if (curr.type === "method_declaration" || curr.type === "function_definition") {
203
+ const nameNode = curr.namedChildren.find((c) => c.type === "name");
204
+ if (nameNode) methodName = nameNode.text;
205
+ } else if (curr.type === "class_declaration" || curr.type === "interface_declaration" || curr.type === "trait_declaration" || curr.type === "enum_declaration") {
206
+ const nameNode = curr.namedChildren.find((c) => c.type === "name");
207
+ if (nameNode) className = nameNode.text;
208
+ break;
209
+ }
210
+ curr = curr.parent;
211
+ }
212
+ return { className, methodName };
213
+ };
214
+ const SCALAR_TYPES = /* @__PURE__ */ new Set([
215
+ "string",
216
+ "int",
217
+ "integer",
218
+ "float",
219
+ "double",
220
+ "bool",
221
+ "boolean",
222
+ "array",
223
+ "object",
224
+ "callable",
225
+ "iterable",
226
+ "void",
227
+ "null",
228
+ "never",
229
+ "mixed",
230
+ "self",
231
+ "static",
232
+ "parent",
233
+ "Collection",
234
+ "Builder",
235
+ "Request",
236
+ "Response"
237
+ ]);
238
+ const processTypeHints = (capturesList, edgeType) => {
239
+ for (const capture of capturesList) {
240
+ const startLine = capture.node.startPosition.row + 1;
241
+ const { className, methodName } = getEnclosingScope(capture.node);
242
+ const sourceSymbol = methodName || className;
243
+ const namedTypes = findNamedTypes(capture.node);
244
+ for (const typeNode of namedTypes) {
245
+ const typeText = typeNode.text;
246
+ if (SCALAR_TYPES.has(typeText)) continue;
247
+ if (typeText.startsWith("\\Illuminate\\") || typeText.startsWith("Illuminate\\")) continue;
248
+ const resolved = resolveToFqn(typeText);
249
+ references.push({
250
+ sourceSymbol,
251
+ targetName: resolved,
252
+ referenceType: edgeType,
253
+ startLine,
254
+ verifiability: "verified"
255
+ });
256
+ }
257
+ }
258
+ };
259
+ processTypeHints(refCaptures.get("ref.target_param") || [], "param_type");
260
+ processTypeHints(refCaptures.get("ref.target_return_type") || [], "return_type");
261
+ processTypeHints(refCaptures.get("ref.target_property") || [], "param_type");
262
+ const RELATIONSHIP_TYPES = {
263
+ hasOne: "one-to-one",
264
+ morphOne: "one-to-one",
265
+ hasMany: "one-to-many",
266
+ morphMany: "one-to-many",
267
+ hasOneThrough: "one-to-many",
268
+ hasManyThrough: "one-to-many",
269
+ belongsTo: "many-to-one",
270
+ morphTo: "many-to-one",
271
+ belongsToMany: "many-to-many",
272
+ morphToMany: "many-to-many",
273
+ morphedByMany: "many-to-many"
274
+ };
275
+ const cleanQuotes = (str) => {
276
+ return str.replace(/^['"]|['"]$/g, "").trim();
277
+ };
278
+ const getArgText = (argsNode, idx) => {
279
+ if (!argsNode || argsNode.type !== "arguments") return null;
280
+ const argNode = argsNode.namedChild(idx);
281
+ if (!argNode) return null;
282
+ const valNode = argNode.type === "argument" ? argNode.namedChild(0) || argNode : argNode;
283
+ if (valNode.type === "class_constant_access_expression") {
284
+ const classNode = valNode.namedChild(0);
285
+ if (classNode) return classNode.text;
286
+ }
287
+ return cleanQuotes(valNode.text);
288
+ };
289
+ const modelClasses = /* @__PURE__ */ new Set();
290
+ const controllerClasses = /* @__PURE__ */ new Set();
291
+ const serviceProviderClasses = /* @__PURE__ */ new Set();
292
+ const relationMethodCaptures = refCaptures.get("ref.relation_method_name") || [];
293
+ for (const cap of relationMethodCaptures) {
294
+ const methodName = cap.node.text;
295
+ if (!ELOQUENT_RELATIONSHIP_METHODS.has(methodName)) continue;
296
+ const parent = cap.node.parent;
297
+ if (!parent || parent.type !== "member_call_expression") continue;
298
+ const obj = parent.child(0);
299
+ if (!obj || obj.text !== "$this") continue;
300
+ const { className } = getEnclosingScope(cap.node);
301
+ if (!className) continue;
302
+ modelClasses.add(className);
303
+ const argsNode = parent.namedChildren.find((c) => c.type === "arguments");
304
+ if (!argsNode) continue;
305
+ const targetArgText = getArgText(argsNode, 0);
306
+ if (targetArgText) {
307
+ const targetFqn = resolveToFqn(targetArgText);
308
+ const startLine = cap.node.startPosition.row + 1;
309
+ const arg0 = argsNode.namedChild(0);
310
+ if (arg0) {
311
+ const valNode = arg0.type === "argument" ? arg0.namedChild(0) || arg0 : arg0;
312
+ const isClassConst = valNode ? valNode.type === "class_constant_access_expression" : false;
313
+ references.push({
314
+ sourceSymbol: className,
315
+ targetName: targetFqn,
316
+ referenceType: "relation",
317
+ startLine,
318
+ verifiability: isClassConst ? "verified" : "inferred",
319
+ metadata: {
320
+ relationshipMethod: methodName,
321
+ relationshipType: RELATIONSHIP_TYPES[methodName] || "one-to-many"
322
+ }
323
+ });
324
+ }
325
+ }
326
+ }
327
+ const CONTAINER_BINDING_METHODS = /* @__PURE__ */ new Set(["bind", "singleton", "scoped", "instance", "alias"]);
328
+ const bindingMethodCaptures = refCaptures.get("ref.binding_method_name") || [];
329
+ for (const cap of bindingMethodCaptures) {
330
+ const methodName = cap.node.text;
331
+ if (!CONTAINER_BINDING_METHODS.has(methodName)) continue;
332
+ const parent = cap.node.parent;
333
+ if (!parent || parent.type !== "member_call_expression") continue;
334
+ const obj = parent.child(0);
335
+ if (!obj) continue;
336
+ const objText = obj.text;
337
+ const isApp = objText.startsWith("$this->app") || objText === "$app" || objText.startsWith("app(");
338
+ if (!isApp) continue;
339
+ const { className, methodName: encMethod } = getEnclosingScope(cap.node);
340
+ if (className) {
341
+ serviceProviderClasses.add(className);
342
+ }
343
+ const argsNode = parent.namedChildren.find((c) => c.type === "arguments");
344
+ if (!argsNode) continue;
345
+ const abstractVal = getArgText(argsNode, 0);
346
+ if (abstractVal) {
347
+ const concreteVal = getArgText(argsNode, 1);
348
+ const abstractFqn = resolveToFqn(abstractVal);
349
+ const concreteFqn = concreteVal ? resolveToFqn(concreteVal) : null;
350
+ const startLine = cap.node.startPosition.row + 1;
351
+ const arg0 = argsNode.namedChild(0);
352
+ if (arg0) {
353
+ const valNode0 = arg0.type === "argument" ? arg0.namedChild(0) || arg0 : arg0;
354
+ const isAbstractClassConst = valNode0 ? valNode0.type === "class_constant_access_expression" : false;
355
+ references.push({
356
+ sourceSymbol: encMethod || "register",
357
+ targetName: abstractFqn,
358
+ referenceType: "binding",
359
+ startLine,
360
+ verifiability: isAbstractClassConst ? "verified" : "inferred",
361
+ metadata: {
362
+ bindingType: methodName,
363
+ concreteClass: concreteFqn,
364
+ serviceProviderPhase: encMethod === "boot" ? "boot" : "register"
365
+ }
366
+ });
367
+ }
368
+ }
369
+ }
370
+ const targetDispatchCaptures = refCaptures.get("ref.target_dispatch") || [];
371
+ for (const cap of targetDispatchCaptures) {
372
+ const targetRaw = cap.node.text;
373
+ const targetFqn = resolveToFqn(targetRaw);
374
+ const startLine = cap.node.startPosition.row + 1;
375
+ const { methodName } = getEnclosingScope(cap.node);
376
+ let curr = cap.node;
377
+ let fnName = "dispatch";
378
+ while (curr) {
379
+ if (curr.type === "function_call_expression") {
380
+ fnName = curr.childForFieldName("function")?.text || "dispatch";
381
+ break;
382
+ }
383
+ curr = curr.parent;
384
+ }
385
+ const dispatchedRole = fnName === "event" ? "event" : "job";
386
+ references.push({
387
+ sourceSymbol: methodName,
388
+ targetName: targetFqn,
389
+ referenceType: "dispatch",
390
+ startLine,
391
+ verifiability: "verified",
392
+ metadata: {
393
+ dispatchMethod: fnName,
394
+ dispatchedRole
395
+ }
396
+ });
397
+ }
398
+ const targetDispatchStaticCaptures = refCaptures.get("ref.target_dispatch_static") || [];
399
+ for (const cap of targetDispatchStaticCaptures) {
400
+ const targetRaw = cap.node.text;
401
+ const targetFqn = resolveToFqn(targetRaw);
402
+ const startLine = cap.node.startPosition.row + 1;
403
+ const { methodName } = getEnclosingScope(cap.node);
404
+ let curr = cap.node;
405
+ let methodCallName = "dispatch";
406
+ while (curr) {
407
+ if (curr.type === "scoped_call_expression") {
408
+ methodCallName = curr.childForFieldName("name")?.text || "dispatch";
409
+ break;
410
+ }
411
+ curr = curr.parent;
412
+ }
413
+ references.push({
414
+ sourceSymbol: methodName,
415
+ targetName: targetFqn,
416
+ referenceType: "dispatch",
417
+ startLine,
418
+ verifiability: "verified",
419
+ metadata: {
420
+ dispatchMethod: methodCallName,
421
+ dispatchedRole: "job"
422
+ }
423
+ });
424
+ }
425
+ const targetNotifyCaptures = refCaptures.get("ref.target_notify") || [];
426
+ for (const cap of targetNotifyCaptures) {
427
+ const targetRaw = cap.node.text;
428
+ const targetFqn = resolveToFqn(targetRaw);
429
+ const startLine = cap.node.startPosition.row + 1;
430
+ const { methodName } = getEnclosingScope(cap.node);
431
+ let curr = cap.node;
432
+ let sendMethod = "notify";
433
+ while (curr) {
434
+ if (curr.type === "member_call_expression") {
435
+ sendMethod = curr.childForFieldName("name")?.text || "notify";
436
+ break;
437
+ }
438
+ if (curr.type === "scoped_call_expression") {
439
+ const scope = curr.childForFieldName("scope")?.text;
440
+ const name = curr.childForFieldName("name")?.text;
441
+ if (scope === "Notification") {
442
+ sendMethod = `Notification::${name}`;
443
+ break;
444
+ }
445
+ }
446
+ curr = curr.parent;
447
+ }
448
+ references.push({
449
+ sourceSymbol: methodName,
450
+ targetName: targetFqn,
451
+ referenceType: "notify",
452
+ startLine,
453
+ verifiability: "verified",
454
+ metadata: {
455
+ sendMethod
456
+ }
457
+ });
458
+ }
459
+ const classExtends = /* @__PURE__ */ new Map();
460
+ const classImplements = /* @__PURE__ */ new Map();
461
+ const classesWithHandle = /* @__PURE__ */ new Set();
462
+ for (const sym of symbols) {
463
+ if (sym.kind === "method" && sym.name === "handle" && sym.scope) {
464
+ classesWithHandle.add(sym.scope);
465
+ }
466
+ }
467
+ const extendsCapList = refCaptures.get("ref.target_extends") || [];
468
+ for (const ext of extendsCapList) {
469
+ const { className } = getEnclosingScope(ext.node);
470
+ if (!className) continue;
471
+ const extText = ext.node.text;
472
+ classExtends.set(className, extText);
473
+ if (extText === "Model" || extText === "Authenticatable" || extText === "Pivot" || extText.endsWith("\\Model") || extText.endsWith("\\Authenticatable") || extText.endsWith("\\Pivot")) {
474
+ modelClasses.add(className);
475
+ }
476
+ if (extText === "Controller" || extText === "BaseController" || extText.endsWith("\\Controller") || extText.endsWith("\\BaseController")) {
477
+ controllerClasses.add(className);
478
+ }
479
+ if (extText === "ServiceProvider" || extText.endsWith("\\ServiceProvider")) {
480
+ serviceProviderClasses.add(className);
481
+ }
482
+ }
483
+ const implementsCapList = refCaptures.get("ref.target_implements") || [];
484
+ for (const imp of implementsCapList) {
485
+ const { className } = getEnclosingScope(imp.node);
486
+ if (!className) continue;
487
+ const impText = imp.node.text;
488
+ if (!classImplements.has(className)) {
489
+ classImplements.set(className, []);
490
+ }
491
+ classImplements.get(className).push(impText);
492
+ }
493
+ const eventClasses = /* @__PURE__ */ new Set();
494
+ const jobClasses = /* @__PURE__ */ new Set();
495
+ const notificationClasses = /* @__PURE__ */ new Set();
496
+ const listenerClasses = /* @__PURE__ */ new Set();
497
+ for (const sym of symbols) {
498
+ if (sym.kind === "class") {
499
+ const className = sym.name;
500
+ const extText = classExtends.get(className);
501
+ const imps = classImplements.get(className) || [];
502
+ const isEvent = filePath.includes("/Events/") || className.endsWith("Event") || imps.includes("ShouldBroadcast") || imps.includes("ShouldBroadcastNow");
503
+ const isJob = filePath.includes("/Jobs/") || className.endsWith("Job") || imps.includes("ShouldQueue") || imps.includes("ShouldBeUnique");
504
+ const isNotification = filePath.includes("/Notifications/") || className.endsWith("Notification") || extText === "Notification" || extText?.endsWith("\\Notification");
505
+ const isListener = filePath.includes("/Listeners/") || className.endsWith("Listener") || classesWithHandle.has(className) && (imps.includes("ShouldQueue") || filePath.includes("/Listeners/"));
506
+ if (isEvent) eventClasses.add(className);
507
+ else if (isJob) jobClasses.add(className);
508
+ else if (isNotification) notificationClasses.add(className);
509
+ else if (isListener) listenerClasses.add(className);
510
+ }
511
+ }
512
+ for (const sym of symbols) {
513
+ if (sym.kind === "class") {
514
+ if (modelClasses.has(sym.name)) {
515
+ sym.metadata.laravelRole = "model";
516
+ } else if (controllerClasses.has(sym.name)) {
517
+ sym.metadata.laravelRole = "controller";
518
+ } else if (serviceProviderClasses.has(sym.name)) {
519
+ sym.metadata.laravelRole = "service_provider";
520
+ } else if (eventClasses.has(sym.name)) {
521
+ sym.metadata.laravelRole = "event";
522
+ } else if (jobClasses.has(sym.name)) {
523
+ sym.metadata.laravelRole = "job";
524
+ } else if (notificationClasses.has(sym.name)) {
525
+ sym.metadata.laravelRole = "notification";
526
+ } else if (listenerClasses.has(sym.name)) {
527
+ sym.metadata.laravelRole = "listener";
528
+ }
529
+ }
530
+ }
531
+ const isRouteFile = filePath.replace(/\\/g, "/").includes("routes/");
532
+ if (isRouteFile) {
533
+ fileMetadata = { laravelRole: "route_file" };
534
+ }
535
+ let isMigration = filePath.includes("/migrations/");
536
+ let isSeeder = filePath.includes("/seeders/");
537
+ let isFactory = filePath.includes("/factories/");
538
+ for (const ext of extendsCapList) {
539
+ const extText = ext.node.text;
540
+ if (extText === "Migration" || extText === "Illuminate\\Database\\Migrations\\Migration" || extText === "\\Illuminate\\Database\\Migrations\\Migration") {
541
+ isMigration = true;
542
+ }
543
+ if (extText === "Seeder" || extText === "DatabaseSeeder") {
544
+ isSeeder = true;
545
+ }
546
+ if (extText === "Factory") {
547
+ isFactory = true;
548
+ }
549
+ }
550
+ let laravelRole = null;
551
+ if (isMigration) laravelRole = "migration";
552
+ else if (isSeeder) laravelRole = "seeder";
553
+ else if (isFactory) laravelRole = "factory";
554
+ if (laravelRole) {
555
+ for (const sym of symbols) {
556
+ sym.metadata.laravelRole = laravelRole;
557
+ }
558
+ references.length = 0;
559
+ }
560
+ } catch (e) {
561
+ errors.push({ message: e.message, line: 0 });
562
+ }
563
+ const specificTargets = /* @__PURE__ */ new Set();
564
+ for (const ref of references) {
565
+ if (ref.referenceType === "dispatch" || ref.referenceType === "notify") {
566
+ specificTargets.add(`${ref.targetName}:${ref.startLine}`);
567
+ }
568
+ }
569
+ const finalReferences = references.filter((ref) => {
570
+ if (ref.referenceType === "instantiation" || ref.referenceType === "call") {
571
+ if (specificTargets.has(`${ref.targetName}:${ref.startLine}`)) {
572
+ return false;
573
+ }
574
+ }
575
+ return true;
576
+ });
577
+ const mergedFacadeMap = {
578
+ ...LARAVEL_FACADE_MAP,
579
+ ...options?.facadeMap || {}
580
+ };
581
+ for (const ref of finalReferences) {
582
+ if (!ref.targetName || typeof ref.targetName !== "string") continue;
583
+ if (ref.referenceType === "call" || ref.referenceType === "instantiation") {
584
+ const shortName = ref.targetName.split("\\").at(-1) ?? ref.targetName;
585
+ if (shortName !== "Route") {
586
+ const resolved = mergedFacadeMap[shortName];
587
+ if (resolved) {
588
+ ref.targetName = resolved;
589
+ ref.verifiability = "inferred";
590
+ ref.metadata = {
591
+ ...ref.metadata,
592
+ facadeAlias: shortName,
593
+ isRawDbAccess: shortName === "DB"
594
+ };
595
+ }
596
+ }
597
+ }
598
+ }
599
+ return { symbols, references: finalReferences, errors, fileMetadata };
600
+ }
601
+ extractSignature(source, node, name, kind, startLine) {
602
+ const lines = source.split("\n");
603
+ const lineIdx = startLine - 1;
604
+ if (lineIdx >= lines.length) return name;
605
+ const line = lines[lineIdx];
606
+ const trimmed = line.trim();
607
+ if (kind === "method" || kind === "function") {
608
+ const match = trimmed.match(/function\s+\w+\s*\([^)]*\)/);
609
+ if (match) {
610
+ let sig = match[0];
611
+ const colonIdx = trimmed.indexOf(":", trimmed.indexOf(")"));
612
+ if (colonIdx !== -1) {
613
+ const returnType = trimmed.substring(colonIdx, trimmed.indexOf("{") !== -1 ? trimmed.indexOf("{") : void 0).trim();
614
+ if (returnType) sig += " " + returnType;
615
+ }
616
+ return sig;
617
+ }
618
+ }
619
+ if (kind === "class" || kind === "interface" || kind === "trait" || kind === "enum") {
620
+ const match = trimmed.match(/(class|interface|trait|enum)\s+\w+[^{]*/);
621
+ if (match) return match[0].trim();
622
+ }
623
+ return name;
624
+ }
625
+ cleanTargetName(name, refType) {
626
+ if (refType === "require") {
627
+ return name.replace(/^['"]|['"]$/g, "");
628
+ }
629
+ return name;
630
+ }
631
+ mapRefType(refType) {
632
+ const map = {
633
+ import: "import",
634
+ require: "require",
635
+ extends: "extends",
636
+ implements: "implements",
637
+ call: "call",
638
+ instantiation: "instantiation",
639
+ dispatch: "dispatch",
640
+ notify: "notify"
641
+ };
642
+ return map[refType] || "call";
643
+ }
644
+ }
645
+ export {
646
+ LARAVEL_FACADE_MAP,
647
+ PhpParser
648
+ };
@@ -0,0 +1,10 @@
1
+ import { GenericWasmParser } from '../generic-wasm-parser.js';
2
+ import { LanguageDefinition } from '../../languages/registry.js';
3
+ import '../parser-interface.js';
4
+ import '../../types.js';
5
+
6
+ declare class TypeScriptParser extends GenericWasmParser {
7
+ constructor(langDef: LanguageDefinition);
8
+ }
9
+
10
+ export { TypeScriptParser };
@@ -0,0 +1,9 @@
1
+ import { GenericWasmParser } from "../generic-wasm-parser.js";
2
+ class TypeScriptParser extends GenericWasmParser {
3
+ constructor(langDef) {
4
+ super(langDef);
5
+ }
6
+ }
7
+ export {
8
+ TypeScriptParser
9
+ };
@@ -0,0 +1,13 @@
1
+ import { LanguageParser } from '../parser-interface.js';
2
+ import { ParseResult } from '../../types.js';
3
+ import { LanguageDefinition } from '../../languages/registry.js';
4
+
5
+ declare class VueParser implements LanguageParser {
6
+ readonly languageName = "vue";
7
+ readonly supportedExtensions: string[];
8
+ private tsParser;
9
+ constructor(langDef: LanguageDefinition);
10
+ parse(filePath: string, source: string, options?: any): Promise<ParseResult>;
11
+ }
12
+
13
+ export { VueParser };