kirograph 0.12.2 → 0.13.1
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 +197 -87
- package/dist/architecture/layers/index.js +9 -1
- package/dist/architecture/layers/index.js.map +2 -2
- package/dist/architecture/layers/ocaml.js +105 -0
- package/dist/architecture/layers/ocaml.js.map +7 -0
- package/dist/architecture/layers/scala.js +120 -0
- package/dist/architecture/layers/scala.js.map +7 -0
- package/dist/architecture/layers/solidity.js +105 -0
- package/dist/architecture/layers/solidity.js.map +7 -0
- package/dist/architecture/layers/vue.js +111 -0
- package/dist/architecture/layers/vue.js.map +7 -0
- package/dist/architecture/manifest/elm.js +91 -0
- package/dist/architecture/manifest/elm.js.map +7 -0
- package/dist/architecture/manifest/index.js +13 -2
- package/dist/architecture/manifest/index.js.map +2 -2
- package/dist/architecture/manifest/ocaml.js +166 -0
- package/dist/architecture/manifest/ocaml.js.map +7 -0
- package/dist/architecture/manifest/scala.js +117 -0
- package/dist/architecture/manifest/scala.js.map +7 -0
- package/dist/bin/commands/caveman.js +12 -0
- package/dist/bin/commands/caveman.js.map +2 -2
- package/dist/bin/commands/help.js +6 -4
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +8 -2
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/serve.js +2 -2
- package/dist/bin/commands/serve.js.map +2 -2
- package/dist/bin/commands/uninit.js +65 -41
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/installer/cli-agent.js +5 -25
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.js +154 -0
- package/dist/bin/installer/common.js.map +7 -0
- package/dist/bin/installer/hooks.js +21 -1
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.js +99 -86
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +60 -0
- package/dist/bin/installer/instructions.js.map +7 -0
- package/dist/bin/installer/mcp.js +6 -36
- package/dist/bin/installer/mcp.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +79 -0
- package/dist/bin/installer/targets/claude.js.map +7 -0
- package/dist/bin/installer/targets/codex.js +77 -0
- package/dist/bin/installer/targets/codex.js.map +7 -0
- package/dist/bin/installer/targets/index.js +57 -0
- package/dist/bin/installer/targets/index.js.map +7 -0
- package/dist/bin/installer/targets/kiro.js +61 -0
- package/dist/bin/installer/targets/kiro.js.map +7 -0
- package/dist/bin/kirograph.js +1 -1
- package/dist/extraction/extractor.js +65 -2
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.js +22 -0
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/languages.js +39 -1
- package/dist/extraction/languages.js.map +2 -2
- package/dist/extraction/wasm/tree-sitter-hcl.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scss.wasm +0 -0
- package/dist/frameworks/amplify.js +175 -0
- package/dist/frameworks/amplify.js.map +7 -0
- package/dist/frameworks/angular.js +132 -0
- package/dist/frameworks/angular.js.map +7 -0
- package/dist/frameworks/ansible.js +151 -0
- package/dist/frameworks/ansible.js.map +7 -0
- package/dist/frameworks/cloudformation.js +148 -0
- package/dist/frameworks/cloudformation.js.map +7 -0
- package/dist/frameworks/docker.js +149 -0
- package/dist/frameworks/docker.js.map +7 -0
- package/dist/frameworks/iac.js +401 -0
- package/dist/frameworks/iac.js.map +7 -0
- package/dist/frameworks/index.js +81 -3
- package/dist/frameworks/index.js.map +3 -3
- package/dist/frameworks/kubernetes.js +176 -0
- package/dist/frameworks/kubernetes.js.map +7 -0
- package/dist/frameworks/pulumi.js +93 -0
- package/dist/frameworks/pulumi.js.map +7 -0
- package/dist/frameworks/scala.js +124 -0
- package/dist/frameworks/scala.js.map +7 -0
- package/dist/frameworks/solidity.js +93 -0
- package/dist/frameworks/solidity.js.map +7 -0
- package/dist/frameworks/terraform.js +278 -0
- package/dist/frameworks/terraform.js.map +7 -0
- package/dist/frameworks/vue.js +163 -0
- package/dist/frameworks/vue.js.map +7 -0
- package/dist/graph/queries.js +1 -1
- package/dist/graph/queries.js.map +1 -1
- package/dist/mcp/tool-names.js +48 -0
- package/dist/mcp/tool-names.js.map +7 -0
- package/dist/mcp/tools.js +3 -0
- package/dist/mcp/tools.js.map +2 -2
- package/dist/types.js.map +2 -2
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/frameworks/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Framework Resolver Registry\n *\n * Mirrors CodeGraph src/resolution/frameworks/index.ts\n * Manages framework-specific resolvers and detection.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logDebug, logWarn } from '../errors';\nimport { updateConfig } from '../config';\nimport type { Node } from '../types';\nimport type { GraphDatabase } from '../db/database';\nimport type { FrameworkResolver, ResolutionContext } from './types';\n\n// Re-export types\nexport type { FrameworkResolver, ResolutionContext, UnresolvedRef, ResolvedRef } from './types';\n\n// Re-export individual resolvers\nexport { reactResolver } from './react';\nexport { svelteResolver } from './svelte';\nexport { expressResolver } from './express';\nexport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nexport { railsResolver } from './ruby';\nexport { springResolver } from './java';\nexport { goResolver } from './go';\nexport { rustResolver } from './rust';\nexport { aspnetResolver } from './csharp';\nexport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nexport { laravelResolver, FACADE_MAPPINGS } from './laravel';\nexport { phoenixResolver } from './elixir';\n\n// \u2500\u2500 Registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nimport { reactResolver } from './react';\nimport { svelteResolver } from './svelte';\nimport { expressResolver } from './express';\nimport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nimport { railsResolver } from './ruby';\nimport { springResolver } from './java';\nimport { goResolver } from './go';\nimport { rustResolver } from './rust';\nimport { aspnetResolver } from './csharp';\nimport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nimport { laravelResolver } from './laravel';\nimport { phoenixResolver } from './elixir';\n\nconst FRAMEWORK_RESOLVERS: FrameworkResolver[] = [\n // PHP\n laravelResolver,\n // JavaScript / TypeScript\n expressResolver,\n reactResolver,\n svelteResolver,\n // Python\n djangoResolver,\n flaskResolver,\n fastapiResolver,\n // Ruby\n railsResolver,\n // Java\n springResolver,\n // Go\n goResolver,\n // Rust\n rustResolver,\n // C#\n aspnetResolver,\n // Swift\n swiftUIResolver,\n uikitResolver,\n vaporResolver,\n // Elixir\n phoenixResolver,\n];\n\nexport function getAllFrameworkResolvers(): FrameworkResolver[] {\n return FRAMEWORK_RESOLVERS;\n}\n\nexport function getFrameworkResolver(name: string): FrameworkResolver | undefined {\n return FRAMEWORK_RESOLVERS.find(r => r.name === name);\n}\n\nexport function registerFrameworkResolver(resolver: FrameworkResolver): void {\n const index = FRAMEWORK_RESOLVERS.findIndex(r => r.name === resolver.name);\n if (index !== -1) FRAMEWORK_RESOLVERS.splice(index, 1);\n FRAMEWORK_RESOLVERS.push(resolver);\n}\n\n// \u2500\u2500 Context builder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction buildResolutionContext(projectRoot: string, db: GraphDatabase): ResolutionContext {\n const fileCache = new Map<string, string | null>();\n const nodeCache = new Map<string, Node[]>();\n\n return {\n getNodesInFile(filePath: string): Node[] {\n if (!nodeCache.has(filePath)) {\n nodeCache.set(filePath, db.getNodesByFile(filePath));\n }\n return nodeCache.get(filePath)!;\n },\n getNodesByName(name: string): Node[] {\n return db.findNodesByExactName(name);\n },\n getNodesByKind(kind: Node['kind']): Node[] {\n return db.getNodesByKind(kind);\n },\n fileExists(filePath: string): boolean {\n return fs.existsSync(path.join(projectRoot, filePath));\n },\n readFile(filePath: string): string | null {\n if (fileCache.has(filePath)) return fileCache.get(filePath)!;\n try {\n const content = fs.readFileSync(path.join(projectRoot, filePath), 'utf8');\n fileCache.set(filePath, content);\n return content;\n } catch {\n fileCache.set(filePath, null);\n return null;\n }\n },\n getProjectRoot(): string {\n return projectRoot;\n },\n getAllFiles(): string[] {\n return db.getAllFiles().map(f => f.path);\n },\n };\n}\n\n// \u2500\u2500 detectFrameworks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Detect which frameworks are used in a project.\n * Mirrors CodeGraph detectFrameworks() \u2014 uses ResolutionContext for file access.\n * Records detected framework names in config via updateConfig().\n */\nexport async function detectFrameworks(projectRoot: string, db?: GraphDatabase): Promise<FrameworkResolver[]> {\n // If no db provided, fall back to package.json-only detection\n if (!db) {\n return detectFromPackageJson(projectRoot);\n }\n\n const context = buildResolutionContext(projectRoot, db);\n const detected: FrameworkResolver[] = [];\n\n for (const resolver of FRAMEWORK_RESOLVERS) {\n try {\n if (resolver.detect(context)) {\n logDebug(`detectFrameworks: detected ${resolver.name}`);\n detected.push(resolver);\n }\n } catch (err) {\n logWarn(`detectFrameworks: error detecting ${resolver.name}`, { error: String(err) });\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n\n/**\n * Lightweight fallback: detect frameworks from package.json only (no DB needed).\n */\nasync function detectFromPackageJson(projectRoot: string): Promise<FrameworkResolver[]> {\n const pkgPath = path.join(projectRoot, 'package.json');\n if (!fs.existsSync(pkgPath)) return [];\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as Record<string, unknown>;\n } catch {\n return [];\n }\n\n const deps: Record<string, string> = {\n ...((pkg.dependencies as Record<string, string>) ?? {}),\n ...((pkg.devDependencies as Record<string, string>) ?? {}),\n };\n\n const PACKAGE_TO_RESOLVER: Record<string, string> = {\n react: 'react', next: 'react', 'react-native': 'react',\n svelte: 'svelte', '@sveltejs/kit': 'svelte',\n express: 'express', fastify: 'express', koa: 'express',\n };\n\n const detectedNames = new Set<string>();\n const detected: FrameworkResolver[] = [];\n\n for (const [pkg, resolverName] of Object.entries(PACKAGE_TO_RESOLVER)) {\n if (Object.prototype.hasOwnProperty.call(deps, pkg) && !detectedNames.has(resolverName)) {\n const resolver = getFrameworkResolver(resolverName);\n if (resolver) {\n detectedNames.add(resolverName);\n detected.push(resolver);\n }\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_react", "import_svelte", "import_express", "import_python", "import_ruby", "import_java", "import_go", "import_rust", "import_csharp", "import_swift", "import_laravel", "import_elixir", "pkg"]
|
|
4
|
+
"sourcesContent": ["/**\n * Framework Resolver Registry\n *\n * Mirrors CodeGraph src/resolution/frameworks/index.ts\n * Manages framework-specific resolvers and detection.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logDebug, logWarn } from '../errors';\nimport { updateConfig } from '../config';\nimport type { Node } from '../types';\nimport type { GraphDatabase } from '../db/database';\nimport type { FrameworkResolver, ResolutionContext } from './types';\n\n// Re-export types\nexport type { FrameworkResolver, ResolutionContext, UnresolvedRef, ResolvedRef } from './types';\n\n// Re-export individual resolvers\nexport { reactResolver } from './react';\nexport { svelteResolver } from './svelte';\nexport { expressResolver } from './express';\nexport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nexport { railsResolver } from './ruby';\nexport { springResolver } from './java';\nexport { goResolver } from './go';\nexport { rustResolver } from './rust';\nexport { aspnetResolver } from './csharp';\nexport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nexport { laravelResolver, FACADE_MAPPINGS } from './laravel';\nexport { phoenixResolver } from './elixir';\nexport { playResolver } from './scala';\nexport { nuxtResolver, vueResolver } from './vue';\nexport { solidityResolver } from './solidity';\nexport { sstResolver, cdkResolver, serverlessResolver, samResolver } from './iac';\nexport { terraformResolver } from './terraform';\nexport { pulumiResolver } from './pulumi';\nexport { cloudformationResolver } from './cloudformation';\nexport { kubernetesResolver } from './kubernetes';\nexport { dockerComposeResolver } from './docker';\nexport { ansibleResolver } from './ansible';\nexport { angularResolver } from './angular';\nexport { amplifyResolver } from './amplify';\n\n// \u2500\u2500 Registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nimport { reactResolver } from './react';\nimport { svelteResolver } from './svelte';\nimport { expressResolver } from './express';\nimport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nimport { railsResolver } from './ruby';\nimport { springResolver } from './java';\nimport { goResolver } from './go';\nimport { rustResolver } from './rust';\nimport { aspnetResolver } from './csharp';\nimport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nimport { laravelResolver } from './laravel';\nimport { phoenixResolver } from './elixir';\nimport { playResolver } from './scala';\nimport { nuxtResolver, vueResolver } from './vue';\nimport { solidityResolver } from './solidity';\nimport { sstResolver, cdkResolver, serverlessResolver, samResolver } from './iac';\nimport { terraformResolver } from './terraform';\nimport { pulumiResolver } from './pulumi';\nimport { cloudformationResolver } from './cloudformation';\nimport { kubernetesResolver } from './kubernetes';\nimport { dockerComposeResolver } from './docker';\nimport { ansibleResolver } from './ansible';\nimport { angularResolver } from './angular';\nimport { amplifyResolver } from './amplify';\n\nconst FRAMEWORK_RESOLVERS: FrameworkResolver[] = [\n // PHP\n laravelResolver,\n // JavaScript / TypeScript\n expressResolver,\n reactResolver,\n svelteResolver,\n angularResolver,\n // Vue / Nuxt\n nuxtResolver,\n vueResolver,\n // Python\n djangoResolver,\n flaskResolver,\n fastapiResolver,\n // Ruby\n railsResolver,\n // Java\n springResolver,\n // Go\n goResolver,\n // Rust\n rustResolver,\n // C#\n aspnetResolver,\n // Swift\n swiftUIResolver,\n uikitResolver,\n vaporResolver,\n // Elixir\n phoenixResolver,\n // Scala\n playResolver,\n // Solidity\n solidityResolver,\n // Infrastructure as Code\n sstResolver,\n cdkResolver,\n serverlessResolver,\n samResolver,\n terraformResolver,\n pulumiResolver,\n cloudformationResolver,\n amplifyResolver,\n // Containers & Orchestration\n kubernetesResolver,\n dockerComposeResolver,\n // Configuration Management\n ansibleResolver,\n];\n\nexport function getAllFrameworkResolvers(): FrameworkResolver[] {\n return FRAMEWORK_RESOLVERS;\n}\n\nexport function getFrameworkResolver(name: string): FrameworkResolver | undefined {\n return FRAMEWORK_RESOLVERS.find(r => r.name === name);\n}\n\nexport function registerFrameworkResolver(resolver: FrameworkResolver): void {\n const index = FRAMEWORK_RESOLVERS.findIndex(r => r.name === resolver.name);\n if (index !== -1) FRAMEWORK_RESOLVERS.splice(index, 1);\n FRAMEWORK_RESOLVERS.push(resolver);\n}\n\n// \u2500\u2500 Context builder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction buildResolutionContext(projectRoot: string, db: GraphDatabase): ResolutionContext {\n const fileCache = new Map<string, string | null>();\n const nodeCache = new Map<string, Node[]>();\n\n return {\n getNodesInFile(filePath: string): Node[] {\n if (!nodeCache.has(filePath)) {\n nodeCache.set(filePath, db.getNodesByFile(filePath));\n }\n return nodeCache.get(filePath)!;\n },\n getNodesByName(name: string): Node[] {\n return db.findNodesByExactName(name);\n },\n getNodesByKind(kind: Node['kind']): Node[] {\n return db.getNodesByKind(kind);\n },\n fileExists(filePath: string): boolean {\n return fs.existsSync(path.join(projectRoot, filePath));\n },\n readFile(filePath: string): string | null {\n if (fileCache.has(filePath)) return fileCache.get(filePath)!;\n try {\n const content = fs.readFileSync(path.join(projectRoot, filePath), 'utf8');\n fileCache.set(filePath, content);\n return content;\n } catch {\n fileCache.set(filePath, null);\n return null;\n }\n },\n getProjectRoot(): string {\n return projectRoot;\n },\n getAllFiles(): string[] {\n return db.getAllFiles().map(f => f.path);\n },\n };\n}\n\n// \u2500\u2500 detectFrameworks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Detect which frameworks are used in a project.\n * Mirrors CodeGraph detectFrameworks() \u2014 uses ResolutionContext for file access.\n * Records detected framework names in config via updateConfig().\n */\nexport async function detectFrameworks(projectRoot: string, db?: GraphDatabase): Promise<FrameworkResolver[]> {\n // If no db provided, fall back to package.json-only detection\n if (!db) {\n return detectFromPackageJson(projectRoot);\n }\n\n const context = buildResolutionContext(projectRoot, db);\n const detected: FrameworkResolver[] = [];\n\n for (const resolver of FRAMEWORK_RESOLVERS) {\n try {\n if (resolver.detect(context)) {\n logDebug(`detectFrameworks: detected ${resolver.name}`);\n detected.push(resolver);\n }\n } catch (err) {\n logWarn(`detectFrameworks: error detecting ${resolver.name}`, { error: String(err) });\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n\n/**\n * Lightweight fallback: detect frameworks from package.json only (no DB needed).\n */\nasync function detectFromPackageJson(projectRoot: string): Promise<FrameworkResolver[]> {\n const pkgPath = path.join(projectRoot, 'package.json');\n if (!fs.existsSync(pkgPath)) return [];\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as Record<string, unknown>;\n } catch {\n return [];\n }\n\n const deps: Record<string, string> = {\n ...((pkg.dependencies as Record<string, string>) ?? {}),\n ...((pkg.devDependencies as Record<string, string>) ?? {}),\n };\n\n const PACKAGE_TO_RESOLVER: Record<string, string> = {\n react: 'react', next: 'react', 'react-native': 'react',\n svelte: 'svelte', '@sveltejs/kit': 'svelte',\n express: 'express', fastify: 'express', koa: 'express',\n };\n\n const detectedNames = new Set<string>();\n const detected: FrameworkResolver[] = [];\n\n for (const [pkg, resolverName] of Object.entries(PACKAGE_TO_RESOLVER)) {\n if (Object.prototype.hasOwnProperty.call(deps, pkg) && !detectedNames.has(resolverName)) {\n const resolver = getFrameworkResolver(resolverName);\n if (resolver) {\n detectedNames.add(resolverName);\n detected.push(resolver);\n }\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_react", "import_svelte", "import_express", "import_python", "import_ruby", "import_java", "import_go", "import_rust", "import_csharp", "import_swift", "import_laravel", "import_elixir", "import_scala", "import_vue", "import_solidity", "import_iac", "import_terraform", "import_pulumi", "import_cloudformation", "import_kubernetes", "import_docker", "import_ansible", "import_angular", "import_amplify", "pkg"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var kubernetes_exports = {};
|
|
20
|
+
__export(kubernetes_exports, {
|
|
21
|
+
kubernetesResolver: () => kubernetesResolver
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(kubernetes_exports);
|
|
24
|
+
const kubernetesResolver = {
|
|
25
|
+
name: "kubernetes",
|
|
26
|
+
detect(context) {
|
|
27
|
+
if (context.fileExists("Chart.yaml") || context.fileExists("Chart.yml")) return true;
|
|
28
|
+
if (context.getAllFiles().some(
|
|
29
|
+
(f) => (f.includes("k8s/") || f.includes("kubernetes/") || f.includes("manifests/") || f.includes("deploy/")) && (f.endsWith(".yaml") || f.endsWith(".yml"))
|
|
30
|
+
)) {
|
|
31
|
+
for (const file of context.getAllFiles()) {
|
|
32
|
+
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
33
|
+
if (!file.includes("k8s/") && !file.includes("kubernetes/") && !file.includes("manifests/") && !file.includes("deploy/")) continue;
|
|
34
|
+
const content = context.readFile(file);
|
|
35
|
+
if (content && content.includes("apiVersion:") && content.includes("kind:")) return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
},
|
|
40
|
+
resolve(ref, context) {
|
|
41
|
+
if (/^[a-z][a-z0-9-]*$/.test(ref.referenceName)) {
|
|
42
|
+
const id = resolveK8sResource(ref.referenceName, context);
|
|
43
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
},
|
|
47
|
+
extractNodes(filePath, content) {
|
|
48
|
+
const nodes = [];
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
if (!content.includes("apiVersion:") || !content.includes("kind:")) return nodes;
|
|
51
|
+
const documents = content.split(/^---\s*$/m);
|
|
52
|
+
for (const doc of documents) {
|
|
53
|
+
if (!doc.trim()) continue;
|
|
54
|
+
const kindMatch = doc.match(/^kind:\s*(\w+)/m);
|
|
55
|
+
const nameMatch = doc.match(/^\s+name:\s*["']?([^\s"']+)/m);
|
|
56
|
+
const apiVersionMatch = doc.match(/^apiVersion:\s*(\S+)/m);
|
|
57
|
+
if (!kindMatch || !nameMatch) continue;
|
|
58
|
+
const kind = kindMatch[1];
|
|
59
|
+
const name = nameMatch[1];
|
|
60
|
+
const apiVersion = apiVersionMatch ? apiVersionMatch[1] : "";
|
|
61
|
+
const docStart = content.indexOf(doc);
|
|
62
|
+
const line = content.slice(0, docStart).split("\n").length;
|
|
63
|
+
const nodeKind = mapK8sKind(kind);
|
|
64
|
+
if (!nodeKind) continue;
|
|
65
|
+
nodes.push({
|
|
66
|
+
id: `k8s:${filePath}:${kind}:${name}:${line}`,
|
|
67
|
+
kind: nodeKind,
|
|
68
|
+
name: `${kind}/${name}`,
|
|
69
|
+
qualifiedName: `${filePath}::${kind}.${name}`,
|
|
70
|
+
filePath,
|
|
71
|
+
startLine: line,
|
|
72
|
+
endLine: line + doc.split("\n").length - 1,
|
|
73
|
+
startColumn: 0,
|
|
74
|
+
endColumn: 0,
|
|
75
|
+
language: "yaml",
|
|
76
|
+
updatedAt: now,
|
|
77
|
+
signature: `${kind} (${apiVersion})`
|
|
78
|
+
});
|
|
79
|
+
if (kind === "Ingress") {
|
|
80
|
+
const pathPattern = /path:\s*["']?([^\s"']+)["']?/g;
|
|
81
|
+
let pathMatch;
|
|
82
|
+
while ((pathMatch = pathPattern.exec(doc)) !== null) {
|
|
83
|
+
const pathLine = content.slice(0, docStart).split("\n").length + doc.slice(0, pathMatch.index).split("\n").length - 1;
|
|
84
|
+
const routePath = pathMatch[1];
|
|
85
|
+
nodes.push({
|
|
86
|
+
id: `route:${filePath}:INGRESS:${routePath}:${pathLine}`,
|
|
87
|
+
kind: "route",
|
|
88
|
+
name: `INGRESS ${routePath}`,
|
|
89
|
+
qualifiedName: `${filePath}::ingress.${routePath}`,
|
|
90
|
+
filePath,
|
|
91
|
+
startLine: pathLine,
|
|
92
|
+
endLine: pathLine,
|
|
93
|
+
startColumn: 0,
|
|
94
|
+
endColumn: pathMatch[0].length,
|
|
95
|
+
language: "yaml",
|
|
96
|
+
updatedAt: now
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (kind === "Service") {
|
|
101
|
+
const portPattern = /port:\s*(\d+)/g;
|
|
102
|
+
let portMatch;
|
|
103
|
+
while ((portMatch = portPattern.exec(doc)) !== null) {
|
|
104
|
+
const portLine = content.slice(0, docStart).split("\n").length + doc.slice(0, portMatch.index).split("\n").length - 1;
|
|
105
|
+
const port = portMatch[1];
|
|
106
|
+
nodes.push({
|
|
107
|
+
id: `route:${filePath}:SVC:${name}:${port}:${portLine}`,
|
|
108
|
+
kind: "route",
|
|
109
|
+
name: `${name}:${port}`,
|
|
110
|
+
qualifiedName: `${filePath}::svc.${name}.${port}`,
|
|
111
|
+
filePath,
|
|
112
|
+
startLine: portLine,
|
|
113
|
+
endLine: portLine,
|
|
114
|
+
startColumn: 0,
|
|
115
|
+
endColumn: portMatch[0].length,
|
|
116
|
+
language: "yaml",
|
|
117
|
+
updatedAt: now
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return nodes;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
function mapK8sKind(kind) {
|
|
126
|
+
switch (kind) {
|
|
127
|
+
case "Deployment":
|
|
128
|
+
case "StatefulSet":
|
|
129
|
+
case "DaemonSet":
|
|
130
|
+
case "Job":
|
|
131
|
+
case "CronJob":
|
|
132
|
+
return "component";
|
|
133
|
+
case "Service":
|
|
134
|
+
case "Ingress":
|
|
135
|
+
case "Gateway":
|
|
136
|
+
case "VirtualService":
|
|
137
|
+
return "route";
|
|
138
|
+
case "ConfigMap":
|
|
139
|
+
case "Secret":
|
|
140
|
+
return "variable";
|
|
141
|
+
case "Namespace":
|
|
142
|
+
return "namespace";
|
|
143
|
+
case "ServiceAccount":
|
|
144
|
+
case "Role":
|
|
145
|
+
case "ClusterRole":
|
|
146
|
+
case "RoleBinding":
|
|
147
|
+
case "ClusterRoleBinding":
|
|
148
|
+
return "interface";
|
|
149
|
+
case "PersistentVolumeClaim":
|
|
150
|
+
case "PersistentVolume":
|
|
151
|
+
case "StorageClass":
|
|
152
|
+
return "variable";
|
|
153
|
+
case "HorizontalPodAutoscaler":
|
|
154
|
+
case "NetworkPolicy":
|
|
155
|
+
return "variable";
|
|
156
|
+
case "CustomResourceDefinition":
|
|
157
|
+
return "type_alias";
|
|
158
|
+
default:
|
|
159
|
+
return "class";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function resolveK8sResource(name, context) {
|
|
163
|
+
for (const file of context.getAllFiles()) {
|
|
164
|
+
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
165
|
+
const node = context.getNodesInFile(file).find(
|
|
166
|
+
(n) => n.name.endsWith(`/${name}`) || n.name === name
|
|
167
|
+
);
|
|
168
|
+
if (node) return node.id;
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
173
|
+
0 && (module.exports = {
|
|
174
|
+
kubernetesResolver
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=kubernetes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/frameworks/kubernetes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Kubernetes / Helm Framework Resolver\n *\n * Extracts Deployments, Services, ConfigMaps, Ingress routes from K8s manifests.\n * Detects both raw manifests and Helm charts.\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const kubernetesResolver: FrameworkResolver = {\n name: 'kubernetes',\n detect(context: ResolutionContext): boolean {\n // Helm chart\n if (context.fileExists('Chart.yaml') || context.fileExists('Chart.yml')) return true;\n // K8s manifests directory\n if (context.getAllFiles().some(f =>\n (f.includes('k8s/') || f.includes('kubernetes/') || f.includes('manifests/') || f.includes('deploy/')) &&\n (f.endsWith('.yaml') || f.endsWith('.yml'))\n )) {\n // Verify at least one file has apiVersion\n for (const file of context.getAllFiles()) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n if (!file.includes('k8s/') && !file.includes('kubernetes/') && !file.includes('manifests/') && !file.includes('deploy/')) continue;\n const content = context.readFile(file);\n if (content && content.includes('apiVersion:') && content.includes('kind:')) return true;\n }\n }\n return false;\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve K8s resource name references (e.g., service names, configmap names)\n if (/^[a-z][a-z0-9-]*$/.test(ref.referenceName)) {\n const id = resolveK8sResource(ref.referenceName, context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n if (!content.includes('apiVersion:') || !content.includes('kind:')) return nodes;\n\n // Split multi-document YAML\n const documents = content.split(/^---\\s*$/m);\n\n for (const doc of documents) {\n if (!doc.trim()) continue;\n\n const kindMatch = doc.match(/^kind:\\s*(\\w+)/m);\n const nameMatch = doc.match(/^\\s+name:\\s*[\"']?([^\\s\"']+)/m);\n const apiVersionMatch = doc.match(/^apiVersion:\\s*(\\S+)/m);\n\n if (!kindMatch || !nameMatch) continue;\n\n const kind = kindMatch[1]!;\n const name = nameMatch[1]!;\n const apiVersion = apiVersionMatch ? apiVersionMatch[1]! : '';\n const docStart = content.indexOf(doc);\n const line = content.slice(0, docStart).split('\\n').length;\n\n // Map K8s kinds to graph node kinds\n const nodeKind = mapK8sKind(kind);\n if (!nodeKind) continue;\n\n nodes.push({\n id: `k8s:${filePath}:${kind}:${name}:${line}`,\n kind: nodeKind,\n name: `${kind}/${name}`,\n qualifiedName: `${filePath}::${kind}.${name}`,\n filePath, startLine: line, endLine: line + doc.split('\\n').length - 1,\n startColumn: 0, endColumn: 0,\n language: 'yaml', updatedAt: now,\n signature: `${kind} (${apiVersion})`,\n });\n\n // Extract Ingress routes\n if (kind === 'Ingress') {\n const pathPattern = /path:\\s*[\"']?([^\\s\"']+)[\"']?/g;\n let pathMatch: RegExpExecArray | null;\n while ((pathMatch = pathPattern.exec(doc)) !== null) {\n const pathLine = content.slice(0, docStart).split('\\n').length +\n doc.slice(0, pathMatch.index).split('\\n').length - 1;\n const routePath = pathMatch[1]!;\n nodes.push({\n id: `route:${filePath}:INGRESS:${routePath}:${pathLine}`,\n kind: 'route',\n name: `INGRESS ${routePath}`,\n qualifiedName: `${filePath}::ingress.${routePath}`,\n filePath, startLine: pathLine, endLine: pathLine, startColumn: 0, endColumn: pathMatch[0].length,\n language: 'yaml', updatedAt: now,\n });\n }\n }\n\n // Extract Service ports\n if (kind === 'Service') {\n const portPattern = /port:\\s*(\\d+)/g;\n let portMatch: RegExpExecArray | null;\n while ((portMatch = portPattern.exec(doc)) !== null) {\n const portLine = content.slice(0, docStart).split('\\n').length +\n doc.slice(0, portMatch.index).split('\\n').length - 1;\n const port = portMatch[1]!;\n nodes.push({\n id: `route:${filePath}:SVC:${name}:${port}:${portLine}`,\n kind: 'route',\n name: `${name}:${port}`,\n qualifiedName: `${filePath}::svc.${name}.${port}`,\n filePath, startLine: portLine, endLine: portLine, startColumn: 0, endColumn: portMatch[0].length,\n language: 'yaml', updatedAt: now,\n });\n }\n }\n }\n\n return nodes;\n },\n};\n\nfunction mapK8sKind(kind: string): Node['kind'] | null {\n switch (kind) {\n case 'Deployment':\n case 'StatefulSet':\n case 'DaemonSet':\n case 'Job':\n case 'CronJob':\n return 'component';\n case 'Service':\n case 'Ingress':\n case 'Gateway':\n case 'VirtualService':\n return 'route';\n case 'ConfigMap':\n case 'Secret':\n return 'variable';\n case 'Namespace':\n return 'namespace';\n case 'ServiceAccount':\n case 'Role':\n case 'ClusterRole':\n case 'RoleBinding':\n case 'ClusterRoleBinding':\n return 'interface';\n case 'PersistentVolumeClaim':\n case 'PersistentVolume':\n case 'StorageClass':\n return 'variable';\n case 'HorizontalPodAutoscaler':\n case 'NetworkPolicy':\n return 'variable';\n case 'CustomResourceDefinition':\n return 'type_alias';\n default:\n return 'class';\n }\n}\n\nfunction resolveK8sResource(name: string, context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n const node = context.getNodesInFile(file).find(n =>\n n.name.endsWith(`/${name}`) || n.name === name\n );\n if (node) return node.id;\n }\n return null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var pulumi_exports = {};
|
|
20
|
+
__export(pulumi_exports, {
|
|
21
|
+
pulumiResolver: () => pulumiResolver
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(pulumi_exports);
|
|
24
|
+
const pulumiResolver = {
|
|
25
|
+
name: "pulumi",
|
|
26
|
+
detect(context) {
|
|
27
|
+
if (context.fileExists("Pulumi.yaml") || context.fileExists("Pulumi.yml")) return true;
|
|
28
|
+
const pkg = context.readFile("package.json");
|
|
29
|
+
if (pkg) {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(pkg);
|
|
32
|
+
const deps = { ...parsed.dependencies, ...parsed.devDependencies };
|
|
33
|
+
if (Object.keys(deps).some((d) => d.startsWith("@pulumi/"))) return true;
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const requirements = context.readFile("requirements.txt");
|
|
38
|
+
if (requirements && requirements.includes("pulumi")) return true;
|
|
39
|
+
return false;
|
|
40
|
+
},
|
|
41
|
+
resolve(ref, context) {
|
|
42
|
+
if (/^[a-z][a-zA-Z0-9]*\.[a-zA-Z]/.test(ref.referenceName)) {
|
|
43
|
+
const varName = ref.referenceName.split(".")[0];
|
|
44
|
+
const id = resolveInDirs(varName, ["index", "src", "infra", "infrastructure", "lib"], context);
|
|
45
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
|
|
46
|
+
}
|
|
47
|
+
if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
|
|
48
|
+
const id = resolveInDirs(ref.referenceName, ["components", "src", "infra", "lib"], context);
|
|
49
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: "framework" };
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
extractNodes(filePath, content) {
|
|
54
|
+
const nodes = [];
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const routePattern = /path\s*:\s*["']([^"']+)["'][^}]*method\s*:\s*["'](\w+)["']/g;
|
|
57
|
+
let match;
|
|
58
|
+
while ((match = routePattern.exec(content)) !== null) {
|
|
59
|
+
const line = content.slice(0, match.index).split("\n").length;
|
|
60
|
+
const routePath = match[1];
|
|
61
|
+
const method = match[2].toUpperCase();
|
|
62
|
+
const name = `${method} ${routePath}`;
|
|
63
|
+
nodes.push({
|
|
64
|
+
id: `route:${filePath}:${method}:${routePath}:${line}`,
|
|
65
|
+
kind: "route",
|
|
66
|
+
name,
|
|
67
|
+
qualifiedName: `${filePath}::${name}`,
|
|
68
|
+
filePath,
|
|
69
|
+
startLine: line,
|
|
70
|
+
endLine: line,
|
|
71
|
+
startColumn: 0,
|
|
72
|
+
endColumn: match[0].length,
|
|
73
|
+
language: filePath.endsWith(".py") ? "python" : "typescript",
|
|
74
|
+
updatedAt: now
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return nodes;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
function resolveInDirs(name, dirs, context) {
|
|
81
|
+
for (const file of context.getAllFiles()) {
|
|
82
|
+
if (!(file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".py") || file.endsWith(".go"))) continue;
|
|
83
|
+
if (!dirs.some((d) => file.includes(`/${d}/`) || file.includes(`/${d}.`))) continue;
|
|
84
|
+
const node = context.getNodesInFile(file).find((n) => n.name === name);
|
|
85
|
+
if (node) return node.id;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
90
|
+
0 && (module.exports = {
|
|
91
|
+
pulumiResolver
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=pulumi.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/frameworks/pulumi.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Pulumi Framework Resolver\n *\n * Pulumi is already TypeScript/Python/Go code \u2014 tree-sitter handles parsing.\n * This resolver adds detection, resource reference resolution, and route extraction.\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const pulumiResolver: FrameworkResolver = {\n name: 'pulumi',\n detect(context: ResolutionContext): boolean {\n if (context.fileExists('Pulumi.yaml') || context.fileExists('Pulumi.yml')) return true;\n const pkg = context.readFile('package.json');\n if (pkg) {\n try {\n const parsed = JSON.parse(pkg);\n const deps = { ...parsed.dependencies, ...parsed.devDependencies };\n if (Object.keys(deps).some(d => d.startsWith('@pulumi/'))) return true;\n } catch { /* ignore */ }\n }\n // Python\n const requirements = context.readFile('requirements.txt');\n if (requirements && requirements.includes('pulumi')) return true;\n return false;\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve resource property references (e.g., bucket.bucketName)\n if (/^[a-z][a-zA-Z0-9]*\\.[a-zA-Z]/.test(ref.referenceName)) {\n const varName = ref.referenceName.split('.')[0]!;\n const id = resolveInDirs(varName, ['index', 'src', 'infra', 'infrastructure', 'lib'], context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: 'framework' };\n }\n // Resolve component/stack class references\n if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {\n const id = resolveInDirs(ref.referenceName, ['components', 'src', 'infra', 'lib'], context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n // Extract Pulumi API Gateway routes (awsx, apigateway)\n // Pattern: { path: \"/users\", method: \"GET\", ... }\n const routePattern = /path\\s*:\\s*[\"']([^\"']+)[\"'][^}]*method\\s*:\\s*[\"'](\\w+)[\"']/g;\n let match: RegExpExecArray | null;\n while ((match = routePattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const routePath = match[1]!;\n const method = match[2]!.toUpperCase();\n const name = `${method} ${routePath}`;\n nodes.push({\n id: `route:${filePath}:${method}:${routePath}:${line}`,\n kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: filePath.endsWith('.py') ? 'python' : 'typescript', updatedAt: now,\n });\n }\n\n return nodes;\n },\n};\n\nfunction resolveInDirs(name: string, dirs: string[], context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (!(file.endsWith('.ts') || file.endsWith('.js') || file.endsWith('.py') || file.endsWith('.go'))) continue;\n if (!dirs.some(d => file.includes(`/${d}/`) || file.includes(`/${d}.`))) continue;\n const node = context.getNodesInFile(file).find(n => n.name === name);\n if (node) return node.id;\n }\n return null;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,MAAM,iBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO,SAAqC;AAC1C,QAAI,QAAQ,WAAW,aAAa,KAAK,QAAQ,WAAW,YAAY,EAAG,QAAO;AAClF,UAAM,MAAM,QAAQ,SAAS,cAAc;AAC3C,QAAI,KAAK;AACP,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cAAM,OAAO,EAAE,GAAG,OAAO,cAAc,GAAG,OAAO,gBAAgB;AACjE,YAAI,OAAO,KAAK,IAAI,EAAE,KAAK,OAAK,EAAE,WAAW,UAAU,CAAC,EAAG,QAAO;AAAA,MACpE,QAAQ;AAAA,MAAe;AAAA,IACzB;AAEA,UAAM,eAAe,QAAQ,SAAS,kBAAkB;AACxD,QAAI,gBAAgB,aAAa,SAAS,QAAQ,EAAG,QAAO;AAC5D,WAAO;AAAA,EACT;AAAA,EACA,QAAQ,KAAoB,SAAgD;AAE1E,QAAI,+BAA+B,KAAK,IAAI,aAAa,GAAG;AAC1D,YAAM,UAAU,IAAI,cAAc,MAAM,GAAG,EAAE,CAAC;AAC9C,YAAM,KAAK,cAAc,SAAS,CAAC,SAAS,OAAO,SAAS,kBAAkB,KAAK,GAAG,OAAO;AAC7F,UAAI,GAAI,QAAO,EAAE,UAAU,KAAK,cAAc,IAAI,YAAY,MAAM,YAAY,YAAY;AAAA,IAC9F;AAEA,QAAI,mBAAmB,KAAK,IAAI,aAAa,GAAG;AAC9C,YAAM,KAAK,cAAc,IAAI,eAAe,CAAC,cAAc,OAAO,SAAS,KAAK,GAAG,OAAO;AAC1F,UAAI,GAAI,QAAO,EAAE,UAAU,KAAK,cAAc,IAAI,YAAY,KAAK,YAAY,YAAY;AAAA,IAC7F;AACA,WAAO;AAAA,EACT;AAAA,EACA,aAAa,UAAkB,SAAyB;AACtD,UAAM,QAAgB,CAAC;AACvB,UAAM,MAAM,KAAK,IAAI;AAIrB,UAAM,eAAe;AACrB,QAAI;AACJ,YAAQ,QAAQ,aAAa,KAAK,OAAO,OAAO,MAAM;AACpD,YAAM,OAAO,QAAQ,MAAM,GAAG,MAAM,KAAK,EAAE,MAAM,IAAI,EAAE;AACvD,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,SAAS,MAAM,CAAC,EAAG,YAAY;AACrC,YAAM,OAAO,GAAG,MAAM,IAAI,SAAS;AACnC,YAAM,KAAK;AAAA,QACT,IAAI,SAAS,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI,IAAI;AAAA,QACpD,MAAM;AAAA,QAAS;AAAA,QACf,eAAe,GAAG,QAAQ,KAAK,IAAI;AAAA,QACnC;AAAA,QAAU,WAAW;AAAA,QAAM,SAAS;AAAA,QAAM,aAAa;AAAA,QAAG,WAAW,MAAM,CAAC,EAAE;AAAA,QAC9E,UAAU,SAAS,SAAS,KAAK,IAAI,WAAW;AAAA,QAAc,WAAW;AAAA,MAC3E,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,MAAc,MAAgB,SAA2C;AAC9F,aAAW,QAAQ,QAAQ,YAAY,GAAG;AACxC,QAAI,EAAE,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,GAAI;AACrG,QAAI,CAAC,KAAK,KAAK,OAAK,KAAK,SAAS,IAAI,CAAC,GAAG,KAAK,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAAG;AACzE,UAAM,OAAO,QAAQ,eAAe,IAAI,EAAE,KAAK,OAAK,EAAE,SAAS,IAAI;AACnE,QAAI,KAAM,QAAO,KAAK;AAAA,EACxB;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var scala_exports = {};
|
|
20
|
+
__export(scala_exports, {
|
|
21
|
+
playResolver: () => playResolver
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(scala_exports);
|
|
24
|
+
const playResolver = {
|
|
25
|
+
name: "play",
|
|
26
|
+
detect(context) {
|
|
27
|
+
const buildSbt = context.readFile("build.sbt");
|
|
28
|
+
if (buildSbt && (buildSbt.includes("PlayScala") || buildSbt.includes("play-"))) return true;
|
|
29
|
+
const plugins = context.readFile("project/plugins.sbt");
|
|
30
|
+
if (plugins && plugins.includes("sbt-plugin")) return true;
|
|
31
|
+
return context.getAllFiles().some((f) => f.includes("/controllers/") && f.endsWith(".scala"));
|
|
32
|
+
},
|
|
33
|
+
resolve(ref, context) {
|
|
34
|
+
if (ref.referenceName.endsWith("Controller")) {
|
|
35
|
+
const id = resolveInDirs(ref.referenceName, ["controllers", "app/controllers"], ".scala", "class", context);
|
|
36
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: "framework" };
|
|
37
|
+
}
|
|
38
|
+
if (ref.referenceName.endsWith("Service") || ref.referenceName.endsWith("Repository")) {
|
|
39
|
+
const id = resolveInDirs(ref.referenceName, ["services", "repositories", "app/services", "app/repositories"], ".scala", null, context);
|
|
40
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: "framework" };
|
|
41
|
+
}
|
|
42
|
+
if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
|
|
43
|
+
const id = resolveInDirs(ref.referenceName, ["models", "app/models", "domain"], ".scala", "class", context);
|
|
44
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: "framework" };
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
},
|
|
48
|
+
extractNodes(filePath, content) {
|
|
49
|
+
const nodes = [];
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
if (filePath.endsWith("/routes") || filePath.endsWith("/routes.conf")) {
|
|
52
|
+
const routePattern = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+(\S+)/gm;
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = routePattern.exec(content)) !== null) {
|
|
55
|
+
const line = content.slice(0, match.index).split("\n").length;
|
|
56
|
+
const [, method, routePath] = match;
|
|
57
|
+
const name = `${method} ${routePath}`;
|
|
58
|
+
nodes.push({
|
|
59
|
+
id: `route:${filePath}:${method}:${routePath}:${line}`,
|
|
60
|
+
kind: "route",
|
|
61
|
+
name,
|
|
62
|
+
qualifiedName: `${filePath}::${name}`,
|
|
63
|
+
filePath,
|
|
64
|
+
startLine: line,
|
|
65
|
+
endLine: line,
|
|
66
|
+
startColumn: 0,
|
|
67
|
+
endColumn: match[0].length,
|
|
68
|
+
language: "scala",
|
|
69
|
+
updatedAt: now
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return nodes;
|
|
73
|
+
}
|
|
74
|
+
const dslPatterns = [
|
|
75
|
+
// Akka HTTP: path("users") { get { ... } }
|
|
76
|
+
/(?:path|pathPrefix)\s*\(\s*"([^"]+)"\s*\)/g,
|
|
77
|
+
// http4s: case GET -> Root / "users"
|
|
78
|
+
/case\s+(GET|POST|PUT|PATCH|DELETE)\s+->\s+Root\s*\/\s*"([^"]+)"/g
|
|
79
|
+
];
|
|
80
|
+
for (const pattern of dslPatterns) {
|
|
81
|
+
let match;
|
|
82
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
83
|
+
const line = content.slice(0, match.index).split("\n").length;
|
|
84
|
+
const isHttp4s = pattern.source.includes("case");
|
|
85
|
+
const method = isHttp4s ? match[1] : "ANY";
|
|
86
|
+
const routePath = isHttp4s ? `/${match[2]}` : `/${match[1]}`;
|
|
87
|
+
const name = `${method} ${routePath}`;
|
|
88
|
+
const id = `route:${filePath}:${method}:${routePath}:${line}`;
|
|
89
|
+
if (!nodes.some((n) => n.id === id)) {
|
|
90
|
+
nodes.push({
|
|
91
|
+
id,
|
|
92
|
+
kind: "route",
|
|
93
|
+
name,
|
|
94
|
+
qualifiedName: `${filePath}::${name}`,
|
|
95
|
+
filePath,
|
|
96
|
+
startLine: line,
|
|
97
|
+
endLine: line,
|
|
98
|
+
startColumn: 0,
|
|
99
|
+
endColumn: match[0].length,
|
|
100
|
+
language: "scala",
|
|
101
|
+
updatedAt: now
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return nodes;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
function resolveInDirs(name, dirs, ext, kind, context) {
|
|
110
|
+
for (const file of context.getAllFiles()) {
|
|
111
|
+
if (file.endsWith(ext) && dirs.some((d) => file.includes(`/${d}/`) || file.includes(`/${d}`))) {
|
|
112
|
+
const node = context.getNodesInFile(file).find(
|
|
113
|
+
(n) => n.name === name && (kind === null || n.kind === kind)
|
|
114
|
+
);
|
|
115
|
+
if (node) return node.id;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
121
|
+
0 && (module.exports = {
|
|
122
|
+
playResolver
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=scala.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/frameworks/scala.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Scala Framework Resolver (Play, Akka HTTP, http4s)\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const playResolver: FrameworkResolver = {\n name: 'play',\n detect(context: ResolutionContext): boolean {\n // Check build.sbt or plugins.sbt for Play plugin\n const buildSbt = context.readFile('build.sbt');\n if (buildSbt && (buildSbt.includes('PlayScala') || buildSbt.includes('play-'))) return true;\n const plugins = context.readFile('project/plugins.sbt');\n if (plugins && plugins.includes('sbt-plugin')) return true;\n return context.getAllFiles().some(f => f.includes('/controllers/') && f.endsWith('.scala'));\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve controller references\n if (ref.referenceName.endsWith('Controller')) {\n const id = resolveInDirs(ref.referenceName, ['controllers', 'app/controllers'], '.scala', 'class', context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: 'framework' };\n }\n // Resolve service references\n if (ref.referenceName.endsWith('Service') || ref.referenceName.endsWith('Repository')) {\n const id = resolveInDirs(ref.referenceName, ['services', 'repositories', 'app/services', 'app/repositories'], '.scala', null, context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: 'framework' };\n }\n // Resolve model references\n if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {\n const id = resolveInDirs(ref.referenceName, ['models', 'app/models', 'domain'], '.scala', 'class', context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n // Play routes file (conf/routes)\n if (filePath.endsWith('/routes') || filePath.endsWith('/routes.conf')) {\n const routePattern = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s+(\\S+)/gm;\n let match: RegExpExecArray | null;\n while ((match = routePattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const [, method, routePath] = match;\n const name = `${method} ${routePath}`;\n nodes.push({\n id: `route:${filePath}:${method}:${routePath}:${line}`,\n kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: 'scala', updatedAt: now,\n });\n }\n return nodes;\n }\n\n // Akka HTTP / http4s route DSL\n const dslPatterns = [\n // Akka HTTP: path(\"users\") { get { ... } }\n /(?:path|pathPrefix)\\s*\\(\\s*\"([^\"]+)\"\\s*\\)/g,\n // http4s: case GET -> Root / \"users\"\n /case\\s+(GET|POST|PUT|PATCH|DELETE)\\s+->\\s+Root\\s*\\/\\s*\"([^\"]+)\"/g,\n ];\n for (const pattern of dslPatterns) {\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const isHttp4s = pattern.source.includes('case');\n const method = isHttp4s ? match[1]! : 'ANY';\n const routePath = isHttp4s ? `/${match[2]}` : `/${match[1]}`;\n const name = `${method} ${routePath}`;\n const id = `route:${filePath}:${method}:${routePath}:${line}`;\n if (!nodes.some(n => n.id === id)) {\n nodes.push({\n id, kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: 'scala', updatedAt: now,\n });\n }\n }\n }\n\n return nodes;\n },\n};\n\nfunction resolveInDirs(name: string, dirs: string[], ext: string, kind: string | null, context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (file.endsWith(ext) && dirs.some(d => file.includes(`/${d}/`) || file.includes(`/${d}`))) {\n const node = context.getNodesInFile(file).find(\n n => n.name === name && (kind === null || n.kind === kind)\n );\n if (node) return node.id;\n }\n }\n return null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var solidity_exports = {};
|
|
20
|
+
__export(solidity_exports, {
|
|
21
|
+
solidityResolver: () => solidityResolver
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(solidity_exports);
|
|
24
|
+
const solidityResolver = {
|
|
25
|
+
name: "solidity",
|
|
26
|
+
detect(context) {
|
|
27
|
+
if (context.fileExists("hardhat.config.ts") || context.fileExists("hardhat.config.js")) return true;
|
|
28
|
+
if (context.fileExists("foundry.toml")) return true;
|
|
29
|
+
if (context.fileExists("truffle-config.js")) return true;
|
|
30
|
+
return context.getAllFiles().some((f) => f.endsWith(".sol"));
|
|
31
|
+
},
|
|
32
|
+
resolve(ref, context) {
|
|
33
|
+
if (ref.referenceName.startsWith("I") && /^I[A-Z]/.test(ref.referenceName)) {
|
|
34
|
+
const id = resolveInterface(ref.referenceName, context);
|
|
35
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: "framework" };
|
|
36
|
+
}
|
|
37
|
+
if (/^[A-Z][a-zA-Z0-9]+$/.test(ref.referenceName)) {
|
|
38
|
+
const id = resolveContract(ref.referenceName, context);
|
|
39
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: "framework" };
|
|
40
|
+
}
|
|
41
|
+
if (ref.referenceKind === "function") {
|
|
42
|
+
const id = resolveLibraryFunction(ref.referenceName, context);
|
|
43
|
+
if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
},
|
|
47
|
+
extractNodes(filePath, content) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
function resolveInterface(name, context) {
|
|
52
|
+
const dirs = ["interfaces", "contracts/interfaces", "src/interfaces"];
|
|
53
|
+
for (const file of context.getAllFiles()) {
|
|
54
|
+
if (!file.endsWith(".sol")) continue;
|
|
55
|
+
if (dirs.some((d) => file.includes(`/${d}/`))) {
|
|
56
|
+
const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "interface");
|
|
57
|
+
if (node) return node.id;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const file of context.getAllFiles()) {
|
|
61
|
+
if (!file.endsWith(".sol")) continue;
|
|
62
|
+
const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "interface");
|
|
63
|
+
if (node) return node.id;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
function resolveContract(name, context) {
|
|
68
|
+
const dirs = ["contracts", "src", "lib"];
|
|
69
|
+
for (const file of context.getAllFiles()) {
|
|
70
|
+
if (!file.endsWith(".sol")) continue;
|
|
71
|
+
if (dirs.some((d) => file.includes(`/${d}/`))) {
|
|
72
|
+
const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "class");
|
|
73
|
+
if (node) return node.id;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
function resolveLibraryFunction(name, context) {
|
|
79
|
+
const dirs = ["libraries", "contracts/libraries", "lib"];
|
|
80
|
+
for (const file of context.getAllFiles()) {
|
|
81
|
+
if (!file.endsWith(".sol")) continue;
|
|
82
|
+
if (dirs.some((d) => file.includes(`/${d}/`))) {
|
|
83
|
+
const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "function");
|
|
84
|
+
if (node) return node.id;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
90
|
+
0 && (module.exports = {
|
|
91
|
+
solidityResolver
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=solidity.js.map
|