@@ -23,8 +23,10 @@ class ImportMapConfigReader
23
23
{
24
24
private ImportMapEntries $ rootImportMapEntries ;
25
25
26
- public function __construct (private readonly string $ importMapConfigPath )
27
- {
26
+ public function __construct (
27
+ private readonly string $ importMapConfigPath ,
28
+ private readonly RemotePackageStorage $ remotePackageStorage ,
29
+ ) {
28
30
}
29
31
30
32
public function getEntries (): ImportMapEntries
@@ -38,7 +40,7 @@ public function getEntries(): ImportMapEntries
38
40
39
41
$ entries = new ImportMapEntries ();
40
42
foreach ($ importMapConfig ?? [] as $ importName => $ data ) {
41
- $ validKeys = ['path ' , 'version ' , 'type ' , 'entrypoint ' , 'url ' ];
43
+ $ validKeys = ['path ' , 'version ' , 'type ' , 'entrypoint ' , 'url ' , ' package_specifier ' ];
42
44
if ($ invalidKeys = array_diff (array_keys ($ data ), $ validKeys )) {
43
45
throw new \InvalidArgumentException (sprintf ('The following keys are not valid for the importmap entry "%s": "%s". Valid keys are: "%s". ' , $ importName , implode ('", " ' , $ invalidKeys ), implode ('", " ' , $ validKeys )));
44
46
}
@@ -49,36 +51,33 @@ public function getEntries(): ImportMapEntries
49
51
}
50
52
51
53
$ type = isset ($ data ['type ' ]) ? ImportMapType::tryFrom ($ data ['type ' ]) : ImportMapType::JS ;
52
- $ isEntry = $ data ['entrypoint ' ] ?? false ;
54
+ $ isEntrypoint = $ data ['entrypoint ' ] ?? false ;
55
+
56
+ if (isset ($ data ['path ' ])) {
57
+ if (isset ($ data ['version ' ])) {
58
+ throw new RuntimeException (sprintf ('The importmap entry "%s" cannot have both a "path" and "version" option. ' , $ importName ));
59
+ }
60
+ if (isset ($ data ['package_specifier ' ])) {
61
+ throw new RuntimeException (sprintf ('The importmap entry "%s" cannot have both a "path" and "package_specifier" option. ' , $ importName ));
62
+ }
63
+
64
+ $ entries ->add (ImportMapEntry::createLocal ($ importName , $ type , $ data ['path ' ], $ isEntrypoint ));
53
65
54
- if ($ isEntry && ImportMapType::JS !== $ type ) {
55
- throw new RuntimeException (sprintf ('The "entrypoint" option can only be used with the "js" type. Found "%s" in importmap.php for key "%s". ' , $ importName , $ type ->value ));
66
+ continue ;
56
67
}
57
68
58
- $ path = $ data ['path ' ] ?? null ;
59
69
$ version = $ data ['version ' ] ?? null ;
60
70
if (null === $ version && ($ data ['url ' ] ?? null )) {
61
71
// BC layer for 6.3->6.4
62
72
$ version = $ this ->extractVersionFromLegacyUrl ($ data ['url ' ]);
63
73
}
64
- if (null === $ version && null === $ path ) {
74
+
75
+ if (null === $ version ) {
65
76
throw new RuntimeException (sprintf ('The importmap entry "%s" must have either a "path" or "version" option. ' , $ importName ));
66
77
}
67
- if (null !== $ version && null !== $ path ) {
68
- throw new RuntimeException (sprintf ('The importmap entry "%s" cannot have both a "path" and "version" option. ' , $ importName ));
69
- }
70
78
71
- [$ packageName , $ filePath ] = self ::splitPackageNameAndFilePath ($ importName );
72
-
73
- $ entries ->add (new ImportMapEntry (
74
- $ importName ,
75
- path: $ path ,
76
- version: $ version ,
77
- type: $ type ,
78
- isEntrypoint: $ isEntry ,
79
- packageName: $ packageName ,
80
- filePath: $ filePath ,
81
- ));
79
+ $ packageModuleSpecifier = $ data ['package_specifier ' ] ?? $ importName ;
80
+ $ entries ->add ($ this ->createRemoteEntry ($ importName , $ type , $ version , $ packageModuleSpecifier , $ isEntrypoint ));
82
81
}
83
82
84
83
return $ this ->rootImportMapEntries = $ entries ;
@@ -91,19 +90,21 @@ public function writeEntries(ImportMapEntries $entries): void
91
90
$ importMapConfig = [];
92
91
foreach ($ entries as $ entry ) {
93
92
$ config = [];
94
- if ($ entry ->path ) {
95
- $ path = $ entry ->path ;
96
- $ config ['path ' ] = $ path ;
97
- }
98
- if ($ entry ->version ) {
93
+ if ($ entry ->isRemotePackage ()) {
99
94
$ config ['version ' ] = $ entry ->version ;
95
+ if ($ entry ->packageModuleSpecifier !== $ entry ->importName ) {
96
+ $ config ['package_specifier ' ] = $ entry ->packageModuleSpecifier ;
97
+ }
98
+ } else {
99
+ $ config ['path ' ] = $ entry ->path ;
100
100
}
101
101
if (ImportMapType::JS !== $ entry ->type ) {
102
102
$ config ['type ' ] = $ entry ->type ->value ;
103
103
}
104
104
if ($ entry ->isEntrypoint ) {
105
105
$ config ['entrypoint ' ] = true ;
106
106
}
107
+
107
108
$ importMapConfig [$ entry ->importName ] = $ config ;
108
109
}
109
110
@@ -129,6 +130,13 @@ public function writeEntries(ImportMapEntries $entries): void
129
130
EOF );
130
131
}
131
132
133
+ public function createRemoteEntry (string $ importName , ImportMapType $ type , string $ version , string $ packageModuleSpecifier , bool $ isEntrypoint ): ImportMapEntry
134
+ {
135
+ $ path = $ this ->remotePackageStorage ->getDownloadPath ($ packageModuleSpecifier , $ type );
136
+
137
+ return ImportMapEntry::createRemote ($ importName , $ type , $ path , $ version , $ packageModuleSpecifier , $ isEntrypoint );
138
+ }
139
+
132
140
public function getRootDirectory (): string
133
141
{
134
142
return \dirname ($ this ->importMapConfigPath );
@@ -148,18 +156,4 @@ private function extractVersionFromLegacyUrl(string $url): ?string
148
156
149
157
return substr ($ url , $ lastAt + 1 , $ nextSlash - $ lastAt - 1 );
150
158
}
151
-
152
- public static function splitPackageNameAndFilePath (string $ packageName ): array
153
- {
154
- $ filePath = '' ;
155
- $ i = strpos ($ packageName , '/ ' );
156
-
157
- if ($ i && (!str_starts_with ($ packageName , '@ ' ) || $ i = strpos ($ packageName , '/ ' , $ i + 1 ))) {
158
- // @vendor/package/filepath or package/filepath
159
- $ filePath = substr ($ packageName , $ i );
160
- $ packageName = substr ($ packageName , 0 , $ i );
161
- }
162
-
163
- return [$ packageName , $ filePath ];
164
- }
165
159
}
0 commit comments