@saluzi/codegraph 0.1.0
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/dist/bin/codegraph.d.ts +25 -0
- package/dist/bin/node-version-check.d.ts +37 -0
- package/dist/bin/uninstall.d.ts +14 -0
- package/dist/context/formatter.d.ts +33 -0
- package/dist/context/formatter.js +244 -0
- package/dist/context/index.d.ts +117 -0
- package/dist/context/index.js +1050 -0
- package/dist/db/index.d.ts +101 -0
- package/dist/db/index.js +250 -0
- package/dist/db/migrations.d.ts +47 -0
- package/dist/db/migrations.js +131 -0
- package/dist/db/queries.d.ts +291 -0
- package/dist/db/queries.js +1349 -0
- package/dist/db/schema.sql +151 -0
- package/dist/db/sqlite-adapter.d.ts +49 -0
- package/dist/db/sqlite-adapter.js +141 -0
- package/dist/directory.d.ts +62 -0
- package/dist/directory.js +264 -0
- package/dist/errors.d.ts +149 -0
- package/dist/errors.js +219 -0
- package/dist/extraction/dfm-extractor.d.ts +31 -0
- package/dist/extraction/dfm-extractor.js +151 -0
- package/dist/extraction/grammars.d.ts +94 -0
- package/dist/extraction/grammars.js +357 -0
- package/dist/extraction/index.d.ts +148 -0
- package/dist/extraction/index.js +1286 -0
- package/dist/extraction/languages/c-cpp.d.ts +4 -0
- package/dist/extraction/languages/c-cpp.js +126 -0
- package/dist/extraction/languages/csharp.d.ts +3 -0
- package/dist/extraction/languages/csharp.js +72 -0
- package/dist/extraction/languages/dart.d.ts +3 -0
- package/dist/extraction/languages/dart.js +192 -0
- package/dist/extraction/languages/go.d.ts +3 -0
- package/dist/extraction/languages/go.js +58 -0
- package/dist/extraction/languages/index.d.ts +10 -0
- package/dist/extraction/languages/index.js +49 -0
- package/dist/extraction/languages/java.d.ts +3 -0
- package/dist/extraction/languages/java.js +64 -0
- package/dist/extraction/languages/javascript.d.ts +3 -0
- package/dist/extraction/languages/javascript.js +90 -0
- package/dist/extraction/languages/kotlin.d.ts +3 -0
- package/dist/extraction/languages/kotlin.js +253 -0
- package/dist/extraction/languages/lua.d.ts +3 -0
- package/dist/extraction/languages/lua.js +150 -0
- package/dist/extraction/languages/luau.d.ts +3 -0
- package/dist/extraction/languages/luau.js +37 -0
- package/dist/extraction/languages/pascal.d.ts +3 -0
- package/dist/extraction/languages/pascal.js +66 -0
- package/dist/extraction/languages/php.d.ts +3 -0
- package/dist/extraction/languages/php.js +107 -0
- package/dist/extraction/languages/python.d.ts +3 -0
- package/dist/extraction/languages/python.js +56 -0
- package/dist/extraction/languages/ruby.d.ts +3 -0
- package/dist/extraction/languages/ruby.js +114 -0
- package/dist/extraction/languages/rust.d.ts +3 -0
- package/dist/extraction/languages/rust.js +109 -0
- package/dist/extraction/languages/scala.d.ts +3 -0
- package/dist/extraction/languages/scala.js +139 -0
- package/dist/extraction/languages/swift.d.ts +3 -0
- package/dist/extraction/languages/swift.js +91 -0
- package/dist/extraction/languages/typescript.d.ts +3 -0
- package/dist/extraction/languages/typescript.js +129 -0
- package/dist/extraction/liquid-extractor.d.ts +52 -0
- package/dist/extraction/liquid-extractor.js +313 -0
- package/dist/extraction/parse-worker.d.ts +8 -0
- package/dist/extraction/parse-worker.js +94 -0
- package/dist/extraction/svelte-extractor.d.ts +56 -0
- package/dist/extraction/svelte-extractor.js +272 -0
- package/dist/extraction/tree-sitter-helpers.d.ts +39 -0
- package/dist/extraction/tree-sitter-helpers.js +103 -0
- package/dist/extraction/tree-sitter-types.d.ts +191 -0
- package/dist/extraction/tree-sitter-types.js +10 -0
- package/dist/extraction/tree-sitter.d.ts +238 -0
- package/dist/extraction/tree-sitter.js +2430 -0
- package/dist/extraction/vue-extractor.d.ts +36 -0
- package/dist/extraction/vue-extractor.js +163 -0
- package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +46 -0
- package/dist/extraction/wasm-runtime-flags.js +105 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.js +13 -0
- package/dist/graph/queries.d.ts +109 -0
- package/dist/graph/queries.js +366 -0
- package/dist/graph/traversal.d.ts +137 -0
- package/dist/graph/traversal.js +528 -0
- package/dist/index.d.ts +509 -0
- package/dist/index.js +800 -0
- package/dist/installer/claude-md-template.d.ts +19 -0
- package/dist/installer/config-writer.d.ts +29 -0
- package/dist/installer/index.d.ts +140 -0
- package/dist/installer/instructions-template.d.ts +30 -0
- package/dist/installer/targets/claude.d.ts +55 -0
- package/dist/installer/targets/codex.d.ts +18 -0
- package/dist/installer/targets/cursor.d.ts +35 -0
- package/dist/installer/targets/hermes.d.ts +18 -0
- package/dist/installer/targets/opencode.d.ts +30 -0
- package/dist/installer/targets/registry.d.ts +38 -0
- package/dist/installer/targets/shared.d.ts +92 -0
- package/dist/installer/targets/toml.d.ts +64 -0
- package/dist/installer/targets/types.d.ts +122 -0
- package/dist/mcp/index.d.ts +98 -0
- package/dist/mcp/server-instructions.d.ts +20 -0
- package/dist/mcp/tools.d.ts +269 -0
- package/dist/mcp/transport.d.ts +117 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts +20 -0
- package/dist/resolution/frameworks/cargo-workspace.js +225 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/csharp.js +213 -0
- package/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/dist/resolution/frameworks/drupal.js +335 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/express.js +225 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/go.js +158 -0
- package/dist/resolution/frameworks/index.d.ts +52 -0
- package/dist/resolution/frameworks/index.js +137 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/java.js +177 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/laravel.js +248 -0
- package/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/dist/resolution/frameworks/nestjs.js +374 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/python.js +278 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/react.js +272 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.js +198 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/rust.js +207 -0
- package/dist/resolution/frameworks/svelte.d.ts +9 -0
- package/dist/resolution/frameworks/svelte.js +249 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/swift.js +376 -0
- package/dist/resolution/frameworks/vue.d.ts +9 -0
- package/dist/resolution/frameworks/vue.js +306 -0
- package/dist/resolution/import-resolver.d.ts +61 -0
- package/dist/resolution/import-resolver.js +663 -0
- package/dist/resolution/index.d.ts +118 -0
- package/dist/resolution/index.js +744 -0
- package/dist/resolution/lru-cache.d.ts +24 -0
- package/dist/resolution/lru-cache.js +62 -0
- package/dist/resolution/name-matcher.d.ts +50 -0
- package/dist/resolution/name-matcher.js +384 -0
- package/dist/resolution/path-aliases.d.ts +72 -0
- package/dist/resolution/path-aliases.js +238 -0
- package/dist/resolution/strip-comments.d.ts +40 -0
- package/dist/resolution/strip-comments.js +441 -0
- package/dist/resolution/types.d.ts +181 -0
- package/dist/resolution/types.js +8 -0
- package/dist/search/query-parser.d.ts +61 -0
- package/dist/search/query-parser.js +177 -0
- package/dist/search/query-utils.d.ts +59 -0
- package/dist/search/query-utils.js +383 -0
- package/dist/sync/git-hooks.d.ts +54 -0
- package/dist/sync/git-hooks.js +223 -0
- package/dist/sync/index.d.ts +25 -0
- package/dist/sync/index.js +28 -0
- package/dist/sync/watch-policy.d.ts +51 -0
- package/dist/sync/watch-policy.js +124 -0
- package/dist/sync/watcher.d.ts +83 -0
- package/dist/sync/watcher.js +192 -0
- package/dist/types.d.ts +433 -0
- package/dist/types.js +75 -0
- package/dist/ui/glyphs.d.ts +42 -0
- package/dist/ui/shimmer-progress.d.ts +11 -0
- package/dist/ui/shimmer-worker.d.ts +2 -0
- package/dist/ui/types.d.ts +20 -0
- package/dist/utils.d.ts +231 -0
- package/dist/utils.js +549 -0
- package/package.json +24 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ruby Framework Resolver
|
|
4
|
+
*
|
|
5
|
+
* Handles Ruby on Rails patterns.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.railsResolver = void 0;
|
|
9
|
+
const strip_comments_1 = require("../strip-comments");
|
|
10
|
+
exports.railsResolver = {
|
|
11
|
+
name: 'rails',
|
|
12
|
+
languages: ['ruby'],
|
|
13
|
+
detect(context) {
|
|
14
|
+
// Check for Gemfile with rails
|
|
15
|
+
const gemfile = context.readFile('Gemfile');
|
|
16
|
+
if (gemfile && gemfile.includes("'rails'")) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
// Check for config/application.rb (Rails signature)
|
|
20
|
+
if (context.fileExists('config/application.rb')) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// Check for typical Rails directory structure
|
|
24
|
+
return (context.fileExists('app/controllers/application_controller.rb') ||
|
|
25
|
+
context.fileExists('config/routes.rb'));
|
|
26
|
+
},
|
|
27
|
+
resolve(ref, context) {
|
|
28
|
+
// Pattern 1: Model references (ActiveRecord)
|
|
29
|
+
if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
|
|
30
|
+
const result = resolveModel(ref.referenceName, context);
|
|
31
|
+
if (result) {
|
|
32
|
+
return {
|
|
33
|
+
original: ref,
|
|
34
|
+
targetNodeId: result,
|
|
35
|
+
confidence: 0.8,
|
|
36
|
+
resolvedBy: 'framework',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Pattern 2: Controller references
|
|
41
|
+
if (ref.referenceName.endsWith('Controller')) {
|
|
42
|
+
const result = resolveController(ref.referenceName, context);
|
|
43
|
+
if (result) {
|
|
44
|
+
return {
|
|
45
|
+
original: ref,
|
|
46
|
+
targetNodeId: result,
|
|
47
|
+
confidence: 0.85,
|
|
48
|
+
resolvedBy: 'framework',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Pattern 3: Helper references
|
|
53
|
+
if (ref.referenceName.endsWith('Helper')) {
|
|
54
|
+
const result = resolveHelper(ref.referenceName, context);
|
|
55
|
+
if (result) {
|
|
56
|
+
return {
|
|
57
|
+
original: ref,
|
|
58
|
+
targetNodeId: result,
|
|
59
|
+
confidence: 0.8,
|
|
60
|
+
resolvedBy: 'framework',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Pattern 4: Service/Job references
|
|
65
|
+
if (ref.referenceName.endsWith('Service') || ref.referenceName.endsWith('Job')) {
|
|
66
|
+
const result = resolveService(ref.referenceName, context);
|
|
67
|
+
if (result) {
|
|
68
|
+
return {
|
|
69
|
+
original: ref,
|
|
70
|
+
targetNodeId: result,
|
|
71
|
+
confidence: 0.8,
|
|
72
|
+
resolvedBy: 'framework',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
},
|
|
78
|
+
extract(filePath, content) {
|
|
79
|
+
if (!filePath.endsWith('.rb'))
|
|
80
|
+
return { nodes: [], references: [] };
|
|
81
|
+
const nodes = [];
|
|
82
|
+
const references = [];
|
|
83
|
+
const now = Date.now();
|
|
84
|
+
const safe = (0, strip_comments_1.stripCommentsForRegex)(content, 'ruby');
|
|
85
|
+
// get/post/put/patch/delete/match '/path', to: 'controller#action'
|
|
86
|
+
// Also: get '/path' => 'controller#action'
|
|
87
|
+
const routeRegex = /\b(get|post|put|patch|delete|match)\s+['"]([^'"]+)['"]\s*(?:,\s*to:\s*|=>\s*)['"]([^#'"]+)#([^'"]+)['"]/g;
|
|
88
|
+
let match;
|
|
89
|
+
while ((match = routeRegex.exec(safe)) !== null) {
|
|
90
|
+
const [, method, routePath, _controller, action] = match;
|
|
91
|
+
const line = safe.slice(0, match.index).split('\n').length;
|
|
92
|
+
const upper = method.toUpperCase();
|
|
93
|
+
const routeNode = {
|
|
94
|
+
id: `route:${filePath}:${line}:${upper}:${routePath}`,
|
|
95
|
+
kind: 'route',
|
|
96
|
+
name: `${upper} ${routePath}`,
|
|
97
|
+
qualifiedName: `${filePath}::route:${routePath}`,
|
|
98
|
+
filePath,
|
|
99
|
+
startLine: line,
|
|
100
|
+
endLine: line,
|
|
101
|
+
startColumn: 0,
|
|
102
|
+
endColumn: match[0].length,
|
|
103
|
+
language: 'ruby',
|
|
104
|
+
updatedAt: now,
|
|
105
|
+
};
|
|
106
|
+
nodes.push(routeNode);
|
|
107
|
+
references.push({
|
|
108
|
+
fromNodeId: routeNode.id,
|
|
109
|
+
referenceName: action,
|
|
110
|
+
referenceKind: 'references',
|
|
111
|
+
line,
|
|
112
|
+
column: 0,
|
|
113
|
+
filePath,
|
|
114
|
+
language: 'ruby',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return { nodes, references };
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
// Helper functions
|
|
121
|
+
function resolveModel(name, context) {
|
|
122
|
+
// Try direct file path lookup first (Rails convention: CamelCase -> snake_case.rb)
|
|
123
|
+
const snakeName = name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
|
|
124
|
+
const possiblePaths = [
|
|
125
|
+
`app/models/${snakeName}.rb`,
|
|
126
|
+
`app/models/concerns/${snakeName}.rb`,
|
|
127
|
+
];
|
|
128
|
+
for (const modelPath of possiblePaths) {
|
|
129
|
+
if (context.fileExists(modelPath)) {
|
|
130
|
+
const nodes = context.getNodesInFile(modelPath);
|
|
131
|
+
const modelNode = nodes.find((n) => n.kind === 'class' && n.name === name);
|
|
132
|
+
if (modelNode) {
|
|
133
|
+
return modelNode.id;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Fall back to name-based lookup
|
|
138
|
+
const candidates = context.getNodesByName(name);
|
|
139
|
+
const modelNode = candidates.find((n) => n.kind === 'class' && n.filePath.includes('app/models/'));
|
|
140
|
+
if (modelNode)
|
|
141
|
+
return modelNode.id;
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function resolveController(name, context) {
|
|
145
|
+
// Try direct file path lookup first
|
|
146
|
+
const snakeName = name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
|
|
147
|
+
const possiblePaths = [
|
|
148
|
+
`app/controllers/${snakeName}.rb`,
|
|
149
|
+
`app/controllers/api/${snakeName}.rb`,
|
|
150
|
+
`app/controllers/api/v1/${snakeName}.rb`,
|
|
151
|
+
];
|
|
152
|
+
for (const controllerPath of possiblePaths) {
|
|
153
|
+
if (context.fileExists(controllerPath)) {
|
|
154
|
+
const nodes = context.getNodesInFile(controllerPath);
|
|
155
|
+
const controllerNode = nodes.find((n) => n.kind === 'class' && n.name === name);
|
|
156
|
+
if (controllerNode) {
|
|
157
|
+
return controllerNode.id;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Fall back to name-based lookup
|
|
162
|
+
const candidates = context.getNodesByName(name);
|
|
163
|
+
const controllerNode = candidates.find((n) => n.kind === 'class' && n.filePath.includes('controllers/'));
|
|
164
|
+
if (controllerNode)
|
|
165
|
+
return controllerNode.id;
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
function resolveHelper(name, context) {
|
|
169
|
+
const snakeName = name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
|
|
170
|
+
const helperPath = `app/helpers/${snakeName}.rb`;
|
|
171
|
+
if (context.fileExists(helperPath)) {
|
|
172
|
+
const nodes = context.getNodesInFile(helperPath);
|
|
173
|
+
const helperNode = nodes.find((n) => n.kind === 'module' && n.name === name);
|
|
174
|
+
if (helperNode) {
|
|
175
|
+
return helperNode.id;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
function resolveService(name, context) {
|
|
181
|
+
const snakeName = name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
|
|
182
|
+
const possiblePaths = [
|
|
183
|
+
`app/services/${snakeName}.rb`,
|
|
184
|
+
`app/jobs/${snakeName}.rb`,
|
|
185
|
+
`app/workers/${snakeName}.rb`,
|
|
186
|
+
];
|
|
187
|
+
for (const servicePath of possiblePaths) {
|
|
188
|
+
if (context.fileExists(servicePath)) {
|
|
189
|
+
const nodes = context.getNodesInFile(servicePath);
|
|
190
|
+
const serviceNode = nodes.find((n) => n.kind === 'class' && n.name === name);
|
|
191
|
+
if (serviceNode) {
|
|
192
|
+
return serviceNode.id;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=ruby.js.map
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rust Framework Resolver
|
|
4
|
+
*
|
|
5
|
+
* Handles Actix-web, Rocket, Axum, and common Rust patterns.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.rustResolver = void 0;
|
|
9
|
+
const strip_comments_1 = require("../strip-comments");
|
|
10
|
+
const cargo_workspace_1 = require("./cargo-workspace");
|
|
11
|
+
const cargoWorkspaceMapCache = new WeakMap();
|
|
12
|
+
function getCachedCargoWorkspaceCrateMap(context) {
|
|
13
|
+
const cached = cargoWorkspaceMapCache.get(context);
|
|
14
|
+
if (cached)
|
|
15
|
+
return cached;
|
|
16
|
+
const map = (0, cargo_workspace_1.getCargoWorkspaceCrateMap)(context);
|
|
17
|
+
cargoWorkspaceMapCache.set(context, map);
|
|
18
|
+
return map;
|
|
19
|
+
}
|
|
20
|
+
exports.rustResolver = {
|
|
21
|
+
name: 'rust',
|
|
22
|
+
languages: ['rust'],
|
|
23
|
+
detect(context) {
|
|
24
|
+
// Check for Cargo.toml (Rust project signature)
|
|
25
|
+
return context.fileExists('Cargo.toml');
|
|
26
|
+
},
|
|
27
|
+
resolve(ref, context) {
|
|
28
|
+
// Pattern 1: Handler references
|
|
29
|
+
if (ref.referenceName.endsWith('_handler') || ref.referenceName.startsWith('handle_')) {
|
|
30
|
+
const result = resolveByNameAndKind(ref.referenceName, FUNCTION_KINDS, HANDLER_DIRS, context);
|
|
31
|
+
if (result) {
|
|
32
|
+
return {
|
|
33
|
+
original: ref,
|
|
34
|
+
targetNodeId: result,
|
|
35
|
+
confidence: 0.8,
|
|
36
|
+
resolvedBy: 'framework',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Pattern 2: Service/Repository trait implementations
|
|
41
|
+
if (ref.referenceName.endsWith('Service') || ref.referenceName.endsWith('Repository')) {
|
|
42
|
+
const result = resolveByNameAndKind(ref.referenceName, SERVICE_KINDS, SERVICE_DIRS, context);
|
|
43
|
+
if (result) {
|
|
44
|
+
return {
|
|
45
|
+
original: ref,
|
|
46
|
+
targetNodeId: result,
|
|
47
|
+
confidence: 0.8,
|
|
48
|
+
resolvedBy: 'framework',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Pattern 3: Struct references (PascalCase)
|
|
53
|
+
if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
|
|
54
|
+
const result = resolveByNameAndKind(ref.referenceName, STRUCT_KINDS, MODEL_DIRS, context);
|
|
55
|
+
if (result) {
|
|
56
|
+
return {
|
|
57
|
+
original: ref,
|
|
58
|
+
targetNodeId: result,
|
|
59
|
+
confidence: 0.7,
|
|
60
|
+
resolvedBy: 'framework',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Pattern 4: Module references
|
|
65
|
+
if (/^[a-z_]+$/.test(ref.referenceName)) {
|
|
66
|
+
const result = resolveModule(ref.referenceName, context);
|
|
67
|
+
if (result) {
|
|
68
|
+
// Workspace-manifest hits are an exact crate-name -> crate-root
|
|
69
|
+
// mapping straight from Cargo.toml, so we trust them above
|
|
70
|
+
// name-matcher self-file matches (which otherwise win at 0.7
|
|
71
|
+
// because every file containing `use foo::...` has its own
|
|
72
|
+
// import node named `foo`).
|
|
73
|
+
return {
|
|
74
|
+
original: ref,
|
|
75
|
+
targetNodeId: result.targetId,
|
|
76
|
+
confidence: result.fromWorkspace ? 0.95 : 0.6,
|
|
77
|
+
resolvedBy: 'framework',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
},
|
|
83
|
+
extract(filePath, content) {
|
|
84
|
+
if (!filePath.endsWith('.rs'))
|
|
85
|
+
return { nodes: [], references: [] };
|
|
86
|
+
const nodes = [];
|
|
87
|
+
const references = [];
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
const safe = (0, strip_comments_1.stripCommentsForRegex)(content, 'rust');
|
|
90
|
+
// Actix-web / Rocket attribute: #[get("/path")] fn handler(..)
|
|
91
|
+
// Capture the method, path, and the fn identifier that follows.
|
|
92
|
+
const attrRegex = /#\[(get|post|put|patch|delete|head|options)\s*\(\s*["']([^"']+)["'][^\]]*\)\]/g;
|
|
93
|
+
let match;
|
|
94
|
+
while ((match = attrRegex.exec(safe)) !== null) {
|
|
95
|
+
const [, method, routePath] = match;
|
|
96
|
+
const line = safe.slice(0, match.index).split('\n').length;
|
|
97
|
+
const upper = method.toUpperCase();
|
|
98
|
+
const routeNode = {
|
|
99
|
+
id: `route:${filePath}:${line}:${upper}:${routePath}`,
|
|
100
|
+
kind: 'route',
|
|
101
|
+
name: `${upper} ${routePath}`,
|
|
102
|
+
qualifiedName: `${filePath}::route:${routePath}`,
|
|
103
|
+
filePath,
|
|
104
|
+
startLine: line,
|
|
105
|
+
endLine: line,
|
|
106
|
+
startColumn: 0,
|
|
107
|
+
endColumn: match[0].length,
|
|
108
|
+
language: 'rust',
|
|
109
|
+
updatedAt: now,
|
|
110
|
+
};
|
|
111
|
+
nodes.push(routeNode);
|
|
112
|
+
const tail = safe.slice(match.index + match[0].length);
|
|
113
|
+
const fnMatch = tail.match(/\n\s*(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/);
|
|
114
|
+
if (fnMatch) {
|
|
115
|
+
references.push({
|
|
116
|
+
fromNodeId: routeNode.id,
|
|
117
|
+
referenceName: fnMatch[1],
|
|
118
|
+
referenceKind: 'references',
|
|
119
|
+
line,
|
|
120
|
+
column: 0,
|
|
121
|
+
filePath,
|
|
122
|
+
language: 'rust',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Axum: .route("/path", get(handler))
|
|
127
|
+
const axumRegex = /\.route\s*\(\s*"([^"]+)"\s*,\s*(get|post|put|patch|delete)\s*\(\s*(\w+)/g;
|
|
128
|
+
while ((match = axumRegex.exec(safe)) !== null) {
|
|
129
|
+
const [, routePath, method, handler] = match;
|
|
130
|
+
const line = safe.slice(0, match.index).split('\n').length;
|
|
131
|
+
const upper = method.toUpperCase();
|
|
132
|
+
const routeNode = {
|
|
133
|
+
id: `route:${filePath}:${line}:${upper}:${routePath}`,
|
|
134
|
+
kind: 'route',
|
|
135
|
+
name: `${upper} ${routePath}`,
|
|
136
|
+
qualifiedName: `${filePath}::route:${routePath}`,
|
|
137
|
+
filePath,
|
|
138
|
+
startLine: line,
|
|
139
|
+
endLine: line,
|
|
140
|
+
startColumn: 0,
|
|
141
|
+
endColumn: match[0].length,
|
|
142
|
+
language: 'rust',
|
|
143
|
+
updatedAt: now,
|
|
144
|
+
};
|
|
145
|
+
nodes.push(routeNode);
|
|
146
|
+
references.push({
|
|
147
|
+
fromNodeId: routeNode.id,
|
|
148
|
+
referenceName: handler,
|
|
149
|
+
referenceKind: 'references',
|
|
150
|
+
line,
|
|
151
|
+
column: 0,
|
|
152
|
+
filePath,
|
|
153
|
+
language: 'rust',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return { nodes, references };
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
// Directory patterns
|
|
160
|
+
const HANDLER_DIRS = ['/handlers/', '/handler/', '/api/', '/routes/', '/controllers/'];
|
|
161
|
+
const SERVICE_DIRS = ['/services/', '/service/', '/repository/', '/domain/'];
|
|
162
|
+
const MODEL_DIRS = ['/models/', '/model/', '/entities/', '/entity/', '/domain/', '/types/'];
|
|
163
|
+
const FUNCTION_KINDS = new Set(['function']);
|
|
164
|
+
const SERVICE_KINDS = new Set(['struct', 'trait']);
|
|
165
|
+
const STRUCT_KINDS = new Set(['struct']);
|
|
166
|
+
/**
|
|
167
|
+
* Resolve a symbol by name using indexed queries instead of scanning all files.
|
|
168
|
+
*/
|
|
169
|
+
function resolveByNameAndKind(name, kinds, preferredDirPatterns, context) {
|
|
170
|
+
const candidates = context.getNodesByName(name);
|
|
171
|
+
if (candidates.length === 0)
|
|
172
|
+
return null;
|
|
173
|
+
const kindFiltered = candidates.filter((n) => kinds.has(n.kind));
|
|
174
|
+
if (kindFiltered.length === 0)
|
|
175
|
+
return null;
|
|
176
|
+
// Prefer candidates in framework-conventional directories
|
|
177
|
+
const preferred = kindFiltered.filter((n) => preferredDirPatterns.some((d) => n.filePath.includes(d)));
|
|
178
|
+
if (preferred.length > 0)
|
|
179
|
+
return preferred[0].id;
|
|
180
|
+
// Fall back to any match
|
|
181
|
+
return kindFiltered[0].id;
|
|
182
|
+
}
|
|
183
|
+
function resolveModule(name, context) {
|
|
184
|
+
// Rust modules can be either mod.rs in a directory or name.rs
|
|
185
|
+
const localPaths = [`src/${name}.rs`, `src/${name}/mod.rs`];
|
|
186
|
+
const workspaceCrates = getCachedCargoWorkspaceCrateMap(context);
|
|
187
|
+
const cratePath = workspaceCrates.get(name);
|
|
188
|
+
const workspacePaths = cratePath
|
|
189
|
+
? [`${cratePath}/src/lib.rs`, `${cratePath}/src/main.rs`]
|
|
190
|
+
: [];
|
|
191
|
+
const candidates = [
|
|
192
|
+
...localPaths.map((path) => ({ path, fromWorkspace: false })),
|
|
193
|
+
...workspacePaths.map((path) => ({ path, fromWorkspace: true })),
|
|
194
|
+
];
|
|
195
|
+
for (const { path: modPath, fromWorkspace } of candidates) {
|
|
196
|
+
if (!context.fileExists(modPath))
|
|
197
|
+
continue;
|
|
198
|
+
const nodes = context.getNodesInFile(modPath);
|
|
199
|
+
const modNode = nodes.find((n) => n.kind === 'module');
|
|
200
|
+
if (modNode)
|
|
201
|
+
return { targetId: modNode.id, fromWorkspace };
|
|
202
|
+
if (nodes.length > 0)
|
|
203
|
+
return { targetId: nodes[0].id, fromWorkspace };
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=rust.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte / SvelteKit Framework Resolver
|
|
3
|
+
*
|
|
4
|
+
* Handles Svelte component references, Svelte 5 runes,
|
|
5
|
+
* store auto-subscriptions, and SvelteKit route/module patterns.
|
|
6
|
+
*/
|
|
7
|
+
import { FrameworkResolver } from '../types'
|
|
8
|
+
export declare const svelteResolver: FrameworkResolver
|
|
9
|
+
//# sourceMappingURL=svelte.d.ts.map
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Svelte / SvelteKit Framework Resolver
|
|
4
|
+
*
|
|
5
|
+
* Handles Svelte component references, Svelte 5 runes,
|
|
6
|
+
* store auto-subscriptions, and SvelteKit route/module patterns.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.svelteResolver = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* Svelte 5 runes — compiler-provided, not user code
|
|
12
|
+
*/
|
|
13
|
+
const SVELTE_RUNES = new Set([
|
|
14
|
+
'$state',
|
|
15
|
+
'$state.raw',
|
|
16
|
+
'$state.snapshot',
|
|
17
|
+
'$derived',
|
|
18
|
+
'$derived.by',
|
|
19
|
+
'$effect',
|
|
20
|
+
'$effect.pre',
|
|
21
|
+
'$effect.root',
|
|
22
|
+
'$effect.tracking',
|
|
23
|
+
'$props',
|
|
24
|
+
'$bindable',
|
|
25
|
+
'$inspect',
|
|
26
|
+
'$host',
|
|
27
|
+
]);
|
|
28
|
+
/**
|
|
29
|
+
* SvelteKit framework-provided module prefixes
|
|
30
|
+
*/
|
|
31
|
+
const SVELTEKIT_MODULE_PREFIXES = [
|
|
32
|
+
'$app/navigation',
|
|
33
|
+
'$app/stores',
|
|
34
|
+
'$app/environment',
|
|
35
|
+
'$app/forms',
|
|
36
|
+
'$app/paths',
|
|
37
|
+
'$env/static/private',
|
|
38
|
+
'$env/static/public',
|
|
39
|
+
'$env/dynamic/private',
|
|
40
|
+
'$env/dynamic/public',
|
|
41
|
+
];
|
|
42
|
+
exports.svelteResolver = {
|
|
43
|
+
name: 'svelte',
|
|
44
|
+
languages: ['svelte'],
|
|
45
|
+
detect(context) {
|
|
46
|
+
// Check for svelte or @sveltejs/kit in package.json
|
|
47
|
+
const packageJson = context.readFile('package.json');
|
|
48
|
+
if (packageJson) {
|
|
49
|
+
try {
|
|
50
|
+
const pkg = JSON.parse(packageJson);
|
|
51
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
52
|
+
if (deps.svelte || deps['@sveltejs/kit']) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Invalid JSON
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Check for .svelte files in project
|
|
61
|
+
const allFiles = context.getAllFiles();
|
|
62
|
+
return allFiles.some((f) => f.endsWith('.svelte'));
|
|
63
|
+
},
|
|
64
|
+
resolve(ref, context) {
|
|
65
|
+
// Pattern 1: Svelte runes ($state, $derived, $effect, etc.)
|
|
66
|
+
if (isRuneReference(ref.referenceName)) {
|
|
67
|
+
// Runes are compiler-provided — return a high-confidence "framework" resolution
|
|
68
|
+
// so CodeGraph doesn't waste time searching for user-defined symbols.
|
|
69
|
+
// We use the fromNodeId as targetNodeId since runes don't have real targets.
|
|
70
|
+
return {
|
|
71
|
+
original: ref,
|
|
72
|
+
targetNodeId: ref.fromNodeId,
|
|
73
|
+
confidence: 1.0,
|
|
74
|
+
resolvedBy: 'framework',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Pattern 2: Store auto-subscriptions ($storeName)
|
|
78
|
+
if (ref.referenceName.startsWith('$') && !ref.referenceName.startsWith('$$')) {
|
|
79
|
+
const storeName = ref.referenceName.substring(1);
|
|
80
|
+
const storeNode = context.getNodesByName(storeName).find((n) => n.kind === 'variable' || n.kind === 'constant');
|
|
81
|
+
if (storeNode) {
|
|
82
|
+
return {
|
|
83
|
+
original: ref,
|
|
84
|
+
targetNodeId: storeNode.id,
|
|
85
|
+
confidence: 0.85,
|
|
86
|
+
resolvedBy: 'framework',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Pattern 3: SvelteKit module imports ($app/*, $env/*, $lib/*)
|
|
91
|
+
if (ref.referenceKind === 'imports' && ref.referenceName.startsWith('$')) {
|
|
92
|
+
// $lib/* resolves to src/lib/* — try to find the target file
|
|
93
|
+
if (ref.referenceName.startsWith('$lib/')) {
|
|
94
|
+
const libPath = ref.referenceName.replace('$lib/', 'src/lib/');
|
|
95
|
+
// Try common extensions
|
|
96
|
+
for (const ext of ['', '.ts', '.js', '.svelte', '/index.ts', '/index.js']) {
|
|
97
|
+
const fullPath = libPath + ext;
|
|
98
|
+
if (context.fileExists(fullPath)) {
|
|
99
|
+
const nodes = context.getNodesInFile(fullPath);
|
|
100
|
+
if (nodes.length > 0) {
|
|
101
|
+
return {
|
|
102
|
+
original: ref,
|
|
103
|
+
targetNodeId: nodes[0].id,
|
|
104
|
+
confidence: 0.9,
|
|
105
|
+
resolvedBy: 'framework',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// $app/* and $env/* are framework-provided
|
|
112
|
+
if (SVELTEKIT_MODULE_PREFIXES.some((prefix) => ref.referenceName.startsWith(prefix))) {
|
|
113
|
+
return {
|
|
114
|
+
original: ref,
|
|
115
|
+
targetNodeId: ref.fromNodeId,
|
|
116
|
+
confidence: 1.0,
|
|
117
|
+
resolvedBy: 'framework',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Pattern 4: Component references (PascalCase) — resolve to .svelte files
|
|
122
|
+
if (isPascalCase(ref.referenceName) && ref.referenceKind === 'calls') {
|
|
123
|
+
const result = resolveComponent(ref.referenceName, ref.filePath, context);
|
|
124
|
+
if (result) {
|
|
125
|
+
return {
|
|
126
|
+
original: ref,
|
|
127
|
+
targetNodeId: result,
|
|
128
|
+
confidence: 0.8,
|
|
129
|
+
resolvedBy: 'framework',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
},
|
|
135
|
+
extract(filePath, _content) {
|
|
136
|
+
const nodes = [];
|
|
137
|
+
const now = Date.now();
|
|
138
|
+
// Detect SvelteKit route files
|
|
139
|
+
const fileName = filePath.split(/[/\\]/).pop() || '';
|
|
140
|
+
const routeMatch = getSvelteKitRouteInfo(fileName);
|
|
141
|
+
if (routeMatch) {
|
|
142
|
+
// Extract route path from directory structure
|
|
143
|
+
// e.g., src/routes/blog/[slug]/+page.svelte -> /blog/:slug
|
|
144
|
+
const routePath = filePathToSvelteKitRoute(filePath);
|
|
145
|
+
if (routePath) {
|
|
146
|
+
nodes.push({
|
|
147
|
+
id: `route:${filePath}:${routePath}:1`,
|
|
148
|
+
kind: 'route',
|
|
149
|
+
name: routePath,
|
|
150
|
+
qualifiedName: `${filePath}::route:${routePath}`,
|
|
151
|
+
filePath,
|
|
152
|
+
startLine: 1,
|
|
153
|
+
endLine: 1,
|
|
154
|
+
startColumn: 0,
|
|
155
|
+
endColumn: 0,
|
|
156
|
+
language: filePath.endsWith('.svelte') ? 'svelte' : 'typescript',
|
|
157
|
+
updatedAt: now,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { nodes, references: [] };
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Check if a reference name is a Svelte rune
|
|
166
|
+
*/
|
|
167
|
+
function isRuneReference(name) {
|
|
168
|
+
// Direct match (e.g. $state, $derived)
|
|
169
|
+
if (SVELTE_RUNES.has(name))
|
|
170
|
+
return true;
|
|
171
|
+
// Rune method calls come through as the base rune name
|
|
172
|
+
// e.g. $state.raw -> the call is to "$state" with ".raw" accessed as property
|
|
173
|
+
// Check if it's a base rune that has sub-methods
|
|
174
|
+
if (name === '$state' || name === '$derived' || name === '$effect')
|
|
175
|
+
return true;
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if string is PascalCase
|
|
180
|
+
*/
|
|
181
|
+
function isPascalCase(str) {
|
|
182
|
+
return /^[A-Z][a-zA-Z0-9]*$/.test(str);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Resolve a Svelte component reference using name-based lookup
|
|
186
|
+
*/
|
|
187
|
+
function resolveComponent(name, fromFile, context) {
|
|
188
|
+
// Look for component nodes by name
|
|
189
|
+
const candidates = context.getNodesByName(name);
|
|
190
|
+
const components = candidates.filter((n) => n.kind === 'component');
|
|
191
|
+
if (components.length === 0)
|
|
192
|
+
return null;
|
|
193
|
+
// Prefer same directory
|
|
194
|
+
const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));
|
|
195
|
+
const sameDir = components.filter((n) => n.filePath.startsWith(fromDir));
|
|
196
|
+
if (sameDir.length > 0)
|
|
197
|
+
return sameDir[0].id;
|
|
198
|
+
return components[0].id;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* SvelteKit route file patterns
|
|
202
|
+
*/
|
|
203
|
+
const SVELTEKIT_ROUTE_FILES = {
|
|
204
|
+
'+page.svelte': 'page',
|
|
205
|
+
'+page.ts': 'page-load',
|
|
206
|
+
'+page.js': 'page-load',
|
|
207
|
+
'+page.server.ts': 'page-server-load',
|
|
208
|
+
'+page.server.js': 'page-server-load',
|
|
209
|
+
'+layout.svelte': 'layout',
|
|
210
|
+
'+layout.ts': 'layout-load',
|
|
211
|
+
'+layout.js': 'layout-load',
|
|
212
|
+
'+layout.server.ts': 'layout-server-load',
|
|
213
|
+
'+layout.server.js': 'layout-server-load',
|
|
214
|
+
'+server.ts': 'api-endpoint',
|
|
215
|
+
'+server.js': 'api-endpoint',
|
|
216
|
+
'+error.svelte': 'error-page',
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Check if filename is a SvelteKit route file
|
|
220
|
+
*/
|
|
221
|
+
function getSvelteKitRouteInfo(fileName) {
|
|
222
|
+
return SVELTEKIT_ROUTE_FILES[fileName] || null;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Convert a file path to a SvelteKit route path
|
|
226
|
+
*/
|
|
227
|
+
function filePathToSvelteKitRoute(filePath) {
|
|
228
|
+
// Normalize to forward slashes
|
|
229
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
230
|
+
// Find the routes directory
|
|
231
|
+
const routesIndex = normalized.indexOf('/routes/');
|
|
232
|
+
if (routesIndex === -1)
|
|
233
|
+
return null;
|
|
234
|
+
// Extract the path after routes/
|
|
235
|
+
const afterRoutes = normalized.substring(routesIndex + '/routes/'.length);
|
|
236
|
+
// Remove the file name
|
|
237
|
+
const lastSlash = afterRoutes.lastIndexOf('/');
|
|
238
|
+
const dirPath = lastSlash === -1 ? '' : afterRoutes.substring(0, lastSlash);
|
|
239
|
+
// Convert SvelteKit param syntax [param] to :param
|
|
240
|
+
let route = '/' + dirPath
|
|
241
|
+
.replace(/\[\.\.\.([^\]]+)\]/g, '*$1') // [...rest] -> *rest
|
|
242
|
+
.replace(/\[{2}([^\]]+)\]{2}/g, ':$1?') // [[optional]] -> :optional?
|
|
243
|
+
.replace(/\[([^\]]+)\]/g, ':$1'); // [param] -> :param
|
|
244
|
+
if (route === '/')
|
|
245
|
+
return '/';
|
|
246
|
+
// Remove trailing slash
|
|
247
|
+
return route.replace(/\/$/, '');
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=svelte.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swift Framework Resolver
|
|
3
|
+
*
|
|
4
|
+
* Handles SwiftUI, UIKit, and Vapor (server-side Swift) patterns.
|
|
5
|
+
*/
|
|
6
|
+
import { FrameworkResolver } from '../types'
|
|
7
|
+
export declare const swiftUIResolver: FrameworkResolver
|
|
8
|
+
export declare const uikitResolver: FrameworkResolver
|
|
9
|
+
export declare const vaporResolver: FrameworkResolver
|
|
10
|
+
//# sourceMappingURL=swift.d.ts.map
|