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: 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 }}" 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' 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 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", diff --git a/config/nativephp.php b/config/nativephp.php index 817bc12b..d68245fc 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 @@ -131,6 +141,7 @@ 'queues' => ['default'], 'memory_limit' => 128, 'timeout' => 60, + 'sleep' => 3, ], ], 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/AutoUpdater.php b/src/AutoUpdater.php new file mode 100644 index 00000000..79500455 --- /dev/null +++ b/src/AutoUpdater.php @@ -0,0 +1,25 @@ +client->post('auto-updater/check-for-updates'); + } + + 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/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' => [ diff --git a/src/DTOs/QueueConfig.php b/src/DTOs/QueueConfig.php index 0ec3ca01..29308a03 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|float $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/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 @@ +path() === '_native/api/cookie') { return $next($request); 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/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, diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 875a5c2c..2c998080 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -24,13 +24,18 @@ 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}", "--timeout={$config->timeout}", + "--sleep={$config->sleep}", ], 'queue_'.$config->alias, persistent: true, 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 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/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']); 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([