Compare commits

...

3 commits

Author SHA1 Message Date
Benjamin Nussbaum
91e222f7a6 chore: rector
Some checks failed
tests / ci (push) Has been cancelled
2025-10-02 22:29:46 +02:00
Benjamin Nussbaum
203584107f chore: update dependencies 2025-10-02 22:25:12 +02:00
Benjamin Nussbaum
56548a96cb
Update README.md 2025-10-02 22:12:34 +02:00
13 changed files with 240 additions and 291 deletions

View file

@ -11,7 +11,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4.12
- php - 8.4.13
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -25,6 +25,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- rector/rector (RECTOR) - v2
- tailwindcss (TAILWINDCSS) - v4

View file

@ -8,7 +8,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4.12
- php - 8.4.13
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,6 +22,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- rector/rector (RECTOR) - v2
- tailwindcss (TAILWINDCSS) - v4

View file

@ -8,7 +8,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4.12
- php - 8.4.13
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,6 +22,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- rector/rector (RECTOR) - v2
- tailwindcss (TAILWINDCSS) - v4

View file

@ -8,7 +8,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4.12
- php - 8.4.13
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,6 +22,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- rector/rector (RECTOR) - v2
- tailwindcss (TAILWINDCSS) - v4

View file

@ -15,6 +15,7 @@ It allows you to manage TRMNL devices, generate screens using native plugins, re
* 📡 Device Information Display battery status, WiFi strength, firmware version, and more.
* 🔍 Auto-Join Automatically detects and adds devices from your local network.
* 🖥️ Screen Generation Supports Plugins (including Mashups), Recipes, API, Markup, or updates via Code.
* Support for TRMNL [Design Framework](https://usetrmnl.com/framework)
* Over 45 compatible open-source recipes are available in the [community catalog](https://bnussbau.github.io/trmnl-recipe-catalog/)
* Supported Devices
* TRMNL OG (1-bit & 2-bit)
@ -22,8 +23,12 @@ It allows you to manage TRMNL devices, generate screens using native plugins, re
* Seeed Studio (XIAO 7.5" ePaper Panel)
* reTerminal E1001 Monochrome ePaper Display
* Custom ESP32 with TRMNL firmware
* Kindle Devices with [trmnl-kindle](https://github.com/usetrmnl/byos_laravel/pull/27)
* E-Reader Devices
* Kindle ([trmnl-kindle](https://github.com/usetrmnl/byos_laravel/pull/27))
* Nook ([trmnl-nook](https://github.com/usetrmnl/trmnl-nook))
* Kobo ([trmnl-kobo](https://github.com/usetrmnl/trmnl-kobo))
* Android Devices with [trmnl-android](https://github.com/usetrmnl/trmnl-android)
* Raspberry Pi (HDMI output) [trmnl-display](https://github.com/usetrmnl/trmnl-display)
* 🔄 TRMNL API Proxy Can act as a proxy for the native cloud service (requires TRMNL Developer Edition).
* This enables a hybrid setup for example, you can update your custom Train Monitor every 5 minutes in the morning, while displaying native TRMNL plugins throughout the day.
* 🌙 Dark Mode Switch between light and dark mode.

View file

@ -12,7 +12,7 @@ class ExpressionUtils
*/
public static function isAssociativeArray(array $array): bool
{
if (empty($array)) {
if ($array === []) {
return false;
}
@ -81,8 +81,10 @@ class ExpressionUtils
self::evaluateCondition($condition['right'], $variable, $object);
case 'or':
return self::evaluateCondition($condition['left'], $variable, $object) ||
self::evaluateCondition($condition['right'], $variable, $object);
if (self::evaluateCondition($condition['left'], $variable, $object)) {
return true;
}
return self::evaluateCondition($condition['right'], $variable, $object);
case 'comparison':
$leftValue = self::resolveValue($condition['left'], $variable, $object);

View file

@ -36,7 +36,7 @@ class BatteryLow extends Notification
return (new MailMessage)->markdown('mail.battery-low', ['device' => $this->device]);
}
public function toWebhook(object $notifiable)
public function toWebhook(object $notifiable): \App\Notifications\Messages\WebhookMessage
{
return WebhookMessage::create()
->data([

View file

@ -58,6 +58,7 @@ class PluginExportService
// Generate shared.liquid if needed (for liquid templates)
if ($plugin->markup_language === 'liquid') {
$sharedTemplate = $this->generateSharedTemplate();
/** @phpstan-ignore-next-line */
if ($sharedTemplate) {
File::put($tempDir.'/shared.liquid', $sharedTemplate);
}

15
boost.json Normal file
View file

@ -0,0 +1,15 @@
{
"agents": [
"claude_code",
"copilot",
"cursor",
"phpstorm"
],
"editors": [
"claude_code",
"cursor",
"phpstorm",
"vscode"
],
"guidelines": []
}

450
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -18,7 +18,7 @@ beforeEach(function (): void {
Storage::disk('public')->put('/images/sleep.bmp', 'fake-bmp-content');
});
test('command transforms default images for all device models', function () {
test('command transforms default images for all device models', function (): void {
// Ensure we have device models
$deviceModels = DeviceModel::all();
expect($deviceModels)->not->toBeEmpty();
@ -43,7 +43,7 @@ test('command transforms default images for all device models', function () {
}
});
test('getDeviceSpecificDefaultImage returns correct path for device with model', function () {
test('getDeviceSpecificDefaultImage returns correct path for device with model', function (): void {
$deviceModel = DeviceModel::first();
expect($deviceModel)->not->toBeNull();
@ -66,7 +66,7 @@ test('getDeviceSpecificDefaultImage returns correct path for device with model',
expect($sleepImage)->toBe($sleepPath);
});
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function () {
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function (): void {
$device = new Device();
$device->deviceModel = null;
@ -77,7 +77,7 @@ test('getDeviceSpecificDefaultImage falls back to original images for device wit
expect($sleepImage)->toBe('images/sleep.bmp');
});
test('generateDefaultScreenImage creates images from Blade templates', function () {
test('generateDefaultScreenImage creates images from Blade templates', function (): void {
$device = Device::factory()->create();
$setupUuid = ImageGenerationService::generateDefaultScreenImage($device, 'setup-logo');
@ -97,14 +97,14 @@ test('generateDefaultScreenImage creates images from Blade templates', function
expect(Storage::disk('public')->exists($sleepPath))->toBeTrue();
});
test('generateDefaultScreenImage throws exception for invalid image type', function () {
test('generateDefaultScreenImage throws exception for invalid image type', function (): void {
$device = Device::factory()->create();
expect(fn () => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
expect(fn (): string => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
->toThrow(InvalidArgumentException::class);
});
test('getDeviceSpecificDefaultImage returns null for invalid image type', function () {
test('getDeviceSpecificDefaultImage returns null for invalid image type', function (): void {
$device = new Device();
$device->deviceModel = DeviceModel::first();

View file

@ -146,7 +146,7 @@ LIQUID
// Instead of checking for absence of 1 and 2, let's verify the count
// The filtered result should only contain 3, 4, 5
$filteredContent = strip_tags($result);
$filteredContent = strip_tags((string) $result);
$this->assertStringNotContainsString('1', $filteredContent);
$this->assertStringNotContainsString('2', $filteredContent);
});

View file

@ -17,7 +17,7 @@ beforeEach(function (): void {
Storage::disk('public')->put('/images/sleep.bmp', 'fake-bmp-content');
});
test('command transforms default images for all device models', function () {
test('command transforms default images for all device models', function (): void {
// Ensure we have device models
$deviceModels = DeviceModel::all();
expect($deviceModels)->not->toBeEmpty();
@ -42,7 +42,7 @@ test('command transforms default images for all device models', function () {
}
});
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function () {
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function (): void {
$device = new Device();
$device->deviceModel = null;
@ -53,7 +53,7 @@ test('getDeviceSpecificDefaultImage falls back to original images for device wit
expect($sleepImage)->toBe('images/sleep.bmp');
});
test('generateDefaultScreenImage creates images from Blade templates', function () {
test('generateDefaultScreenImage creates images from Blade templates', function (): void {
$device = Device::factory()->create();
$setupUuid = ImageGenerationService::generateDefaultScreenImage($device, 'setup-logo');
@ -71,14 +71,14 @@ test('generateDefaultScreenImage creates images from Blade templates', function
expect(Storage::disk('public')->exists($sleepPath))->toBeTrue();
})->skipOnCI();
test('generateDefaultScreenImage throws exception for invalid image type', function () {
test('generateDefaultScreenImage throws exception for invalid image type', function (): void {
$device = Device::factory()->create();
expect(fn () => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
expect(fn (): string => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
->toThrow(InvalidArgumentException::class);
});
test('getDeviceSpecificDefaultImage returns null for invalid image type', function () {
test('getDeviceSpecificDefaultImage returns null for invalid image type', function (): void {
$device = new Device();
$device->deviceModel = DeviceModel::first();