Compare commits

..

No commits in common. "91e222f7a6a5a002336549644bbe50bacd9e93b7" and "e812f56c114c35d229c6a39402a949e2d26e25e9" have entirely different histories.

13 changed files with 291 additions and 240 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.13
- php - 8.4.12
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -25,7 +25,6 @@ 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
@ -578,4 +577,4 @@ $pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter.
</laravel-boost-guidelines>
</laravel-boost-guidelines>

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.13
- php - 8.4.12
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,7 +22,6 @@ 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
@ -575,4 +574,4 @@ $pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter.
</laravel-boost-guidelines>
</laravel-boost-guidelines>

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.13
- php - 8.4.12
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,7 +22,6 @@ 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
@ -575,4 +574,4 @@ $pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter.
</laravel-boost-guidelines>
</laravel-boost-guidelines>

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.13
- php - 8.4.12
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
@ -22,7 +22,6 @@ 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
@ -575,4 +574,4 @@ $pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter.
</laravel-boost-guidelines>
</laravel-boost-guidelines>

View file

@ -15,7 +15,6 @@ 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)
@ -23,12 +22,8 @@ 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
* 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))
* Kindle Devices with [trmnl-kindle](https://github.com/usetrmnl/byos_laravel/pull/27)
* 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 ($array === []) {
if (empty($array)) {
return false;
}
@ -81,10 +81,8 @@ class ExpressionUtils
self::evaluateCondition($condition['right'], $variable, $object);
case 'or':
if (self::evaluateCondition($condition['left'], $variable, $object)) {
return true;
}
return self::evaluateCondition($condition['right'], $variable, $object);
return self::evaluateCondition($condition['left'], $variable, $object) ||
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): \App\Notifications\Messages\WebhookMessage
public function toWebhook(object $notifiable)
{
return WebhookMessage::create()
->data([

View file

@ -58,7 +58,6 @@ 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);
}

View file

@ -1,15 +0,0 @@
{
"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 (): void {
test('command transforms default images for all device models', function () {
// 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 (): voi
}
});
test('getDeviceSpecificDefaultImage returns correct path for device with model', function (): void {
test('getDeviceSpecificDefaultImage returns correct path for device with model', function () {
$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 (): void {
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function () {
$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 (): void {
test('generateDefaultScreenImage creates images from Blade templates', function () {
$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 (): void {
test('generateDefaultScreenImage throws exception for invalid image type', function () {
$device = Device::factory()->create();
expect(fn (): string => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
expect(fn () => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
->toThrow(InvalidArgumentException::class);
});
test('getDeviceSpecificDefaultImage returns null for invalid image type', function (): void {
test('getDeviceSpecificDefaultImage returns null for invalid image type', function () {
$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((string) $result);
$filteredContent = strip_tags($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 (): void {
test('command transforms default images for all device models', function () {
// 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 (): voi
}
});
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function (): void {
test('getDeviceSpecificDefaultImage falls back to original images for device without model', function () {
$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 (): void {
test('generateDefaultScreenImage creates images from Blade templates', function () {
$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 (): void {
test('generateDefaultScreenImage throws exception for invalid image type', function () {
$device = Device::factory()->create();
expect(fn (): string => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
expect(fn () => ImageGenerationService::generateDefaultScreenImage($device, 'invalid-type'))
->toThrow(InvalidArgumentException::class);
});
test('getDeviceSpecificDefaultImage returns null for invalid image type', function (): void {
test('getDeviceSpecificDefaultImage returns null for invalid image type', function () {
$device = new Device();
$device->deviceModel = DeviceModel::first();