EntrypointLookup::getEntrypointJsonPath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 1
cts 1
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the WebpackEncore plugin for Micro Framework.
7
 * (c) Oleksii Bulba <[email protected]>
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace OleksiiBulba\WebpackEncorePlugin\Asset;
13
14
use OleksiiBulba\WebpackEncorePlugin\Exception\EntrypointNotFoundException;
15
use OleksiiBulba\WebpackEncorePlugin\WebpackEncorePluginConfigurationInterface;
16
use Symfony\Component\Serializer\Encoder\DecoderInterface;
17
use Symfony\Component\Serializer\Encoder\JsonEncoder;
18
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
19
20
class EntrypointLookup implements EntrypointLookupInterface
21
{
22
    private ?array $entriesData = null;
23
24
    private array $returnedFiles = [];
25
26
    public function __construct(
27
        private readonly WebpackEncorePluginConfigurationInterface $configuration,
28
        private readonly DecoderInterface $decoder
29
    ) {
30 15
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function getJavaScriptFiles(string $entryName): array
36
    {
37 5
        return $this->getEntryFiles($entryName, 'js');
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function getCssFiles(string $entryName): array
44
    {
45 2
        return $this->getEntryFiles($entryName, 'css');
46
    }
47
48
    public function entryExists(string $entryName): bool
49
    {
50 8
        $entriesData = $this->getEntriesData();
51
52 3
        return isset($entriesData['entrypoints'][$entryName]);
53
    }
54
55
    /**
56
     * @psalm-return array<string>
57
     */
58
    private function getEntryFiles(string $entryName, string $key): array
59
    {
60 7
        $this->validateEntryName($entryName);
61 4
        $entriesData = $this->getEntriesData();
62
        /** @var array $entryData */
63 4
        $entryData = $entriesData['entrypoints'][$entryName] ?? [];
64
65 4
        if (!isset($entryData[$key])) {
66
            // If we don't find the file type then just send back nothing.
67 1
            return [];
68
        }
69
70
        // make sure to not return the same file multiple times
71
        /** @var array $entryFiles */
72 3
        $entryFiles = $entryData[$key];
73 3
        $newFiles = array_values(array_diff($entryFiles, $this->returnedFiles));
74 3
        $this->returnedFiles = array_merge($this->returnedFiles, $newFiles);
75
76 3
        return $newFiles;
77
    }
78
79
    private function validateEntryName(string $entryName): void
80
    {
81
        /** @var array<string, array> $entriesData */
82 7
        $entriesData = $this->getEntriesData();
83 7
        if (isset($entriesData['entrypoints'][$entryName])) {
84 4
            return;
85
        }
86
87 3
        if (false === $dotPos = strrpos($entryName, '.')) {
88 1
            throw new EntrypointNotFoundException(sprintf('Could not find the entry "%s" in "%s". Found: %s.', $entryName, $this->getEntrypointJsonPath(), implode(', ', array_keys($entriesData['entrypoints']))));
89
        }
90
91 2
        if (isset($entriesData['entrypoints'][$withoutExtension = substr($entryName, 0, $dotPos)])) {
92 1
            throw new EntrypointNotFoundException(sprintf('Could not find the entry "%s". Try "%s" instead (without the extension).', $entryName, $withoutExtension));
93
        }
94
95 1
        throw new EntrypointNotFoundException(sprintf('Could not find the entry "%s" in "%s". Found: %s.', $entryName, $this->getEntrypointJsonPath(), implode(', ', array_keys($entriesData['entrypoints']))));
96
    }
97
98
    private function getEntriesData(): array
99
    {
100 15
        if (null !== $this->entriesData) {
101 4
            return $this->entriesData;
102
        }
103
104 15
        if (!file_exists($this->getEntrypointJsonPath())) {
105 1
            throw new \InvalidArgumentException(sprintf('Could not find the entrypoints file from Webpack: the file "%s" does not exist. Maybe you forgot to run npm/yarn build?', $this->getEntrypointJsonPath()));
106
        }
107
108
        try {
109 14
            $entriesData = $this->decoder->decode(file_get_contents($this->getEntrypointJsonPath()), JsonEncoder::FORMAT);
110 1
        } catch (UnexpectedValueException $e) {
111 1
            throw new \InvalidArgumentException(sprintf('There was a problem JSON decoding the "%s" file. Try to run npm/yarn build to fix the issue.', $this->getEntrypointJsonPath()), 0, $e);
112
        }
113
114 13
        if (!\is_array($entriesData)) {
115 2
            throw new \InvalidArgumentException(sprintf('There was a problem JSON decoding the "%s" file. Try to run npm/yarn build to fix the issue.', $this->getEntrypointJsonPath()));
116
        }
117
118 11
        if (!isset($entriesData['entrypoints'])) {
119 1
            throw new \InvalidArgumentException(sprintf('Could not find an "entrypoints" key in the "%s" file. Try to run npm/yarn build to fix the issue.', $this->getEntrypointJsonPath()));
120
        }
121
122 10
        return $this->entriesData = $entriesData;
123
    }
124
125
    private function getEntrypointJsonPath(): string
126
    {
127 15
        return $this->configuration->getOutputPath().'/entrypoints.json';
128
    }
129
}
130