From 212f11b7b9590c6cb4a0ed16ef11f27310a3677d Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 4 Mar 2025 14:12:45 +0100 Subject: [PATCH 01/39] 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 02/39] 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 03/39] 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 04/39] 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 05/39] 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 06/39] 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 07/39] 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 08/39] 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 09/39] 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 10/39] 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 11/39] 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 12/39] 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 13/39] 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 14/39] 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 15/39] 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 16/39] 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 17/39] 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 18/39] 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 19/39] 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 20/39] 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 21/39] 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 22/39] 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 23/39] 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 24/39] 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 25/39] 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 26/39] 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 27/39] 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 28/39] 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 29/39] 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 30/39] 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 31/39] 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 32/39] 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 33/39] 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 34/39] 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 35/39] 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 36/39] 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 37/39] 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 38/39] 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 39/39] 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",