diff --git a/.idea/develop.iml b/.idea/develop.iml
index b5e53b44ef0..f357c61d82f 100644
--- a/.idea/develop.iml
+++ b/.idea/develop.iml
@@ -8,8 +8,6 @@
-
-
diff --git a/composer.lock b/composer.lock
index 62f95e14593..9a899f6d904 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1129,7 +1129,7 @@
"illuminate/view": "^10.0",
"league/commonmark": "^2.2",
"php": "^8.1",
- "spatie/yaml-front-matter": "^2.0.7",
+ "spatie/yaml-front-matter": "^2.0.9",
"symfony/yaml": "^6.0",
"torchlight/torchlight-commonmark": "^0.5.5"
},
@@ -4429,16 +4429,16 @@
},
{
"name": "spatie/yaml-front-matter",
- "version": "2.0.8",
+ "version": "2.0.9",
"source": {
"type": "git",
"url": "https://github.com/spatie/yaml-front-matter.git",
- "reference": "f2f1f749a405fafc9d6337067c92c062d51a581c"
+ "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/f2f1f749a405fafc9d6337067c92c062d51a581c",
- "reference": "f2f1f749a405fafc9d6337067c92c062d51a581c",
+ "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/cbe67e1cdd0a29a96d74ccab9400fe663e078392",
+ "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392",
"shasum": ""
},
"require": {
@@ -4475,7 +4475,7 @@
"yaml"
],
"support": {
- "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.8"
+ "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.9"
},
"funding": [
{
@@ -4487,7 +4487,7 @@
"type": "github"
}
],
- "time": "2023-12-04T10:02:52+00:00"
+ "time": "2024-06-13T10:20:51+00:00"
},
{
"name": "symfony/console",
diff --git a/package-lock.json b/package-lock.json
index c163c347a65..e9232a7eb9a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,8 +11,8 @@
"hydefront": "^3.3.0",
"laravel-mix": "^6.0.49",
"postcss": "^8.4.38",
- "prettier": "3.3.0",
- "tailwindcss": "^3.4.3"
+ "prettier": "3.3.2",
+ "tailwindcss": "^3.4.4"
}
},
"node_modules/@alloc/quick-lru": {
@@ -2968,12 +2968,12 @@
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -4662,9 +4662,9 @@
}
},
"node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -7529,9 +7529,9 @@
"dev": true
},
"node_modules/prettier": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz",
- "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
+ "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -8732,9 +8732,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
- "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
"dev": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -9760,16 +9760,16 @@
"dev": true
},
"node_modules/ws": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
- "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
+ "utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
@@ -12099,12 +12099,12 @@
}
},
"braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
}
},
"brorand": {
@@ -13411,9 +13411,9 @@
"dev": true
},
"fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
@@ -15447,9 +15447,9 @@
"dev": true
},
"prettier": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz",
- "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
+ "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true
},
"pretty-time": {
@@ -16385,9 +16385,9 @@
}
},
"tailwindcss": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
- "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
"dev": true,
"requires": {
"@alloc/quick-lru": "^5.2.0",
@@ -17107,9 +17107,9 @@
"dev": true
},
"ws": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
- "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true,
"requires": {}
},
diff --git a/package.json b/package.json
index 2e397a2a96e..dbde79ff5c2 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"hydefront": "^3.3.0",
"laravel-mix": "^6.0.49",
"postcss": "^8.4.38",
- "prettier": "3.3.0",
- "tailwindcss": "^3.4.3"
+ "prettier": "3.3.2",
+ "tailwindcss": "^3.4.4"
}
}
diff --git a/packages/framework/composer.json b/packages/framework/composer.json
index bc45ee2fb61..f716759c2d4 100644
--- a/packages/framework/composer.json
+++ b/packages/framework/composer.json
@@ -27,7 +27,7 @@
"illuminate/view": "^10.0",
"symfony/yaml": "^6.0",
"league/commonmark": "^2.2",
- "spatie/yaml-front-matter": "^2.0.7",
+ "spatie/yaml-front-matter": "^2.0.9",
"torchlight/torchlight-commonmark": "^0.5.5"
},
"suggest": {
diff --git a/packages/framework/src/Console/Commands/RouteListCommand.php b/packages/framework/src/Console/Commands/RouteListCommand.php
index 0eb86431379..1c1937b432c 100644
--- a/packages/framework/src/Console/Commands/RouteListCommand.php
+++ b/packages/framework/src/Console/Commands/RouteListCommand.php
@@ -5,11 +5,12 @@
namespace Hyde\Console\Commands;
use Hyde\Hyde;
+use Illuminate\Support\Arr;
use Hyde\Console\Concerns\Command;
use Hyde\Support\Internal\RouteListItem;
-use function array_map;
use function array_keys;
+use function json_encode;
use function array_values;
/**
@@ -18,7 +19,7 @@
class RouteListCommand extends Command
{
/** @var string */
- protected $signature = 'route:list';
+ protected $signature = 'route:list {--format=txt : The output format (txt or json)}';
/** @var string */
protected $description = 'Display all the registered routes';
@@ -27,20 +28,29 @@ public function handle(): int
{
$routes = $this->generate();
- $this->table($this->makeHeader($routes), $routes);
-
- return Command::SUCCESS;
+ return match ($this->option('format')) {
+ 'txt' => $this->table($this->makeHeader($routes), $routes) ?? Command::SUCCESS,
+ 'json' => $this->writeRaw(json_encode($routes, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) ?? Command::SUCCESS,
+ default => $this->error("Invalid format provided. Only 'txt' and 'json' are supported.") ?? Command::FAILURE,
+ };
}
/** @return array> */
protected function generate(): array
{
- return array_map(RouteListItem::format(...), array_values(Hyde::routes()->all()));
+ return Arr::map(array_values(Hyde::routes()->all()), RouteListItem::format(...));
}
/** @param array> $routes */
protected function makeHeader(array $routes): array
{
- return array_map(Hyde::makeTitle(...), array_keys($routes[0]));
+ return Arr::map(array_keys($routes[0]), Hyde::makeTitle(...));
+ }
+
+ /** Write a message without ANSI formatting */
+ protected function writeRaw(string $message): void
+ {
+ $this->output->setDecorated(false);
+ $this->output->writeln($message);
}
}
diff --git a/packages/framework/src/Foundation/Kernel/Hyperlinks.php b/packages/framework/src/Foundation/Kernel/Hyperlinks.php
index 9755841439d..9cec5ca989c 100644
--- a/packages/framework/src/Foundation/Kernel/Hyperlinks.php
+++ b/packages/framework/src/Foundation/Kernel/Hyperlinks.php
@@ -126,27 +126,38 @@ public function asset(string $name, bool $preferQualifiedUrl = false): string
/**
* Check if a site base URL has been set in config (or .env).
+ *
+ * The default value is `http://localhost`, which is not considered a valid site URL.
*/
public function hasSiteUrl(): bool
{
- return ! blank(Config::getNullableString('hyde.url'));
+ $value = Config::getNullableString('hyde.url');
+
+ return ! blank($value) && $value !== 'http://localhost';
}
/**
* Return a qualified URL to the supplied path if a base URL is set.
*
- * @param string $path optional relative path suffix. Omit to return base url.
+ * @param string $path An optional relative path suffix. Omit to return the base URL.
*
- * @throws BaseUrlNotSetException If no site URL is set and no default is provided
+ * @throws BaseUrlNotSetException If no site URL is set and no path is provided.
*/
public function url(string $path = ''): string
{
$path = $this->formatLink(trim($path, '/'));
if ($this->hasSiteUrl()) {
- return rtrim(rtrim((string) Config::getNullableString('hyde.url'), '/')."/$path", '/');
+ return rtrim(rtrim(Config::getString('hyde.url'), '/')."/$path", '/');
+ }
+
+ // Since v1.7.0, we return the relative path even if the base URL is not set,
+ // as this is more likely to be the desired behavior the user's expecting.
+ if (! blank($path)) {
+ return $path;
}
+ // User is trying to get the base URL, but it's not set
throw new BaseUrlNotSetException();
}
diff --git a/packages/framework/src/Framework/Actions/PostBuildTasks/GenerateSitemap.php b/packages/framework/src/Framework/Actions/PostBuildTasks/GenerateSitemap.php
index e2e15c55809..4409ede2934 100644
--- a/packages/framework/src/Framework/Actions/PostBuildTasks/GenerateSitemap.php
+++ b/packages/framework/src/Framework/Actions/PostBuildTasks/GenerateSitemap.php
@@ -9,7 +9,6 @@
use Hyde\Framework\Concerns\InteractsWithDirectories;
use Hyde\Framework\Features\XmlGenerators\SitemapGenerator;
-use function blank;
use function file_put_contents;
class GenerateSitemap extends PostBuildTask
@@ -22,7 +21,7 @@ class GenerateSitemap extends PostBuildTask
public function handle(): void
{
- if (blank(Hyde::url()) || str_starts_with(Hyde::url(), 'http://localhost')) {
+ if (! Hyde::hasSiteUrl()) {
$this->skip('Cannot generate sitemap without a valid base URL');
}
diff --git a/packages/framework/src/Support/DataCollections.php b/packages/framework/src/Support/DataCollections.php
index a6ea6e41466..b5ab786edef 100644
--- a/packages/framework/src/Support/DataCollections.php
+++ b/packages/framework/src/Support/DataCollections.php
@@ -51,7 +51,7 @@ public static function markdown(string $name): static
{
static::needsDirectory(static::$sourceDirectory);
- return new static(DataCollections::findFiles($name, 'md')->mapWithKeys(function (string $file): array {
+ return new static(static::findFiles($name, 'md')->mapWithKeys(function (string $file): array {
return [static::makeIdentifier($file) => MarkdownFileParser::parse($file)];
}));
}
@@ -67,7 +67,7 @@ public static function yaml(string $name): static
{
static::needsDirectory(static::$sourceDirectory);
- return new static(DataCollections::findFiles($name, ['yaml', 'yml'])->mapWithKeys(function (string $file): array {
+ return new static(static::findFiles($name, ['yaml', 'yml'])->mapWithKeys(function (string $file): array {
return [static::makeIdentifier($file) => MarkdownFileParser::parse($file)->matter()];
}));
}
@@ -83,7 +83,7 @@ public static function json(string $name, bool $asArray = false): static
{
static::needsDirectory(static::$sourceDirectory);
- return new static(DataCollections::findFiles($name, 'json')->mapWithKeys(function (string $file) use ($asArray): array {
+ return new static(static::findFiles($name, 'json')->mapWithKeys(function (string $file) use ($asArray): array {
return [static::makeIdentifier($file) => json_decode(Filesystem::get($file), $asArray)];
}));
}
diff --git a/packages/framework/tests/Feature/Commands/RouteListCommandTest.php b/packages/framework/tests/Feature/Commands/RouteListCommandTest.php
index 95edc551478..b715501c251 100644
--- a/packages/framework/tests/Feature/Commands/RouteListCommandTest.php
+++ b/packages/framework/tests/Feature/Commands/RouteListCommandTest.php
@@ -98,6 +98,49 @@ public function testConsoleRouteListWithTypeLabel()
]])->assertExitCode(0);
}
+ public function testConsoleRouteListWithTextFormatOption()
+ {
+ $this->artisan('route:list --format=txt')
+ ->expectsTable($this->headers(), [[
+ 'BladePage',
+ '_pages/404.blade.php',
+ '_site/404.html',
+ '404',
+ ], [
+ 'BladePage',
+ '_pages/index.blade.php',
+ '_site/index.html',
+ 'index',
+ ]])->assertExitCode(0);
+ }
+
+ public function testConsoleRouteListWithJsonFormatOption()
+ {
+ $this->artisan('route:list --format=json')
+ ->expectsOutput(json_encode([
+ [
+ 'page_type' => 'BladePage',
+ 'source_file' => '_pages/404.blade.php',
+ 'output_file' => '_site/404.html',
+ 'route_key' => '404',
+ ],
+ [
+ 'page_type' => 'BladePage',
+ 'source_file' => '_pages/index.blade.php',
+ 'output_file' => '_site/index.html',
+ 'route_key' => 'index',
+ ],
+ ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES))
+ ->assertExitCode(0);
+ }
+
+ public function testConsoleRouteListWithInvalidFormatOption()
+ {
+ $this->artisan('route:list --format=foo')
+ ->expectsOutput("Invalid format provided. Only 'txt' and 'json' are supported.")
+ ->assertExitCode(1);
+ }
+
protected function headers(): array
{
return ['Page Type', 'Source File', 'Output File', 'Route Key'];
diff --git a/packages/framework/tests/Feature/Foundation/HyperlinksTest.php b/packages/framework/tests/Feature/Foundation/HyperlinksTest.php
index 584b8e33d98..bd811f612e1 100644
--- a/packages/framework/tests/Feature/Foundation/HyperlinksTest.php
+++ b/packages/framework/tests/Feature/Foundation/HyperlinksTest.php
@@ -35,7 +35,7 @@ public function testAssetHelperGetsRelativeWebLinkToImageStoredInSiteMediaFolder
];
foreach ($tests as $input => $expected) {
- $this->assertEquals($this->class->asset($input), $expected);
+ $this->assertSame($this->class->asset($input), $expected);
}
}
@@ -50,30 +50,42 @@ public function testAssetHelperResolvesPathsForNestedPages()
foreach ($tests as $input => $expected) {
$this->mockCurrentPage('foo/bar');
- $this->assertEquals($this->class->asset($input), $expected);
+ $this->assertSame($this->class->asset($input), $expected);
}
}
public function testAssetHelperReturnsQualifiedAbsoluteUriWhenRequestedAndSiteHasBaseUrl()
{
- $this->assertEquals('http://localhost/media/test.jpg', $this->class->asset('test.jpg', true));
+ config(['hyde.url' => 'https://example.org']);
+ $this->assertSame('https://example.org/media/test.jpg', $this->class->asset('test.jpg', true));
}
public function testAssetHelperReturnsDefaultRelativePathWhenQualifiedAbsoluteUriIsRequestedButSiteHasNoBaseUrl()
{
config(['hyde.url' => null]);
- $this->assertEquals('media/test.jpg', $this->class->asset('test.jpg', true));
+ $this->assertSame('media/test.jpg', $this->class->asset('test.jpg', true));
+ }
+
+ public function testAssetHelperReturnsDefaultRelativePathWhenQualifiedAbsoluteUriIsRequestedButSiteBaseUrlIsLocalhost()
+ {
+ $this->assertSame('media/test.jpg', $this->class->asset('test.jpg', true));
}
public function testAssetHelperReturnsInputWhenQualifiedAbsoluteUriIsRequestedButImageIsAlreadyQualified()
{
- $this->assertEquals('http://localhost/media/test.jpg', $this->class->asset('http://localhost/media/test.jpg', true));
+ $this->assertSame('http://localhost/media/test.jpg', $this->class->asset('http://localhost/media/test.jpg', true));
+ }
+
+ public function testAssetHelperReturnsInputWhenQualifiedAbsoluteUriIsRequestedButImageIsAlreadyQualifiedRegardlessOfMatchingTheConfiguredUrl()
+ {
+ config(['hyde.url' => 'https://example.org']);
+ $this->assertSame('http://localhost/media/test.jpg', $this->class->asset('http://localhost/media/test.jpg', true));
}
public function testAssetHelperUsesConfiguredMediaDirectory()
{
Hyde::setMediaDirectory('_assets');
- $this->assertEquals('assets/test.jpg', $this->class->asset('test.jpg'));
+ $this->assertSame('assets/test.jpg', $this->class->asset('test.jpg'));
}
public function testMediaLinkHelper()
diff --git a/packages/framework/tests/Feature/HelpersTest.php b/packages/framework/tests/Feature/HelpersTest.php
index a28e49e9497..733a832e7ec 100644
--- a/packages/framework/tests/Feature/HelpersTest.php
+++ b/packages/framework/tests/Feature/HelpersTest.php
@@ -77,7 +77,14 @@ public function testAssetFunction()
public function testAssetFunctionWithQualifiedUrl()
{
$this->assertSame(Hyde::asset('foo', true), asset('foo', true));
- $this->assertSame('http://localhost/media/foo', asset('foo', true));
+ $this->assertSame('media/foo', asset('foo', true));
+ }
+
+ /** @covers ::asset */
+ public function testAssetFunctionWithQualifiedUrlAndSetBaseUrl()
+ {
+ $this->app['config']->set(['hyde.url' => 'https://example.com']);
+ $this->assertSame('https://example.com/media/foo', asset('foo', true));
}
/** @covers ::asset */
@@ -94,6 +101,13 @@ public function testAssetFunctionWithQualifiedUrlAndNoBaseUrl()
$this->assertSame('media/foo', asset('foo', true));
}
+ /** @covers ::asset */
+ public function testAssetFunctionWithQualifiedUrlAndLocalhostBaseUrl()
+ {
+ $this->app['config']->set(['hyde.url' => 'http://localhost']);
+ $this->assertSame('media/foo', asset('foo', true));
+ }
+
/** @covers ::asset */
public function testAssetFunctionFromNestedPage()
{
@@ -145,17 +159,39 @@ public function testUrlFunction()
/** @covers ::url */
public function testUrlFunctionWithBaseUrl()
+ {
+ $this->app['config']->set(['hyde.url' => 'https://example.com']);
+ $this->assertSame('https://example.com/foo', url('foo'));
+ }
+
+ /** @covers ::url */
+ public function testUrlFunctionWithLocalhostBaseUrl()
{
$this->app['config']->set(['hyde.url' => 'http://localhost']);
- $this->assertSame('http://localhost/foo', url('foo'));
+ $this->assertSame('foo', url('foo'));
}
/** @covers ::url */
public function testUrlFunctionWithoutBaseUrl()
{
$this->app['config']->set(['hyde.url' => null]);
+ $this->assertSame('foo', url('foo'));
+ }
+
+ /** @covers ::url */
+ public function testUrlFunctionWithoutBaseUrlOrPath()
+ {
+ $this->app['config']->set(['hyde.url' => null]);
+ $this->expectException(\Hyde\Framework\Exceptions\BaseUrlNotSetException::class);
+ $this->assertNull(url());
+ }
+
+ /** @covers ::url */
+ public function testUrlFunctionWithLocalhostBaseUrlButNoPath()
+ {
+ $this->app['config']->set(['hyde.url' => 'http://localhost']);
$this->expectException(\Hyde\Framework\Exceptions\BaseUrlNotSetException::class);
- $this->assertNull(url('foo'));
+ $this->assertNull(url());
}
/** @covers ::url */
diff --git a/packages/framework/tests/Feature/MarkdownFileParserTest.php b/packages/framework/tests/Feature/MarkdownFileParserTest.php
index 2586eb70dab..09e5b1dc06e 100644
--- a/packages/framework/tests/Feature/MarkdownFileParserTest.php
+++ b/packages/framework/tests/Feature/MarkdownFileParserTest.php
@@ -84,4 +84,19 @@ public function testParsedMarkdownPostContainsValidFrontMatter()
$this->assertSame('Mr. Hyde', $post->matter('author'));
$this->assertSame('blog', $post->matter('category'));
}
+
+ public function testCanParseMarkdownFileWithFrontMatterAndNoMarkdownBody()
+ {
+ file_put_contents(Hyde::path('_posts/test-post.md'), "---\nfoo: bar\n---");
+
+ $document = MarkdownFileParser::parse('_posts/test-post.md');
+
+ $this->assertInstanceOf(MarkdownDocument::class, $document);
+ $this->assertEquals('', $document->markdown);
+ $this->assertSame('', $document->markdown->body());
+
+ $this->assertEquals(FrontMatter::fromArray([
+ 'foo' => 'bar',
+ ]), $document->matter);
+ }
}
diff --git a/packages/framework/tests/Feature/SitesWithoutBaseUrlAreHandledGracefullyTest.php b/packages/framework/tests/Feature/SitesWithoutBaseUrlAreHandledGracefullyTest.php
new file mode 100644
index 00000000000..cd4e9373605
--- /dev/null
+++ b/packages/framework/tests/Feature/SitesWithoutBaseUrlAreHandledGracefullyTest.php
@@ -0,0 +1,77 @@
+ null]);
+
+ $this->assertStringNotContainsString('http://localhost', $this->getHtml($class));
+ }
+
+ /** @dataProvider pageClassProvider */
+ public function testLocalhostLinksAreNotAddedToCompiledHtmlWhenBaseUrlIsNotSet(string $class)
+ {
+ config(['hyde.url' => '']);
+
+ $this->assertStringNotContainsString('http://localhost', $this->getHtml($class));
+ }
+
+ /** @dataProvider pageClassProvider */
+ public function testLocalhostLinksAreNotAddedToCompiledHtmlWhenBaseUrlIsSetToLocalhost(string $class)
+ {
+ config(['hyde.url' => 'http://localhost']);
+
+ $this->assertStringNotContainsString('http://localhost', $this->getHtml($class));
+ }
+
+ /** @dataProvider pageClassProvider */
+ public function testSiteUrlLinksAreAddedToCompiledHtmlWhenBaseUrlIsSetToValidUrl(string $class)
+ {
+ config(['hyde.url' => 'https://example.com']);
+
+ $this->assertStringNotContainsString('http://localhost', $this->getHtml($class));
+ }
+
+ protected function getHtml(string $class): string
+ {
+ $page = new $class('foo');
+
+ Hyde::shareViewData($page);
+
+ return $page->compile();
+ }
+}
diff --git a/packages/framework/tests/Feature/Views/MetadataViewTest.php b/packages/framework/tests/Feature/Views/MetadataViewTest.php
index 199759644d4..54ba018d2d4 100644
--- a/packages/framework/tests/Feature/Views/MetadataViewTest.php
+++ b/packages/framework/tests/Feature/Views/MetadataViewTest.php
@@ -25,7 +25,7 @@ protected function setUp(): void
{
parent::setUp();
- config(['hyde.url' => 'http://localhost']);
+ config(['hyde.url' => 'https://example.com']);
config(['hyde.enable_cache_busting' => false]);
}
@@ -79,7 +79,7 @@ protected function getDefaultTags(): array
'',
'',
'',
- '',
+ '',
'',
'',
];
@@ -93,7 +93,7 @@ public function testMetadataTagsInEmptyBladePage()
$assertions = $this->assertSee('test', array_merge($this->getDefaultTags(), [
'HydePHP - Test',
'',
- '',
+ '',
'',
'',
]));
@@ -109,7 +109,7 @@ public function testMetadataTagsInEmptyMarkdownPage()
$assertions = $this->assertSee('test', array_merge($this->getDefaultTags(), [
'HydePHP - Test',
'',
- '',
+ '',
'',
'',
]));
@@ -125,7 +125,7 @@ public function testMetadataTagsInEmptyDocumentationPage()
$assertions = $this->assertSee('docs/test', array_merge($this->getDefaultTags(), [
'HydePHP - Test',
'',
- '',
+ '',
'',
'',
]));
@@ -140,16 +140,16 @@ public function testMetadataTagsInEmptyMarkdownPost()
$assertions = $this->assertSee('posts/test', array_merge($this->getDefaultTags(), [
'HydePHP - Test',
- '',
+ '',
'',
- '',
+ '',
'',
- '',
+ '',
'',
- '',
+ '',
'',
'',
- '',
+ '',
]));
$this->assertAllTagsWereCovered('posts/test', $assertions);
@@ -177,25 +177,92 @@ public function testMetadataTagsInMarkdownPostWithFlatFrontMatter()
$assertions = $this->assertSee('posts/test', array_merge($this->getDefaultTags(), [
'HydePHP - My title',
- '',
+ '',
'',
- '',
+ '',
'',
'',
'',
'',
- '',
+ '',
'',
- '',
+ '',
'',
'',
'',
'',
- '',
+ '',
'',
'',
]));
$this->assertAllTagsWereCovered('posts/test', $assertions);
}
+
+ public function testCanonicalUrlTagsAreNotAddedWhenCanonicalUrlIsNotSet()
+ {
+ config(['hyde.url' => 'http://localhost']);
+
+ $this->file('_posts/test.md', <<<'MARKDOWN'
+ ---
+ title: "My title"
+ description: "My description"
+ category: "My category"
+ date: "2022-01-01"
+ author: "Mr. Hyde"
+ image: image.jpg
+ ---
+
+ ## Hello World
+
+ Lorem Ipsum Dolor Amet.
+ MARKDOWN
+ );
+ $this->build('_posts/test.md');
+
+ $assertions = $this->assertSee('posts/test', [
+ '',
+ '',
+ '',
+ '',
+ '',
+ 'HydePHP - My title',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+
+ // '',
+ // '',
+ // '',
+ // '',
+ // '',
+ // '',
+ ]);
+
+ $this->assertAllTagsWereCovered('posts/test', $assertions);
+
+ $dontSee = [
+ '= 8"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/immutable": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
- "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
- "dev": true
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/sass": {
- "version": "1.50.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
- "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
- "dev": true,
- "dependencies": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
- "source-map-js": ">=0.6.2 <2.0.0"
- },
- "bin": {
- "sass": "sass.js"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- }
+ "name": "hydefront",
+ "version": "3.3.4",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "hydefront",
+ "version": "3.3.4",
+ "license": "MIT",
+ "devDependencies": {
+ "sass": "1.50.0"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
},
- "dependencies": {
- "anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
- "requires": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "fsevents": "~2.3.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
- "glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "requires": {
- "is-glob": "^4.0.1"
- }
- },
- "immutable": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
- "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
- "dev": true
- },
- "is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "requires": {
- "binary-extensions": "^2.0.0"
- }
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
- "is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
- },
- "picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true
- },
- "readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "requires": {
- "picomatch": "^2.2.1"
- }
- },
- "sass": {
- "version": "1.50.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
- "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
- "dev": true,
- "requires": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
- "source-map-js": ">=0.6.2 <2.0.0"
- }
- },
- "source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "dev": true
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
+ "dev": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.50.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
+ "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ }
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.1.1"
+ }
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "immutable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "sass": {
+ "version": "1.50.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
+ "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
+ "dev": true,
+ "requires": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ }
+ },
+ "source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
}
+ }
}