}|null $core * @param array}> $components */ private function __construct( private ?array $core, private array $components, ) { } public static function path(string $root): string { return rtrim($root, '/') . '/' . self::DIR . '/' . self::FILE; } public static function empty(): self { return new self(null, []); } public static function load(string $root): self { $path = self::path($root); if (!is_file($path)) { return self::empty(); } $data = json_decode((string) file_get_contents($path), true); if (!is_array($data)) { throw new ToolboxException("Lock inválido: {$path}"); } $components = []; foreach (($data['components'] ?? []) as $id => $entry) { $components[$id] = [ 'package' => (string) ($entry['package'] ?? ''), 'version' => (string) ($entry['version'] ?? ''), 'toolbox_commit' => $entry['toolbox_commit'] ?? null, 'mode' => (string) ($entry['mode'] ?? 'copy'), 'origin' => (string) ($entry['origin'] ?? 'toolbox'), 'files' => is_array($entry['files'] ?? null) ? $entry['files'] : [], ]; } return new self($data['core'] ?? null, $components); } /** @return array{version?:string, commit?:string, files?:array}|null */ public function core(): ?array { return $this->core; } /** @return array}> */ public function components(): array { return $this->components; } public function has(string $id): bool { return isset($this->components[$id]); } public function component(string $id): ?array { return $this->components[$id] ?? null; } /** @param array{version?:string, commit?:string, files?:array} $core */ public function setCore(array $core): void { $this->core = $core; } /** @param array{package:string, version:string, toolbox_commit:?string, mode:string, files:array} $entry */ public function setComponent(string $id, array $entry): void { $this->components[$id] = $entry; } public function removeComponent(string $id): void { unset($this->components[$id]); } public function save(string $root): void { $dir = rtrim($root, '/') . '/' . self::DIR; if (!is_dir($dir)) { mkdir($dir, 0777, true); } $data = ['core' => $this->core, 'components' => $this->components]; file_put_contents( self::path($root), json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" ); } }