Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 2.0 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Validation\Rules; 4 5use Closure; 6use Illuminate\Contracts\Validation\ValidationRule; 7 8class Cid implements ValidationRule 9{ 10 /** 11 * Run the validation rule. 12 */ 13 public function validate(string $attribute, mixed $value, Closure $fail): void 14 { 15 if (! is_string($value)) { 16 $fail("The {$attribute} must be a string."); 17 18 return; 19 } 20 21 if (! $this->isValidCid($value)) { 22 $fail("The {$attribute} is not a valid CID."); 23 } 24 } 25 26 /** 27 * Validate CID format. 28 * 29 * CID (Content Identifier) is typically base58 or base32 encoded 30 * CIDv0: Qm... (base58, 46 characters) 31 * CIDv1: b... (base32) or z... (base58) 32 */ 33 protected function isValidCid(string $value): bool 34 { 35 $length = strlen($value); 36 37 // CIDv0: Starts with Qm and is 46 characters 38 if (str_starts_with($value, 'Qm') && $length === 46) { 39 return $this->isBase58($value); 40 } 41 42 // CIDv1: Starts with 'b' (base32) or 'z' (base58) 43 if (str_starts_with($value, 'b') && $length > 10) { 44 return $this->isBase32($value); 45 } 46 47 if (str_starts_with($value, 'z') && $length > 10) { 48 return $this->isBase58($value); 49 } 50 51 // Also accept bafy... (base32 CIDv1) 52 if (str_starts_with($value, 'bafy') && $length > 10) { 53 return $this->isBase32($value); 54 } 55 56 return false; 57 } 58 59 /** 60 * Check if string is valid base58. 61 */ 62 protected function isBase58(string $value): bool 63 { 64 // Base58 alphabet (no 0, O, I, l) 65 return (bool) preg_match('/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/', $value); 66 } 67 68 /** 69 * Check if string is valid base32. 70 */ 71 protected function isBase32(string $value): bool 72 { 73 // Base32 lowercase alphabet 74 return (bool) preg_match('/^[a-z2-7]+$/', $value); 75 } 76}