{
"event": "PreToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/CodeAnalysis\/JsFileParser.php",
"content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\CodeAnalysis;\n\n\/\/ @responsibility: JavaScript-Dateianalyse via Regex (ES6 Modules)\n\nfinal class JsFileParser\n{\n \/**\n * Parst eine JavaScript-Datei und extrahiert Metadaten.\n *\n * @return array{\n * namespace: string|null,\n * classes: array<array{name: string, type: string, line: int}>,\n * functions: array<array{name: string, visibility: string|null, line: int}>,\n * uses: array<string>,\n * extends_class: string|null,\n * implements_interfaces: array<string>,\n * traits_used: array<string>,\n * constructor_deps: array<string>,\n * error: string|null\n * }\n *\/\n public function parse(string $filePath): array\n {\n $result = [\n 'namespace' => null,\n 'classes' => [],\n 'functions' => [],\n 'uses' => [],\n 'extends_class' => null,\n 'implements_interfaces' => [],\n 'traits_used' => [],\n 'constructor_deps' => [],\n 'error' => null,\n ];\n\n if (!file_exists($filePath) || !is_readable($filePath)) {\n $result['error'] = 'Datei nicht lesbar';\n\n return $result;\n }\n\n $content = file_get_contents($filePath);\n if ($content === false) {\n $result['error'] = 'Datei konnte nicht gelesen werden';\n\n return $result;\n }\n\n $lines = explode(\"\\n\", $content);\n\n \/\/ Namespace aus Dateipfad\n $result['namespace'] = $this->extractNamespace($filePath);\n\n \/\/ ES6 Imports: import { X, Y } from 'module'\n if (preg_match_all('\/import\\s+\\{([^}]+)\\}\\s+from\\s+[\\'\"]([^\\'\"]+)[\\'\"]\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $imports = array_map('trim', explode(',', $match[1]));\n $module = $match[2];\n foreach ($imports as $import) {\n \/\/ Handle \"X as Y\" syntax\n $name = preg_replace('\/\\s+as\\s+\\w+\/', '', $import);\n $result['uses'][] = $module . '.' . trim($name);\n }\n }\n }\n\n \/\/ ES6 Default Import: import X from 'module'\n if (preg_match_all('\/import\\s+(\\w+)\\s+from\\s+[\\'\"]([^\\'\"]+)[\\'\"]\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $result['uses'][] = $match[2] . '.' . $match[1];\n }\n }\n\n \/\/ CommonJS: const X = require('module')\n if (preg_match_all('\/(?:const|let|var)\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\\'\"]([^\\'\"]+)[\\'\"]\\s*\\)\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $result['uses'][] = $match[2];\n }\n }\n\n \/\/ Klassen: class X extends Y\n foreach ($lines as $lineNum => $line) {\n if (preg_match('\/^\\s*(?:export\\s+)?class\\s+(\\w+)(?:\\s+extends\\s+(\\w+))?\/', $line, $match)) {\n $result['classes'][] = [\n 'name' => $match[1],\n 'type' => 'class',\n 'line' => $lineNum + 1,\n ];\n\n if (isset($match[2]) && $result['extends_class'] === null) {\n $result['extends_class'] = $match[2];\n }\n }\n }\n\n \/\/ Top-Level Funktionen\n foreach ($lines as $lineNum => $line) {\n \/\/ function name() oder export function name()\n if (preg_match('\/^(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(\/', $line, $match)) {\n $result['functions'][] = [\n 'name' => $match[1],\n 'visibility' => null,\n 'line' => $lineNum + 1,\n ];\n }\n\n \/\/ const name = () => oder const name = function()\n if (preg_match('\/^(?:export\\s+)?(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)\\s*=>|function)\/', $line, $match)) {\n $result['functions'][] = [\n 'name' => $match[1],\n 'visibility' => null,\n 'line' => $lineNum + 1,\n ];\n }\n }\n\n $result['uses'] = array_unique($result['uses']);\n\n return $result;\n }\n\n \/**\n * Extrahiert einen pseudo-Namespace aus dem Dateipfad.\n *\/\n private function extractNamespace(string $filePath): ?string\n {\n \/\/ \/public\/js\/components\/data-table.js -> js.components\n if (preg_match('#\/public\/js\/(.+)\\.js$#', $filePath, $matches)) {\n $subPath = dirname($matches[1]);\n\n if ($subPath === '.') {\n return 'js';\n }\n\n return 'js.' . str_replace('\/', '.', $subPath);\n }\n\n return null;\n }\n}\n"
}
}
{
"tool_response": {
"type": "create",
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/CodeAnalysis\/JsFileParser.php",
"content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\CodeAnalysis;\n\n\/\/ @responsibility: JavaScript-Dateianalyse via Regex (ES6 Modules)\n\nfinal class JsFileParser\n{\n \/**\n * Parst eine JavaScript-Datei und extrahiert Metadaten.\n *\n * @return array{\n * namespace: string|null,\n * classes: array<array{name: string, type: string, line: int}>,\n * functions: array<array{name: string, visibility: string|null, line: int}>,\n * uses: array<string>,\n * extends_class: string|null,\n * implements_interfaces: array<string>,\n * traits_used: array<string>,\n * constructor_deps: array<string>,\n * error: string|null\n * }\n *\/\n public function parse(string $filePath): array\n {\n $result = [\n 'namespace' => null,\n 'classes' => [],\n 'functions' => [],\n 'uses' => [],\n 'extends_class' => null,\n 'implements_interfaces' => [],\n 'traits_used' => [],\n 'constructor_deps' => [],\n 'error' => null,\n ];\n\n if (!file_exists($filePath) || !is_readable($filePath)) {\n $result['error'] = 'Datei nicht lesbar';\n\n return $result;\n }\n\n $content = file_get_contents($filePath);\n if ($content === false) {\n $result['error'] = 'Datei konnte nicht gelesen werden';\n\n return $result;\n }\n\n $lines = explode(\"\\n\", $content);\n\n \/\/ Namespace aus Dateipfad\n $result['namespace'] = $this->extractNamespace($filePath);\n\n \/\/ ES6 Imports: import { X, Y } from 'module'\n if (preg_match_all('\/import\\s+\\{([^}]+)\\}\\s+from\\s+[\\'\"]([^\\'\"]+)[\\'\"]\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $imports = array_map('trim', explode(',', $match[1]));\n $module = $match[2];\n foreach ($imports as $import) {\n \/\/ Handle \"X as Y\" syntax\n $name = preg_replace('\/\\s+as\\s+\\w+\/', '', $import);\n $result['uses'][] = $module . '.' . trim($name);\n }\n }\n }\n\n \/\/ ES6 Default Import: import X from 'module'\n if (preg_match_all('\/import\\s+(\\w+)\\s+from\\s+[\\'\"]([^\\'\"]+)[\\'\"]\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $result['uses'][] = $match[2] . '.' . $match[1];\n }\n }\n\n \/\/ CommonJS: const X = require('module')\n if (preg_match_all('\/(?:const|let|var)\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\\'\"]([^\\'\"]+)[\\'\"]\\s*\\)\/', $content, $matches, PREG_SET_ORDER)) {\n foreach ($matches as $match) {\n $result['uses'][] = $match[2];\n }\n }\n\n \/\/ Klassen: class X extends Y\n foreach ($lines as $lineNum => $line) {\n if (preg_match('\/^\\s*(?:export\\s+)?class\\s+(\\w+)(?:\\s+extends\\s+(\\w+))?\/', $line, $match)) {\n $result['classes'][] = [\n 'name' => $match[1],\n 'type' => 'class',\n 'line' => $lineNum + 1,\n ];\n\n if (isset($match[2]) && $result['extends_class'] === null) {\n $result['extends_class'] = $match[2];\n }\n }\n }\n\n \/\/ Top-Level Funktionen\n foreach ($lines as $lineNum => $line) {\n \/\/ function name() oder export function name()\n if (preg_match('\/^(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(\/', $line, $match)) {\n $result['functions'][] = [\n 'name' => $match[1],\n 'visibility' => null,\n 'line' => $lineNum + 1,\n ];\n }\n\n \/\/ const name = () => oder const name = function()\n if (preg_match('\/^(?:export\\s+)?(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)\\s*=>|function)\/', $line, $match)) {\n $result['functions'][] = [\n 'name' => $match[1],\n 'visibility' => null,\n 'line' => $lineNum + 1,\n ];\n }\n }\n\n $result['uses'] = array_unique($result['uses']);\n\n return $result;\n }\n\n \/**\n * Extrahiert einen pseudo-Namespace aus dem Dateipfad.\n *\/\n private function extractNamespace(string $filePath): ?string\n {\n \/\/ \/public\/js\/components\/data-table.js -> js.components\n if (preg_match('#\/public\/js\/(.+)\\.js$#', $filePath, $matches)) {\n $subPath = dirname($matches[1]);\n\n if ($subPath === '.') {\n return 'js';\n }\n\n return 'js.' . str_replace('\/', '.', $subPath);\n }\n\n return null;\n }\n}\n",
"structuredPatch": [],
"originalFile": null
}
}