Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 2.7 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Generator; 4 5use SocialDept\AtpSchema\Parser\Nsid; 6 7class NamespaceResolver 8{ 9 /** 10 * Base namespace for generated classes. 11 */ 12 protected string $baseNamespace; 13 14 /** 15 * Create a new NamespaceResolver. 16 */ 17 public function __construct(string $baseNamespace = 'App\\Lexicons') 18 { 19 $this->baseNamespace = rtrim($baseNamespace, '\\'); 20 } 21 22 /** 23 * Resolve NSID to PHP namespace. 24 */ 25 public function resolveNamespace(string $nsidString): string 26 { 27 $nsid = Nsid::parse($nsidString); 28 29 // Convert authority to namespace parts (com.example.feed -> Com\Example\Feed) 30 $parts = explode('.', $nsid->getAuthority()); 31 $namespaceParts = array_map(fn ($part) => $this->toPascalCase($part), $parts); 32 33 return $this->baseNamespace.'\\'.implode('\\', $namespaceParts); 34 } 35 36 /** 37 * Resolve NSID to PHP class name. 38 */ 39 public function resolveClassName(string $nsidString, ?string $defName = null): string 40 { 41 $nsid = Nsid::parse($nsidString); 42 43 // Use definition name if provided, otherwise use the name from NSID 44 $name = $defName ?? $nsid->getName(); 45 46 return $this->toPascalCase($name); 47 } 48 49 /** 50 * Resolve full qualified class name. 51 */ 52 public function resolveFullyQualifiedName(string $nsidString, ?string $defName = null): string 53 { 54 $namespace = $this->resolveNamespace($nsidString); 55 $className = $this->resolveClassName($nsidString, $defName); 56 57 return $namespace.'\\'.$className; 58 } 59 60 /** 61 * Convert string to PascalCase. 62 */ 63 protected function toPascalCase(string $string): string 64 { 65 // Replace dots, hyphens, and underscores with spaces 66 $string = str_replace(['.', '-', '_'], ' ', $string); 67 68 // Capitalize each word 69 $string = ucwords($string); 70 71 // Remove spaces 72 return str_replace(' ', '', $string); 73 } 74 75 /** 76 * Convert NSID to file path. 77 */ 78 public function resolveFilePath(string $nsidString, string $baseDirectory, ?string $defName = null): string 79 { 80 $namespace = $this->resolveNamespace($nsidString); 81 $className = $this->resolveClassName($nsidString, $defName); 82 83 // Remove base namespace from full namespace 84 $relativePath = str_replace($this->baseNamespace.'\\', '', $namespace); 85 $relativePath = str_replace('\\', '/', $relativePath); 86 87 return rtrim($baseDirectory, '/').'/'.$relativePath.'/'.$className.'.php'; 88 } 89 90 /** 91 * Get the base namespace. 92 */ 93 public function getBaseNamespace(): string 94 { 95 return $this->baseNamespace; 96 } 97}