From 34bcfd84b1b74ed6d35cbea86578577b8dfe9e62 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 16 Jan 2025 17:44:03 +0100 Subject: [PATCH 01/57] fix: Dock facade (#470) --- src/Facades/Dock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facades/Dock.php b/src/Facades/Dock.php index b088219d..ddeaffb4 100644 --- a/src/Facades/Dock.php +++ b/src/Facades/Dock.php @@ -6,8 +6,8 @@ use Native\Laravel\Menu\Menu; /** - * @method static void bounce() - * @method static void|string badge(string $type = null) + * @method static void bounce(string $type = 'informational') + * @method static void|string badge(?string $type = null) * @method static void cancelBounce() * @method static void hide() * @method static void icon(string $Path) From 4235d2c17cd177ac031efb3e4e81405077cda140 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 16 Jan 2025 17:44:29 +0100 Subject: [PATCH 02/57] fix: child process facade (#471) --- src/Facades/ChildProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facades/ChildProcess.php b/src/Facades/ChildProcess.php index 0436507e..d6793c8b 100644 --- a/src/Facades/ChildProcess.php +++ b/src/Facades/ChildProcess.php @@ -8,7 +8,7 @@ /** * @method static \Native\Laravel\ChildProcess[] all() - * @method static \Native\Laravel\ChildProcess get(string $alias = null) + * @method static \Native\Laravel\ChildProcess|null get(string $alias = null) * @method static \Native\Laravel\ChildProcess message(string $message, string $alias = null) * @method static \Native\Laravel\ChildProcess restart(string $alias = null) * @method static \Native\Laravel\ChildProcess start(string|array $cmd, string $alias, string $cwd = null, array $env = null, bool $persistent = false) From d643e194b92f47369dd348de1d7baa29976914a4 Mon Sep 17 00:00:00 2001 From: simonhamp <31628+simonhamp@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:38:19 +0000 Subject: [PATCH 03/57] Update CHANGELOG --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c33f8d4..1e898901 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 1.0.0-beta.1 - 2025-01-21 + +### What's Changed + +* Child process queue workers by @XbNz in https://github.com/NativePHP/laravel/pull/450 +* fix: static analysis by @SRWieZ in https://github.com/NativePHP/laravel/pull/452 +* feat: default notification title by @SRWieZ in https://github.com/NativePHP/laravel/pull/451 +* Fix menubar not ready by @SRWieZ in https://github.com/NativePHP/laravel/pull/453 +* Add support for Window::show() by @curtisblackwell in https://github.com/NativePHP/laravel/pull/454 +* Fix: Return type mismatch between screen facade and screen class methods. by @kondi3 in https://github.com/NativePHP/laravel/pull/463 + +### New Contributors + +* @kondi3 made their first contribution in https://github.com/NativePHP/laravel/pull/463 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.7.0...0.8.0 + ## 0.7.0 - 2024-12-19 ### What's Changed From 1fe65da9dba54d2d5e7e959b50fc2a9a93a5546b Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 22 Jan 2025 08:42:50 +0100 Subject: [PATCH 04/57] Add queue worker config docblock --- config/nativephp.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 5c6e7a8f..da17b0b7 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -115,6 +115,9 @@ ], ], + /** + * The queue workers that get auto-started on your application start. + */ 'queue_workers' => [ 'default' => [ 'queues' => ['default'], From 597e0dc0056e6356cf38149cc3e8e2c450604c52 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 23 Jan 2025 10:58:18 +0000 Subject: [PATCH 05/57] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 45e26d39..4308c95a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits - [Marcel Pociot](https://github.com/mpociot) +- [Simon Hamp](https://github.com/simonhamp) - [All Contributors](../../contributors) ## License From 3ccd85ed1c294ca76bd50c60b9d539fce1bbce5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 00:35:48 +0000 Subject: [PATCH 06/57] Bump dependabot/fetch-metadata from 2.2.0 to 2.3.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index eb537d8c..2cb1d5e1 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.2.0 + uses: dependabot/fetch-metadata@v2.3.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 7eae6d8e115608cfa27c2cc571675dc1c3f241eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 00:36:22 +0000 Subject: [PATCH 07/57] Bump aglipanci/laravel-pint-action from 2.4 to 2.5 Bumps [aglipanci/laravel-pint-action](https://github.com/aglipanci/laravel-pint-action) from 2.4 to 2.5. - [Release notes](https://github.com/aglipanci/laravel-pint-action/releases) - [Commits](https://github.com/aglipanci/laravel-pint-action/compare/2.4...2.5) --- updated-dependencies: - dependency-name: aglipanci/laravel-pint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 255506b8..0edbd389 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -19,7 +19,7 @@ jobs: ref: ${{ github.head_ref }} - name: Fix PHP code style issues - uses: aglipanci/laravel-pint-action@2.4 + uses: aglipanci/laravel-pint-action@2.5 - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5 From 1f8831baabf8d169bd139a6877814a9f6d9eaba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llstrand=20Modig?= Date: Thu, 13 Feb 2025 15:39:54 +0100 Subject: [PATCH 08/57] Add endpoint to resize MenuBar window (#490) --- src/Facades/MenuBar.php | 4 ++++ src/MenuBar/MenuBarManager.php | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Facades/MenuBar.php b/src/Facades/MenuBar.php index 97abad96..15d9879f 100644 --- a/src/Facades/MenuBar.php +++ b/src/Facades/MenuBar.php @@ -10,6 +10,9 @@ * @method static void show() * @method static void hide() * @method static void label(string $label) + * @method static void tooltip(string $label) + * @method static void icon(string $icon) + * @method static void resize(int $width, int $height) * @method static void contextMenu(Menu $contextMenu) */ class MenuBar extends Facade @@ -19,3 +22,4 @@ protected static function getFacadeAccessor() return \Native\Laravel\MenuBar\MenuBarManager::class; } } + diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index b10992dd..f9c2bdea 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -45,6 +45,14 @@ public function icon(string $icon) ]); } + public function resize(int $width, int $height) + { + $this->client->post('menu-bar/resize', [ + 'width' => $width, + 'height' => $height, + ]); + } + public function contextMenu(Menu $contextMenu) { $this->client->post('menu-bar/context-menu', [ From 182c5d86fa272df01b7b9c8345419f7ef6c7bfe0 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 17 Feb 2025 16:52:09 +0100 Subject: [PATCH 09/57] feat: add missing facades into composer.json (#495) --- composer.json | 16 ++++++++++++++-- src/Facades/MenuBar.php | 1 - 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 9f7b760f..850270b9 100644 --- a/composer.json +++ b/composer.json @@ -85,11 +85,23 @@ "Native\\Laravel\\NativeServiceProvider" ], "aliases": { + "App": "Native\\Laravel\\Facades\\App", + "ChildProcess": "Native\\Laravel\\Facades\\ChildProcess", + "Clipboard": "Native\\Laravel\\Facades\\Clipboard", "ContextMenu": "Native\\Laravel\\Facades\\ContextMenu", "Dock": "Native\\Laravel\\Facades\\Dock", + "GlobalShortcut": "Native\\Laravel\\Facades\\GlobalShortcut", + "Menu": "Native\\Laravel\\Facades\\Menu", + "MenuBar": "Native\\Laravel\\Facades\\MenuBar", + "Notification": "Native\\Laravel\\Facades\\Notification", + "PowerMonitor": "Native\\Laravel\\Facades\\PowerMonitor", "Process": "Native\\Laravel\\Facades\\Process", - "Window": "Native\\Laravel\\Facades\\Window", - "Clipboard": "Native\\Laravel\\Facades\\Clipboard" + "QueueWorker": "Native\\Laravel\\Facades\\QueueWorker", + "Screen": "Native\\Laravel\\Facades\\Screen", + "Settings": "Native\\Laravel\\Facades\\Settings", + "Shell": "Native\\Laravel\\Facades\\Shell", + "System": "Native\\Laravel\\Facades\\System", + "Window": "Native\\Laravel\\Facades\\Window" } } }, diff --git a/src/Facades/MenuBar.php b/src/Facades/MenuBar.php index 15d9879f..b1d4972c 100644 --- a/src/Facades/MenuBar.php +++ b/src/Facades/MenuBar.php @@ -22,4 +22,3 @@ protected static function getFacadeAccessor() return \Native\Laravel\MenuBar\MenuBarManager::class; } } - From dfcd9e29958ade01c693d2264a2e96b91e3a4a6a Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 21 Feb 2025 15:24:51 +0100 Subject: [PATCH 10/57] Notification improvements (#498) * Add support for notification reference * Add reference to Notification clicked class * Support for more notification actions * Make reference public * Support for actions and reply * Add missing methods to the facade * Properly send the actions --- .../NotificationActionClicked.php | 23 ++++++++++ .../Notifications/NotificationClicked.php | 2 + .../Notifications/NotificationClosed.php | 23 ++++++++++ .../Notifications/NotificationReply.php | 23 ++++++++++ src/Facades/Notification.php | 3 ++ src/Notification.php | 45 ++++++++++++++++++- 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 src/Events/Notifications/NotificationActionClicked.php create mode 100644 src/Events/Notifications/NotificationClosed.php create mode 100644 src/Events/Notifications/NotificationReply.php diff --git a/src/Events/Notifications/NotificationActionClicked.php b/src/Events/Notifications/NotificationActionClicked.php new file mode 100644 index 00000000..de658b3c --- /dev/null +++ b/src/Events/Notifications/NotificationActionClicked.php @@ -0,0 +1,23 @@ +title = config('app.name'); @@ -22,6 +30,13 @@ public static function new() return new static(new Client); } + public function reference(string $reference): self + { + $this->reference = $reference; + + return $this; + } + public function title(string $title): self { $this->title = $title; @@ -36,6 +51,21 @@ public function event(string $event): self return $this; } + public function hasReply(string $placeholder = ''): self + { + $this->hasReply = true; + $this->replyPlaceholder = $placeholder; + + return $this; + } + + public function addAction(string $label): self + { + $this->actions[] = $label; + + return $this; + } + public function message(string $body): self { $this->body = $body; @@ -43,12 +73,23 @@ public function message(string $body): self return $this; } - public function show(): void + public function show(): self { - $this->client->post('notification', [ + $response = $this->client->post('notification', [ + 'reference' => $this->reference, 'title' => $this->title, 'body' => $this->body, 'event' => $this->event, + 'hasReply' => $this->hasReply, + 'replyPlaceholder' => $this->replyPlaceholder, + 'actions' => array_map(fn(string $label) => [ + 'type' => 'button', + 'text' => $label + ], $this->actions), ]); + + $this->reference = $response->json('reference'); + + return $this; } } From 2844fe831b4fb2b1b9021a7b7ef169ecb2f6597e Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Fri, 21 Feb 2025 20:52:59 +0100 Subject: [PATCH 11/57] Update cleanup directory defaults (#467) * update cleanup files defaults * add default cleanup_exclude_files to internal config * remove vendor/bin & add */tests to exclude list * remove MinifyApplication command * remove php compactor * moved internal cleanup_exclude files back again This is hard to test when the config I'm asserting on lives on a different repo from the test itself. --- config/nativephp.php | 4 +- src/Commands/MinifyApplicationCommand.php | 111 ------------- src/Compactor/Php.php | 189 ---------------------- src/NativeServiceProvider.php | 2 - 4 files changed, 2 insertions(+), 304 deletions(-) delete mode 100644 src/Commands/MinifyApplicationCommand.php delete mode 100644 src/Compactor/Php.php diff --git a/config/nativephp.php b/config/nativephp.php index da17b0b7..45f82250 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -61,8 +61,8 @@ */ 'cleanup_exclude_files' => [ 'content', - 'storage/app/framework/{sessions,testing,cache}', - 'storage/logs/laravel.log', + 'node_modules', + '*/tests' ], /** diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php deleted file mode 100644 index 37d8378b..00000000 --- a/src/Commands/MinifyApplicationCommand.php +++ /dev/null @@ -1,111 +0,0 @@ -argument('app')); - - if (! is_dir($appPath)) { - $this->error('The app path is not a directory'); - - return; - } - - $this->info('Minifying application…'); - - $this->cleanUpEnvFile($appPath); - $this->removeIgnoredFilesAndFolders($appPath); - - $compactor = new Php; - - $phpFiles = Finder::create() - ->files() - ->name('*.php') - ->in($appPath); - - foreach ($phpFiles as $phpFile) { - $minifiedContent = $compactor->compact($phpFile->getRealPath(), $phpFile->getContents()); - file_put_contents($phpFile->getRealPath(), $minifiedContent); - } - } - - protected function cleanUpEnvFile(string $appPath): void - { - $envFile = $appPath.'/.env'; - - if (! file_exists($envFile)) { - return; - } - - $this->info('Cleaning up .env file…'); - - $cleanUpKeys = config('nativephp.cleanup_env_keys', []); - - $envContent = file_get_contents($envFile); - $envValues = collect(explode("\n", $envContent)) - ->filter(function (string $line) use ($cleanUpKeys) { - $key = Str::before($line, '='); - - return ! Str::is($cleanUpKeys, $key); - }) - ->join("\n"); - - file_put_contents($envFile, $envValues); - } - - protected function removeIgnoredFilesAndFolders(string $appPath): void - { - $this->info('Cleaning up ignored files and folders…'); - - $itemsToRemove = config('nativephp.cleanup_exclude_files', []); - - foreach ($itemsToRemove as $item) { - $fullPath = $appPath.'/'.$item; - - if (file_exists($fullPath)) { - if (is_dir($fullPath)) { - $this->deleteDirectoryRecursive($fullPath); - } else { - array_map('unlink', glob($fullPath)); - } - } else { - foreach (glob($item) as $pathFound) { - unlink($pathFound); - } - } - } - } - - private function deleteDirectoryRecursive(string $directory): bool - { - if (! file_exists($directory)) { - return true; - } - - if (! is_dir($directory)) { - return unlink($directory); - } - - foreach (scandir($directory) as $item) { - if ($item == '.' || $item == '..') { - continue; - } - - if (! $this->deleteDirectoryRecursive($directory.'/'.$item)) { - return false; - } - } - - return rmdir($directory); - } -} diff --git a/src/Compactor/Php.php b/src/Compactor/Php.php deleted file mode 100644 index 7b5d3ad1..00000000 --- a/src/Compactor/Php.php +++ /dev/null @@ -1,189 +0,0 @@ -canProcessFile($file)) { - return $this->compactContent($contents); - } - - return $this->compactContent($contents); - } - - protected function compactContent(string $contents): string - { - $output = ''; - $tokens = PhpToken::tokenize($contents); - $tokenCount = count($tokens); - - for ($index = 0; $index < $tokenCount; $index++) { - $token = $tokens[$index]; - $tokenText = $token->text; - - if ($token->is([T_COMMENT, T_DOC_COMMENT])) { - if (str_starts_with($tokenText, '#[')) { - // This is, in all likelihood, the start of a PHP >= 8.0 attribute. - // Note: $tokens may be updated by reference as well! - $retokenized = $this->retokenizeAttribute($tokens, $index); - - if ($retokenized !== null) { - array_splice($tokens, $index, 1, $retokenized); - $tokenCount = count($tokens); - } - - $attributeCloser = self::findAttributeCloser($tokens, $index); - - if (is_int($attributeCloser)) { - $output .= '#['; - } else { - // Turns out this was not an attribute. Treat it as a plain comment. - $output .= str_repeat("\n", mb_substr_count($tokenText, "\n")); - } - } elseif (str_contains($tokenText, '@')) { - try { - $output .= $this->compactAnnotations($tokenText); - } catch (RuntimeException) { - $output .= $tokenText; - } - } else { - $output .= str_repeat("\n", mb_substr_count($tokenText, "\n")); - } - } elseif ($token->is(T_WHITESPACE)) { - $whitespace = $tokenText; - $previousIndex = ($index - 1); - - // Handle whitespace potentially being split into two tokens after attribute retokenization. - $nextToken = $tokens[$index + 1] ?? null; - - if ($nextToken !== null - && $nextToken->is(T_WHITESPACE) - ) { - $whitespace .= $nextToken->text; - $index++; - } - - // reduce wide spaces - $whitespace = preg_replace('{[ \t]+}', ' ', $whitespace); - - // normalize newlines to \n - $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); - - // If the new line was split off from the whitespace token due to it being included in - // the previous (comment) token (PHP < 8), remove leading spaces. - - $previousToken = $tokens[$previousIndex]; - - if ($previousToken->is(T_COMMENT) - && str_contains($previousToken->text, "\n") - ) { - $whitespace = ltrim($whitespace, ' '); - } - - // trim leading spaces - $whitespace = preg_replace('{\n +}', "\n", $whitespace); - - $output .= $whitespace; - } else { - $output .= $tokenText; - } - } - - return $output; - } - - private function compactAnnotations(string $docblock): string - { - return $docblock; - } - - /** - * @param list $tokens - */ - private static function findAttributeCloser(array $tokens, int $opener): ?int - { - $tokenCount = count($tokens); - $brackets = [$opener]; - $closer = null; - - for ($i = ($opener + 1); $i < $tokenCount; $i++) { - $tokenText = $tokens[$i]->text; - - // Allow for short arrays within attributes. - if ($tokenText === '[') { - $brackets[] = $i; - - continue; - } - - if ($tokenText === ']') { - array_pop($brackets); - - if (count($brackets) === 0) { - $closer = $i; - break; - } - } - } - - return $closer; - } - - /** - * @param non-empty-list $tokens - */ - private function retokenizeAttribute(array &$tokens, int $opener): ?array - { - Assert::keyExists($tokens, $opener); - - $token = $tokens[$opener]; - $attributeBody = mb_substr($token->text, 2); - $subTokens = PhpToken::tokenize('text; - } - - $subTokens = PhpToken::tokenize('hasConfigFile() ->hasRoute('api') From dc1d2f1d69a13bf50829dd055b2c21f43465c2c9 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Sat, 22 Feb 2025 14:41:53 +0000 Subject: [PATCH 12/57] Implement default config for pre and post build keys (#496) --- config/nativephp.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 45f82250..8c62e006 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -125,4 +125,15 @@ 'timeout' => 60, ], ], + + /** + * Define your own scripts to run before and after the build process. + */ + 'prebuild' => [ + // 'npm run build', + ], + + 'postbuild' => [ + // 'rm -rf public/build', + ], ]; From a2183f2f1196286edc101ae5334c6f67a1c949f3 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 14:04:19 +0100 Subject: [PATCH 13/57] chore: delete outdated tests (#500) --- config/nativephp.php | 2 +- src/Notification.php | 4 +- tests/Command/IgnoreFilesAndFoldersTest.php | 88 --------------------- 3 files changed, 3 insertions(+), 91 deletions(-) delete mode 100644 tests/Command/IgnoreFilesAndFoldersTest.php diff --git a/config/nativephp.php b/config/nativephp.php index 8c62e006..6e4edcf1 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -62,7 +62,7 @@ 'cleanup_exclude_files' => [ 'content', 'node_modules', - '*/tests' + '*/tests', ], /** diff --git a/src/Notification.php b/src/Notification.php index a1da4847..578d860e 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -82,9 +82,9 @@ public function show(): self 'event' => $this->event, 'hasReply' => $this->hasReply, 'replyPlaceholder' => $this->replyPlaceholder, - 'actions' => array_map(fn(string $label) => [ + 'actions' => array_map(fn (string $label) => [ 'type' => 'button', - 'text' => $label + 'text' => $label, ], $this->actions), ]); diff --git a/tests/Command/IgnoreFilesAndFoldersTest.php b/tests/Command/IgnoreFilesAndFoldersTest.php deleted file mode 100644 index e805cc0a..00000000 --- a/tests/Command/IgnoreFilesAndFoldersTest.php +++ /dev/null @@ -1,88 +0,0 @@ -artisan('native:minify resources/app'); - $this->assertFalse(file_exists($laravelLog)); - - // Clean up after ourselves - if (file_exists($laravelLog)) { - unlink($laravelLog); - } - if (file_exists('resources/app/storage/logs')) { - rmdir('resources/app/storage/logs'); - } - if (file_exists('resources/app/storage')) { - rmdir('resources/app/storage'); - } - removeAppFolder(); -}); - -it('will remove the content folder by default before building', function () { - $contentPath = 'resources/app/content'; - - // Create a dummy copy of the folder - if (! file_exists($contentPath)) { - mkdir($contentPath, 0755, true); - } - - // Run the test - $this->artisan('native:minify resources/app'); - $this->assertFalse(file_exists($contentPath)); - - // Clean up after ourselves - if (file_exists($contentPath)) { - unlink($contentPath); - } - removeAppFolder(); -}); - -it('will remove only files that match a globbed path', function () { - $wildcardPath = 'resources/app/wildcardPath'; - $yes1DeletePath = $wildcardPath.'/YES1.txt'; - $yes2DeletePath = $wildcardPath.'/YES2.txt'; - $noDeletePath = $wildcardPath.'/NO.txt'; - - config()->set('nativephp.cleanup_exclude_files', [$wildcardPath.'/YES*']); - - // Create some dummy files - if (! file_exists($wildcardPath)) { - mkdir($wildcardPath, 0755, true); - } - file_put_contents($yes1DeletePath, 'PLEASE DELETE ME'); - file_put_contents($yes2DeletePath, 'PLEASE DELETE ME TOO'); - file_put_contents($noDeletePath, 'DO NOT DELETE ME'); - - // Run the test - $this->artisan('native:minify resources/app'); - $this->assertFalse(file_exists($yes1DeletePath)); - $this->assertFalse(file_exists($yes2DeletePath)); - $this->assertTrue(file_exists($noDeletePath)); - - // Clean up after ourselves - foreach ([$yes1DeletePath, $yes2DeletePath, $noDeletePath] as $remove) { - if (file_exists($remove)) { - unlink($remove); - } - } - if (file_exists($wildcardPath)) { - rmdir($wildcardPath); - } - removeAppFolder(); -}); - -function removeAppFolder() -{ - if (file_exists('resources/app')) { - rmdir('resources/app'); - } -} From cea2b0d606d16db831c42eed33a9e376e86dfcdc Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 16:11:28 +0100 Subject: [PATCH 14/57] fix: linting workflow (#499) --- .../workflows/fix-php-code-style-issues.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 0edbd389..eb79b6e0 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -1,9 +1,15 @@ -name: Fix PHP code style issues +# Check and fix PHP code style issues +# Pull request: automatically fix PHP code style issues +# Main branch: only check PHP code style issues since we don't have write permission +name: Check and fix PHP code style issues on: push: paths: - '**.php' + pull_request: + paths: + - '**.php' permissions: contents: write @@ -18,10 +24,20 @@ jobs: with: ref: ${{ github.head_ref }} + - name: Check PHP code style issues + if: github.event_name == 'push' + uses: aglipanci/laravel-pint-action@2.5 + with: + verboseMode: true + testMode: true + - name: Fix PHP code style issues + if: github.event_name == 'pull_request' uses: aglipanci/laravel-pint-action@2.5 - name: Commit changes + if: github.event_name == 'pull_request' uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Fix styling + From 0ff6ae6042a60450d3086d21073f902e5ad3d726 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 16:11:38 +0100 Subject: [PATCH 15/57] fix: deprecated error in tests (#501) --- tests/DTOs/QueueWorkerTest.php | 56 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/tests/DTOs/QueueWorkerTest.php b/tests/DTOs/QueueWorkerTest.php index bc1b764f..76209c8b 100644 --- a/tests/DTOs/QueueWorkerTest.php +++ b/tests/DTOs/QueueWorkerTest.php @@ -17,8 +17,10 @@ )->queuesToConsume->toBe(['default'] ); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); continue; } @@ -29,37 +31,45 @@ )->queuesToConsume->toBe($worker['queues'] ?? ['default'] ); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); } })->with([ [ - 'queue_workers' => [ - 'some_worker' => [ - 'queues' => ['default'], - 'memory_limit' => 64, - 'timeout' => 60, + [ + 'queue_workers' => [ + 'some_worker' => [ + 'queues' => ['default'], + 'memory_limit' => 64, + 'timeout' => 60, + ], ], ], ], [ - 'queue_workers' => [ - 'some_worker' => [], - 'another_worker' => [], + [ + 'queue_workers' => [ + 'some_worker' => [], + 'another_worker' => [], + ], ], ], [ - 'queue_workers' => [ - 'some_worker' => [ - ], - 'another_worker' => [ - 'queues' => ['default', 'another'], - ], - 'yet_another_worker' => [ - 'memory_limit' => 256, - ], - 'one_more_worker' => [ - 'timeout' => 120, + [ + 'queue_workers' => [ + 'some_worker' => [ + ], + 'another_worker' => [ + 'queues' => ['default', 'another'], + ], + 'yet_another_worker' => [ + 'memory_limit' => 256, + ], + 'one_more_worker' => [ + 'timeout' => 120, + ], ], ], ], From 0102a92c7eec291bf12e1477a31a59f67698034b Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 17:00:58 +0100 Subject: [PATCH 16/57] Support Laravel 12.x & PHP 8.4 (#494) --- .github/workflows/run-tests.yml | 27 ++++++---------- composer.json | 18 +++++------ phpstan.neon | 9 ++++-- src/Commands/LoadPHPConfigurationCommand.php | 2 ++ src/Concerns/InteractsWithNativeApp.php | 34 -------------------- 5 files changed, 27 insertions(+), 63 deletions(-) delete mode 100644 src/Concerns/InteractsWithNativeApp.php diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 107761bf..a1909f62 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -10,28 +10,18 @@ jobs: test: runs-on: ${{ matrix.os }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - php: [8.3, 8.2, 8.1] - laravel: [11.*, 10.*] + php: [8.4, 8.3, 8.2, 8.1] + laravel: [12.*, 11.*, 10.*] stability: [prefer-lowest, prefer-stable] - include: - - laravel: 11.* - testbench: 9.* - carbon: ^3.2 - laravel-package-tools: ^1.16.4 - collision: ^8.1.1 - - - laravel: 10.* - testbench: 8.* - carbon: ^2.63 - laravel-package-tools: ^1.16.4 - collision: 7.* exclude: - laravel: 11.* php: 8.1 + - laravel: 12.* + php: 8.1 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} @@ -53,11 +43,14 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-package-tools:${{ matrix.laravel-package-tools }}" "nunomaduro/collision:${{ matrix.collision }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction - name: List Installed Dependencies - run: composer show -D + run: composer show + +# - name: Debug PhpUnit version +# run: composer why phpunit/phpunit -t - name: Execute tests run: vendor/bin/pest diff --git a/composer.json b/composer.json index 850270b9..71336edd 100644 --- a/composer.json +++ b/composer.json @@ -32,22 +32,22 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^10.0|^11.0", + "illuminate/contracts": "^10.0|^11.0|^12.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.0", - "larastan/larastan": "^2.0|^3.0", "laravel/pint": "^1.0", - "nunomaduro/collision": "^7.9", - "orchestra/testbench": "^8.0", - "pestphp/pest": "^2.0", - "pestphp/pest-plugin-arch": "^2.0", - "pestphp/pest-plugin-laravel": "^2.0", + "larastan/larastan": "^2.0|^3.1", + "nunomaduro/collision": "^7.11|^8.1.1", + "orchestra/testbench": "^8.0|^9.0|^10.0", + "pestphp/pest": "^v2.30|^3.0", + "pestphp/pest-plugin-arch": "^2.0|^3.0", + "pestphp/pest-plugin-laravel": "^2.0|^3.1", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", + "phpstan/phpstan-phpunit": "^1.0|^2.0", "spatie/laravel-ray": "^1.26" }, "autoload": { diff --git a/phpstan.neon b/phpstan.neon index 33be1e3a..b6543b0b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,10 +9,13 @@ parameters: # Level 9 is the highest level level: 5 + + noEnvCallsOutsideOfConfig: false # Don't know why he doesn't consider our config/ directory as config + ignoreErrors: - '#Class App\\Providers\\NativeAppServiceProvider not found#' - '#Class Native\\Laravel\\ChildProcess has an uninitialized readonly property#' -# -# excludePaths: -# - ./*/*/FileToBeExcluded.php + + excludePaths: + - ./src/NativeServiceProvider.php diff --git a/src/Commands/LoadPHPConfigurationCommand.php b/src/Commands/LoadPHPConfigurationCommand.php index b3b7a714..1a2ba579 100644 --- a/src/Commands/LoadPHPConfigurationCommand.php +++ b/src/Commands/LoadPHPConfigurationCommand.php @@ -14,6 +14,8 @@ public function handle() /** @var ProvidesPhpIni $provider */ $provider = app(config('nativephp.provider')); $phpIni = []; + + /* * @phpstan-ignore-next-line */ if (method_exists($provider, 'phpIni')) { $phpIni = $provider->phpIni(); } diff --git a/src/Concerns/InteractsWithNativeApp.php b/src/Concerns/InteractsWithNativeApp.php deleted file mode 100644 index 7dd6ee78..00000000 --- a/src/Concerns/InteractsWithNativeApp.php +++ /dev/null @@ -1,34 +0,0 @@ -start(); - - if (is_iterable($totalSteps)) { - foreach ($totalSteps as $value) { - $callback($value, $bar); - - $bar->advance(); - } - } else { - $callback($bar); - } - - $bar->finish(); - - if (is_iterable($totalSteps)) { - return $totalSteps; - } - } -} From 212f11b7b9590c6cb4a0ed16ef11f27310a3677d Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 4 Mar 2025 14:12:45 +0100 Subject: [PATCH 17/57] feat: zephpyr configs --- config/nativephp-internal.php | 9 +++++++++ config/nativephp.php | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/config/nativephp-internal.php b/config/nativephp-internal.php index 4210df92..a9d97c79 100644 --- a/config/nativephp-internal.php +++ b/config/nativephp-internal.php @@ -29,4 +29,13 @@ * The URL to the NativePHP API. */ 'api_url' => env('NATIVEPHP_API_URL', 'http://localhost:4000/api/'), + + /** + * Configuration for the Zephpyr API. + */ + 'zephpyr' => [ + 'host' => env('ZEPHPYR_HOST', 'https://zephpyr.com'), + 'token' => env('ZEPHPYR_TOKEN'), + 'key' => env('ZEPHPYR_KEY'), + ], ]; diff --git a/config/nativephp.php b/config/nativephp.php index 6e4edcf1..49eacd84 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -48,6 +48,7 @@ 'GITHUB_*', 'DO_SPACES_*', '*_SECRET', + 'ZEPHPYR_*', 'NATIVEPHP_UPDATER_PATH', 'NATIVEPHP_APPLE_ID', 'NATIVEPHP_APPLE_ID_PASS', @@ -60,6 +61,8 @@ * You may use glob / wildcard patterns here. */ 'cleanup_exclude_files' => [ + 'build', + 'temp', 'content', 'node_modules', '*/tests', @@ -136,4 +139,9 @@ 'postbuild' => [ // 'rm -rf public/build', ], + + /** + * Custom PHP binary path. + */ + 'binary_path' => env('NATIVEPHP_BINARY_PATH', null), ]; From 334b5dedfeb901763906a1ff128c432bb51f546e Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 4 Mar 2025 14:14:12 +0100 Subject: [PATCH 18/57] fix: don't create database inside a phar --- src/NativeServiceProvider.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index b5b32252..1c134031 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -25,6 +25,7 @@ use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; +use Phar; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -148,7 +149,8 @@ public function rewriteDatabase() { $databasePath = config('nativephp-internal.database_path'); - if (config('app.debug')) { + // Automatically create the database in development mode but not if we are running in a Phar + if (config('app.debug') && ! Phar::running()) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From 6103ed50222679e48e8672625c59e6bf63b9530c Mon Sep 17 00:00:00 2001 From: SRWieZ <1408020+SRWieZ@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:14:59 +0000 Subject: [PATCH 19/57] Fix styling --- src/NativeServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 1c134031..526c8cf5 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -150,7 +150,7 @@ public function rewriteDatabase() $databasePath = config('nativephp-internal.database_path'); // Automatically create the database in development mode but not if we are running in a Phar - if (config('app.debug') && ! Phar::running()) { + if (config('app.debug') && ! Phar::running()) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From 15d04bd9705abad0349ace2453ac0a72d5964536 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 10 Mar 2025 12:46:53 +0100 Subject: [PATCH 20/57] feat: isRunningBundled --- src/App.php | 6 ++++++ src/Facades/App.php | 1 + 2 files changed, 7 insertions(+) diff --git a/src/App.php b/src/App.php index 81f1a26c..b45dd11d 100644 --- a/src/App.php +++ b/src/App.php @@ -3,6 +3,7 @@ namespace Native\Laravel; use Native\Laravel\Client\Client; +use Phar; class App { @@ -57,4 +58,9 @@ public function clearRecentDocuments(): void { $this->client->delete('app/recent-documents'); } + + public function isRunningBundled(): bool + { + return Phar::running() !== ''; + } } diff --git a/src/Facades/App.php b/src/Facades/App.php index 6f3d99a6..4bbf3319 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -13,6 +13,7 @@ * @method static void addRecentDocument(string $path) * @method static array recentDocuments() * @method static void clearRecentDocuments() + * @method static bool isRunningBundled() */ class App extends Facade { From 35ab017a6e5c54ed75d766413695b92b75211a26 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:16:56 +0100 Subject: [PATCH 21/57] wip: fix running artisan commands in bundle --- src/QueueWorker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 1eb0c000..3a820f1d 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -24,11 +24,11 @@ public function up(string|QueueConfig $config): void throw new \InvalidArgumentException("Invalid queue configuration alias [$config]"); } - $this->childProcess->php( + $this->childProcess->artisan( [ - '-d', - "memory_limit={$config->memoryLimit}M", - 'artisan', + // '-d', + // "memory_limit={$config->memoryLimit}M", + // 'artisan', 'queue:work', "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), From f2584d00b45405064d458e30f7f50d63c3cb41bf Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:39:53 +0100 Subject: [PATCH 22/57] feat: artisan commands in bundles --- src/ChildProcess.php | 7 ++++--- src/Contracts/ChildProcess.php | 4 ++-- src/Events/ChildProcess/StartupError.php | 22 ++++++++++++++++++++++ src/Fakes/ChildProcessFake.php | 8 ++++++-- src/QueueWorker.php | 3 --- 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/Events/ChildProcess/StartupError.php diff --git a/src/ChildProcess.php b/src/ChildProcess.php index f524370c..19a94201 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -80,7 +80,7 @@ public function start( * @param string|string[] $cmd * @return $this */ - public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self { $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; @@ -90,6 +90,7 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool 'cwd' => base_path(), 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ])->json(); return $this->fromRuntimeProcess($process); @@ -99,13 +100,13 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool * @param string|string[] $cmd * @return $this */ - public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self { $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; $cmd = ['artisan', ...$cmd]; - return $this->php($cmd, $alias, env: $env, persistent: $persistent); + return $this->php($cmd, $alias, env: $env, persistent: $persistent, iniSettings: $iniSettings); } public function stop(?string $alias = null): void diff --git a/src/Contracts/ChildProcess.php b/src/Contracts/ChildProcess.php index 9859e3e6..0a4f8777 100644 --- a/src/Contracts/ChildProcess.php +++ b/src/Contracts/ChildProcess.php @@ -16,9 +16,9 @@ public function start( bool $persistent = false ): self; - public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self; + public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self; - public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self; + public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self; public function stop(?string $alias = null): void; diff --git a/src/Events/ChildProcess/StartupError.php b/src/Events/ChildProcess/StartupError.php new file mode 100644 index 00000000..8adb2ed3 --- /dev/null +++ b/src/Events/ChildProcess/StartupError.php @@ -0,0 +1,22 @@ +phps[] = [ 'cmd' => $cmd, 'alias' => $alias, 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ]; return $this; @@ -93,13 +95,15 @@ public function artisan( array|string $cmd, string $alias, ?array $env = null, - ?bool $persistent = false + ?bool $persistent = false, + ?array $iniSettings = null ): self { $this->artisans[] = [ 'cmd' => $cmd, 'alias' => $alias, 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ]; return $this; diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 3a820f1d..e39803ff 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -26,9 +26,6 @@ public function up(string|QueueConfig $config): void $this->childProcess->artisan( [ - // '-d', - // "memory_limit={$config->memoryLimit}M", - // 'artisan', 'queue:work', "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), From 3228b9880ada90469531d30208843a98c6923cdc Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:49:09 +0100 Subject: [PATCH 23/57] feat: artisan commands in bundles --- src/QueueWorker.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index e39803ff..875a5c2c 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -32,13 +32,16 @@ public function up(string|QueueConfig $config): void "--memory={$config->memoryLimit}", "--timeout={$config->timeout}", ], - $config->alias, + 'queue_'.$config->alias, persistent: true, + iniSettings: [ + 'memory_limit' => "{$config->memoryLimit}M", + ] ); } public function down(string $alias): void { - $this->childProcess->stop($alias); + $this->childProcess->stop('queue_'.$alias); } } From f7b8f528a7b497022266d7d57b8f32436cb15652 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 12 Mar 2025 14:01:14 +0100 Subject: [PATCH 24/57] refactor: this should not be necessary anymore --- src/NativeServiceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 526c8cf5..1adad862 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -149,8 +149,8 @@ public function rewriteDatabase() { $databasePath = config('nativephp-internal.database_path'); - // Automatically create the database in development mode but not if we are running in a Phar - if (config('app.debug') && ! Phar::running()) { + // Automatically create the database in development mode + if (config('app.debug')) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From fbf7b236d7b69820d4442b7c222119f12df12be8 Mon Sep 17 00:00:00 2001 From: SRWieZ <1408020+SRWieZ@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:01:42 +0000 Subject: [PATCH 25/57] Fix styling --- src/NativeServiceProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 1adad862..ce1537f9 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -25,7 +25,6 @@ use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; -use Phar; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; From ee3945576e5e78645877dfbae9f7670168cf8f6a Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sat, 15 Mar 2025 14:06:33 +0100 Subject: [PATCH 26/57] fix: NATIVEPHP_PHP_BINARY_PATH --- config/nativephp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nativephp.php b/config/nativephp.php index 49eacd84..1ecd30aa 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -143,5 +143,5 @@ /** * Custom PHP binary path. */ - 'binary_path' => env('NATIVEPHP_BINARY_PATH', null), + 'binary_path' => env('NATIVEPHP_PHP_BINARY_PATH', null), ]; From 3e27e0b186664b05be4a2a09cf0198e3665beb2e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 18 Mar 2025 03:20:39 +0000 Subject: [PATCH 27/57] Test fixes --- tests/Fakes/FakeChildProcessTest.php | 12 ++++++------ tests/QueueWorker/QueueWorkerTest.php | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/Fakes/FakeChildProcessTest.php b/tests/Fakes/FakeChildProcessTest.php index 57b0c354..aae9d264 100644 --- a/tests/Fakes/FakeChildProcessTest.php +++ b/tests/Fakes/FakeChildProcessTest.php @@ -82,18 +82,18 @@ $fake->php('cmdA', 'aliasA', ['envA'], true); $fake->php('cmdB', 'aliasB', ['envB'], false); - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasA' && $cmd === 'cmdA' && $env === ['envA'] && $persistent === true); - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasB' && $cmd === 'cmdB' && $env === ['envB'] && $persistent === false); try { - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasC'); } catch (AssertionFailedError) { return; } @@ -107,18 +107,18 @@ $fake->artisan('cmdA', 'aliasA', ['envA'], true); $fake->artisan('cmdB', 'aliasB', ['envB'], false); - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasA' && $cmd === 'cmdA' && $env === ['envA'] && $persistent === true); - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasB' && $cmd === 'cmdB' && $env === ['envB'] && $persistent === false); try { - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasC'); } catch (AssertionFailedError) { return; } diff --git a/tests/QueueWorker/QueueWorkerTest.php b/tests/QueueWorker/QueueWorkerTest.php index a3fbd576..2a6c1372 100644 --- a/tests/QueueWorker/QueueWorkerTest.php +++ b/tests/QueueWorker/QueueWorkerTest.php @@ -6,23 +6,27 @@ it('hits the child process with relevant queue config to spin up a new queue worker', function () { ChildProcess::fake(); - $config = new QueueConfig('some_worker', ['default'], 128, 61); + + $workerName = 'some_worker'; + + $config = new QueueConfig($workerName, ['default'], 128, 61); QueueWorker::up($config); - ChildProcess::assertPhp(function (array $cmd, string $alias, $env, $persistent) { + ChildProcess::assertArtisan(function (array $cmd, string $alias, $env, $persistent, $iniSettings) use ($workerName) { expect($cmd)->toBe([ - '-d', - 'memory_limit=128M', - 'artisan', 'queue:work', - "--name={$alias}", + "--name={$workerName}", '--queue=default', '--memory=128', '--timeout=61', ]); - expect($alias)->toBe('some_worker'); + expect($iniSettings)->toBe([ + 'memory_limit' => '128M', + ]); + + expect($alias)->toBe('queue_some_worker'); expect($env)->toBeNull(); expect($persistent)->toBeTrue(); @@ -35,5 +39,5 @@ QueueWorker::down('some_worker'); - ChildProcess::assertStop('some_worker'); + ChildProcess::assertStop('queue_some_worker'); }); From 60ac44a4693e6524ff3a6f92f7481c0b8b70e0e9 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 18 Mar 2025 10:35:10 +0100 Subject: [PATCH 28/57] feat: add quit method to App class (#519) * feat: add quit method to App class * Method for facade added --- src/App.php | 5 +++++ src/Facades/App.php | 1 + 2 files changed, 6 insertions(+) diff --git a/src/App.php b/src/App.php index 81f1a26c..32390265 100644 --- a/src/App.php +++ b/src/App.php @@ -8,6 +8,11 @@ class App { public function __construct(protected Client $client) {} + public function quit(): void + { + $this->client->post('app/quit'); + } + public function focus(): void { $this->client->post('app/focus'); diff --git a/src/Facades/App.php b/src/Facades/App.php index 6f3d99a6..41817cf4 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Facade; /** + * @method static void quit() * @method static void focus() * @method static void hide() * @method static bool isHidden() From 372614dff197401aee651bc772bd88846826c7ea Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 18 Mar 2025 10:37:28 +0100 Subject: [PATCH 29/57] feat: add openAtLogin method to manage app startup behavior (#520) * feat: add openAtLogin method to manage app startup behavior * Method for facade added --- src/App.php | 13 +++++++++++++ src/Facades/App.php | 1 + 2 files changed, 14 insertions(+) diff --git a/src/App.php b/src/App.php index 32390265..bb8ef2e6 100644 --- a/src/App.php +++ b/src/App.php @@ -62,4 +62,17 @@ public function clearRecentDocuments(): void { $this->client->delete('app/recent-documents'); } + + public function openAtLogin(?bool $open = null): bool + { + if ($open === null) { + return (bool) $this->client->get('app/open-at-login')->json('open'); + } + + $this->client->post('app/open-at-login', [ + 'open' => $open, + ]); + + return $open; + } } diff --git a/src/Facades/App.php b/src/Facades/App.php index 41817cf4..dbc25915 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -14,6 +14,7 @@ * @method static void addRecentDocument(string $path) * @method static array recentDocuments() * @method static void clearRecentDocuments() + * @method static bool openAtLogin(?bool $open = null) */ class App extends Facade { From b8a753a4084df43207dff52a8555b186cfc8d6c3 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Wed, 19 Mar 2025 13:04:06 +0000 Subject: [PATCH 30/57] Implement Debug Command (#516) * Implement Debug Command * Fix styling * Output to Clipboard support * Windows support for path detection * Fix styling * z vs s - z wins * Remove error log parsing for now * Implement config vars for notarization * Add PHP Binary Path to config --- config/nativephp-internal.php | 14 +++ src/Commands/DebugCommand.php | 165 ++++++++++++++++++++++++++++++++++ src/NativeServiceProvider.php | 4 +- 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/Commands/DebugCommand.php diff --git a/config/nativephp-internal.php b/config/nativephp-internal.php index 4210df92..2fbb4a31 100644 --- a/config/nativephp-internal.php +++ b/config/nativephp-internal.php @@ -29,4 +29,18 @@ * The URL to the NativePHP API. */ 'api_url' => env('NATIVEPHP_API_URL', 'http://localhost:4000/api/'), + + /** + * The credentials to use Apples Notarization service. + */ + 'notarization' => [ + 'apple_id' => env('NATIVEPHP_APPLE_ID'), + 'apple_id_pass' => env('NATIVEPHP_APPLE_ID_PASS'), + 'apple_team_id' => env('NATIVEPHP_APPLE_TEAM_ID'), + ], + + /** + * The binary path of PHP for NativePHP to use at build. + */ + 'php_binary_path' => env('NATIVEPHP_PHP_BINARY_PATH'), ]; diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php new file mode 100644 index 00000000..3900d3c7 --- /dev/null +++ b/src/Commands/DebugCommand.php @@ -0,0 +1,165 @@ +debugInfo = collect(); + intro('Generating Debug Information...'); + + $this->processEnvironment() + ->processNativePHP(); + + switch ($this->argument('output')) { + case 'File': + $this->outputToFile(); + break; + case 'Clipboard': + $this->outputToClipboard(); + break; + case 'Console': + $this->outputToConsole(); + break; + default: + error('Invalid output option specified.'); + } + + outro('Debug Information Generated.'); + } + + private function processEnvironment(): static + { + $locationCommand = 'which'; + + if (PHP_OS_FAMILY === 'Windows') { + $locationCommand = 'where'; + } + + info('Generating Environment Data...'); + $environment = [ + 'PHP' => [ + 'Version' => phpversion(), + 'Path' => PHP_BINARY, + ], + 'Laravel' => [ + 'Version' => app()->version(), + 'ConfigCached' => file_exists($this->laravel->getCachedConfigPath()), + 'DebugEnabled' => $this->laravel->hasDebugModeEnabled(), + ], + 'Node' => [ + 'Version' => trim(Process::run('node -v')->output()), + 'Path' => trim(Process::run("$locationCommand node")->output()), + ], + 'NPM' => [ + 'Version' => trim(Process::run('npm -v')->output()), + 'Path' => trim(Process::run("$locationCommand npm")->output()), + ], + 'OperatingSystem' => PHP_OS, + ]; + + $this->debugInfo->put('Environment', $environment); + + return $this; + } + + private function processNativePHP(): static + { + info('Processing NativePHP Data...'); + // Get composer versions + $versions = collect([ + 'nativephp/electron' => null, + 'nativephp/laravel' => null, + 'nativephp/php-bin' => null, + ])->mapWithKeys(function ($version, $key) { + try { + $version = InstalledVersions::getVersion($key); + } catch (\OutOfBoundsException) { + $version = 'Not Installed'; + } + + return [$key => $version]; + }); + + $isNotarizationConfigured = config('nativephp-internal.notarization.apple_id') + && config('nativephp-internal.notarization.apple_id_pass') + && config('nativephp-internal.notarization.apple_team_id'); + + $this->debugInfo->put( + 'NativePHP', + [ + 'Versions' => $versions, + 'Configuration' => [ + 'Provider' => config('nativephp.provider'), + 'BuildHooks' => [ + 'Pre' => config('nativephp.prebuild'), + 'Post' => config('nativephp.postbuild'), + ], + 'NotarizationEnabled' => $isNotarizationConfigured, + 'CustomPHPBinary' => config('nativephp-internal.php_binary_path') ?? false, + ], + ] + ); + + return $this; + } + + protected function promptForMissingArgumentsUsing(): array + { + return [ + 'output' => fn () => select( + 'Where would you like to output the debug information?', + ['File', 'Clipboard', 'Console'], + 'File' + ), + ]; + } + + private function outputToFile(): void + { + File::put(base_path('nativephp_debug.json'), json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + note('Debug information saved to '.base_path('nativephp_debug.json')); + } + + private function outputToConsole(): void + { + $this->output->writeln( + print_r($this->debugInfo->toArray(), true) + ); + } + + private function outputToClipboard(): void + { + $json = json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + + // Copy json to clipboard + if (PHP_OS_FAMILY === 'Windows') { + Process::run('echo '.escapeshellarg($json).' | clip'); + } elseif (PHP_OS_FAMILY === 'Linux') { + Process::run('echo '.escapeshellarg($json).' | xclip -selection clipboard'); + } else { + Process::run('echo '.escapeshellarg($json).' | pbcopy'); + } + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index b5b32252..c425e565 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; use Native\Laravel\ChildProcess as ChildProcessImplementation; +use Native\Laravel\Commands\DebugCommand; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; @@ -35,8 +36,9 @@ public function configurePackage(Package $package): void $package ->name('nativephp') ->hasCommands([ - MigrateCommand::class, + DebugCommand::class, FreshCommand::class, + MigrateCommand::class, SeedDatabaseCommand::class, ]) ->hasConfigFile() From 6899c2cb5ab784e6ee1ebd46397c98df0a18e905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20S=C3=A1nchez=20Palma?= <40817962+JA-Developer@users.noreply.github.com> Date: Mon, 24 Mar 2025 06:24:12 -0600 Subject: [PATCH 31/57] Fixed error "method_exists(): Argument #1 ($object_or_class) must be of type object|string, array given" when using Livewire and AdminLTE. (#524) * Fixed error 'method_exists(): Argument #1 ($object_or_class) must be of type object|string, array given' when using Darryldecode\Cart\Cart. * Check if the $event variable is an object before checking if it was dispatched by NativePHP. --- src/Events/EventWatcher.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index bae9ae7d..8163e1a6 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -14,6 +14,10 @@ public function register(): void Event::listen('*', function (string $eventName, array $data) { $event = $data[0] ?? (object) null; + if(! is_object($event)) { + return; + } + if (! method_exists($event, 'broadcastOn')) { return; } From 5992b012af721d3fb48cfdcc105753c123a1b012 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 25 Mar 2025 06:56:45 +0100 Subject: [PATCH 32/57] feat: implement Alert class and facade for alert management (#523) * feat: implement Alert class and facade for alert management * refactor: remove unused methods from Alert class --- src/Alert.php | 94 +++++++++++++++++++++++++++++++++++++++++++ src/Facades/Alert.php | 23 +++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/Alert.php create mode 100644 src/Facades/Alert.php diff --git a/src/Alert.php b/src/Alert.php new file mode 100644 index 00000000..4ddcb8f5 --- /dev/null +++ b/src/Alert.php @@ -0,0 +1,94 @@ +type = $type; + + return $this; + } + + public function title(string $title): self + { + $this->title = $title; + + return $this; + } + + public function detail(string $detail): self + { + $this->detail = $detail; + + return $this; + } + + public function buttons(array $buttons): self + { + $this->buttons = $buttons; + + return $this; + } + + public function defaultId(int $defaultId): self + { + $this->defaultId = $defaultId; + + return $this; + } + + public function cancelId(int $cancelId): self + { + $this->cancelId = $cancelId; + + return $this; + } + + public function show(string $message): int + { + $response = $this->client->post('alert/message', [ + 'message' => $message, + 'type' => $this->type, + 'title' => $this->title, + 'detail' => $this->detail, + 'buttons' => $this->buttons, + 'defaultId' => $this->defaultId, + 'cancelId' => $this->cancelId + ]); + + return (int) $response->json('result'); + } + + public function error(string $title, string $message): bool + { + $response = $this->client->post('alert/error', [ + 'title' => $title, + 'message' => $message, + ]); + + return (bool) $response->json('result'); + } +} diff --git a/src/Facades/Alert.php b/src/Facades/Alert.php new file mode 100644 index 00000000..a4b151fa --- /dev/null +++ b/src/Facades/Alert.php @@ -0,0 +1,23 @@ + Date: Thu, 27 Mar 2025 16:57:44 +0000 Subject: [PATCH 33/57] Environment Helper (#527) * Add Environment Class with OS Helpers * Abstract all usages of PHP_OS_FAMILY to Environment class * Fix styling --------- Co-authored-by: Pete Bishop --- src/Alert.php | 14 +++++++------- src/Commands/DebugCommand.php | 7 ++++--- src/Events/EventWatcher.php | 2 +- src/Support/Environment.php | 31 +++++++++++++++++++++++++++++++ src/System.php | 3 ++- 5 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 src/Support/Environment.php diff --git a/src/Alert.php b/src/Alert.php index 4ddcb8f5..d00e7eff 100644 --- a/src/Alert.php +++ b/src/Alert.php @@ -2,23 +2,23 @@ namespace Native\Laravel; -use Illuminate\Support\Traits\Conditionable; -use Illuminate\Support\Traits\Macroable; use Native\Laravel\Client\Client; -use Native\Laravel\Facades\Window; class Alert { protected ?string $type; + protected ?string $title; + protected ?string $detail; + protected ?array $buttons; + protected ?int $defaultId; + protected ?int $cancelId; - final public function __construct(protected Client $client) - { - } + final public function __construct(protected Client $client) {} public static function new() { @@ -76,7 +76,7 @@ public function show(string $message): int 'detail' => $this->detail, 'buttons' => $this->buttons, 'defaultId' => $this->defaultId, - 'cancelId' => $this->cancelId + 'cancelId' => $this->cancelId, ]); return (int) $response->json('result'); diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php index 3900d3c7..ad79c3b6 100644 --- a/src/Commands/DebugCommand.php +++ b/src/Commands/DebugCommand.php @@ -8,6 +8,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Process; +use Native\Laravel\Support\Environment; use function Laravel\Prompts\error; use function Laravel\Prompts\info; @@ -53,7 +54,7 @@ private function processEnvironment(): static { $locationCommand = 'which'; - if (PHP_OS_FAMILY === 'Windows') { + if (Environment::isWindows()) { $locationCommand = 'where'; } @@ -154,9 +155,9 @@ private function outputToClipboard(): void $json = json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); // Copy json to clipboard - if (PHP_OS_FAMILY === 'Windows') { + if (Environment::isWindows()) { Process::run('echo '.escapeshellarg($json).' | clip'); - } elseif (PHP_OS_FAMILY === 'Linux') { + } elseif (Environment::isLinux()) { Process::run('echo '.escapeshellarg($json).' | xclip -selection clipboard'); } else { Process::run('echo '.escapeshellarg($json).' | pbcopy'); diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index 8163e1a6..6df7e248 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -14,7 +14,7 @@ public function register(): void Event::listen('*', function (string $eventName, array $data) { $event = $data[0] ?? (object) null; - if(! is_object($event)) { + if (! is_object($event)) { return; } diff --git a/src/Support/Environment.php b/src/Support/Environment.php new file mode 100644 index 00000000..70f20367 --- /dev/null +++ b/src/Support/Environment.php @@ -0,0 +1,31 @@ +translateFromWindowsString(exec('tzutil /g')); } else { $timezone = $timezones->translateFromAbbreviatedString(exec('date +%Z')); From 29b877947e75a09339b54a943df3909a7423ccf5 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 10:59:10 +0200 Subject: [PATCH 34/57] fix: initialize properties in Alert class and update new method signature (#529) --- src/Alert.php | 14 +++++++------- src/Facades/Alert.php | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Alert.php b/src/Alert.php index d00e7eff..1303721c 100644 --- a/src/Alert.php +++ b/src/Alert.php @@ -6,21 +6,21 @@ class Alert { - protected ?string $type; + protected ?string $type = null; - protected ?string $title; + protected ?string $title = null; - protected ?string $detail; + protected ?string $detail = null; - protected ?array $buttons; + protected ?array $buttons = null; - protected ?int $defaultId; + protected ?int $defaultId = null; - protected ?int $cancelId; + protected ?int $cancelId = null; final public function __construct(protected Client $client) {} - public static function new() + public static function new(): self { return new static(new Client); } diff --git a/src/Facades/Alert.php b/src/Facades/Alert.php index a4b151fa..2d5e1f2b 100644 --- a/src/Facades/Alert.php +++ b/src/Facades/Alert.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Facade; /** + * @method static static new() * @method static static type(string $type) * @method static static title(string $title) * @method static static detail(string $detail) From afe7316242a51789e5e943ebac749dddc7b78240 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 11:01:42 +0200 Subject: [PATCH 35/57] feat: add theme method to System class and create SystemThemesEnum (#530) --- src/Enums/SystemThemesEnum.php | 10 ++++++++++ src/Facades/System.php | 2 ++ src/System.php | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/Enums/SystemThemesEnum.php diff --git a/src/Enums/SystemThemesEnum.php b/src/Enums/SystemThemesEnum.php new file mode 100644 index 00000000..e290dbca --- /dev/null +++ b/src/Enums/SystemThemesEnum.php @@ -0,0 +1,10 @@ +client->post('system/theme', [ + 'theme' => $theme, + ])->json('result'); + } else { + $result = $this->client->get('system/theme')->json('result'); + } + + return SystemThemesEnum::from($result); + } } From 15b6d75b98d4ea9bf69b0fb8aab9001061fa571d Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 31 Mar 2025 15:47:23 +0100 Subject: [PATCH 36/57] PHP Support Sync (#532) * Set PHP support to min 8.3 * Drop PHP 8.1 and 8.2 support from workflows --- .github/workflows/run-tests.yml | 8 +------- composer.json | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a1909f62..18fb032d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,16 +13,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - php: [8.4, 8.3, 8.2, 8.1] + php: [8.4, 8.3] laravel: [12.*, 11.*, 10.*] stability: [prefer-lowest, prefer-stable] - exclude: - - laravel: 11.* - php: 8.1 - - laravel: 12.* - php: 8.1 - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: diff --git a/composer.json b/composer.json index 71336edd..73e68c51 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.3", "illuminate/contracts": "^10.0|^11.0|^12.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" From c1f334dc268103b5772d46f455de93a846c0c042 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 17:20:40 +0200 Subject: [PATCH 37/57] feat: add copyright notice configuration to nativephp.php (#534) --- config/nativephp.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 1ecd30aa..817bc12b 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -31,6 +31,11 @@ */ 'author' => env('NATIVEPHP_APP_AUTHOR'), + /** + * The copyright notice for your application. + */ + 'copyright' => env('NATIVEPHP_APP_COPYRIGHT'), + /** * The default service provider for your application. This provider * takes care of bootstrapping your application and configuring From 5ca07c4450233a397d4258abf7764a61ba6da129 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 1 Apr 2025 14:57:07 +0200 Subject: [PATCH 38/57] fix: $iniSettings on ChildProcess.php (#535) * fix: $iniSettings on ChildProcess.php * fix: ensure properties are set only if they exist * fix: throw exception for non-existent properties in ChildProcess --- src/ChildProcess.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ChildProcess.php b/src/ChildProcess.php index 19a94201..6ba99721 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -19,6 +19,8 @@ class ChildProcess implements ChildProcessContract public readonly bool $persistent; + public readonly ?array $iniSettings; + final public function __construct(protected Client $client) {} public function get(?string $alias = null): ?self @@ -147,6 +149,10 @@ protected function fromRuntimeProcess($process) } foreach ($process['settings'] as $key => $value) { + if (! property_exists($this, $key)) { + throw new \RuntimeException("Property {$key} does not exist on ".__CLASS__); + } + $this->{$key} = $value; } From 1e525896b0af75dec8cd1e6cd74035a0983d99f7 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 2 Apr 2025 14:52:13 +0200 Subject: [PATCH 39/57] fix: menu facade + better default for quit (#536) --- src/Facades/Menu.php | 37 +++++++++++++++++++------------------ src/Menu/MenuBuilder.php | 4 ++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/Facades/Menu.php b/src/Facades/Menu.php index 332de247..d197305e 100644 --- a/src/Facades/Menu.php +++ b/src/Facades/Menu.php @@ -19,25 +19,26 @@ * @method static Link route(string $url, string $label = null, ?string $hotkey = null) * @method static Radio radio(string $label, bool $checked = false, ?string $hotkey = null) * @method static Role app() - * @method static Role file() - * @method static Role edit() - * @method static Role view() - * @method static Role window() - * @method static Role help() - * @method static Role fullscreen() + * @method static Role about(?string $label = null) + * @method static Role file(?string $label = null) + * @method static Role edit(?string $label = null) + * @method static Role view(?string $label = null) + * @method static Role window(?string $label = null) + * @method static Role help(?string $label = null) + * @method static Role fullscreen(?string $label = null) * @method static Role separator() - * @method static Role devTools() - * @method static Role undo() - * @method static Role redo() - * @method static Role cut() - * @method static Role copy() - * @method static Role paste() - * @method static Role pasteAndMatchStyle() - * @method static Role reload() - * @method static Role minimize() - * @method static Role close() - * @method static Role quit() - * @method static Role hide() + * @method static Role devTools(?string $label = null) + * @method static Role undo(?string $label = null) + * @method static Role redo(?string $label = null) + * @method static Role cut(?string $label = null) + * @method static Role copy(?string $label = null) + * @method static Role paste(?string $label = null) + * @method static Role pasteAndMatchStyle(?string $label = null) + * @method static Role reload(?string $label = null) + * @method static Role minimize(?string $label = null) + * @method static Role close(?string $label = null) + * @method static Role quit(?string $label = null) + * @method static Role hide(?string $label = null) * @method static void create(MenuItem ...$items) * @method static void default() */ diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index f0627f78..f2ef764a 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -150,6 +150,10 @@ public function close(?string $label = null): Items\Role public function quit(?string $label = null): Items\Role { + if (is_null($label)) { + $label = __('Quit').' '.config('app.name'); + } + return new Items\Role(RolesEnum::QUIT, $label); } From 91f487cb40fdea5ce737fc7128f4f17dc2a2e92f Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 3 Apr 2025 14:37:25 +0200 Subject: [PATCH 40/57] fix: failed jobs on the nativephp database (#538) * fix: failed jobs on the nativephp database * fix: add batching database configuration for nativephp queue * fix: add database connection configuration for nativephp queue --- src/NativeServiceProvider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 7e000a70..a1910a4b 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -172,6 +172,9 @@ public function rewriteDatabase() ]); config(['database.default' => 'nativephp']); + config(['queue.failed.database' => 'nativephp']); + config(['queue.batching.database' => 'nativephp']); + config(['queue.connections.database.connection' => 'nativephp']); if (file_exists($databasePath)) { DB::statement('PRAGMA journal_mode=WAL;'); From 9e9166d698e55e1877ba1726ba7d25999c85065f Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 7 Apr 2025 15:52:57 +0100 Subject: [PATCH 41/57] Remove L10 from test matrix (#541) * Remove L10 from test matrix * Remove PHPStan ignore line... --- .github/workflows/run-tests.yml | 2 +- src/NativeServiceProvider.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 18fb032d..68e6ca9b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -14,7 +14,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] php: [8.4, 8.3] - laravel: [12.*, 11.*, 10.*] + laravel: [12.*, 11.*] stability: [prefer-lowest, prefer-stable] name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index a1910a4b..ad222f9b 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -51,7 +51,6 @@ public function packageRegistered() $this->mergeConfigFrom($this->package->basePath('/../config/nativephp-internal.php'), 'nativephp-internal'); $this->app->singleton(FreshCommand::class, function ($app) { - /* @phpstan-ignore-next-line (beacause we support Laravel 10 & 11) */ return new FreshCommand($app['migrator']); }); From e4b8e0accf74395670828c6dea4c17c8fbad196e Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:09:12 +0100 Subject: [PATCH 42/57] Reduce number of fields on bug report, replacing many with native:debug (#545) --- .github/ISSUE_TEMPLATE/bug.yml | 47 ++++++++-------------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index f4547857..29e73812 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -7,9 +7,11 @@ body: attributes: value: | We're sorry to hear you have a problem. - + Before submitting your report, please make sure you've been through the section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" in the docs. + Please also ensure that you have the latest version of NativePHP packages installed, and are using [supported versions](https://nativephp.com/docs/desktop/1/getting-started/support-policy) of PHP and Laravel. + If nothing here has helped you, please provide as much useful context as you can here to help us solve help you. Note that reams and reams of logs isn't helpful - please share only relevant errors. @@ -23,6 +25,7 @@ body: placeholder: Trying to build my app for production validations: required: true + - type: textarea id: what-happened attributes: @@ -31,6 +34,7 @@ body: placeholder: I cannot currently do X thing because when I do, it breaks X thing. validations: required: true + - type: textarea id: how-to-reproduce attributes: @@ -39,37 +43,15 @@ body: placeholder: When I do X I see Y. validations: required: true + - type: textarea - id: package-version - attributes: - label: Package Versions - description: What versions of the NativePHP packages are you running? Output of `composer show "nativephp/*" --format=json` - validations: - required: true - - type: input - id: php-version + id: debug attributes: - label: PHP Version - description: What version of PHP are you running? Please be as specific as possible - placeholder: 8.2.0 + label: Debug Output + description: Please provide output from the NativePHP Debug command. This will help us understand your environment and the issue you're facing. (`php artisan native:debug`) validations: required: true - - type: input - id: laravel-version - attributes: - label: Laravel Version - description: What version of Laravel are you running? Please be as specific as possible - placeholder: 9.0.0 - validations: - required: true - - type: input - id: node-version - attributes: - label: Node Version - description: What version of Node are you running? Please be as specific as possible - placeholder: '18.17' - validations: - required: true + - type: dropdown id: operating-systems attributes: @@ -80,14 +62,7 @@ body: - macOS - Windows - Linux - - type: input - id: os-version - attributes: - label: OS version - description: Which version of these OSes are you using? - placeholder: 'win11 (23H2), macos14.1 (23B74)' - validations: - required: true + - type: textarea id: notes attributes: From 31e630b9ac315a1e5b0779b1203eafa58e0cac33 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 9 Apr 2025 02:33:19 +0100 Subject: [PATCH 43/57] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4308c95a..c1284be9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [KaasHosting](https://www.kaashosting.nl/?lang=en) - Minecraft Server and VPS hosting from The Netherlands. -- [Borah Digital Labs](https://borah.digital/) - An MVP building studio from the sunny Canary Islands focusing on AI, SaaS and online platforms. ## Changelog From 540e9a474cb9248a941b7dbe7b5c22bb13a45fc6 Mon Sep 17 00:00:00 2001 From: Justas Raudonius <10882793+justRau@users.noreply.github.com> Date: Mon, 14 Apr 2025 12:30:09 +0300 Subject: [PATCH 44/57] Update DebugCommand.php (#550) --- src/Commands/DebugCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php index ad79c3b6..2bb7633d 100644 --- a/src/Commands/DebugCommand.php +++ b/src/Commands/DebugCommand.php @@ -66,7 +66,8 @@ private function processEnvironment(): static ], 'Laravel' => [ 'Version' => app()->version(), - 'ConfigCached' => file_exists($this->laravel->getCachedConfigPath()), + 'ConfigCached' => $this->laravel->configurationIsCached(), + 'RoutesCached' => $this->laravel->routesAreCached(), 'DebugEnabled' => $this->laravel->hasDebugModeEnabled(), ], 'Node' => [ From ff9adc83be4120268c659e5dde0e3cc83da88cde Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 28 Apr 2025 12:13:19 +0200 Subject: [PATCH 45/57] Add 'description' and 'website' fields to nativephp config (#571) * Add 'description' and 'website' fields to nativephp config These new fields allow developers to define a description and website for their application via environment variables. This enhances configurability and provides more application metadata. * Added Defaults - config/nativephp.php Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> * Added Defaults - config/nativephp.php Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> --------- Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> --- config/nativephp.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 817bc12b..96b6b1e5 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -36,6 +36,16 @@ */ 'copyright' => env('NATIVEPHP_APP_COPYRIGHT'), + /** + * The description of your application. + */ + 'description' => env('NATIVEPHP_APP_DESCRIPTION', 'An awesome app built with NativePHP'), + + /** + * The Website of your application. + */ + 'website' => env('NATIVEPHP_APP_WEBSITE', 'https://nativephp.com'), + /** * The default service provider for your application. This provider * takes care of bootstrapping your application and configuring From e3d5974dafc0d4d51e426db0eb7fd5a0a0d67475 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 28 Apr 2025 14:12:29 +0200 Subject: [PATCH 46/57] Add relaunch functionality to App and its facade (#569) --- src/App.php | 5 +++++ src/Facades/App.php | 1 + 2 files changed, 6 insertions(+) diff --git a/src/App.php b/src/App.php index 039579e9..f7fa1c3a 100644 --- a/src/App.php +++ b/src/App.php @@ -14,6 +14,11 @@ public function quit(): void $this->client->post('app/quit'); } + public function relaunch(): void + { + $this->client->post('app/relaunch'); + } + public function focus(): void { $this->client->post('app/focus'); diff --git a/src/Facades/App.php b/src/Facades/App.php index 69abb2e5..14e42f87 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -6,6 +6,7 @@ /** * @method static void quit() + * @method static void relaunch() * @method static void focus() * @method static void hide() * @method static bool isHidden() From 5af2e3ee8c416d4cd0cfba460420ed8866dc063e Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 29 Apr 2025 12:38:32 +0200 Subject: [PATCH 47/57] Add "showOnAllWorkspaces" option to MenuBar (#568) Introduce a new `showOnAllWorkspaces` property and its corresponding method to configure this behavior. Update the `toArray` method to include this property and adjust tests to validate its functionality. --- src/MenuBar/MenuBar.php | 10 ++++++++++ tests/MenuBar/MenuBarTest.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/MenuBar/MenuBar.php b/src/MenuBar/MenuBar.php index 13a57092..c3b6ce8a 100644 --- a/src/MenuBar/MenuBar.php +++ b/src/MenuBar/MenuBar.php @@ -32,6 +32,8 @@ class MenuBar protected bool $showDockIcon = false; + protected bool $showOnAllWorkspaces = false; + protected Client $client; public function __construct() @@ -95,6 +97,13 @@ public function alwaysOnTop($alwaysOnTop = true): self return $this; } + public function showOnAllWorkspaces($showOnAllWorkspaces = true): self + { + $this->showOnAllWorkspaces = $showOnAllWorkspaces; + + return $this; + } + public function withContextMenu(Menu $menu): self { $this->contextMenu = $menu; @@ -122,6 +131,7 @@ public function toArray(): array 'onlyShowContextMenu' => $this->onlyShowContextMenu, 'contextMenu' => ! is_null($this->contextMenu) ? $this->contextMenu->toArray()['submenu'] : null, 'alwaysOnTop' => $this->alwaysOnTop, + 'showOnAllWorkspaces' => $this->showOnAllWorkspaces, ]; } } diff --git a/tests/MenuBar/MenuBarTest.php b/tests/MenuBar/MenuBarTest.php index 4b86aa95..79dbb801 100644 --- a/tests/MenuBar/MenuBarTest.php +++ b/tests/MenuBar/MenuBarTest.php @@ -9,6 +9,7 @@ $menuBar = MenuBar::create() ->showDockIcon() ->alwaysOnTop() + ->showOnAllWorkspaces() ->label('milwad') ->icon('nativephp.png') ->url('https://github.com/milwad-dev') @@ -22,6 +23,7 @@ $this->assertTrue($menuBarArray['showDockIcon']); $this->assertTrue($menuBarArray['alwaysOnTop']); + $this->assertTrue($menuBarArray['showOnAllWorkspaces']); $this->assertEquals('milwad', $menuBarArray['label']); $this->assertEquals('https://github.com/milwad-dev', $menuBarArray['url']); $this->assertEquals('nativephp.png', $menuBarArray['icon']); From 949c1ac15d75a3c5f0c619f9731cfb17b211a583 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:19:53 +0100 Subject: [PATCH 48/57] Update fix-php-code-style-issues.yml (#573) --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index eb79b6e0..4ae67bf2 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -22,7 +22,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: - ref: ${{ github.head_ref }} + ref: ${{ github.head_ref || github.sha }} - name: Check PHP code style issues if: github.event_name == 'push' From a19e54fa778182c25786051ded8bf46afd831fac Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Thu, 8 May 2025 10:15:27 +0200 Subject: [PATCH 49/57] Add AutoUpdater feature with events and facade support (#570) * Add AutoUpdater feature with events and facade support Introduces the `AutoUpdater` class to manage update processes via the client. Adds events such as `UpdateAvailable`, `UpdateDownloaded`, and others for broadcasting update states. A facade is also provided for convenient usage. * Add DownloadProgress event for real-time update broadcasting This event handles broadcasting download progress updates through a 'nativephp' channel. It includes details such as total size, delta, transferred bytes, percentage completed, and speed. * fix: update property types in DownloadProgress constructor Adjusted the types of total, delta, and bytesPerSecond from float to int to ensure type consistency and accuracy. This change prevents potential precision issues and aligns with expected data formats. --- src/AutoUpdater.php | 20 ++++++++++++++++ src/Events/AutoUpdater/CheckingForUpdate.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/DownloadProgress.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/Error.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateAvailable.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateDownloaded.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateNotAvailable.php | 21 +++++++++++++++++ src/Facades/AutoUpdater.php | 17 ++++++++++++++ 8 files changed, 173 insertions(+) create mode 100644 src/AutoUpdater.php create mode 100644 src/Events/AutoUpdater/CheckingForUpdate.php create mode 100644 src/Events/AutoUpdater/DownloadProgress.php create mode 100644 src/Events/AutoUpdater/Error.php create mode 100644 src/Events/AutoUpdater/UpdateAvailable.php create mode 100644 src/Events/AutoUpdater/UpdateDownloaded.php create mode 100644 src/Events/AutoUpdater/UpdateNotAvailable.php create mode 100644 src/Facades/AutoUpdater.php diff --git a/src/AutoUpdater.php b/src/AutoUpdater.php new file mode 100644 index 00000000..e714a0f1 --- /dev/null +++ b/src/AutoUpdater.php @@ -0,0 +1,20 @@ +client->post('auto-updater/check-for-updates'); + } + + public function quitAndInstall(): void + { + $this->client->post('auto-updater/quit-and-install'); + } +} diff --git a/src/Events/AutoUpdater/CheckingForUpdate.php b/src/Events/AutoUpdater/CheckingForUpdate.php new file mode 100644 index 00000000..a646d329 --- /dev/null +++ b/src/Events/AutoUpdater/CheckingForUpdate.php @@ -0,0 +1,23 @@ + Date: Thu, 8 May 2025 09:27:47 +0100 Subject: [PATCH 50/57] Include sleep option in queue config (#564) * feat/add-sleep-option-to-queue-config | expose sleep option to QueueConfig * feat/add-sleep-option-to-queue-config | include default sleep option in nativephp config file --- config/nativephp.php | 1 + src/DTOs/QueueConfig.php | 2 ++ src/QueueWorker.php | 1 + tests/DTOs/QueueWorkerTest.php | 5 +++++ tests/Fakes/FakeQueueWorkerTest.php | 4 ++-- tests/QueueWorker/QueueWorkerTest.php | 3 ++- 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/config/nativephp.php b/config/nativephp.php index 96b6b1e5..d68245fc 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -141,6 +141,7 @@ 'queues' => ['default'], 'memory_limit' => 128, 'timeout' => 60, + 'sleep' => 3, ], ], diff --git a/src/DTOs/QueueConfig.php b/src/DTOs/QueueConfig.php index 0ec3ca01..df04d0c1 100644 --- a/src/DTOs/QueueConfig.php +++ b/src/DTOs/QueueConfig.php @@ -12,6 +12,7 @@ public function __construct( public readonly array $queuesToConsume, public readonly int $memoryLimit, public readonly int $timeout, + public readonly int $sleep, ) {} /** @@ -26,6 +27,7 @@ function (array|string $worker, string $alias) { $worker['queues'] ?? ['default'], $worker['memory_limit'] ?? 128, $worker['timeout'] ?? 60, + $worker['sleep'] ?? 3, ); }, $config, diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 875a5c2c..f9c2ea19 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -31,6 +31,7 @@ public function up(string|QueueConfig $config): void '--queue='.implode(',', $config->queuesToConsume), "--memory={$config->memoryLimit}", "--timeout={$config->timeout}", + "--sleep={$config->sleep}", ], 'queue_'.$config->alias, persistent: true, diff --git a/tests/DTOs/QueueWorkerTest.php b/tests/DTOs/QueueWorkerTest.php index 76209c8b..01197aac 100644 --- a/tests/DTOs/QueueWorkerTest.php +++ b/tests/DTOs/QueueWorkerTest.php @@ -21,6 +21,8 @@ fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->sleep->toBe(3); continue; } @@ -35,6 +37,8 @@ fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->sleep->toBe($worker['sleep'] ?? 3); } })->with([ [ @@ -44,6 +48,7 @@ 'queues' => ['default'], 'memory_limit' => 64, 'timeout' => 60, + 'sleep' => 3, ], ], ], diff --git a/tests/Fakes/FakeQueueWorkerTest.php b/tests/Fakes/FakeQueueWorkerTest.php index 4b22f34d..150f2a28 100644 --- a/tests/Fakes/FakeQueueWorkerTest.php +++ b/tests/Fakes/FakeQueueWorkerTest.php @@ -17,8 +17,8 @@ it('asserts up using callable', function () { swap(QueueWorkerContract::class, $fake = app(QueueWorkerFake::class)); - $fake->up(new QueueConfig('testA', ['default'], 123, 123)); - $fake->up(new QueueConfig('testB', ['default'], 123, 123)); + $fake->up(new QueueConfig('testA', ['default'], 123, 123, 0)); + $fake->up(new QueueConfig('testB', ['default'], 123, 123, 0)); $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testA'); $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testB'); diff --git a/tests/QueueWorker/QueueWorkerTest.php b/tests/QueueWorker/QueueWorkerTest.php index 2a6c1372..7605a565 100644 --- a/tests/QueueWorker/QueueWorkerTest.php +++ b/tests/QueueWorker/QueueWorkerTest.php @@ -9,7 +9,7 @@ $workerName = 'some_worker'; - $config = new QueueConfig($workerName, ['default'], 128, 61); + $config = new QueueConfig($workerName, ['default'], 128, 61, 5); QueueWorker::up($config); @@ -20,6 +20,7 @@ '--queue=default', '--memory=128', '--timeout=61', + '--sleep=5', ]); expect($iniSettings)->toBe([ From 11cb34fdfeb5a30cc450296ae3f204024c54cd89 Mon Sep 17 00:00:00 2001 From: AJ <60591772+devajmeireles@users.noreply.github.com> Date: Thu, 8 May 2025 05:53:06 -0300 Subject: [PATCH 51/57] Updated get method in Settings.php to handle default values better (#562) --- src/Settings.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Settings.php b/src/Settings.php index e849c729..ddcc0302 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -17,7 +17,13 @@ public function set(string $key, $value): void public function get(string $key, $default = null): mixed { - return $this->client->get('settings/'.$key)->json('value') ?? $default; + $response = $this->client->get('settings/'.$key)->json('value'); + + if ($response === null) { + return $default instanceof \Closure ? $default() : $default; + } + + return $response; } public function forget(string $key): void From 9d1fc92db58474650f87d4a94e0846f6ad7e85d7 Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Mon, 12 May 2025 13:09:22 +0200 Subject: [PATCH 52/57] Automatically apply PreventBrowserAccess middleware (#551) * skip when running tests * skip when not in Electron context * automatically apply middleware to 'web' group * apply middleware to all routes --- src/Http/Middleware/PreventRegularBrowserAccess.php | 4 ++++ src/NativeServiceProvider.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/Http/Middleware/PreventRegularBrowserAccess.php b/src/Http/Middleware/PreventRegularBrowserAccess.php index de1c72bf..6722a3da 100644 --- a/src/Http/Middleware/PreventRegularBrowserAccess.php +++ b/src/Http/Middleware/PreventRegularBrowserAccess.php @@ -9,6 +9,10 @@ class PreventRegularBrowserAccess { public function handle(Request $request, Closure $next) { + if (! config('nativephp-internal.running')) { + return $next($request); + } + // Explicitly skip for the cookie-setting route if ($request->path() === '_native/api/cookie') { return $next($request); diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index ad222f9b..74dfba3c 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Console\Application; use Illuminate\Foundation\Application as Foundation; +use Illuminate\Foundation\Http\Kernel; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; @@ -23,6 +24,7 @@ use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; +use Native\Laravel\Http\Middleware\PreventRegularBrowserAccess; use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; @@ -84,6 +86,11 @@ public function packageRegistered() Handler::class ); + // Automatically prevent browser access + $this->app->make(Kernel::class)->pushMiddleware( + PreventRegularBrowserAccess::class, + ); + Application::starting(function ($app) { $app->resolveCommands([ LoadStartupConfigurationCommand::class, From 9175e4648f5f5f16f60adff33b2427020eebc953 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 13 May 2025 08:19:02 +0200 Subject: [PATCH 53/57] fix: use queue:listen in local environment for QueueWorker (#587) --- src/QueueWorker.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index f9c2ea19..2c998080 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -24,9 +24,13 @@ public function up(string|QueueConfig $config): void throw new \InvalidArgumentException("Invalid queue configuration alias [$config]"); } + $command = app()->isLocal() + ? 'queue:listen' + : 'queue:work'; + $this->childProcess->artisan( [ - 'queue:work', + $command, "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), "--memory={$config->memoryLimit}", From 584033d7c0d3d5ea466ca0371b09e5c5cfb380ae Mon Sep 17 00:00:00 2001 From: Chris Keller <67823070+chr15k@users.noreply.github.com> Date: Sat, 17 May 2025 11:30:37 -0400 Subject: [PATCH 54/57] feat/queue-sleep-option-config-type-hint-update | update sleep type hint to allow float values (#583) --- src/DTOs/QueueConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DTOs/QueueConfig.php b/src/DTOs/QueueConfig.php index df04d0c1..29308a03 100644 --- a/src/DTOs/QueueConfig.php +++ b/src/DTOs/QueueConfig.php @@ -12,7 +12,7 @@ public function __construct( public readonly array $queuesToConsume, public readonly int $memoryLimit, public readonly int $timeout, - public readonly int $sleep, + public readonly int|float $sleep, ) {} /** From 2aa5e4ff01b65baaaea9dc0528872167d99721f3 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 21 May 2025 20:12:51 +0200 Subject: [PATCH 55/57] fix: remove App facade from composer.json aliases (#586) --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 73e68c51..7d55ade2 100644 --- a/composer.json +++ b/composer.json @@ -85,7 +85,6 @@ "Native\\Laravel\\NativeServiceProvider" ], "aliases": { - "App": "Native\\Laravel\\Facades\\App", "ChildProcess": "Native\\Laravel\\Facades\\ChildProcess", "Clipboard": "Native\\Laravel\\Facades\\Clipboard", "ContextMenu": "Native\\Laravel\\Facades\\ContextMenu", From 3b79aa9cef55acc17893854af74db822d1f059ae Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Thu, 22 May 2025 14:41:58 +0200 Subject: [PATCH 56/57] Add support for detailed auto-updater event handling (#590) Expanded event constructors to include more detailed update metadata such as version, files, release information, and system requirements. Added a `downloadUpdate` method to the AutoUpdater facade. These updates enhance event broadcasting and improve client interaction with the auto-updater. --- src/AutoUpdater.php | 5 +++ src/Events/AutoUpdater/DownloadProgress.php | 8 ++++- src/Events/AutoUpdater/Error.php | 6 +++- src/Events/AutoUpdater/UpdateAvailable.php | 10 +++++- src/Events/AutoUpdater/UpdateCancelled.php | 31 +++++++++++++++++++ src/Events/AutoUpdater/UpdateDownloaded.php | 11 ++++++- src/Events/AutoUpdater/UpdateNotAvailable.php | 10 ++++++ src/Facades/AutoUpdater.php | 1 + 8 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 src/Events/AutoUpdater/UpdateCancelled.php diff --git a/src/AutoUpdater.php b/src/AutoUpdater.php index e714a0f1..79500455 100644 --- a/src/AutoUpdater.php +++ b/src/AutoUpdater.php @@ -17,4 +17,9 @@ public function quitAndInstall(): void { $this->client->post('auto-updater/quit-and-install'); } + + public function downloadUpdate(): void + { + $this->client->post('auto-updater/download-update'); + } } diff --git a/src/Events/AutoUpdater/DownloadProgress.php b/src/Events/AutoUpdater/DownloadProgress.php index 42045b27..23393157 100644 --- a/src/Events/AutoUpdater/DownloadProgress.php +++ b/src/Events/AutoUpdater/DownloadProgress.php @@ -12,7 +12,13 @@ class DownloadProgress implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public int $total, public int $delta, public int $transferred, public float $percent, public int $bytesPerSecond) {} + public function __construct( + public int $total, + public int $delta, + public int $transferred, + public float $percent, + public int $bytesPerSecond + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/Error.php b/src/Events/AutoUpdater/Error.php index 8444dcd1..9d2219d3 100644 --- a/src/Events/AutoUpdater/Error.php +++ b/src/Events/AutoUpdater/Error.php @@ -12,7 +12,11 @@ class Error implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public string $error) {} + public function __construct( + public string $name, + public string $message, + public ?string $stack, + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/UpdateAvailable.php b/src/Events/AutoUpdater/UpdateAvailable.php index 5dc55cdc..1fb05fb7 100644 --- a/src/Events/AutoUpdater/UpdateAvailable.php +++ b/src/Events/AutoUpdater/UpdateAvailable.php @@ -12,7 +12,15 @@ class UpdateAvailable implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct() {} + public function __construct( + public string $version, + public array $files, + public string $releaseDate, + public ?string $releaseName, + public string|array|null $releaseNotes, + public ?int $stagingPercentage, + public ?string $minimumSystemVersion, + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/UpdateCancelled.php b/src/Events/AutoUpdater/UpdateCancelled.php new file mode 100644 index 00000000..09d01b69 --- /dev/null +++ b/src/Events/AutoUpdater/UpdateCancelled.php @@ -0,0 +1,31 @@ + Date: Thu, 22 May 2025 13:43:16 +0100 Subject: [PATCH 57/57] chore(deps): bump dependabot/fetch-metadata from 2.3.0 to 2.4.0 (#585) Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.3.0...v2.4.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 2cb1d5e1..1a13177d 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.3.0 + uses: dependabot/fetch-metadata@v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}"