Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m9s
Added ProviderResourceBinding model, migrations, policies, and supporting framework for canonical resource identity mapping as defined in Spec 381.
129 lines
4.2 KiB
PHP
129 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Resources;
|
|
|
|
use App\Support\Baselines\SubjectClass;
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
use JsonSerializable;
|
|
|
|
/**
|
|
* @implements Arrayable<string, mixed>
|
|
*/
|
|
final readonly class ProviderResourceDescriptor implements Arrayable, JsonSerializable
|
|
{
|
|
/**
|
|
* @param array<string, string|int|float|bool|null> $sourceReferences
|
|
*/
|
|
public function __construct(
|
|
public ResourceIdentity $identity,
|
|
public ?string $displayLabel,
|
|
public string $subjectDomain,
|
|
public SubjectClass|string $subjectClass,
|
|
public string $subjectTypeKey,
|
|
public array $sourceReferences = [],
|
|
public ?string $fingerprint = null,
|
|
public ?string $lastSeenAt = null,
|
|
) {}
|
|
|
|
/**
|
|
* @param array<string, string|int|float|bool|null> $sourceReferences
|
|
*/
|
|
public static function fromIdentity(
|
|
ResourceIdentity $identity,
|
|
string $subjectDomain,
|
|
SubjectClass|string $subjectClass,
|
|
string $subjectTypeKey,
|
|
?string $displayLabel = null,
|
|
array $sourceReferences = [],
|
|
?string $fingerprint = null,
|
|
?string $lastSeenAt = null,
|
|
): self {
|
|
return new self(
|
|
identity: $identity,
|
|
displayLabel: $displayLabel,
|
|
subjectDomain: $subjectDomain,
|
|
subjectClass: $subjectClass,
|
|
subjectTypeKey: $subjectTypeKey,
|
|
sourceReferences: self::safeSourceReferences($sourceReferences),
|
|
fingerprint: $fingerprint,
|
|
lastSeenAt: $lastSeenAt,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $payload
|
|
*/
|
|
public static function fromArray(array $payload): self
|
|
{
|
|
$identityPayload = $payload['identity'] ?? [];
|
|
|
|
return new self(
|
|
identity: ResourceIdentity::fromArray(is_array($identityPayload) ? $identityPayload : []),
|
|
displayLabel: self::nullableString($payload['display_label'] ?? null),
|
|
subjectDomain: (string) ($payload['subject_domain'] ?? ''),
|
|
subjectClass: (string) ($payload['subject_class'] ?? ''),
|
|
subjectTypeKey: (string) ($payload['subject_type_key'] ?? ''),
|
|
sourceReferences: self::safeSourceReferences(is_array($payload['source_references'] ?? null) ? $payload['source_references'] : []),
|
|
fingerprint: self::nullableString($payload['fingerprint'] ?? null),
|
|
lastSeenAt: self::nullableString($payload['last_seen_at'] ?? null),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* identity: array<string, mixed>,
|
|
* display_label: ?string,
|
|
* subject_domain: string,
|
|
* subject_class: string,
|
|
* subject_type_key: string,
|
|
* source_references: array<string, string|int|float|bool|null>,
|
|
* fingerprint: ?string,
|
|
* last_seen_at: ?string
|
|
* }
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'identity' => $this->identity->toArray(),
|
|
'display_label' => $this->displayLabel,
|
|
'subject_domain' => $this->subjectDomain,
|
|
'subject_class' => $this->subjectClass instanceof SubjectClass ? $this->subjectClass->value : $this->subjectClass,
|
|
'subject_type_key' => $this->subjectTypeKey,
|
|
'source_references' => self::safeSourceReferences($this->sourceReferences),
|
|
'fingerprint' => $this->fingerprint,
|
|
'last_seen_at' => $this->lastSeenAt,
|
|
];
|
|
}
|
|
|
|
public function jsonSerialize(): array
|
|
{
|
|
return $this->toArray();
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $sourceReferences
|
|
* @return array<string, string|int|float|bool|null>
|
|
*/
|
|
private static function safeSourceReferences(array $sourceReferences): array
|
|
{
|
|
$safe = [];
|
|
|
|
foreach ($sourceReferences as $key => $value) {
|
|
if (! is_string($key) || trim($key) === '' || (! is_scalar($value) && $value !== null)) {
|
|
continue;
|
|
}
|
|
|
|
$safe[$key] = $value;
|
|
}
|
|
|
|
return $safe;
|
|
}
|
|
|
|
private static function nullableString(mixed $value): ?string
|
|
{
|
|
return is_string($value) && trim($value) !== '' ? trim($value) : null;
|
|
}
|
|
}
|