Lines 100.00% 16 / 16
Methods 100.00% 3 / 3
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 resolvedReferences 100.00% 1 / 1 100.00% 1 / 1 1
 resolvedReferencesColumns 100.00% 14 / 14 100.00% 1 / 1 4
31final class ForeignKey
32{
33    /**
34     * Create a foreign-key declaration.
35     *
36     * @param  list<string>  $columns
37     * @param  ForeignKeyReference  $references
38     * @param  list<string>|null  $referencesColumns
39     * @param  ForeignKeyAction|string|null  $onDelete
40     * @param  ForeignKeyAction|string|null  $onUpdate
41     * @param  bool  $deferrable
42     * @param  bool  $initiallyDeferred  Implies `$deferrable`.
43     */
44    public function __construct(
45        public array $columns,
46        public string $references,
47        public array|null $referencesColumns = null,
48        public ForeignKeyAction|string|null $onDelete = null,
49        public ForeignKeyAction|string|null $onUpdate = null,
50        public bool $deferrable = false,
51        public bool $initiallyDeferred = false,
52    ) {
53    }
54
55    /**
56     * The resolved referenced table name.
57     *
58     * @return string
59     * @throws \InvalidArgumentException
60     */
61    public function resolvedReferences(): string
62    {
63        return ReferenceResolver::resolve($this->references);
64    }
65
66    /**
67     * The resolved referenced columns.
68     *
69     * @return list<string>
70     * @throws \InvalidArgumentException
71     */
72    public function resolvedReferencesColumns(): array
73    {
74        if ($this->referencesColumns !== null) {
75            return $this->referencesColumns;
76        }
77
78        if (!str_contains($this->references, '\\')) {
79            return ['id']; // plain table + no columns → the PK convention.
80        }
81
82        // resolve() validated existence + Model-ness; the is_a guard
83        // narrows the string to class-string<Model> for the metadata call.
84        $model = $this->references;
85
86        if (!is_a($model, \BlueprintAU\Radiant\Model::class, true)) {
87            throw new \LogicException(
88                "Reference [{$model}] resolved as a model but is not one."
89            );
90        }
91
92        $metadata = MetadataFactory::for($model);
93
94        return array_map(
95            fn (Column $primaryKey) => $primaryKey->name ?? '',
96            $metadata->primaryKeys,
97        );
98    }
99}