Skip to content

Commit 658940e

Browse files
wip
1 parent 4bfb40e commit 658940e

20 files changed

+590
-204
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"phpstan/phpdoc-parser": "^1.13",
2121
"spatie/file-system-watcher": "^1.1",
2222
"spatie/laravel-package-tools": "^1.14.0",
23-
"spatie/php-structure-discoverer": "^1.1"
23+
"spatie/php-structure-discoverer": "^1.1",
24+
"spatie/temporary-directory": "^2.1"
2425
},
2526
"require-dev": {
2627
"laravel/pint": "^1.0",

src/Actions/ConnectReferencesAction.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
class ConnectReferencesAction
1414
{
1515
public function __construct(
16-
protected TypeScriptTransformerConfig $config,
1716
) {
1817
}
1918

src/Actions/FormatFilesAction.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Spatie\TypeScriptTransformer\Actions;
44

55
use Spatie\TypeScriptTransformer\Support\TypeScriptTransformerLog;
6-
use Spatie\TypeScriptTransformer\Support\WrittenFile;
6+
use Spatie\TypeScriptTransformer\Support\WriteableFile;
77
use Spatie\TypeScriptTransformer\TypeScriptTransformerConfig;
88

99
class FormatFilesAction
@@ -14,7 +14,7 @@ public function __construct(
1414
}
1515

1616
/**
17-
* @param array<WrittenFile> $writtenFiles
17+
* @param array<WriteableFile> $writtenFiles
1818
*/
1919
public function execute(array $writtenFiles): void
2020
{
@@ -23,7 +23,7 @@ public function execute(array $writtenFiles): void
2323
}
2424

2525
$this->config->formatter->format(
26-
array_map(fn (WrittenFile $writtenFile) => $writtenFile->path, $writtenFiles)
26+
array_map(fn (WriteableFile $writtenFile) => $writtenFile->path, $writtenFiles)
2727
);
2828
}
2929
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Spatie\TypeScriptTransformer\Actions;
4+
5+
use Closure;
6+
use Spatie\TypeScriptTransformer\Collections\ImportsCollection;
7+
use Spatie\TypeScriptTransformer\Collections\ReferenceMap;
8+
use Spatie\TypeScriptTransformer\Support\ImportName;
9+
use Spatie\TypeScriptTransformer\Support\Location;
10+
use Spatie\TypeScriptTransformer\Transformed\Transformed;
11+
12+
class ResolveModuleImportsAction
13+
{
14+
/**
15+
* @param ResolveRelativePathAction $resolveRelativePathAction
16+
* @param Closure(array<string>,string):string|null $alternativeNamesResolver
17+
*/
18+
public function __construct(
19+
protected ResolveRelativePathAction $resolveRelativePathAction = new ResolveRelativePathAction(),
20+
protected ?Closure $alternativeNamesResolver = null,
21+
) {
22+
}
23+
24+
public function execute(
25+
Location $location,
26+
ReferenceMap $referenceMap,
27+
): ImportsCollection {
28+
$collection = new ImportsCollection();
29+
30+
$usedNamesInModule = array_values(
31+
array_map(fn (Transformed $transformed) => $transformed->getName(), $location->transformed)
32+
);
33+
34+
foreach ($location->transformed as $transformedItem) {
35+
foreach ($transformedItem->references as $reference) {
36+
$referencedTransformed = $referenceMap->get($reference);
37+
38+
if ($referencedTransformed->location === $location->segments) {
39+
continue;
40+
}
41+
42+
if ($collection->hasReferenceImported($referencedTransformed->reference)) {
43+
continue;
44+
}
45+
46+
$name = $referencedTransformed->getName();
47+
48+
$resolveImportedName = $this->resolveImportedName($usedNamesInModule, $name);
49+
50+
$usedNamesInModule[] = $resolveImportedName;
51+
52+
$importName = new ImportName(
53+
$name,
54+
$referencedTransformed->reference,
55+
$name === $resolveImportedName ? null : $resolveImportedName,
56+
);
57+
58+
$relativePath = $this->resolveRelativePathAction->execute(
59+
$location->segments,
60+
$referencedTransformed->location,
61+
);
62+
63+
$collection->add($relativePath, $importName);
64+
}
65+
}
66+
67+
return $collection;
68+
}
69+
70+
protected function resolveImportedName(
71+
array $usedNamesInScope,
72+
string $name,
73+
): string {
74+
if ($this->alternativeNamesResolver) {
75+
return ($this->alternativeNamesResolver)($usedNamesInScope, $name);
76+
}
77+
78+
if (! in_array($name, $usedNamesInScope)) {
79+
return $name;
80+
}
81+
82+
if (! in_array("{$name}Import", $usedNamesInScope)) {
83+
return "{$name}Alt";
84+
}
85+
86+
$counter = 2;
87+
88+
while (in_array("{$name}Import{$counter}", $usedNamesInScope)) {
89+
$counter++;
90+
}
91+
92+
return "{$name}Import{$counter}";
93+
}
94+
}

src/Actions/ResolveRelativePathAction.php

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,32 @@
44

55
class ResolveRelativePathAction
66
{
7-
public function execute(
8-
array $currentNamespaceSegments,
9-
array $requestedNamespaceSegments,
10-
): ?string {
11-
$currentNamespaceSegments = array_values($currentNamespaceSegments);
12-
$requestedNamespaceSegments = array_values($requestedNamespaceSegments);
13-
14-
$maxIndex = max(
15-
count($currentNamespaceSegments),
16-
count($requestedNamespaceSegments)
17-
);
18-
19-
for ($i = 0; $i < $maxIndex; $i++) {
20-
if (
21-
array_key_exists($i, $currentNamespaceSegments)
22-
&& array_key_exists($i, $requestedNamespaceSegments)
23-
&& $currentNamespaceSegments[$i] === $requestedNamespaceSegments[$i]) {
24-
unset($currentNamespaceSegments[$i]);
25-
unset($requestedNamespaceSegments[$i]);
26-
}
7+
public function execute(array $from, array $to): ?string
8+
{
9+
if ($from === $to) {
10+
return null;
2711
}
2812

29-
$currentNamespaceSegments = array_values($currentNamespaceSegments);
30-
$requestedNamespaceSegments = array_values($requestedNamespaceSegments);
13+
$commonDepth = 0;
14+
$maxDepth = min(count($from), count($to));
3115

32-
if (empty($currentNamespaceSegments) && empty($requestedNamespaceSegments)) {
33-
return null;
16+
for ($i = 0; $i < $maxDepth; $i++) {
17+
if ($from[$i] !== $to[$i]) {
18+
break;
19+
}
20+
$commonDepth++;
3421
}
3522

36-
$segments = ['.'];
23+
$relativeSegments = [];
3724

38-
foreach ($currentNamespaceSegments as $i) {
39-
$segments[] = '..';
25+
for ($i = $commonDepth; $i < count($from); $i++) {
26+
$relativeSegments[] = '..';
4027
}
4128

42-
array_push($segments, ...$requestedNamespaceSegments);
29+
for ($i = $commonDepth; $i < count($to); $i++) {
30+
$relativeSegments[] = $to[$i];
31+
}
4332

44-
return implode('/', $segments);
45-
}
33+
return implode('/', $relativeSegments);
34+
}
4635
}

src/Actions/WriteFilesAction.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Spatie\TypeScriptTransformer\Actions;
4+
5+
use Spatie\TypeScriptTransformer\Support\WriteableFile;
6+
use Spatie\TypeScriptTransformer\TypeScriptTransformerConfig;
7+
8+
class WriteFilesAction
9+
{
10+
public function __construct(
11+
public TypeScriptTransformerConfig $config,
12+
) {
13+
}
14+
15+
/** @param array<WriteableFile> $writeableFiles */
16+
public function execute(
17+
array $writeableFiles
18+
): void {
19+
foreach ($writeableFiles as $writeableFile) {
20+
$this->writeFile($writeableFile);
21+
}
22+
}
23+
24+
protected function writeFile(WriteableFile $file): void
25+
{
26+
$directory = dirname($file->path);
27+
28+
if (is_dir($directory) === false) {
29+
mkdir($directory, recursive: true);
30+
}
31+
32+
file_put_contents($file->path, $file->contents);
33+
}
34+
}

src/Actions/WriteTypesAction.php

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/Collections/ImportsCollection.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Spatie\TypeScriptTransformer\Collections;
4+
5+
use IteratorAggregate;
6+
use Spatie\TypeScriptTransformer\References\Reference;
7+
use Spatie\TypeScriptTransformer\Support\ImportLocation;
8+
use Spatie\TypeScriptTransformer\Support\ImportName;
9+
use Spatie\TypeScriptTransformer\TypeScript\TypeScriptImport;
10+
use Traversable;
11+
12+
class ImportsCollection implements IteratorAggregate
13+
{
14+
/**
15+
* @param array<string, ImportLocation> $imports
16+
*/
17+
public function __construct(
18+
protected array $imports = [],
19+
) {
20+
}
21+
22+
public function add(string $relativePath, ImportName $name): void
23+
{
24+
if (! array_key_exists($relativePath, $this->imports)) {
25+
$this->imports[$relativePath] = new ImportLocation($relativePath);
26+
}
27+
28+
$this->imports[$relativePath]->addName($name);
29+
}
30+
31+
public function getAliasOrNameForReference(Reference $reference): ?string
32+
{
33+
foreach ($this->imports as $import) {
34+
if ($aliasOrName = $import->getAliasOrNameForReference($reference)) {
35+
return $aliasOrName;
36+
}
37+
}
38+
39+
return null;
40+
}
41+
42+
public function hasReferenceImported(Reference $reference): bool
43+
{
44+
return $this->getAliasOrNameForReference($reference) !== null;
45+
}
46+
47+
public function isEmpty(): bool
48+
{
49+
return empty($this->imports);
50+
}
51+
52+
public function getIterator(): Traversable
53+
{
54+
return new \ArrayIterator($this->imports);
55+
}
56+
57+
/**
58+
* @return array<TypeScriptImport>
59+
*/
60+
public function getTypeScriptNodes(): array
61+
{
62+
return array_map(
63+
fn (ImportLocation $import) => $import->toTypeScriptNode(),
64+
$this->imports,
65+
);
66+
}
67+
}

src/Collections/ReferenceMap.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,19 @@
88

99
class ReferenceMap
1010
{
11+
/** @var array<string, Transformed> */
1112
protected array $references = [];
1213

14+
/**
15+
* @param array<Transformed> $references
16+
*/
17+
public function __construct(array $references = [])
18+
{
19+
foreach ($references as $reference) {
20+
$this->add($reference);
21+
}
22+
}
23+
1324
public function add(
1425
Transformed $transformed
1526
): void {

src/Laravel/LaravelTypesProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected function eloquentCollection(): Transformed
6565
[new TypeScriptIdentifier('T')],
6666
),
6767
new TypeScriptGeneric(
68-
new TypeScriptIdentifier('Array'),
68+
new TypeReference(new ClassStringReference(Collection::class)),
6969
[new TypeScriptIdentifier('T')],
7070
),
7171
),

0 commit comments

Comments
 (0)