diff --git a/src/Symfony/Component/AssetMapper/ImportMap/Resolver/JsDelivrEsmResolver.php b/src/Symfony/Component/AssetMapper/ImportMap/Resolver/JsDelivrEsmResolver.php index c4440482f4b68..49e0c6aa63fef 100644 --- a/src/Symfony/Component/AssetMapper/ImportMap/Resolver/JsDelivrEsmResolver.php +++ b/src/Symfony/Component/AssetMapper/ImportMap/Resolver/JsDelivrEsmResolver.php @@ -26,7 +26,7 @@ final class JsDelivrEsmResolver implements PackageResolverInterface public const URL_PATTERN_DIST = self::URL_PATTERN_DIST_CSS.'/+esm'; public const URL_PATTERN_ENTRYPOINT = 'https://data.jsdelivr.com/v1/packages/npm/%s@%s/entrypoints'; - public const IMPORT_REGEX = '{from"/npm/((?:@[^/]+/)?[^@]+?)(?:@([^/]+))?((?:/[^/]+)*?)/\+esm"}'; + public const IMPORT_REGEX = '#(?:import\s*(?:(?:\{[^}]*\}|\w+|\*\s*as\s+\w+)\s*\bfrom\s*)?|export\s*(?:\{[^}]*\}|\*)\s*from\s*)("/npm/((?:@[^/]+/)?[^@]+?)(?:@([^/]+))?((?:/[^/]+)*?)/\+esm")#'; private HttpClientInterface $httpClient; @@ -221,9 +221,9 @@ private function fetchPackageRequirementsFromImports(string $content): array // imports from jsdelivr follow a predictable format preg_match_all(self::IMPORT_REGEX, $content, $matches); $dependencies = []; - foreach ($matches[1] as $index => $packageName) { - $version = $matches[2][$index] ?: null; - $packageName .= $matches[3][$index]; // add the path if any + foreach ($matches[2] as $index => $packageName) { + $version = $matches[3][$index] ?: null; + $packageName .= $matches[4][$index]; // add the path if any $dependencies[] = new PackageRequireOptions($packageName, $version); } @@ -239,10 +239,11 @@ private function fetchPackageRequirementsFromImports(string $content): array private function makeImportsBare(string $content, array &$dependencies): string { $content = preg_replace_callback(self::IMPORT_REGEX, function ($matches) use (&$dependencies) { - $packageName = $matches[1].$matches[3]; // add the path if any + $packageName = $matches[2].$matches[4]; // add the path if any $dependencies[] = $packageName; - return sprintf('from"%s"', $packageName); + // replace the "/npm/package@version/+esm" with "package@version" + return str_replace($matches[1], sprintf('"%s"', $packageName), $matches[0]); }, $content); // source maps are not also downloaded - so remove the sourceMappingURL diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/Resolver/JsDelivrEsmResolverTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/Resolver/JsDelivrEsmResolverTest.php index 733ecfedcdb16..d2c184b89043b 100644 --- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/Resolver/JsDelivrEsmResolverTest.php +++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/Resolver/JsDelivrEsmResolverTest.php @@ -463,12 +463,12 @@ public function testImportRegex(string $subject, array $expectedPackages) $expectedVersions[] = $packageData[1]; } $actualNames = []; - foreach ($matches[1] as $i => $name) { - $actualNames[] = $name.$matches[3][$i]; + foreach ($matches[2] as $i => $name) { + $actualNames[] = $name.$matches[4][$i]; } $this->assertSame($expectedNames, $actualNames); - $this->assertSame($expectedVersions, $matches[2]); + $this->assertSame($expectedVersions, $matches[3]); } public static function provideImportRegex(): iterable @@ -529,6 +529,26 @@ public static function provideImportRegex(): iterable ['prosemirror-state/php/strings/sprintf', '1.4.3'], ], ]; + + yield 'import without importing a value' => [ + 'import "/npm/jquery@3.7.1/+esm";', + [ + ['jquery', '3.7.1'], + ], + ]; + + yield 'multiple imports and exports with and without values' => [ + 'import"/npm/jquery@3.7.1/+esm";import e from"/npm/datatables.net-bs5@1.13.7/+esm";export{default}from"/npm/datatables.net-bs5@1.13.7/+esm";import"/npm/datatables.net-select@1.7.0/+esm"; + /*! Bootstrap 5 styling wrapper for Select + * © SpryMedia Ltd - datatables.net/license + */', + [ + ['jquery', '3.7.1'], + ['datatables.net-bs5', '1.13.7'], + ['datatables.net-bs5', '1.13.7'], + ['datatables.net-select', '1.7.0'], + ], + ]; } private static function createRemoteEntry(string $importName, string $version, ImportMapType $type = ImportMapType::JS, string $packageSpecifier = null): ImportMapEntry