73 lines
2.6 KiB
PHP
73 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Addon;
|
|
|
|
/**
|
|
* Static catalogue of installable integrations. Each definition is UI-only metadata; runtime
|
|
* state (installed?, connected?, secrets) lives on the {@see Addon} row. Adding an integration
|
|
* later is a new entry here plus its normalizer under Support/Mqtt (H3).
|
|
*/
|
|
class AddonRegistry
|
|
{
|
|
/** @return array<string, array<string, mixed>> */
|
|
public static function all(): array
|
|
{
|
|
return [
|
|
'ring' => [
|
|
'key' => 'ring',
|
|
'name' => 'Ring',
|
|
'vendor' => 'Ring',
|
|
'icon' => 'doorbell',
|
|
// Ring has no local API — the established bridge is ring-mqtt (cloud, token auth).
|
|
'cloud' => true,
|
|
'summary_key' => 'addons.ring.summary',
|
|
'body_key' => 'addons.ring.body',
|
|
// The ring-mqtt sidecar generates a refresh token from an interactive Ring login
|
|
// (email + password + 2FA). We store that token; the sidecar does the rest.
|
|
'backend' => 'ring-mqtt',
|
|
'docs' => 'https://github.com/tsightler/ring-mqtt',
|
|
'fields' => [
|
|
['name' => 'email', 'type' => 'email', 'label_key' => 'addons.ring.email', 'secret' => false],
|
|
['name' => 'password', 'type' => 'password', 'label_key' => 'addons.ring.password', 'secret' => true],
|
|
['name' => 'code', 'type' => 'text', 'label_key' => 'addons.ring.code', 'secret' => false, 'optional' => true],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
public static function get(string $key): ?array
|
|
{
|
|
return static::all()[$key] ?? null;
|
|
}
|
|
|
|
public static function has(string $key): bool
|
|
{
|
|
return isset(static::all()[$key]);
|
|
}
|
|
|
|
/**
|
|
* Merge each catalogue definition with its persisted state, creating rows lazily so the
|
|
* page can render before anything is installed.
|
|
*
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public static function withState(): array
|
|
{
|
|
$rows = Addon::whereIn('key', array_keys(static::all()))->get()->keyBy('key');
|
|
|
|
return collect(static::all())->map(function (array $def) use ($rows) {
|
|
$state = $rows->get($def['key']);
|
|
|
|
return $def + [
|
|
'installed' => (bool) ($state?->installed ?? false),
|
|
'status' => $state?->status ?? 'disconnected',
|
|
'status_detail' => $state?->status_detail,
|
|
'connected_at' => $state?->connected_at,
|
|
'uuid' => $state?->uuid,
|
|
];
|
|
})->values()->all();
|
|
}
|
|
}
|