Something went wrong. Try again.
Parse and validate AT Protocol Lexicons with DTO generation for Laravel
Something went wrong. Try again.
4.8 kB · 215 lines
PHP
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216<?php
namespace SocialDept\AtpSchema\Data;
use SocialDept\AtpSchema\Exceptions\SchemaValidationException;use SocialDept\AtpSchema\Parser\Nsid;
class LexiconDocument{ /** * Lexicon version. */ public readonly int $lexicon;
/** * NSID identifier. */ public readonly Nsid $id;
/** * Schema description. */ public readonly ?string $description;
/** * Schema definitions. * * @var array<string, array> */ public readonly array $defs;
/** * Raw schema data. */ public readonly array $raw;
/** * Source of the schema (file path, URL, etc). */ public readonly ?string $source;
/** * Create a new LexiconDocument. * * @param array<string, array> $defs */ public function __construct( int $lexicon, Nsid $id, array $defs, ?string $description = null, ?string $source = null, ?array $raw = null ) { $this->lexicon = $lexicon; $this->id = $id; $this->defs = $defs; $this->description = $description; $this->source = $source; $this->raw = $raw ?? []; }
/** * Create from array data. */ public static function fromArray(array $data, ?string $source = null): self { if (! isset($data['lexicon'])) { throw SchemaValidationException::missingField('unknown', 'lexicon'); }
if (! isset($data['id'])) { throw SchemaValidationException::missingField('unknown', 'id'); }
if (! isset($data['defs'])) { throw SchemaValidationException::missingField($data['id'], 'defs'); }
$lexicon = (int) $data['lexicon']; if ($lexicon !== 1) { throw SchemaValidationException::invalidVersion($data['id'], $lexicon); }
return new self( lexicon: $lexicon, id: Nsid::parse($data['id']), defs: $data['defs'], description: $data['description'] ?? null, source: $source, raw: $data ); }
/** * Create from JSON string. */ public static function fromJson(string $json, ?string $source = null): self { $data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) { throw new \InvalidArgumentException('Invalid JSON: '.json_last_error_msg()); }
if (! is_array($data)) { throw new \InvalidArgumentException('JSON must decode to an array'); }
return self::fromArray($data, $source); }
/** * Get a definition by name. */ public function getDefinition(string $name): ?array { return $this->defs[$name] ?? null; }
/** * Check if definition exists. */ public function hasDefinition(string $name): bool { return isset($this->defs[$name]); }
/** * Get the main definition. */ public function getMainDefinition(): ?array { return $this->getDefinition('main'); }
/** * Get all definition names. * * @return array<string> */ public function getDefinitionNames(): array { return array_keys($this->defs); }
/** * Get NSID as string. */ public function getNsid(): string { return $this->id->toString(); }
/** * Get lexicon version. */ public function getVersion(): int { return $this->lexicon; }
/** * Convert to array. */ public function toArray(): array { return [ 'lexicon' => $this->lexicon, 'id' => $this->id->toString(), 'description' => $this->description, 'defs' => $this->defs, ]; }
/** * Check if this is a record schema. */ public function isRecord(): bool { $main = $this->getMainDefinition();
return $main !== null && ($main['type'] ?? null) === 'record'; }
/** * Check if this is a query schema. */ public function isQuery(): bool { $main = $this->getMainDefinition();
return $main !== null && ($main['type'] ?? null) === 'query'; }
/** * Check if this is a procedure schema. */ public function isProcedure(): bool { $main = $this->getMainDefinition();
return $main !== null && ($main['type'] ?? null) === 'procedure'; }
/** * Check if this is a subscription schema. */ public function isSubscription(): bool { $main = $this->getMainDefinition();
return $main !== null && ($main['type'] ?? null) === 'subscription'; }}