From cb86f8e3626d8ddcf7b370a09393fca511f0f50d Mon Sep 17 00:00:00 2001 From: subhajit Date: Fri, 12 Jun 2026 18:22:10 +0530 Subject: [PATCH] update --- .agents/skills/fluxui-development/SKILL.md | 81 ++ .agents/skills/fortify-development/SKILL.md | 2 +- .../skills/laravel-best-practices/SKILL.md | 2 +- .../rules/advanced-queries.md | 2 +- .../rules/architecture.md | 2 +- .../rules/blade-views.md | 2 +- .../laravel-best-practices/rules/caching.md | 2 +- .../rules/collections.md | 2 +- .../laravel-best-practices/rules/config.md | 2 +- .../rules/db-performance.md | 2 +- .../laravel-best-practices/rules/eloquent.md | 2 +- .../rules/error-handling.md | 2 +- .../rules/events-notifications.md | 2 +- .../rules/http-client.md | 2 +- .../laravel-best-practices/rules/mail.md | 2 +- .../rules/migrations.md | 2 +- .../rules/queue-jobs.md | 2 +- .../laravel-best-practices/rules/routing.md | 2 +- .../rules/scheduling.md | 2 +- .../laravel-best-practices/rules/security.md | 2 +- .../laravel-best-practices/rules/style.md | 2 +- .../laravel-best-practices/rules/testing.md | 2 +- .../rules/validation.md | 2 +- .agents/skills/livewire-development/SKILL.md | 2 +- .../reference/javascript-hooks.md | 2 +- .agents/skills/pest-testing/SKILL.md | 2 +- .../skills/tailwindcss-development/SKILL.md | 2 +- .claude/skills/fluxui-development/SKILL.md | 4 +- .claude/skills/fortify-development/SKILL.md | 2 +- .../skills/laravel-best-practices/SKILL.md | 2 +- .../rules/advanced-queries.md | 2 +- .../rules/architecture.md | 2 +- .../rules/blade-views.md | 2 +- .../laravel-best-practices/rules/caching.md | 2 +- .../rules/collections.md | 2 +- .../laravel-best-practices/rules/config.md | 2 +- .../rules/db-performance.md | 2 +- .../laravel-best-practices/rules/eloquent.md | 2 +- .../rules/error-handling.md | 2 +- .../rules/events-notifications.md | 2 +- .../rules/http-client.md | 2 +- .../laravel-best-practices/rules/mail.md | 2 +- .../rules/migrations.md | 2 +- .../rules/queue-jobs.md | 2 +- .../laravel-best-practices/rules/routing.md | 2 +- .../rules/scheduling.md | 2 +- .../laravel-best-practices/rules/security.md | 2 +- .../laravel-best-practices/rules/style.md | 2 +- .../laravel-best-practices/rules/testing.md | 2 +- .../rules/validation.md | 2 +- .claude/skills/livewire-development/SKILL.md | 2 +- .../reference/javascript-hooks.md | 2 +- .claude/skills/pest-testing/SKILL.md | 2 +- .../skills/tailwindcss-development/SKILL.md | 2 +- .github/skills/fluxui-development/SKILL.md | 4 +- .github/skills/fortify-development/SKILL.md | 2 +- .../skills/laravel-best-practices/SKILL.md | 2 +- .../rules/advanced-queries.md | 2 +- .../rules/architecture.md | 2 +- .../rules/blade-views.md | 2 +- .../laravel-best-practices/rules/caching.md | 2 +- .../rules/collections.md | 2 +- .../laravel-best-practices/rules/config.md | 2 +- .../rules/db-performance.md | 2 +- .../laravel-best-practices/rules/eloquent.md | 2 +- .../rules/error-handling.md | 2 +- .../rules/events-notifications.md | 2 +- .../rules/http-client.md | 2 +- .../laravel-best-practices/rules/mail.md | 2 +- .../rules/migrations.md | 2 +- .../rules/queue-jobs.md | 2 +- .../laravel-best-practices/rules/routing.md | 2 +- .../rules/scheduling.md | 2 +- .../laravel-best-practices/rules/security.md | 2 +- .../laravel-best-practices/rules/style.md | 2 +- .../laravel-best-practices/rules/testing.md | 2 +- .../rules/validation.md | 2 +- .github/skills/livewire-development/SKILL.md | 2 +- .../reference/javascript-hooks.md | 2 +- .github/skills/pest-testing/SKILL.md | 2 +- .../skills/tailwindcss-development/SKILL.md | 2 +- AGENTS.md | 3 +- CLAUDE.md | 3 +- .../Controllers/KekaOutlookController.php | 101 ++ app/Models/User.php | 1 + app/Services/KekaOutlookService.php | 224 ++++ boost.json | 7 +- composer.json | 2 +- composer.lock | 1131 ++++++++--------- config/app.php | 17 + config/microsoft.php | 16 + ...2543_add_keka_ms_fields_to_users_table.php | 30 + resources/views/test/keka.blade.php | 37 + routes/web.php | 9 + 94 files changed, 1156 insertions(+), 670 deletions(-) create mode 100644 .agents/skills/fluxui-development/SKILL.md create mode 100644 app/Http/Controllers/KekaOutlookController.php create mode 100644 app/Services/KekaOutlookService.php create mode 100644 config/microsoft.php create mode 100644 database/migrations/2026_06_12_122543_add_keka_ms_fields_to_users_table.php create mode 100644 resources/views/test/keka.blade.php diff --git a/.agents/skills/fluxui-development/SKILL.md b/.agents/skills/fluxui-development/SKILL.md new file mode 100644 index 0000000..d4fb5a0 --- /dev/null +++ b/.agents/skills/fluxui-development/SKILL.md @@ -0,0 +1,81 @@ +--- +name: fluxui-development +description: "Use this skill for Flux UI development in Livewire applications only. Trigger when working with components, building or customizing Livewire component UIs, creating forms, modals, tables, or other interactive elements. Covers: flux: components (buttons, inputs, modals, forms, tables, date-pickers, kanban, badges, tooltips, etc.), component composition, Tailwind CSS styling, Heroicons/Lucide icon integration, validation patterns, responsive design, and theming. Do not use for non-Livewire frameworks or non-component styling." +license: MIT +metadata: + author: laravel +--- + +# Flux UI Development + +## Documentation + +Use `search-docs` for detailed Flux UI patterns and documentation. + +## Basic Usage + +This project uses the free edition of Flux UI, which includes all free components and variants but not Pro components. + +Flux UI is a component library for Livewire built with Tailwind CSS. It provides components that are easy to use and customize. + +Use Flux UI components when available. Fall back to standard Blade components when no Flux component exists for your needs. + + +```blade +Click me +``` + +## Available Components (Free Edition) + +Available: avatar, badge, brand, breadcrumbs, button, callout, card, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, pagination, profile, progress, radio, select, separator, skeleton, switch, table, text, textarea, toast, tooltip + +## Icons + +Flux includes [Heroicons](https://heroicons.com/) as its default icon set. Search for exact icon names on the Heroicons site - do not guess or invent icon names. + + +```blade +Export +``` + +For icons not available in Heroicons, use [Lucide](https://lucide.dev/). Import the icons you need with the Artisan command: + +```bash +php artisan flux:icon crown grip-vertical github +``` + +## Common Patterns + +### Form Fields + + +```blade + + Email + + + +``` + +### Modals + + +```blade + + Title +

Content

+
+``` + +## Verification + +1. Check component renders correctly +2. Test interactive states +3. Verify mobile responsiveness + +## Common Pitfalls + +- Trying to use Pro-only components in the free edition +- Not checking if a Flux component exists before creating custom implementations +- Forgetting to use the `search-docs` tool for component-specific documentation +- Not following existing project patterns for Flux usage diff --git a/.agents/skills/fortify-development/SKILL.md b/.agents/skills/fortify-development/SKILL.md index beb1734..2c4e84f 100644 --- a/.agents/skills/fortify-development/SKILL.md +++ b/.agents/skills/fortify-development/SKILL.md @@ -148,4 +148,4 @@ ## Key Endpoints | Passkey Confirm | POST | `/passkeys/confirm` | | Passkey Options | GET | `/user/passkeys/options` | | Register Passkey | POST | `/user/passkeys` | -| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | \ No newline at end of file +| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | diff --git a/.agents/skills/laravel-best-practices/SKILL.md b/.agents/skills/laravel-best-practices/SKILL.md index aca32c9..965e267 100644 --- a/.agents/skills/laravel-best-practices/SKILL.md +++ b/.agents/skills/laravel-best-practices/SKILL.md @@ -187,4 +187,4 @@ ## How to Apply 1. Identify the file type and select relevant sections (e.g., migration → §16, controller → §1, §3, §5, §6, §10) 2. Check sibling files for existing patterns — follow those first per Consistency First -3. Verify API syntax with `search-docs` for the installed Laravel version \ No newline at end of file +3. Verify API syntax with `search-docs` for the installed Laravel version diff --git a/.agents/skills/laravel-best-practices/rules/advanced-queries.md b/.agents/skills/laravel-best-practices/rules/advanced-queries.md index 920714a..f12876e 100644 --- a/.agents/skills/laravel-best-practices/rules/advanced-queries.md +++ b/.agents/skills/laravel-best-practices/rules/advanced-queries.md @@ -103,4 +103,4 @@ ## Use Correlated Subqueries for Has-Many Ordering ->take(1) ); } -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/architecture.md b/.agents/skills/laravel-best-practices/rules/architecture.md index 6112a63..51c6e65 100644 --- a/.agents/skills/laravel-best-practices/rules/architecture.md +++ b/.agents/skills/laravel-best-practices/rules/architecture.md @@ -199,4 +199,4 @@ ## Convention Over Configuration return $this->belongsToMany(Role::class); } } -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/blade-views.md b/.agents/skills/laravel-best-practices/rules/blade-views.md index c6f8aaf..5f0b3a1 100644 --- a/.agents/skills/laravel-best-practices/rules/blade-views.md +++ b/.agents/skills/laravel-best-practices/rules/blade-views.md @@ -33,4 +33,4 @@ ## Use Blade Fragments for Partial Re-Renders (htmx/Turbo) ## Use `@aware` for Deeply Nested Component Props -Avoids re-passing parent props through every level of nested components. \ No newline at end of file +Avoids re-passing parent props through every level of nested components. diff --git a/.agents/skills/laravel-best-practices/rules/caching.md b/.agents/skills/laravel-best-practices/rules/caching.md index e65146d..67408d6 100644 --- a/.agents/skills/laravel-best-practices/rules/caching.md +++ b/.agents/skills/laravel-best-practices/rules/caching.md @@ -67,4 +67,4 @@ ## Configure Failover Cache Stores in Production ```php 'failover' => ['driver' => 'failover', 'stores' => ['redis', 'database']], -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/collections.md b/.agents/skills/laravel-best-practices/rules/collections.md index 14f683d..18e8d9e 100644 --- a/.agents/skills/laravel-best-practices/rules/collections.md +++ b/.agents/skills/laravel-best-practices/rules/collections.md @@ -41,4 +41,4 @@ ## Use `#[CollectedBy]` for Custom Collection Classes ```php #[CollectedBy(UserCollection::class)] class User extends Model {} -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/config.md b/.agents/skills/laravel-best-practices/rules/config.md index 193155d..9bea727 100644 --- a/.agents/skills/laravel-best-practices/rules/config.md +++ b/.agents/skills/laravel-best-practices/rules/config.md @@ -70,4 +70,4 @@ ## Use Constants and Language Files ```php // Only when lang files already exist in the project return back()->with('message', __('app.article_added')); -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/db-performance.md b/.agents/skills/laravel-best-practices/rules/db-performance.md index 8fb7193..c49ba16 100644 --- a/.agents/skills/laravel-best-practices/rules/db-performance.md +++ b/.agents/skills/laravel-best-practices/rules/db-performance.md @@ -189,4 +189,4 @@ ## No Queries in Blade Templates @foreach ($users as $user) {{ $user->profile->name }} @endforeach -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/eloquent.md b/.agents/skills/laravel-best-practices/rules/eloquent.md index 09cd66a..413d5da 100644 --- a/.agents/skills/laravel-best-practices/rules/eloquent.md +++ b/.agents/skills/laravel-best-practices/rules/eloquent.md @@ -145,4 +145,4 @@ ## Avoid Hardcoded Table Names in Queries Prefer Eloquent queries and relationships over `DB::table()` whenever possible — they already reference the model's table. When `DB::table()` or raw joins are unavoidable, always use `(new Model)->getTable()` to keep the reference traceable. -**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. \ No newline at end of file +**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. diff --git a/.agents/skills/laravel-best-practices/rules/error-handling.md b/.agents/skills/laravel-best-practices/rules/error-handling.md index bb8e7a3..4b14866 100644 --- a/.agents/skills/laravel-best-practices/rules/error-handling.md +++ b/.agents/skills/laravel-best-practices/rules/error-handling.md @@ -69,4 +69,4 @@ ## Add Context to Exception Classes return ['order_id' => $this->orderId]; } } -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/events-notifications.md b/.agents/skills/laravel-best-practices/rules/events-notifications.md index 47fcf32..82e329e 100644 --- a/.agents/skills/laravel-best-practices/rules/events-notifications.md +++ b/.agents/skills/laravel-best-practices/rules/events-notifications.md @@ -49,4 +49,4 @@ ## Use On-Demand Notifications for Non-User Recipients ## Implement `HasLocalePreference` on Notifiable Models -Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. \ No newline at end of file +Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. diff --git a/.agents/skills/laravel-best-practices/rules/http-client.md b/.agents/skills/laravel-best-practices/rules/http-client.md index fd37ddb..8e2f16e 100644 --- a/.agents/skills/laravel-best-practices/rules/http-client.md +++ b/.agents/skills/laravel-best-practices/rules/http-client.md @@ -157,4 +157,4 @@ ## Fake HTTP Calls in Tests Http::fake([ 'api.example.com/*' => Http::failedConnection(), ]); -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/mail.md b/.agents/skills/laravel-best-practices/rules/mail.md index 2435d9c..7c71733 100644 --- a/.agents/skills/laravel-best-practices/rules/mail.md +++ b/.agents/skills/laravel-best-practices/rules/mail.md @@ -24,4 +24,4 @@ ## Separate Content Tests from Sending Tests Content tests: instantiate the mailable directly, call `assertSeeInHtml()`. Sending tests: use `Mail::fake()` and `assertSent()`/`assertQueued()`. -Don't mix them — it conflates concerns and makes tests brittle. \ No newline at end of file +Don't mix them — it conflates concerns and makes tests brittle. diff --git a/.agents/skills/laravel-best-practices/rules/migrations.md b/.agents/skills/laravel-best-practices/rules/migrations.md index de25aa3..df6f5f3 100644 --- a/.agents/skills/laravel-best-practices/rules/migrations.md +++ b/.agents/skills/laravel-best-practices/rules/migrations.md @@ -118,4 +118,4 @@ ## Keep Migrations Focused // Migration 2: seed_default_settings DB::table('settings')->insert(['key' => 'version', 'value' => '1.0']); -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/queue-jobs.md b/.agents/skills/laravel-best-practices/rules/queue-jobs.md index f7aa548..c41915e 100644 --- a/.agents/skills/laravel-best-practices/rules/queue-jobs.md +++ b/.agents/skills/laravel-best-practices/rules/queue-jobs.md @@ -141,4 +141,4 @@ ## Use Horizon for Complex Queue Scenarios ], ], ], -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/routing.md b/.agents/skills/laravel-best-practices/rules/routing.md index 977d136..b6e3086 100644 --- a/.agents/skills/laravel-best-practices/rules/routing.md +++ b/.agents/skills/laravel-best-practices/rules/routing.md @@ -96,4 +96,4 @@ ## Type-Hint Form Requests return redirect()->route('posts.index'); } -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/scheduling.md b/.agents/skills/laravel-best-practices/rules/scheduling.md index dfaefa2..a984794 100644 --- a/.agents/skills/laravel-best-practices/rules/scheduling.md +++ b/.agents/skills/laravel-best-practices/rules/scheduling.md @@ -36,4 +36,4 @@ ## Use Schedule Groups for Shared Configuration Schedule::command('emails:send --force'); Schedule::command('emails:prune'); }); -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/security.md b/.agents/skills/laravel-best-practices/rules/security.md index 909ff91..2d7200c 100644 --- a/.agents/skills/laravel-best-practices/rules/security.md +++ b/.agents/skills/laravel-best-practices/rules/security.md @@ -195,4 +195,4 @@ ## Encrypt Sensitive Database Fields ]; } } -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/style.md b/.agents/skills/laravel-best-practices/rules/style.md index 67af989..64d1730 100644 --- a/.agents/skills/laravel-best-practices/rules/style.md +++ b/.agents/skills/laravel-best-practices/rules/style.md @@ -122,4 +122,4 @@ ## No Unnecessary Comments Correct: ```php if ($this->hasJoins()) -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/testing.md b/.agents/skills/laravel-best-practices/rules/testing.md index 287b083..4fbf12f 100644 --- a/.agents/skills/laravel-best-practices/rules/testing.md +++ b/.agents/skills/laravel-best-practices/rules/testing.md @@ -40,4 +40,4 @@ ## Use `recycle()` to Share Relationship Instances Across Factories Ticket::factory() ->recycle(Airline::factory()->create()) ->create(); -``` \ No newline at end of file +``` diff --git a/.agents/skills/laravel-best-practices/rules/validation.md b/.agents/skills/laravel-best-practices/rules/validation.md index a20202f..5fde106 100644 --- a/.agents/skills/laravel-best-practices/rules/validation.md +++ b/.agents/skills/laravel-best-practices/rules/validation.md @@ -72,4 +72,4 @@ ## Use the `after()` Method for Custom Validation }, ]; } -``` \ No newline at end of file +``` diff --git a/.agents/skills/livewire-development/SKILL.md b/.agents/skills/livewire-development/SKILL.md index 62d032d..0ae356e 100644 --- a/.agents/skills/livewire-development/SKILL.md +++ b/.agents/skills/livewire-development/SKILL.md @@ -172,4 +172,4 @@ ## Common Pitfalls - Expecting `wire:model` real-time → use `wire:model.live` - Unclosed component tags → syntax errors in v4 - Using deprecated config keys or JS hooks -- Including Alpine.js separately (already bundled in Livewire 4) \ No newline at end of file +- Including Alpine.js separately (already bundled in Livewire 4) diff --git a/.agents/skills/livewire-development/reference/javascript-hooks.md b/.agents/skills/livewire-development/reference/javascript-hooks.md index d6a4417..660d66b 100644 --- a/.agents/skills/livewire-development/reference/javascript-hooks.md +++ b/.agents/skills/livewire-development/reference/javascript-hooks.md @@ -36,4 +36,4 @@ ### Component-Scoped Interceptors ## Magic Properties - `$errors` - Access validation errors from JavaScript -- `$intercept` - Component-scoped interceptors \ No newline at end of file +- `$intercept` - Component-scoped interceptors diff --git a/.agents/skills/pest-testing/SKILL.md b/.agents/skills/pest-testing/SKILL.md index f748676..ab27161 100644 --- a/.agents/skills/pest-testing/SKILL.md +++ b/.agents/skills/pest-testing/SKILL.md @@ -163,4 +163,4 @@ ## Common Pitfalls - Forgetting datasets for repetitive validation tests - Deleting tests without approval - Forgetting `assertNoJavaScriptErrors()` in browser tests -- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` \ No newline at end of file +- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` diff --git a/.agents/skills/tailwindcss-development/SKILL.md b/.agents/skills/tailwindcss-development/SKILL.md index 7c8e295..c0cb2fb 100644 --- a/.agents/skills/tailwindcss-development/SKILL.md +++ b/.agents/skills/tailwindcss-development/SKILL.md @@ -116,4 +116,4 @@ ## Common Pitfalls - Using `@tailwind` directives instead of `@import "tailwindcss"` - Trying to use `tailwind.config.js` instead of CSS `@theme` directive - Using margins for spacing between siblings instead of gap utilities -- Forgetting to add dark mode variants when the project uses dark mode \ No newline at end of file +- Forgetting to add dark mode variants when the project uses dark mode diff --git a/.claude/skills/fluxui-development/SKILL.md b/.claude/skills/fluxui-development/SKILL.md index 4b5aabb..d4fb5a0 100644 --- a/.claude/skills/fluxui-development/SKILL.md +++ b/.claude/skills/fluxui-development/SKILL.md @@ -27,7 +27,7 @@ ## Basic Usage ## Available Components (Free Edition) -Available: avatar, badge, brand, breadcrumbs, button, callout, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, profile, radio, select, separator, skeleton, switch, text, textarea, tooltip +Available: avatar, badge, brand, breadcrumbs, button, callout, card, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, pagination, profile, progress, radio, select, separator, skeleton, switch, table, text, textarea, toast, tooltip ## Icons @@ -78,4 +78,4 @@ ## Common Pitfalls - Trying to use Pro-only components in the free edition - Not checking if a Flux component exists before creating custom implementations - Forgetting to use the `search-docs` tool for component-specific documentation -- Not following existing project patterns for Flux usage \ No newline at end of file +- Not following existing project patterns for Flux usage diff --git a/.claude/skills/fortify-development/SKILL.md b/.claude/skills/fortify-development/SKILL.md index beb1734..2c4e84f 100644 --- a/.claude/skills/fortify-development/SKILL.md +++ b/.claude/skills/fortify-development/SKILL.md @@ -148,4 +148,4 @@ ## Key Endpoints | Passkey Confirm | POST | `/passkeys/confirm` | | Passkey Options | GET | `/user/passkeys/options` | | Register Passkey | POST | `/user/passkeys` | -| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | \ No newline at end of file +| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | diff --git a/.claude/skills/laravel-best-practices/SKILL.md b/.claude/skills/laravel-best-practices/SKILL.md index aca32c9..965e267 100644 --- a/.claude/skills/laravel-best-practices/SKILL.md +++ b/.claude/skills/laravel-best-practices/SKILL.md @@ -187,4 +187,4 @@ ## How to Apply 1. Identify the file type and select relevant sections (e.g., migration → §16, controller → §1, §3, §5, §6, §10) 2. Check sibling files for existing patterns — follow those first per Consistency First -3. Verify API syntax with `search-docs` for the installed Laravel version \ No newline at end of file +3. Verify API syntax with `search-docs` for the installed Laravel version diff --git a/.claude/skills/laravel-best-practices/rules/advanced-queries.md b/.claude/skills/laravel-best-practices/rules/advanced-queries.md index 920714a..f12876e 100644 --- a/.claude/skills/laravel-best-practices/rules/advanced-queries.md +++ b/.claude/skills/laravel-best-practices/rules/advanced-queries.md @@ -103,4 +103,4 @@ ## Use Correlated Subqueries for Has-Many Ordering ->take(1) ); } -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/architecture.md b/.claude/skills/laravel-best-practices/rules/architecture.md index 6112a63..51c6e65 100644 --- a/.claude/skills/laravel-best-practices/rules/architecture.md +++ b/.claude/skills/laravel-best-practices/rules/architecture.md @@ -199,4 +199,4 @@ ## Convention Over Configuration return $this->belongsToMany(Role::class); } } -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/blade-views.md b/.claude/skills/laravel-best-practices/rules/blade-views.md index c6f8aaf..5f0b3a1 100644 --- a/.claude/skills/laravel-best-practices/rules/blade-views.md +++ b/.claude/skills/laravel-best-practices/rules/blade-views.md @@ -33,4 +33,4 @@ ## Use Blade Fragments for Partial Re-Renders (htmx/Turbo) ## Use `@aware` for Deeply Nested Component Props -Avoids re-passing parent props through every level of nested components. \ No newline at end of file +Avoids re-passing parent props through every level of nested components. diff --git a/.claude/skills/laravel-best-practices/rules/caching.md b/.claude/skills/laravel-best-practices/rules/caching.md index e65146d..67408d6 100644 --- a/.claude/skills/laravel-best-practices/rules/caching.md +++ b/.claude/skills/laravel-best-practices/rules/caching.md @@ -67,4 +67,4 @@ ## Configure Failover Cache Stores in Production ```php 'failover' => ['driver' => 'failover', 'stores' => ['redis', 'database']], -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/collections.md b/.claude/skills/laravel-best-practices/rules/collections.md index 14f683d..18e8d9e 100644 --- a/.claude/skills/laravel-best-practices/rules/collections.md +++ b/.claude/skills/laravel-best-practices/rules/collections.md @@ -41,4 +41,4 @@ ## Use `#[CollectedBy]` for Custom Collection Classes ```php #[CollectedBy(UserCollection::class)] class User extends Model {} -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/config.md b/.claude/skills/laravel-best-practices/rules/config.md index 193155d..9bea727 100644 --- a/.claude/skills/laravel-best-practices/rules/config.md +++ b/.claude/skills/laravel-best-practices/rules/config.md @@ -70,4 +70,4 @@ ## Use Constants and Language Files ```php // Only when lang files already exist in the project return back()->with('message', __('app.article_added')); -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/db-performance.md b/.claude/skills/laravel-best-practices/rules/db-performance.md index 8fb7193..c49ba16 100644 --- a/.claude/skills/laravel-best-practices/rules/db-performance.md +++ b/.claude/skills/laravel-best-practices/rules/db-performance.md @@ -189,4 +189,4 @@ ## No Queries in Blade Templates @foreach ($users as $user) {{ $user->profile->name }} @endforeach -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/eloquent.md b/.claude/skills/laravel-best-practices/rules/eloquent.md index 09cd66a..413d5da 100644 --- a/.claude/skills/laravel-best-practices/rules/eloquent.md +++ b/.claude/skills/laravel-best-practices/rules/eloquent.md @@ -145,4 +145,4 @@ ## Avoid Hardcoded Table Names in Queries Prefer Eloquent queries and relationships over `DB::table()` whenever possible — they already reference the model's table. When `DB::table()` or raw joins are unavoidable, always use `(new Model)->getTable()` to keep the reference traceable. -**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. \ No newline at end of file +**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. diff --git a/.claude/skills/laravel-best-practices/rules/error-handling.md b/.claude/skills/laravel-best-practices/rules/error-handling.md index bb8e7a3..4b14866 100644 --- a/.claude/skills/laravel-best-practices/rules/error-handling.md +++ b/.claude/skills/laravel-best-practices/rules/error-handling.md @@ -69,4 +69,4 @@ ## Add Context to Exception Classes return ['order_id' => $this->orderId]; } } -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/events-notifications.md b/.claude/skills/laravel-best-practices/rules/events-notifications.md index 47fcf32..82e329e 100644 --- a/.claude/skills/laravel-best-practices/rules/events-notifications.md +++ b/.claude/skills/laravel-best-practices/rules/events-notifications.md @@ -49,4 +49,4 @@ ## Use On-Demand Notifications for Non-User Recipients ## Implement `HasLocalePreference` on Notifiable Models -Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. \ No newline at end of file +Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. diff --git a/.claude/skills/laravel-best-practices/rules/http-client.md b/.claude/skills/laravel-best-practices/rules/http-client.md index fd37ddb..8e2f16e 100644 --- a/.claude/skills/laravel-best-practices/rules/http-client.md +++ b/.claude/skills/laravel-best-practices/rules/http-client.md @@ -157,4 +157,4 @@ ## Fake HTTP Calls in Tests Http::fake([ 'api.example.com/*' => Http::failedConnection(), ]); -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/mail.md b/.claude/skills/laravel-best-practices/rules/mail.md index 2435d9c..7c71733 100644 --- a/.claude/skills/laravel-best-practices/rules/mail.md +++ b/.claude/skills/laravel-best-practices/rules/mail.md @@ -24,4 +24,4 @@ ## Separate Content Tests from Sending Tests Content tests: instantiate the mailable directly, call `assertSeeInHtml()`. Sending tests: use `Mail::fake()` and `assertSent()`/`assertQueued()`. -Don't mix them — it conflates concerns and makes tests brittle. \ No newline at end of file +Don't mix them — it conflates concerns and makes tests brittle. diff --git a/.claude/skills/laravel-best-practices/rules/migrations.md b/.claude/skills/laravel-best-practices/rules/migrations.md index de25aa3..df6f5f3 100644 --- a/.claude/skills/laravel-best-practices/rules/migrations.md +++ b/.claude/skills/laravel-best-practices/rules/migrations.md @@ -118,4 +118,4 @@ ## Keep Migrations Focused // Migration 2: seed_default_settings DB::table('settings')->insert(['key' => 'version', 'value' => '1.0']); -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/queue-jobs.md b/.claude/skills/laravel-best-practices/rules/queue-jobs.md index f7aa548..c41915e 100644 --- a/.claude/skills/laravel-best-practices/rules/queue-jobs.md +++ b/.claude/skills/laravel-best-practices/rules/queue-jobs.md @@ -141,4 +141,4 @@ ## Use Horizon for Complex Queue Scenarios ], ], ], -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/routing.md b/.claude/skills/laravel-best-practices/rules/routing.md index 977d136..b6e3086 100644 --- a/.claude/skills/laravel-best-practices/rules/routing.md +++ b/.claude/skills/laravel-best-practices/rules/routing.md @@ -96,4 +96,4 @@ ## Type-Hint Form Requests return redirect()->route('posts.index'); } -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/scheduling.md b/.claude/skills/laravel-best-practices/rules/scheduling.md index dfaefa2..a984794 100644 --- a/.claude/skills/laravel-best-practices/rules/scheduling.md +++ b/.claude/skills/laravel-best-practices/rules/scheduling.md @@ -36,4 +36,4 @@ ## Use Schedule Groups for Shared Configuration Schedule::command('emails:send --force'); Schedule::command('emails:prune'); }); -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/security.md b/.claude/skills/laravel-best-practices/rules/security.md index 909ff91..2d7200c 100644 --- a/.claude/skills/laravel-best-practices/rules/security.md +++ b/.claude/skills/laravel-best-practices/rules/security.md @@ -195,4 +195,4 @@ ## Encrypt Sensitive Database Fields ]; } } -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/style.md b/.claude/skills/laravel-best-practices/rules/style.md index 67af989..64d1730 100644 --- a/.claude/skills/laravel-best-practices/rules/style.md +++ b/.claude/skills/laravel-best-practices/rules/style.md @@ -122,4 +122,4 @@ ## No Unnecessary Comments Correct: ```php if ($this->hasJoins()) -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/testing.md b/.claude/skills/laravel-best-practices/rules/testing.md index 287b083..4fbf12f 100644 --- a/.claude/skills/laravel-best-practices/rules/testing.md +++ b/.claude/skills/laravel-best-practices/rules/testing.md @@ -40,4 +40,4 @@ ## Use `recycle()` to Share Relationship Instances Across Factories Ticket::factory() ->recycle(Airline::factory()->create()) ->create(); -``` \ No newline at end of file +``` diff --git a/.claude/skills/laravel-best-practices/rules/validation.md b/.claude/skills/laravel-best-practices/rules/validation.md index a20202f..5fde106 100644 --- a/.claude/skills/laravel-best-practices/rules/validation.md +++ b/.claude/skills/laravel-best-practices/rules/validation.md @@ -72,4 +72,4 @@ ## Use the `after()` Method for Custom Validation }, ]; } -``` \ No newline at end of file +``` diff --git a/.claude/skills/livewire-development/SKILL.md b/.claude/skills/livewire-development/SKILL.md index 62d032d..0ae356e 100644 --- a/.claude/skills/livewire-development/SKILL.md +++ b/.claude/skills/livewire-development/SKILL.md @@ -172,4 +172,4 @@ ## Common Pitfalls - Expecting `wire:model` real-time → use `wire:model.live` - Unclosed component tags → syntax errors in v4 - Using deprecated config keys or JS hooks -- Including Alpine.js separately (already bundled in Livewire 4) \ No newline at end of file +- Including Alpine.js separately (already bundled in Livewire 4) diff --git a/.claude/skills/livewire-development/reference/javascript-hooks.md b/.claude/skills/livewire-development/reference/javascript-hooks.md index d6a4417..660d66b 100644 --- a/.claude/skills/livewire-development/reference/javascript-hooks.md +++ b/.claude/skills/livewire-development/reference/javascript-hooks.md @@ -36,4 +36,4 @@ ### Component-Scoped Interceptors ## Magic Properties - `$errors` - Access validation errors from JavaScript -- `$intercept` - Component-scoped interceptors \ No newline at end of file +- `$intercept` - Component-scoped interceptors diff --git a/.claude/skills/pest-testing/SKILL.md b/.claude/skills/pest-testing/SKILL.md index f748676..ab27161 100644 --- a/.claude/skills/pest-testing/SKILL.md +++ b/.claude/skills/pest-testing/SKILL.md @@ -163,4 +163,4 @@ ## Common Pitfalls - Forgetting datasets for repetitive validation tests - Deleting tests without approval - Forgetting `assertNoJavaScriptErrors()` in browser tests -- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` \ No newline at end of file +- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` diff --git a/.claude/skills/tailwindcss-development/SKILL.md b/.claude/skills/tailwindcss-development/SKILL.md index 7c8e295..c0cb2fb 100644 --- a/.claude/skills/tailwindcss-development/SKILL.md +++ b/.claude/skills/tailwindcss-development/SKILL.md @@ -116,4 +116,4 @@ ## Common Pitfalls - Using `@tailwind` directives instead of `@import "tailwindcss"` - Trying to use `tailwind.config.js` instead of CSS `@theme` directive - Using margins for spacing between siblings instead of gap utilities -- Forgetting to add dark mode variants when the project uses dark mode \ No newline at end of file +- Forgetting to add dark mode variants when the project uses dark mode diff --git a/.github/skills/fluxui-development/SKILL.md b/.github/skills/fluxui-development/SKILL.md index 4b5aabb..d4fb5a0 100644 --- a/.github/skills/fluxui-development/SKILL.md +++ b/.github/skills/fluxui-development/SKILL.md @@ -27,7 +27,7 @@ ## Basic Usage ## Available Components (Free Edition) -Available: avatar, badge, brand, breadcrumbs, button, callout, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, profile, radio, select, separator, skeleton, switch, text, textarea, tooltip +Available: avatar, badge, brand, breadcrumbs, button, callout, card, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, pagination, profile, progress, radio, select, separator, skeleton, switch, table, text, textarea, toast, tooltip ## Icons @@ -78,4 +78,4 @@ ## Common Pitfalls - Trying to use Pro-only components in the free edition - Not checking if a Flux component exists before creating custom implementations - Forgetting to use the `search-docs` tool for component-specific documentation -- Not following existing project patterns for Flux usage \ No newline at end of file +- Not following existing project patterns for Flux usage diff --git a/.github/skills/fortify-development/SKILL.md b/.github/skills/fortify-development/SKILL.md index beb1734..2c4e84f 100644 --- a/.github/skills/fortify-development/SKILL.md +++ b/.github/skills/fortify-development/SKILL.md @@ -148,4 +148,4 @@ ## Key Endpoints | Passkey Confirm | POST | `/passkeys/confirm` | | Passkey Options | GET | `/user/passkeys/options` | | Register Passkey | POST | `/user/passkeys` | -| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | \ No newline at end of file +| Delete Passkey | DELETE | `/user/passkeys/{passkey}` | diff --git a/.github/skills/laravel-best-practices/SKILL.md b/.github/skills/laravel-best-practices/SKILL.md index aca32c9..965e267 100644 --- a/.github/skills/laravel-best-practices/SKILL.md +++ b/.github/skills/laravel-best-practices/SKILL.md @@ -187,4 +187,4 @@ ## How to Apply 1. Identify the file type and select relevant sections (e.g., migration → §16, controller → §1, §3, §5, §6, §10) 2. Check sibling files for existing patterns — follow those first per Consistency First -3. Verify API syntax with `search-docs` for the installed Laravel version \ No newline at end of file +3. Verify API syntax with `search-docs` for the installed Laravel version diff --git a/.github/skills/laravel-best-practices/rules/advanced-queries.md b/.github/skills/laravel-best-practices/rules/advanced-queries.md index 920714a..f12876e 100644 --- a/.github/skills/laravel-best-practices/rules/advanced-queries.md +++ b/.github/skills/laravel-best-practices/rules/advanced-queries.md @@ -103,4 +103,4 @@ ## Use Correlated Subqueries for Has-Many Ordering ->take(1) ); } -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/architecture.md b/.github/skills/laravel-best-practices/rules/architecture.md index 6112a63..51c6e65 100644 --- a/.github/skills/laravel-best-practices/rules/architecture.md +++ b/.github/skills/laravel-best-practices/rules/architecture.md @@ -199,4 +199,4 @@ ## Convention Over Configuration return $this->belongsToMany(Role::class); } } -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/blade-views.md b/.github/skills/laravel-best-practices/rules/blade-views.md index c6f8aaf..5f0b3a1 100644 --- a/.github/skills/laravel-best-practices/rules/blade-views.md +++ b/.github/skills/laravel-best-practices/rules/blade-views.md @@ -33,4 +33,4 @@ ## Use Blade Fragments for Partial Re-Renders (htmx/Turbo) ## Use `@aware` for Deeply Nested Component Props -Avoids re-passing parent props through every level of nested components. \ No newline at end of file +Avoids re-passing parent props through every level of nested components. diff --git a/.github/skills/laravel-best-practices/rules/caching.md b/.github/skills/laravel-best-practices/rules/caching.md index e65146d..67408d6 100644 --- a/.github/skills/laravel-best-practices/rules/caching.md +++ b/.github/skills/laravel-best-practices/rules/caching.md @@ -67,4 +67,4 @@ ## Configure Failover Cache Stores in Production ```php 'failover' => ['driver' => 'failover', 'stores' => ['redis', 'database']], -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/collections.md b/.github/skills/laravel-best-practices/rules/collections.md index 14f683d..18e8d9e 100644 --- a/.github/skills/laravel-best-practices/rules/collections.md +++ b/.github/skills/laravel-best-practices/rules/collections.md @@ -41,4 +41,4 @@ ## Use `#[CollectedBy]` for Custom Collection Classes ```php #[CollectedBy(UserCollection::class)] class User extends Model {} -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/config.md b/.github/skills/laravel-best-practices/rules/config.md index 193155d..9bea727 100644 --- a/.github/skills/laravel-best-practices/rules/config.md +++ b/.github/skills/laravel-best-practices/rules/config.md @@ -70,4 +70,4 @@ ## Use Constants and Language Files ```php // Only when lang files already exist in the project return back()->with('message', __('app.article_added')); -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/db-performance.md b/.github/skills/laravel-best-practices/rules/db-performance.md index 8fb7193..c49ba16 100644 --- a/.github/skills/laravel-best-practices/rules/db-performance.md +++ b/.github/skills/laravel-best-practices/rules/db-performance.md @@ -189,4 +189,4 @@ ## No Queries in Blade Templates @foreach ($users as $user) {{ $user->profile->name }} @endforeach -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/eloquent.md b/.github/skills/laravel-best-practices/rules/eloquent.md index 09cd66a..413d5da 100644 --- a/.github/skills/laravel-best-practices/rules/eloquent.md +++ b/.github/skills/laravel-best-practices/rules/eloquent.md @@ -145,4 +145,4 @@ ## Avoid Hardcoded Table Names in Queries Prefer Eloquent queries and relationships over `DB::table()` whenever possible — they already reference the model's table. When `DB::table()` or raw joins are unavoidable, always use `(new Model)->getTable()` to keep the reference traceable. -**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. \ No newline at end of file +**Exception — migrations:** In migrations, hardcoded table names via `DB::table('settings')` are acceptable and preferred. Models change over time but migrations are frozen snapshots — referencing a model that is later renamed or deleted would break the migration. diff --git a/.github/skills/laravel-best-practices/rules/error-handling.md b/.github/skills/laravel-best-practices/rules/error-handling.md index bb8e7a3..4b14866 100644 --- a/.github/skills/laravel-best-practices/rules/error-handling.md +++ b/.github/skills/laravel-best-practices/rules/error-handling.md @@ -69,4 +69,4 @@ ## Add Context to Exception Classes return ['order_id' => $this->orderId]; } } -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/events-notifications.md b/.github/skills/laravel-best-practices/rules/events-notifications.md index 47fcf32..82e329e 100644 --- a/.github/skills/laravel-best-practices/rules/events-notifications.md +++ b/.github/skills/laravel-best-practices/rules/events-notifications.md @@ -49,4 +49,4 @@ ## Use On-Demand Notifications for Non-User Recipients ## Implement `HasLocalePreference` on Notifiable Models -Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. \ No newline at end of file +Laravel automatically uses the user's preferred locale for all notifications and mailables — no per-call `locale()` needed. diff --git a/.github/skills/laravel-best-practices/rules/http-client.md b/.github/skills/laravel-best-practices/rules/http-client.md index fd37ddb..8e2f16e 100644 --- a/.github/skills/laravel-best-practices/rules/http-client.md +++ b/.github/skills/laravel-best-practices/rules/http-client.md @@ -157,4 +157,4 @@ ## Fake HTTP Calls in Tests Http::fake([ 'api.example.com/*' => Http::failedConnection(), ]); -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/mail.md b/.github/skills/laravel-best-practices/rules/mail.md index 2435d9c..7c71733 100644 --- a/.github/skills/laravel-best-practices/rules/mail.md +++ b/.github/skills/laravel-best-practices/rules/mail.md @@ -24,4 +24,4 @@ ## Separate Content Tests from Sending Tests Content tests: instantiate the mailable directly, call `assertSeeInHtml()`. Sending tests: use `Mail::fake()` and `assertSent()`/`assertQueued()`. -Don't mix them — it conflates concerns and makes tests brittle. \ No newline at end of file +Don't mix them — it conflates concerns and makes tests brittle. diff --git a/.github/skills/laravel-best-practices/rules/migrations.md b/.github/skills/laravel-best-practices/rules/migrations.md index de25aa3..df6f5f3 100644 --- a/.github/skills/laravel-best-practices/rules/migrations.md +++ b/.github/skills/laravel-best-practices/rules/migrations.md @@ -118,4 +118,4 @@ ## Keep Migrations Focused // Migration 2: seed_default_settings DB::table('settings')->insert(['key' => 'version', 'value' => '1.0']); -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/queue-jobs.md b/.github/skills/laravel-best-practices/rules/queue-jobs.md index f7aa548..c41915e 100644 --- a/.github/skills/laravel-best-practices/rules/queue-jobs.md +++ b/.github/skills/laravel-best-practices/rules/queue-jobs.md @@ -141,4 +141,4 @@ ## Use Horizon for Complex Queue Scenarios ], ], ], -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/routing.md b/.github/skills/laravel-best-practices/rules/routing.md index 977d136..b6e3086 100644 --- a/.github/skills/laravel-best-practices/rules/routing.md +++ b/.github/skills/laravel-best-practices/rules/routing.md @@ -96,4 +96,4 @@ ## Type-Hint Form Requests return redirect()->route('posts.index'); } -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/scheduling.md b/.github/skills/laravel-best-practices/rules/scheduling.md index dfaefa2..a984794 100644 --- a/.github/skills/laravel-best-practices/rules/scheduling.md +++ b/.github/skills/laravel-best-practices/rules/scheduling.md @@ -36,4 +36,4 @@ ## Use Schedule Groups for Shared Configuration Schedule::command('emails:send --force'); Schedule::command('emails:prune'); }); -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/security.md b/.github/skills/laravel-best-practices/rules/security.md index 909ff91..2d7200c 100644 --- a/.github/skills/laravel-best-practices/rules/security.md +++ b/.github/skills/laravel-best-practices/rules/security.md @@ -195,4 +195,4 @@ ## Encrypt Sensitive Database Fields ]; } } -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/style.md b/.github/skills/laravel-best-practices/rules/style.md index 67af989..64d1730 100644 --- a/.github/skills/laravel-best-practices/rules/style.md +++ b/.github/skills/laravel-best-practices/rules/style.md @@ -122,4 +122,4 @@ ## No Unnecessary Comments Correct: ```php if ($this->hasJoins()) -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/testing.md b/.github/skills/laravel-best-practices/rules/testing.md index 287b083..4fbf12f 100644 --- a/.github/skills/laravel-best-practices/rules/testing.md +++ b/.github/skills/laravel-best-practices/rules/testing.md @@ -40,4 +40,4 @@ ## Use `recycle()` to Share Relationship Instances Across Factories Ticket::factory() ->recycle(Airline::factory()->create()) ->create(); -``` \ No newline at end of file +``` diff --git a/.github/skills/laravel-best-practices/rules/validation.md b/.github/skills/laravel-best-practices/rules/validation.md index a20202f..5fde106 100644 --- a/.github/skills/laravel-best-practices/rules/validation.md +++ b/.github/skills/laravel-best-practices/rules/validation.md @@ -72,4 +72,4 @@ ## Use the `after()` Method for Custom Validation }, ]; } -``` \ No newline at end of file +``` diff --git a/.github/skills/livewire-development/SKILL.md b/.github/skills/livewire-development/SKILL.md index 62d032d..0ae356e 100644 --- a/.github/skills/livewire-development/SKILL.md +++ b/.github/skills/livewire-development/SKILL.md @@ -172,4 +172,4 @@ ## Common Pitfalls - Expecting `wire:model` real-time → use `wire:model.live` - Unclosed component tags → syntax errors in v4 - Using deprecated config keys or JS hooks -- Including Alpine.js separately (already bundled in Livewire 4) \ No newline at end of file +- Including Alpine.js separately (already bundled in Livewire 4) diff --git a/.github/skills/livewire-development/reference/javascript-hooks.md b/.github/skills/livewire-development/reference/javascript-hooks.md index d6a4417..660d66b 100644 --- a/.github/skills/livewire-development/reference/javascript-hooks.md +++ b/.github/skills/livewire-development/reference/javascript-hooks.md @@ -36,4 +36,4 @@ ### Component-Scoped Interceptors ## Magic Properties - `$errors` - Access validation errors from JavaScript -- `$intercept` - Component-scoped interceptors \ No newline at end of file +- `$intercept` - Component-scoped interceptors diff --git a/.github/skills/pest-testing/SKILL.md b/.github/skills/pest-testing/SKILL.md index f748676..ab27161 100644 --- a/.github/skills/pest-testing/SKILL.md +++ b/.github/skills/pest-testing/SKILL.md @@ -163,4 +163,4 @@ ## Common Pitfalls - Forgetting datasets for repetitive validation tests - Deleting tests without approval - Forgetting `assertNoJavaScriptErrors()` in browser tests -- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` \ No newline at end of file +- Prefixing `Feature/` or `Unit/` in `{name}` when using `make:test` diff --git a/.github/skills/tailwindcss-development/SKILL.md b/.github/skills/tailwindcss-development/SKILL.md index 7c8e295..c0cb2fb 100644 --- a/.github/skills/tailwindcss-development/SKILL.md +++ b/.github/skills/tailwindcss-development/SKILL.md @@ -116,4 +116,4 @@ ## Common Pitfalls - Using `@tailwind` directives instead of `@import "tailwindcss"` - Trying to use `tailwind.config.js` instead of CSS `@theme` directive - Using margins for spacing between siblings instead of gap utilities -- Forgetting to add dark mode variants when the project uses dark mode \ No newline at end of file +- Forgetting to add dark mode variants when the project uses dark mode diff --git a/AGENTS.md b/AGENTS.md index fbc0295..f1c8848 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ ## 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.5 +- php - 8.4 - laravel/fortify (FORTIFY) - v1 - laravel/framework (LARAVEL) - v13 - laravel/prompts (PROMPTS) - v0 @@ -87,7 +87,6 @@ ## Artisan - Run Artisan commands directly via the command line (e.g., `php artisan route:list`). Use `php artisan list` to discover available commands and `php artisan [command] --help` to check parameters. - Inspect routes with `php artisan route:list`. Filter with: `--method=GET`, `--name=users`, `--path=api`, `--except-vendor`, `--only-vendor`. - Read configuration values using dot notation: `php artisan config:show app.name`, `php artisan config:show database.default`. Or read config files directly from the `config/` directory. -- To check environment variables, read the `.env` file directly. ## Tinker diff --git a/CLAUDE.md b/CLAUDE.md index fbc0295..f1c8848 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,7 +9,7 @@ ## 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.5 +- php - 8.4 - laravel/fortify (FORTIFY) - v1 - laravel/framework (LARAVEL) - v13 - laravel/prompts (PROMPTS) - v0 @@ -87,7 +87,6 @@ ## Artisan - Run Artisan commands directly via the command line (e.g., `php artisan route:list`). Use `php artisan list` to discover available commands and `php artisan [command] --help` to check parameters. - Inspect routes with `php artisan route:list`. Filter with: `--method=GET`, `--name=users`, `--path=api`, `--except-vendor`, `--only-vendor`. - Read configuration values using dot notation: `php artisan config:show app.name`, `php artisan config:show database.default`. Or read config files directly from the `config/` directory. -- To check environment variables, read the `.env` file directly. ## Tinker diff --git a/app/Http/Controllers/KekaOutlookController.php b/app/Http/Controllers/KekaOutlookController.php new file mode 100644 index 0000000..2a299fb --- /dev/null +++ b/app/Http/Controllers/KekaOutlookController.php @@ -0,0 +1,101 @@ +user(); + + if ($this->kekaOutlook->isConnected($user)) { + try { + // Ensures token is fresh; throws if refresh token is invalid/revoked. + $this->kekaOutlook->getValidToken($user); + + return redirect()->away($this->kekaWebsiteUrl()); + } catch (\RuntimeException $e) { + // Refresh failed -> fall through to re-login below. + } + } + + return redirect()->away($this->kekaOutlook->getAuthUrl()); + } + + /** + * GET /keka/callback + * + * Microsoft redirects here after login with ?code=... or ?error=... + */ + public function callback(Request $request): RedirectResponse + { + if ($request->filled('error')) { + return redirect() + ->route('dashboard') + ->with('error', 'Microsoft login was cancelled or failed: '.$request->get('error_description', $request->get('error'))); + } + + if (! $this->kekaOutlook->isValidState($request->get('state'))) { + return redirect() + ->route('dashboard') + ->with('error', 'Invalid login session. Please try connecting again.'); + } + + $code = $request->get('code'); + + if (! $code) { + return redirect() + ->route('dashboard') + ->with('error', 'No authorization code received from Microsoft.'); + } + + $result = $this->kekaOutlook->handleCallback($request->user(), $code); + + if (! $result['success']) { + return redirect() + ->route('dashboard') + ->with('error', 'Failed to connect: '.($result['message'] ?? 'Unknown error')); + } + + return redirect()->away($this->kekaWebsiteUrl()); + } + + /** + * POST /keka/disconnect + * + * Wipes stored tokens. User must go through Microsoft login again next time. + */ + public function disconnect(Request $request): RedirectResponse + { + $this->kekaOutlook->disconnect($request->user()); + + return redirect() + ->route('dashboard') + ->with('success', 'Keka has been disconnected.'); + } + + /** + * The Keka website URL the user lands on after a successful (silent) connection. + */ + private function kekaWebsiteUrl(): string + { + return (string) config('microsoft.keka_website_url', 'https://app.keka.com'); + } +} \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index 00e43fd..c7935cc 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -59,6 +59,7 @@ protected function casts(): array return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', + 'keka_ms_token_expires_at' => 'datetime', ]; } diff --git a/app/Services/KekaOutlookService.php b/app/Services/KekaOutlookService.php new file mode 100644 index 0000000..b36d8d3 --- /dev/null +++ b/app/Services/KekaOutlookService.php @@ -0,0 +1,224 @@ + build Microsoft login URL + * - handleCallback() -> exchange code for tokens, store on user + * - getValidToken() -> return a valid access token, refreshing silently if expired + * - disconnect() -> wipe stored tokens for the user + */ +final class KekaOutlookService +{ + private string $clientId; + + private string $clientSecret; + + private string $tenantId; + + private string $redirectUri; + + private array $scopes; + + public function __construct() + { + $this->clientId = (string) config('microsoft.client_id'); + $this->clientSecret = (string) config('microsoft.client_secret'); + $this->tenantId = (string) config('microsoft.tenant_id'); + $this->redirectUri = (string) config('microsoft.keka_redirect_uri'); + $this->scopes = config('microsoft.keka_scopes', [ + 'openid', + 'profile', + 'email', + 'offline_access', + 'User.Read', + 'Mail.Read', + 'Mail.ReadWrite', + 'Mail.Send', + ]); + } + + /** + * Build the Microsoft login URL the user is redirected to. + * A random "state" value is generated and stored in the session to prevent CSRF. + */ + public function getAuthUrl(): string + { + $state = Str::random(40); + session(['keka_ms_oauth_state' => $state]); + + $query = http_build_query([ + 'client_id' => $this->clientId, + 'response_type' => 'code', + 'redirect_uri' => $this->redirectUri, + 'response_mode' => 'query', + 'scope' => implode(' ', $this->scopes), + 'state' => $state, + // prompt=select_account forces account chooser on first connect. + 'prompt' => 'select_account', + ]); + + return "https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/authorize?{$query}"; + } + + /** + * Validate the "state" returned by Microsoft against the one stored in session. + */ + public function isValidState(?string $state): bool + { + $expected = session('keka_ms_oauth_state'); + + if (! $expected || ! $state) { + return false; + } + + return hash_equals($expected, $state); + } + + /** + * Exchange the authorization code for access + refresh tokens and store them on the user. + * + * @return array{success: bool, message?: string} + */ + public function handleCallback(User $user, string $code): array + { + $response = Http::asForm()->post( + "https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token", + [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'grant_type' => 'authorization_code', + 'code' => $code, + 'redirect_uri' => $this->redirectUri, + 'scope' => implode(' ', $this->scopes), + ] + ); + + if (! $response->successful()) { + return [ + 'success' => false, + 'message' => $response->json('error_description', 'Failed to exchange code for token.'), + ]; + } + + $data = $response->json(); + + $this->storeTokens($user, $data); + + // Fetch the connected mailbox's email address for display purposes. + $profile = Http::withToken($data['access_token']) + ->get('https://graph.microsoft.com/v1.0/me'); + + if ($profile->successful()) { + $user->keka_ms_email = $profile->json('mail') ?? $profile->json('userPrincipalName'); + $user->save(); + } + + session()->forget('keka_ms_oauth_state'); + + return ['success' => true]; + } + + /** + * Persist tokens + expiry on the user model. + */ + private function storeTokens(User $user, array $tokenData): void + { + $user->keka_ms_access_token = $tokenData['access_token']; + $user->keka_ms_token_expires_at = now()->addSeconds((int) $tokenData['expires_in']); + + // Microsoft only returns refresh_token if 'offline_access' scope was granted. + // If a new one isn't returned on refresh, keep the existing one. + if (! empty($tokenData['refresh_token'])) { + $user->keka_ms_refresh_token = $tokenData['refresh_token']; + } + + $user->save(); + } + + /** + * Returns true if the user has connected Keka/Outlook (has a refresh token stored). + */ + public function isConnected(User $user): bool + { + return ! empty($user->keka_ms_refresh_token); + } + + /** + * Get a valid access token for the user. + * Silently refreshes via refresh_token if the current access token has expired. + * + * @throws \RuntimeException if the user has not connected or refresh fails. + */ + public function getValidToken(User $user): string + { + if (! $this->isConnected($user)) { + throw new \RuntimeException('User has not connected Keka/Outlook.'); + } + + // Still valid? (1 minute buffer) + if ( + $user->keka_ms_access_token + && $user->keka_ms_token_expires_at + && now()->lt($user->keka_ms_token_expires_at->subMinute()) + ) { + return $user->keka_ms_access_token; + } + + return $this->refreshToken($user); + } + + /** + * Use the stored refresh_token to obtain a new access_token silently. + * + * @throws \RuntimeException if Microsoft rejects the refresh token (user must reconnect). + */ + private function refreshToken(User $user): string + { + $response = Http::asForm()->post( + "https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token", + [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'grant_type' => 'refresh_token', + 'refresh_token' => $user->keka_ms_refresh_token, + 'scope' => implode(' ', $this->scopes), + ] + ); + + if (! $response->successful()) { + // Refresh token expired/revoked -> force user to reconnect. + $this->disconnect($user); + + throw new \RuntimeException( + $response->json('error_description', 'Session expired. Please reconnect Keka.') + ); + } + + $data = $response->json(); + $this->storeTokens($user, $data); + + return $data['access_token']; + } + + /** + * Disconnect: wipe stored tokens. User must go through login flow again to reconnect. + */ + public function disconnect(User $user): void + { + $user->keka_ms_access_token = null; + $user->keka_ms_refresh_token = null; + $user->keka_ms_token_expires_at = null; + $user->keka_ms_email = null; + $user->save(); + } +} \ No newline at end of file diff --git a/boost.json b/boost.json index b327db2..1129526 100644 --- a/boost.json +++ b/boost.json @@ -1,5 +1,9 @@ { - "agents": ["claude_code", "copilot", "opencode"], + "agents": [ + "claude_code", + "copilot", + "opencode" + ], "cloud": false, "guidelines": true, "mcp": true, @@ -8,6 +12,7 @@ "skills": [ "fortify-development", "laravel-best-practices", + "fluxui-development", "livewire-development", "pest-testing", "tailwindcss-development" diff --git a/composer.json b/composer.json index 56cb6ab..5e338b9 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "license": "MIT", "require": { - "php": "^8.5", + "php": "^8.3", "gehrisandro/tailwind-merge-laravel": "^1.4", "laravel/fortify": "^1.34", "laravel/framework": "^13.7", diff --git a/composer.lock b/composer.lock index f60b855..effab57 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "63deb63c42b1c08194cd70e47ae3f312", + "content-hash": "de341bcfc1ad1d03eb12923ae8f0a9d2", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1087,25 +1087,26 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.10.1", + "version": "7.11.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "b777df1776c667e287664dda75b0298ad8ae3a14" + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b777df1776c667e287664dda75b0298ad8ae3a14", - "reference": "b777df1776c667e287664dda75b0298ad8ae3a14", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/5af96f374e0ab4ebd747b8310888c99d3adb0a8c", + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^2.3", - "guzzlehttp/psr7": "^2.8", + "guzzlehttp/promises": "^2.5", + "guzzlehttp/psr7": "^2.11", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.24" }, "provide": { "psr/http-client-implementation": "1.0" @@ -1114,7 +1115,7 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.3.2", + "guzzlehttp/test-server": "^0.5", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -1194,7 +1195,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.10.1" + "source": "https://github.com/guzzle/guzzle/tree/7.11.1" }, "funding": [ { @@ -1210,24 +1211,25 @@ "type": "tidelift" } ], - "time": "2026-05-19T18:01:31+00:00" + "time": "2026-06-07T22:54:06+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.3.1", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "d2d8dfae4757f384d630fdffc2d8d6618d8f4c5e" + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/d2d8dfae4757f384d630fdffc2d8d6618d8f4c5e", - "reference": "d2d8dfae4757f384d630fdffc2d8d6618d8f4c5e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e", + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0" + "php": "^7.2.5 || ^8.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -1277,7 +1279,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.3.1" + "source": "https://github.com/guzzle/promises/tree/2.5.0" }, "funding": [ { @@ -1293,27 +1295,29 @@ "type": "tidelift" } ], - "time": "2026-05-19T18:30:48+00:00" + "time": "2026-06-02T12:23:43+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.10.0", + "version": "2.11.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "d5ddaf5743c42a61cb6100f83dc9d5a2bafe75ca" + "reference": "bbb5e61349fa5cb822b3e87842b951088b76b81f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/d5ddaf5743c42a61cb6100f83dc9d5a2bafe75ca", - "reference": "d5ddaf5743c42a61cb6100f83dc9d5a2bafe75ca", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/bbb5e61349fa5cb822b3e87842b951088b76b81f", + "reference": "bbb5e61349fa5cb822b3e87842b951088b76b81f", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" + "ralouphie/getallheaders": "^3.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.24" }, "provide": { "psr/http-factory-implementation": "1.0", @@ -1394,7 +1398,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.10.0" + "source": "https://github.com/guzzle/psr7/tree/2.11.0" }, "funding": [ { @@ -1410,20 +1414,20 @@ "type": "tidelift" } ], - "time": "2026-05-19T17:32:11+00:00" + "time": "2026-06-02T12:30:48+00:00" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.5", + "version": "v1.0.6", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/eef7f87bab6f204eba3c39224d8075c70c637946", + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946", "shasum": "" }, "require": { @@ -1432,7 +1436,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", "uri-template/tests": "1.0.0" }, "type": "library", @@ -1480,7 +1484,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.6" }, "funding": [ { @@ -1496,7 +1500,7 @@ "type": "tidelift" } ], - "time": "2025-08-22T14:27:06+00:00" + "time": "2026-05-23T22:00:21+00:00" }, { "name": "jfcherng/php-color-output", @@ -1737,16 +1741,16 @@ }, { "name": "laravel/fortify", - "version": "v1.37.0", + "version": "v1.37.2", "source": { "type": "git", "url": "https://github.com/laravel/fortify.git", - "reference": "7aa8d43b493998f6c4183cd7a80da425a2cf6343" + "reference": "5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/7aa8d43b493998f6c4183cd7a80da425a2cf6343", - "reference": "7aa8d43b493998f6c4183cd7a80da425a2cf6343", + "url": "https://api.github.com/repos/laravel/fortify/zipball/5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c", + "reference": "5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c", "shasum": "" }, "require": { @@ -1754,7 +1758,7 @@ "ext-json": "*", "illuminate/console": "^11.0|^12.0|^13.0", "illuminate/support": "^11.0|^12.0|^13.0", - "laravel/passkeys": "^0.1.0", + "laravel/passkeys": "^0.2.0", "php": "^8.2", "pragmarx/google2fa": "^9.0" }, @@ -1797,20 +1801,20 @@ "issues": "https://github.com/laravel/fortify/issues", "source": "https://github.com/laravel/fortify" }, - "time": "2026-04-28T11:12:45+00:00" + "time": "2026-05-15T22:59:10+00:00" }, { "name": "laravel/framework", - "version": "v13.11.1", + "version": "v13.15.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "6b70133ea3552afc37307ffb85b9efa48dc187d1" + "reference": "7e23b2aa4e1133a43835c93a810b4bedc40e425b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6b70133ea3552afc37307ffb85b9efa48dc187d1", - "reference": "6b70133ea3552afc37307ffb85b9efa48dc187d1", + "url": "https://api.github.com/repos/laravel/framework/zipball/7e23b2aa4e1133a43835c93a810b4bedc40e425b", + "reference": "7e23b2aa4e1133a43835c93a810b4bedc40e425b", "shasum": "" }, "require": { @@ -2021,20 +2025,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-05-19T20:24:39+00:00" + "time": "2026-06-09T13:45:51+00:00" }, { "name": "laravel/passkeys", - "version": "v0.1.0", + "version": "v0.2.1", "source": { "type": "git", "url": "https://github.com/laravel/passkeys-server.git", - "reference": "64632ef55846e889f41b64071af8e3171ef2196d" + "reference": "a76656ada41b2b4a591f075eddae5ddc67e8ab9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/passkeys-server/zipball/64632ef55846e889f41b64071af8e3171ef2196d", - "reference": "64632ef55846e889f41b64071af8e3171ef2196d", + "url": "https://api.github.com/repos/laravel/passkeys-server/zipball/a76656ada41b2b4a591f075eddae5ddc67e8ab9c", + "reference": "a76656ada41b2b4a591f075eddae5ddc67e8ab9c", "shasum": "" }, "require": { @@ -2044,7 +2048,7 @@ "illuminate/routing": "^11.0|^12.0|^13.0", "illuminate/support": "^11.0|^12.0|^13.0", "php": "^8.2", - "web-auth/webauthn-lib": "5.2.4" + "web-auth/webauthn-lib": "5.3.x" }, "require-dev": { "laravel/pint": "^1.28.0", @@ -2089,7 +2093,7 @@ "issues": "https://github.com/laravel/passkeys-server/issues", "source": "https://github.com/laravel/passkeys-server" }, - "time": "2026-04-22T01:16:23+00:00" + "time": "2026-05-18T16:26:00+00:00" }, { "name": "laravel/prompts", @@ -2907,16 +2911,16 @@ }, { "name": "livewire/livewire", - "version": "v4.3.0", + "version": "v4.3.1", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "19ebb1ee4d057debceccf70ff01950e6a6114edc" + "reference": "6a9dd03f45a4b200abfd0ff644745b23fa7baaaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/19ebb1ee4d057debceccf70ff01950e6a6114edc", - "reference": "19ebb1ee4d057debceccf70ff01950e6a6114edc", + "url": "https://api.github.com/repos/livewire/livewire/zipball/6a9dd03f45a4b200abfd0ff644745b23fa7baaaa", + "reference": "6a9dd03f45a4b200abfd0ff644745b23fa7baaaa", "shasum": "" }, "require": { @@ -2971,7 +2975,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v4.3.0" + "source": "https://github.com/livewire/livewire/tree/v4.3.1" }, "funding": [ { @@ -2979,20 +2983,20 @@ "type": "github" } ], - "time": "2026-05-01T00:46:07+00:00" + "time": "2026-06-02T08:58:52+00:00" }, { "name": "mallardduck/blade-lucide-icons", - "version": "1.26.19", + "version": "1.26.21", "source": { "type": "git", "url": "https://github.com/mallardduck/blade-lucide-icons.git", - "reference": "a6e164dca10d29fd67ca332b9ef78bf2b35e0df8" + "reference": "495df35fc2678415a2b22b44cc6e1eea75dd99fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mallardduck/blade-lucide-icons/zipball/a6e164dca10d29fd67ca332b9ef78bf2b35e0df8", - "reference": "a6e164dca10d29fd67ca332b9ef78bf2b35e0df8", + "url": "https://api.github.com/repos/mallardduck/blade-lucide-icons/zipball/495df35fc2678415a2b22b44cc6e1eea75dd99fb", + "reference": "495df35fc2678415a2b22b44cc6e1eea75dd99fb", "shasum": "" }, "require": { @@ -3037,9 +3041,9 @@ ], "support": { "issues": "https://github.com/mallardduck/blade-lucide-icons/issues", - "source": "https://github.com/mallardduck/blade-lucide-icons/tree/1.26.19" + "source": "https://github.com/mallardduck/blade-lucide-icons/tree/1.26.21" }, - "time": "2026-04-30T00:36:39+00:00" + "time": "2026-05-29T00:45:59+00:00" }, { "name": "monolog/monolog", @@ -3676,16 +3680,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.7", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -3693,8 +3697,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -3704,7 +3708,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -3734,44 +3739,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2026-03-18T20:47:46+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -3792,9 +3797,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpoption/phpoption", @@ -4384,16 +4389,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.22", + "version": "v0.12.23", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f" + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/3be75d5b9244936dd4ac62ade2bfb004d13acf0f", - "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4dcc0f08047d52bbde475eda481146fd8e27e1a4", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4", "shasum": "" }, "require": { @@ -4457,9 +4462,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.22" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.23" }, - "time": "2026-03-22T23:03:24+00:00" + "time": "2026-05-23T13:41:31+00:00" }, { "name": "ralouphie/getallheaders", @@ -4703,16 +4708,16 @@ }, { "name": "robsontenorio/mary", - "version": "2.8.2", + "version": "2.8.3", "source": { "type": "git", "url": "https://github.com/robsontenorio/mary.git", - "reference": "fee6e23a158c54c682b5dd5d7c9377ba4889761a" + "reference": "e32a3ba1be5f1d86e4b7181004d7b606c025fbfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/robsontenorio/mary/zipball/fee6e23a158c54c682b5dd5d7c9377ba4889761a", - "reference": "fee6e23a158c54c682b5dd5d7c9377ba4889761a", + "url": "https://api.github.com/repos/robsontenorio/mary/zipball/e32a3ba1be5f1d86e4b7181004d7b606c025fbfc", + "reference": "e32a3ba1be5f1d86e4b7181004d7b606c025fbfc", "shasum": "" }, "require": { @@ -4777,7 +4782,7 @@ ], "support": { "issues": "https://github.com/robsontenorio/mary/issues", - "source": "https://github.com/robsontenorio/mary/tree/2.8.2" + "source": "https://github.com/robsontenorio/mary/tree/2.8.3" }, "funding": [ { @@ -4785,7 +4790,7 @@ "type": "github" } ], - "time": "2026-04-17T13:40:53+00:00" + "time": "2026-05-21T18:42:50+00:00" }, { "name": "spatie/laravel-activitylog", @@ -4966,16 +4971,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.93.0", + "version": "1.93.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7" + "reference": "d5552849801f2642aea710557463234b59ef65eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", - "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb", + "reference": "d5552849801f2642aea710557463234b59ef65eb", "shasum": "" }, "require": { @@ -5015,7 +5020,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.0" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1" }, "funding": [ { @@ -5023,20 +5028,20 @@ "type": "github" } ], - "time": "2026-02-21T12:49:54+00:00" + "time": "2026-05-19T14:06:37+00:00" }, { "name": "spatie/laravel-permission", - "version": "7.4.1", + "version": "7.4.2", "source": { "type": "git", "url": "https://github.com/spatie/laravel-permission.git", - "reference": "ef42ecb781e5534d368a3853fa161e420ad51397" + "reference": "15a9daf02ba02d3ae77aaa6da582708231ef999b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/ef42ecb781e5534d368a3853fa161e420ad51397", - "reference": "ef42ecb781e5534d368a3853fa161e420ad51397", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/15a9daf02ba02d3ae77aaa6da582708231ef999b", + "reference": "15a9daf02ba02d3ae77aaa6da582708231ef999b", "shasum": "" }, "require": { @@ -5102,7 +5107,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/7.4.1" + "source": "https://github.com/spatie/laravel-permission/tree/7.4.2" }, "funding": [ { @@ -5110,7 +5115,7 @@ "type": "github" } ], - "time": "2026-04-29T07:59:45+00:00" + "time": "2026-05-30T19:21:26+00:00" }, { "name": "spatie/php-structure-discoverer", @@ -5374,22 +5379,21 @@ }, { "name": "symfony/clock", - "version": "v7.4.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111" + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111", + "url": "https://api.github.com/repos/symfony/clock/zipball/701ef4de9705d6c32292ebee5e8044094a09fbf6", + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/clock": "^1.0", - "symfony/polyfill-php83": "^1.28" + "php": ">=8.4.1", + "psr/clock": "^1.0" }, "provide": { "psr/clock-implementation": "1.0" @@ -5428,7 +5432,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.4.8" + "source": "https://github.com/symfony/clock/tree/v8.1.0" }, "funding": [ { @@ -5448,27 +5452,33 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/console", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3156577f46a38aa1b9323aad223de7a9cd426782" + "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3156577f46a38aa1b9323aad223de7a9cd426782", - "reference": "3156577f46a38aa1b9323aad223de7a9cd426782", + "url": "https://api.github.com/repos/symfony/console/zipball/f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", + "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php85": "^1.32", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.4|^8.0" + "symfony/string": "^7.4.6|^8.0.6" + }, + "conflict": { + "symfony/dependency-injection": "<8.1", + "symfony/event-dispatcher": "<8.1" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" @@ -5476,14 +5486,18 @@ "require-dev": { "psr/log": "^1|^2|^3", "symfony/config": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/dependency-injection": "^8.1", + "symfony/event-dispatcher": "^8.1", + "symfony/filesystem": "^7.4|^8.0", "symfony/http-foundation": "^7.4|^8.0", "symfony/http-kernel": "^7.4|^8.0", "symfony/lock": "^7.4|^8.0", "symfony/messenger": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", "symfony/process": "^7.4|^8.0", "symfony/stopwatch": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", @@ -5518,7 +5532,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.0.11" + "source": "https://github.com/symfony/console/tree/v8.1.0" }, "funding": [ { @@ -5538,24 +5552,24 @@ "type": "tidelift" } ], - "time": "2026-05-13T12:07:53+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/css-selector", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "3665cfade90565430909b906394c73c8739e57d0" + "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", - "reference": "3665cfade90565430909b906394c73c8739e57d0", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd", + "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.4.1" }, "type": "library", "autoload": { @@ -5587,7 +5601,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v8.0.9" + "source": "https://github.com/symfony/css-selector/tree/v8.1.0" }, "funding": [ { @@ -5607,7 +5621,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:51:42+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5682,20 +5696,20 @@ }, { "name": "symfony/error-handler", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517" + "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c1119fe8dcfc3825ec74ec061b96ef0c8f281517", - "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/d8aeb1abd3fef84795567850d3a567bdb5945ee5", + "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "psr/log": "^1|^2|^3", "symfony/polyfill-php85": "^1.32", "symfony/var-dumper": "^7.4|^8.0" @@ -5739,7 +5753,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v8.0.8" + "source": "https://github.com/symfony/error-handler/tree/v8.1.0" }, "funding": [ { @@ -5759,24 +5773,25 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", - "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f249ae3f680958b6f1f9dd76e5747cf0695b4102", + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { @@ -5824,7 +5839,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.0" }, "funding": [ { @@ -5844,7 +5859,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:51:42+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -5928,20 +5943,20 @@ }, { "name": "symfony/finder", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8da41214757b87d97f181e3d14a4179286151007" + "reference": "58d2e767a66052c1487356f953445634a8194c64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007", - "reference": "8da41214757b87d97f181e3d14a4179286151007", + "url": "https://api.github.com/repos/symfony/finder/zipball/58d2e767a66052c1487356f953445634a8194c64", + "reference": "58d2e767a66052c1487356f953445634a8194c64", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.4.1" }, "require-dev": { "symfony/filesystem": "^7.4|^8.0" @@ -5972,7 +5987,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.0.8" + "source": "https://github.com/symfony/finder/tree/v8.1.0" }, "funding": [ { @@ -5992,24 +6007,25 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/http-foundation", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b" + "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/02656f7ebeae5c155d659e946f6b3a33df24051b", - "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/af11474600f06718086c2cda4fa6fa8d0a672e7e", + "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "^1.1" }, "conflict": { @@ -6052,7 +6068,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v8.0.8" + "source": "https://github.com/symfony/http-foundation/tree/v8.1.0" }, "funding": [ { @@ -6072,34 +6088,38 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/http-kernel", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "20d3680373f4b791903c09e74b45402b4aeda71c" + "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/20d3680373f4b791903c09e74b45402b4aeda71c", - "reference": "20d3680373f4b791903c09e74b45402b4aeda71c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", + "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^7.4|^8.0", "symfony/event-dispatcher": "^7.4|^8.0", "symfony/http-foundation": "^7.4|^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { + "symfony/dependency-injection": "<8.1", "symfony/flex": "<2.10", "symfony/http-client-contracts": "<2.5", "symfony/translation-contracts": "<2.5", + "symfony/var-dumper": "<8.1", + "symfony/web-profiler-bundle": "<8.1", "twig/twig": "<3.21" }, "provide": { @@ -6112,13 +6132,14 @@ "symfony/config": "^7.4|^8.0", "symfony/console": "^7.4|^8.0", "symfony/css-selector": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", + "symfony/dependency-injection": "^8.1", "symfony/dom-crawler": "^7.4|^8.0", "symfony/expression-language": "^7.4|^8.0", "symfony/finder": "^7.4|^8.0", "symfony/http-client-contracts": "^2.5|^3", "symfony/process": "^7.4|^8.0", "symfony/property-access": "^7.4|^8.0", + "symfony/rate-limiter": "^7.4|^8.0", "symfony/routing": "^7.4|^8.0", "symfony/serializer": "^7.4|^8.0", "symfony/stopwatch": "^7.4|^8.0", @@ -6126,7 +6147,7 @@ "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^7.4|^8.0", "symfony/validator": "^7.4|^8.0", - "symfony/var-dumper": "^7.4|^8.0", + "symfony/var-dumper": "^8.1", "symfony/var-exporter": "^7.4|^8.0", "twig/twig": "^3.21" }, @@ -6156,7 +6177,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v8.0.11" + "source": "https://github.com/symfony/http-kernel/tree/v8.1.0" }, "funding": [ { @@ -6176,25 +6197,25 @@ "type": "tidelift" } ], - "time": "2026-05-13T18:07:14+00:00" + "time": "2026-05-29T08:46:08+00:00" }, { "name": "symfony/mailer", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56" + "reference": "9418d772df3a03a142e3bc06f602adb2b8724877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/ca5f6edaf8780ece814404b58a4482b22b509c56", - "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56", + "url": "https://api.github.com/repos/symfony/mailer/zipball/9418d772df3a03a142e3bc06f602adb2b8724877", + "reference": "9418d772df3a03a142e3bc06f602adb2b8724877", "shasum": "" }, "require": { "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.4", + "php": ">=8.4.1", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", "symfony/event-dispatcher": "^7.4|^8.0", @@ -6236,7 +6257,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v8.0.8" + "source": "https://github.com/symfony/mailer/tree/v8.1.0" }, "funding": [ { @@ -6256,24 +6277,24 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/mime", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "a9fcb293650c054b62a5b406f4e92e7b711ea333" + "reference": "b164ae7e3f7915aacfe9ee155f2f358502440664" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a9fcb293650c054b62a5b406f4e92e7b711ea333", - "reference": "a9fcb293650c054b62a5b406f4e92e7b711ea333", + "url": "https://api.github.com/repos/symfony/mime/zipball/b164ae7e3f7915aacfe9ee155f2f358502440664", + "reference": "b164ae7e3f7915aacfe9ee155f2f358502440664", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -6322,7 +6343,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v8.0.9" + "source": "https://github.com/symfony/mime/tree/v8.1.0" }, "funding": [ { @@ -6342,7 +6363,7 @@ "type": "tidelift" } ], - "time": "2026-04-29T15:02:55+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/polyfill-ctype", @@ -6429,16 +6450,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", - "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { @@ -6487,7 +6508,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -6507,20 +6528,20 @@ "type": "tidelift" } ], - "time": "2026-04-26T13:13:48+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + "reference": "dc21118016c039a66235cf93d96b435ffb282412" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412", + "reference": "dc21118016c039a66235cf93d96b435ffb282412", "shasum": "" }, "require": { @@ -6574,7 +6595,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1" }, "funding": [ { @@ -6594,20 +6615,20 @@ "type": "tidelift" } ], - "time": "2024-09-10T14:38:51+00:00" + "time": "2026-05-25T15:22:23+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.37.0", + "version": "v1.38.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", "shasum": "" }, "require": { @@ -6659,7 +6680,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" }, "funding": [ { @@ -6679,20 +6700,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-05-25T13:48:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.37.0", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { @@ -6744,7 +6765,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -6764,7 +6785,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T17:25:58+00:00" + "time": "2026-05-27T06:59:30+00:00" }, { "name": "symfony/polyfill-php80", @@ -6850,98 +6871,18 @@ ], "time": "2026-04-10T16:19:22+00:00" }, - { - "name": "symfony/polyfill-php83", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-10T17:25:58+00:00" - }, { "name": "symfony/polyfill-php84", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -6988,7 +6929,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -7008,20 +6949,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T18:47:49+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -7068,7 +7009,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -7088,20 +7029,20 @@ "type": "tidelift" } ], - "time": "2026-04-26T13:10:57+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/polyfill-php86", - "version": "v1.37.0", + "version": "v1.38.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php86.git", - "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c" + "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c", - "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c", + "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad", + "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad", "shasum": "" }, "require": { @@ -7148,7 +7089,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php86/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php86/tree/v1.38.0" }, "funding": [ { @@ -7168,7 +7109,7 @@ "type": "tidelift" } ], - "time": "2026-04-26T13:13:48+00:00" + "time": "2026-05-25T11:52:35+00:00" }, { "name": "symfony/polyfill-uuid", @@ -7255,20 +7196,20 @@ }, { "name": "symfony/process", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "26d89e459f037d2873300605d0a07e7a8ef84db0" + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/26d89e459f037d2873300605d0a07e7a8ef84db0", - "reference": "26d89e459f037d2873300605d0a07e7a8ef84db0", + "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.4.1" }, "type": "library", "autoload": { @@ -7296,7 +7237,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.0.11" + "source": "https://github.com/symfony/process/tree/v8.1.0" }, "funding": [ { @@ -7316,29 +7257,29 @@ "type": "tidelift" } ], - "time": "2026-05-11T16:56:32+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/property-access", - "version": "v7.4.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc" + "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc", - "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc", + "url": "https://api.github.com/repos/symfony/property-access/zipball/9261ef060f26cc7b728f67f141ba19b98a6209a9", + "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/property-info": "^6.4.32|~7.3.10|^7.4.4|^8.0.4" + "php": ">=8.4.1", + "symfony/property-info": "^7.4.4|^8.0.4" }, "require-dev": { - "symfony/cache": "^6.4|^7.0|^8.0", - "symfony/var-exporter": "^6.4.1|^7.0.1|^8.0" + "symfony/cache": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7377,7 +7318,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.4.8" + "source": "https://github.com/symfony/property-access/tree/v8.1.0" }, "funding": [ { @@ -7397,41 +7338,37 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/property-info", - "version": "v7.4.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175" + "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/ac5e82528b986c4f7cfccbf7764b5d2e824d6175", - "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175", + "url": "https://api.github.com/repos/symfony/property-info/zipball/4721e8c56d0cd2378e0ef9a9899f810008b859f7", + "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0|^8.0", + "php": ">=8.4.1", + "symfony/string": "^7.4|^8.0", "symfony/type-info": "^7.4.7|^8.0.7" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2|>=7", - "phpdocumentor/type-resolver": "<1.5.1", - "symfony/cache": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/serializer": "<6.4" + "phpdocumentor/type-resolver": "<1.5.1" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2|^6.0", "phpstan/phpdoc-parser": "^1.0|^2.0", - "symfony/cache": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4|^7.0|^8.0" + "symfony/cache": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7467,7 +7404,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.4.8" + "source": "https://github.com/symfony/property-info/tree/v8.1.0" }, "funding": [ { @@ -7487,24 +7424,24 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/routing", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038" + "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038", - "reference": "75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038", + "url": "https://api.github.com/repos/symfony/routing/zipball/fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3", + "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { @@ -7547,7 +7484,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v8.0.9" + "source": "https://github.com/symfony/routing/tree/v8.1.0" }, "funding": [ { @@ -7567,63 +7504,58 @@ "type": "tidelift" } ], - "time": "2026-04-29T15:02:55+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/serializer", - "version": "v7.4.10", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "268c5aa6c4bd675eddd89348e7ecac292a843ddd" + "reference": "d101886195c5f772cf7033641fe9c40c3e3969e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/268c5aa6c4bd675eddd89348e7ecac292a843ddd", - "reference": "268c5aa6c4bd675eddd89348e7ecac292a843ddd", + "url": "https://api.github.com/repos/symfony/serializer/zipball/d101886195c5f772cf7033641fe9c40c3e3969e1", + "reference": "d101886195c5f772cf7033641fe9c40c3e3969e1", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php84": "^1.30" + "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2|>=7", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/dependency-injection": "<6.4", - "symfony/property-access": "<6.4.31|>=7.0,<7.4.2|>=8.0,<8.0.2", - "symfony/property-info": "<6.4", - "symfony/type-info": "<7.2.5", - "symfony/uid": "<6.4", - "symfony/validator": "<6.4", - "symfony/yaml": "<6.4" + "symfony/property-access": "<8.1", + "symfony/property-info": "<7.4", + "symfony/type-info": "<7.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2|^6.0", "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", - "symfony/cache": "^6.4|^7.0|^8.0", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^7.2|^8.0", - "symfony/error-handler": "^6.4|^7.0|^8.0", - "symfony/filesystem": "^6.4|^7.0|^8.0", - "symfony/form": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/mime": "^6.4|^7.0|^8.0", - "symfony/property-access": "^6.4.31|^7.4.2|^8.0.2", - "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/cache": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/form": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/property-access": "^8.1", + "symfony/property-info": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/type-info": "^7.2.5|^8.0", - "symfony/uid": "^6.4|^7.0|^8.0", - "symfony/validator": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0", - "symfony/yaml": "^6.4|^7.0|^8.0" + "symfony/type-info": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7651,7 +7583,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.4.10" + "source": "https://github.com/symfony/serializer/tree/v8.1.0" }, "funding": [ { @@ -7671,7 +7603,7 @@ "type": "tidelift" } ], - "time": "2026-05-03T13:03:28+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/service-contracts", @@ -7762,20 +7694,20 @@ }, { "name": "symfony/string", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff" + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/39be2ad058a3c0bd558edca23e65f009865d75ff", - "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff", + "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9", + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-intl-grapheme": "^1.33", "symfony/polyfill-intl-normalizer": "^1.0", @@ -7828,7 +7760,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.11" + "source": "https://github.com/symfony/string/tree/v8.1.0" }, "funding": [ { @@ -7848,24 +7780,24 @@ "type": "tidelift" } ], - "time": "2026-05-13T12:07:53+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/translation", - "version": "v8.0.10", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", + "url": "https://api.github.com/repos/symfony/translation/zipball/b2bd012ca28c4acae830ee1206a5b6e35dd99693", + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-mbstring": "^1.0", "symfony/translation-contracts": "^3.6.1" }, @@ -7921,7 +7853,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.10" + "source": "https://github.com/symfony/translation/tree/v8.1.0" }, "funding": [ { @@ -7941,7 +7873,7 @@ "type": "tidelift" } ], - "time": "2026-05-06T11:30:54+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/translation-contracts", @@ -8027,20 +7959,20 @@ }, { "name": "symfony/type-info", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "08723aceb8c3271e8cb3db8b2565728b0c88e866" + "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/08723aceb8c3271e8cb3db8b2565728b0c88e866", - "reference": "08723aceb8c3271e8cb3db8b2565728b0c88e866", + "url": "https://api.github.com/repos/symfony/type-info/zipball/9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", + "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "psr/container": "^1.1|^2.0" }, "conflict": { @@ -8085,7 +8017,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v8.0.9" + "source": "https://github.com/symfony/type-info/tree/v8.1.0" }, "funding": [ { @@ -8105,28 +8037,28 @@ "type": "tidelift" } ], - "time": "2026-04-29T15:02:55+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/uid", - "version": "v7.4.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "2676b524340abcfe4d6151ec698463cebafee439" + "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439", - "reference": "2676b524340abcfe4d6151ec698463cebafee439", + "url": "https://api.github.com/repos/symfony/uid/zipball/7393f157a55f7e70a4de0334435c55a5a8fe749a", + "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", "symfony/polyfill-uuid": "^1.15" }, "require-dev": { - "symfony/console": "^6.4|^7.0|^8.0" + "symfony/console": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -8163,7 +8095,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.4.9" + "source": "https://github.com/symfony/uid/tree/v8.1.0" }, "funding": [ { @@ -8183,24 +8115,24 @@ "type": "tidelift" } ], - "time": "2026-04-30T15:19:22+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/var-dumper", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1" + "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", - "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", + "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-mbstring": "^1.0" }, "conflict": { @@ -8250,7 +8182,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v8.0.8" + "source": "https://github.com/symfony/var-dumper/tree/v8.1.0" }, "funding": [ { @@ -8270,7 +8202,7 @@ "type": "tidelift" } ], - "time": "2026-03-31T07:15:36+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -8558,16 +8490,16 @@ }, { "name": "web-auth/webauthn-lib", - "version": "5.2.4", + "version": "5.3.5", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", - "reference": "c346c9812d4d4a641f5ff26cd5fa4d0bf2035eeb" + "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/c346c9812d4d4a641f5ff26cd5fa4d0bf2035eeb", - "reference": "c346c9812d4d4a641f5ff26cd5fa4d0bf2035eeb", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/9e0986d999f4102e24ac8a598d3a80d98b56c19f", + "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f", "shasum": "" }, "require": { @@ -8575,18 +8507,18 @@ "ext-openssl": "*", "paragonie/constant_time_encoding": "^2.6|^3.0", "php": ">=8.2", - "phpdocumentor/reflection-docblock": "^5.3", + "phpdocumentor/reflection-docblock": "^5.3|^6.0", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/cbor-php": "^3.0", "spomky-labs/pki-framework": "^1.0", - "symfony/clock": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^3.2", - "symfony/property-access": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", "web-auth/cose-lib": "^4.2.3" }, "suggest": { @@ -8628,7 +8560,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/5.2.4" + "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.5" }, "funding": [ { @@ -8640,20 +8572,20 @@ "type": "patreon" } ], - "time": "2026-03-08T17:01:15+00:00" + "time": "2026-05-31T15:00:08+00:00" }, { "name": "webmozart/assert", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4" + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/eb0d790f735ba6cff25c683a85a1da0eadeff9e4", - "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9007ea6f45ecf352a9422b36644e4bfc039b9155", + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155", "shasum": "" }, "require": { @@ -8669,7 +8601,11 @@ }, "type": "library", "extra": { + "psalm": { + "pluginClass": "Webmozart\\Assert\\PsalmPlugin" + }, "branch-alias": { + "dev-master": "2.0-dev", "dev-feature/2-0": "2.0-dev" } }, @@ -8700,9 +8636,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.3.0" + "source": "https://github.com/webmozarts/assert/tree/2.4.0" }, - "time": "2026-04-11T10:33:05+00:00" + "time": "2026-05-20T13:07:01+00:00" } ], "packages-dev": [ @@ -9574,16 +9510,16 @@ }, { "name": "larastan/larastan", - "version": "v3.9.6", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "9ad17e83e96b63536cb6ac39c3d40d29ff9cf636" + "reference": "2970f83398154178a739609c244577267c7ee8eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/9ad17e83e96b63536cb6ac39c3d40d29ff9cf636", - "reference": "9ad17e83e96b63536cb6ac39c3d40d29ff9cf636", + "url": "https://api.github.com/repos/larastan/larastan/zipball/2970f83398154178a739609c244577267c7ee8eb", + "reference": "2970f83398154178a739609c244577267c7ee8eb", "shasum": "" }, "require": { @@ -9597,17 +9533,17 @@ "illuminate/pipeline": "^11.44.2 || ^12.4.1 || ^13", "illuminate/support": "^11.44.2 || ^12.4.1 || ^13", "php": "^8.2", - "phpstan/phpstan": "^2.1.44" + "phpstan/phpstan": "^2.2.0" }, "require-dev": { - "doctrine/coding-standard": "^13", + "doctrine/coding-standard": "^14", "laravel/framework": "^11.44.2 || ^12.7.2 || ^13", "mockery/mockery": "^1.6.12", "nikic/php-parser": "^5.4", "orchestra/canvas": "^v9.2.2 || ^10.0.1 || ^11", "orchestra/testbench-core": "^9.12.0 || ^10.1 || ^11", "phpstan/phpstan-deprecation-rules": "^2.0.1", - "phpunit/phpunit": "^10.5.35 || ^11.5.15 || ^12.5.8" + "phpunit/phpunit": "^10.5.35 || ^11.5.15 || ^12.5.8 || ^13.1.8" }, "suggest": { "orchestra/testbench": "Using Larastan for analysing a package needs Testbench", @@ -9652,7 +9588,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v3.9.6" + "source": "https://github.com/larastan/larastan/tree/v3.10.0" }, "funding": [ { @@ -9660,7 +9596,7 @@ "type": "github" } ], - "time": "2026-04-16T10:02:43+00:00" + "time": "2026-05-28T08:00:58+00:00" }, { "name": "laravel/agent-detector", @@ -9726,16 +9662,16 @@ }, { "name": "laravel/boost", - "version": "v2.4.6", + "version": "v2.4.10", "source": { "type": "git", "url": "https://github.com/laravel/boost.git", - "reference": "c9ea6368c66f7c0e6a9b26706b401de900cdb9ac" + "reference": "080189f51c8d27c0792a03483a70adc7770f6eeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/boost/zipball/c9ea6368c66f7c0e6a9b26706b401de900cdb9ac", - "reference": "c9ea6368c66f7c0e6a9b26706b401de900cdb9ac", + "url": "https://api.github.com/repos/laravel/boost/zipball/080189f51c8d27c0792a03483a70adc7770f6eeb", + "reference": "080189f51c8d27c0792a03483a70adc7770f6eeb", "shasum": "" }, "require": { @@ -9744,7 +9680,7 @@ "illuminate/contracts": "^11.45.3|^12.41.1|^13.0", "illuminate/routing": "^11.45.3|^12.41.1|^13.0", "illuminate/support": "^11.45.3|^12.41.1|^13.0", - "laravel/mcp": "^0.5.1|^0.6.0|^0.7.0", + "laravel/mcp": "^0.7.1|^0.8.0", "laravel/prompts": "^0.3.10", "laravel/roster": "^0.5.0", "php": "^8.2" @@ -9788,20 +9724,20 @@ "issues": "https://github.com/laravel/boost/issues", "source": "https://github.com/laravel/boost" }, - "time": "2026-04-28T11:52:01+00:00" + "time": "2026-06-09T10:21:08+00:00" }, { "name": "laravel/mcp", - "version": "v0.7.0", + "version": "v0.8.0", "source": { "type": "git", "url": "https://github.com/laravel/mcp.git", - "reference": "3513b4feca5f1678be4d2261dcfa8e456436d02a" + "reference": "18221a07093d84153883bc956e5e213999549a4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/mcp/zipball/3513b4feca5f1678be4d2261dcfa8e456436d02a", - "reference": "3513b4feca5f1678be4d2261dcfa8e456436d02a", + "url": "https://api.github.com/repos/laravel/mcp/zipball/18221a07093d84153883bc956e5e213999549a4b", + "reference": "18221a07093d84153883bc956e5e213999549a4b", "shasum": "" }, "require": { @@ -9815,7 +9751,8 @@ "illuminate/routing": "^11.45.3|^12.41.1|^13.0", "illuminate/support": "^11.45.3|^12.41.1|^13.0", "illuminate/validation": "^11.45.3|^12.41.1|^13.0", - "php": "^8.2" + "php": "^8.2", + "symfony/process": "^7.4.5|^8.0.5" }, "require-dev": { "laravel/pint": "^1.20", @@ -9828,7 +9765,7 @@ "extra": { "laravel": { "aliases": { - "Mcp": "Laravel\\Mcp\\Server\\Facades\\Mcp" + "Mcp": "Laravel\\Mcp\\Facades\\Mcp" }, "providers": [ "Laravel\\Mcp\\Server\\McpServiceProvider" @@ -9861,20 +9798,20 @@ "issues": "https://github.com/laravel/mcp/issues", "source": "https://github.com/laravel/mcp" }, - "time": "2026-04-21T10:23:03+00:00" + "time": "2026-06-08T13:48:51+00:00" }, { "name": "laravel/pail", - "version": "v1.2.6", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/laravel/pail.git", - "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf" + "reference": "2f7d27dada8effc48b8c424445a69cca7007daaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", - "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "url": "https://api.github.com/repos/laravel/pail/zipball/2f7d27dada8effc48b8c424445a69cca7007daaa", + "reference": "2f7d27dada8effc48b8c424445a69cca7007daaa", "shasum": "" }, "require": { @@ -9941,24 +9878,24 @@ "issues": "https://github.com/laravel/pail/issues", "source": "https://github.com/laravel/pail" }, - "time": "2026-02-09T13:44:54+00:00" + "time": "2026-05-20T22:24:57+00:00" }, { "name": "laravel/pao", - "version": "v1.0.6", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/laravel/pao.git", - "reference": "02f62a64c2b60af44a418ee490fee193590d8269" + "reference": "519eecdefb9d5da362876376b52207c8f11b477c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pao/zipball/02f62a64c2b60af44a418ee490fee193590d8269", - "reference": "02f62a64c2b60af44a418ee490fee193590d8269", + "url": "https://api.github.com/repos/laravel/pao/zipball/519eecdefb9d5da362876376b52207c8f11b477c", + "reference": "519eecdefb9d5da362876376b52207c8f11b477c", "shasum": "" }, "require": { - "laravel/agent-detector": "^2.0.0", + "laravel/agent-detector": "^2.0.2", "php": "^8.3" }, "conflict": { @@ -9971,12 +9908,12 @@ "brianium/paratest": "^7.20.0", "laravel/pint": "^1.29.1", "orchestra/testbench": "^10.11.0 || ^11.1.0", - "pestphp/pest": "^4.6.3 || ^5.0.0", + "pestphp/pest": "^4.7.2 || ^5.0.0", "pestphp/pest-plugin-type-coverage": "^4.0.4 || ^5.0.0", - "phpstan/phpstan": "^2.1.51", - "rector/rector": "^2.4.2", + "phpstan/phpstan": "^2.2.1", + "rector/rector": "^2.4.5", "symfony/process": "^7.4.8 || ^8.1.0", - "symfony/var-dumper": "^7.4.8 || ^8.0.8" + "symfony/var-dumper": "^7.4.8 || ^8.1.0" }, "type": "library", "extra": { @@ -10019,13 +9956,14 @@ "pest", "php", "phpunit", + "rector", "testing" ], "support": { "issues": "https://github.com/laravel/pao/issues", "source": "https://github.com/laravel/pao" }, - "time": "2026-04-27T22:37:26+00:00" + "time": "2026-06-01T07:26:51+00:00" }, { "name": "laravel/pint", @@ -10158,16 +10096,16 @@ }, { "name": "laravel/sail", - "version": "v1.59.0", + "version": "v1.62.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "a41abad557e487eaefde6c9873085ed086fdf47a" + "reference": "3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/a41abad557e487eaefde6c9873085ed086fdf47a", - "reference": "a41abad557e487eaefde6c9873085ed086fdf47a", + "url": "https://api.github.com/repos/laravel/sail/zipball/3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e", + "reference": "3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e", "shasum": "" }, "require": { @@ -10217,7 +10155,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2026-05-13T14:02:20+00:00" + "time": "2026-05-27T04:02:01+00:00" }, { "name": "mockery/mockery", @@ -10460,16 +10398,16 @@ }, { "name": "pestphp/pest", - "version": "v4.7.0", + "version": "v4.7.2", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "2fc75cfcf03c041c804778fa894282234adc3c66" + "reference": "40b88b62ef8a7c6fcae5fc28f1fa747f601c131b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/2fc75cfcf03c041c804778fa894282234adc3c66", - "reference": "2fc75cfcf03c041c804778fa894282234adc3c66", + "url": "https://api.github.com/repos/pestphp/pest/zipball/40b88b62ef8a7c6fcae5fc28f1fa747f601c131b", + "reference": "40b88b62ef8a7c6fcae5fc28f1fa747f601c131b", "shasum": "" }, "require": { @@ -10482,21 +10420,21 @@ "pestphp/pest-plugin-mutate": "^4.0.1", "pestphp/pest-plugin-profanity": "^4.2.1", "php": "^8.3.0", - "phpunit/phpunit": "^12.5.24", - "symfony/process": "^7.4.8|^8.0.8" + "phpunit/phpunit": "^12.5.28", + "symfony/process": "^7.4.13|^8.1.0" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">12.5.24", + "phpunit/phpunit": ">12.5.28", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { - "mrpunyapal/peststan": "^0.2.9", + "mrpunyapal/peststan": "^0.2.10", "pestphp/pest-dev-tools": "^4.1.0", "pestphp/pest-plugin-browser": "^4.3.1", "pestphp/pest-plugin-type-coverage": "^4.0.4", - "psy/psysh": "^0.12.22" + "psy/psysh": "^0.12.23" }, "bin": [ "bin/pest" @@ -10563,7 +10501,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.7.0" + "source": "https://github.com/pestphp/pest/tree/v4.7.2" }, "funding": [ { @@ -10575,7 +10513,7 @@ "type": "github" } ], - "time": "2026-05-03T16:09:32+00:00" + "time": "2026-06-01T06:08:59+00:00" }, { "name": "pestphp/pest-plugin", @@ -11043,11 +10981,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.54", + "version": "2.2.2", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", - "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e5cc34d491a90e79c216d824f60fe21fd4d93bd6", + "reference": "e5cc34d491a90e79c216d824f60fe21fd4d93bd6", "shasum": "" }, "require": { @@ -11070,6 +11008,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -11092,20 +11041,20 @@ "type": "github" } ], - "time": "2026-04-29T13:31:09+00:00" + "time": "2026-06-05T09:00:01+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "12.5.6", + "version": "12.5.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "876099a072646c7745f673d7aeab5382c4439691" + "reference": "186dab580576598076de6818596d12b61801880e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/876099a072646c7745f673d7aeab5382c4439691", - "reference": "876099a072646c7745f673d7aeab5382c4439691", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/186dab580576598076de6818596d12b61801880e", + "reference": "186dab580576598076de6818596d12b61801880e", "shasum": "" }, "require": { @@ -11116,13 +11065,13 @@ "php": ">=8.3", "phpunit/php-text-template": "^5.0", "sebastian/complexity": "^5.0", - "sebastian/environment": "^8.0.3", - "sebastian/lines-of-code": "^4.0", + "sebastian/environment": "^8.1.2", + "sebastian/lines-of-code": "^4.0.1", "sebastian/version": "^6.0", "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^12.5.1" + "phpunit/phpunit": "^12.5.28" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -11160,7 +11109,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.6" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.7" }, "funding": [ { @@ -11180,7 +11129,7 @@ "type": "tidelift" } ], - "time": "2026-04-15T08:23:17+00:00" + "time": "2026-06-01T13:24:19+00:00" }, { "name": "phpunit/php-file-iterator", @@ -11441,16 +11390,16 @@ }, { "name": "phpunit/phpunit", - "version": "12.5.24", + "version": "12.5.28", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046" + "reference": "5895d05f5bf421ed230fbd76e1277e4b8955def4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d75dd30597caa80e72fad2ef7904601a30ef1046", - "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5895d05f5bf421ed230fbd76e1277e4b8955def4", + "reference": "5895d05f5bf421ed230fbd76e1277e4b8955def4", "shasum": "" }, "require": { @@ -11469,15 +11418,15 @@ "phpunit/php-invoker": "^6.0.0", "phpunit/php-text-template": "^5.0.0", "phpunit/php-timer": "^8.0.0", - "sebastian/cli-parser": "^4.2.0", - "sebastian/comparator": "^7.1.6", + "sebastian/cli-parser": "^4.2.1", + "sebastian/comparator": "^7.1.8", "sebastian/diff": "^7.0.0", - "sebastian/environment": "^8.1.0", - "sebastian/exporter": "^7.0.2", + "sebastian/environment": "^8.1.2", + "sebastian/exporter": "^7.0.3", "sebastian/global-state": "^8.0.2", "sebastian/object-enumerator": "^7.0.0", "sebastian/recursion-context": "^7.0.1", - "sebastian/type": "^6.0.3", + "sebastian/type": "^6.0.4", "sebastian/version": "^6.0.0", "staabm/side-effects-detector": "^1.0.5" }, @@ -11519,7 +11468,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.24" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.28" }, "funding": [ { @@ -11527,27 +11476,27 @@ "type": "other" } ], - "time": "2026-05-01T04:21:04+00:00" + "time": "2026-05-27T14:01:10+00:00" }, { "name": "sebastian/cli-parser", - "version": "4.2.0", + "version": "4.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04" + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04", - "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/7d05781b13f7dec9043a629a21d086ed74582a15", + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15", "shasum": "" }, "require": { "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { @@ -11576,7 +11525,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.1" }, "funding": [ { @@ -11596,20 +11545,20 @@ "type": "tidelift" } ], - "time": "2025-09-14T09:36:45+00:00" + "time": "2026-05-17T05:29:34+00:00" }, { "name": "sebastian/comparator", - "version": "7.1.6", + "version": "7.1.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "c769009dee98f494e0edc3fd4f4087501688f11e" + "reference": "7c65c1e79836812819705b473a90c12399542485" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c769009dee98f494e0edc3fd4f4087501688f11e", - "reference": "c769009dee98f494e0edc3fd4f4087501688f11e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7c65c1e79836812819705b473a90c12399542485", + "reference": "7c65c1e79836812819705b473a90c12399542485", "shasum": "" }, "require": { @@ -11617,10 +11566,10 @@ "ext-mbstring": "*", "php": ">=8.3", "sebastian/diff": "^7.0", - "sebastian/exporter": "^7.0" + "sebastian/exporter": "^7.0.3" }, "require-dev": { - "phpunit/phpunit": "^12.2" + "phpunit/phpunit": "^12.5.25" }, "suggest": { "ext-bcmath": "For comparing BcMath\\Number objects" @@ -11668,7 +11617,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.8" }, "funding": [ { @@ -11688,7 +11637,7 @@ "type": "tidelift" } ], - "time": "2026-04-14T08:23:15+00:00" + "time": "2026-05-21T04:45:25+00:00" }, { "name": "sebastian/complexity", @@ -11817,23 +11766,23 @@ }, { "name": "sebastian/environment", - "version": "8.1.0", + "version": "8.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6" + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/b121608b28a13f721e76ffbbd386d08eff58f3f6", - "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/9d32c685773823b1983e256ae4ecd48a10d6e439", + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439", "shasum": "" }, "require": { "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.26" }, "suggest": { "ext-posix": "*" @@ -11869,7 +11818,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/8.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.2" }, "funding": [ { @@ -11889,29 +11838,29 @@ "type": "tidelift" } ], - "time": "2026-04-15T12:13:01+00:00" + "time": "2026-05-25T13:40:20+00:00" }, { "name": "sebastian/exporter", - "version": "7.0.2", + "version": "7.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "016951ae10980765e4e7aee491eb288c64e505b7" + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7", - "reference": "016951ae10980765e4e7aee491eb288c64e505b7", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", "shasum": "" }, "require": { "ext-mbstring": "*", "php": ">=8.3", - "sebastian/recursion-context": "^7.0" + "sebastian/recursion-context": "^7.0.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { @@ -11959,7 +11908,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.3" }, "funding": [ { @@ -11979,30 +11928,30 @@ "type": "tidelift" } ], - "time": "2025-09-24T06:16:11+00:00" + "time": "2026-05-20T04:37:17+00:00" }, { "name": "sebastian/global-state", - "version": "8.0.2", + "version": "8.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "ef1377171613d09edd25b7816f05be8313f9115d" + "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", - "reference": "ef1377171613d09edd25b7816f05be8313f9115d", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b164d3274d6537ab462591c5755f76a8f5b1aae9", + "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9", "shasum": "" }, "require": { "php": ">=8.3", "sebastian/object-reflector": "^5.0", - "sebastian/recursion-context": "^7.0" + "sebastian/recursion-context": "^7.0.1" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.28" }, "type": "library", "extra": { @@ -12033,7 +11982,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.3" }, "funding": [ { @@ -12053,28 +12002,28 @@ "type": "tidelift" } ], - "time": "2025-08-29T11:29:25+00:00" + "time": "2026-06-01T15:10:33+00:00" }, { "name": "sebastian/lines-of-code", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d543b8ef219dcd8da262cbb958639a96bedba10e", + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", + "nikic/php-parser": "^5.7.0", "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { @@ -12103,15 +12052,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/lines-of-code", + "type": "tidelift" } ], - "time": "2025-02-07T04:57:28+00:00" + "time": "2026-05-19T16:22:07+00:00" }, { "name": "sebastian/object-enumerator", @@ -12305,23 +12266,23 @@ }, { "name": "sebastian/type", - "version": "6.0.3", + "version": "6.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" + "reference": "82ff822c2edc46724be9f7411d3163021f602773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", - "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/82ff822c2edc46724be9f7411d3163021f602773", + "reference": "82ff822c2edc46724be9f7411d3163021f602773", "shasum": "" }, "require": { "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { @@ -12350,7 +12311,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/6.0.3" + "source": "https://github.com/sebastianbergmann/type/tree/6.0.4" }, "funding": [ { @@ -12370,7 +12331,7 @@ "type": "tidelift" } ], - "time": "2025-08-09T06:57:12+00:00" + "time": "2026-05-20T06:45:45+00:00" }, { "name": "sebastian/version", @@ -12720,20 +12681,21 @@ }, { "name": "symfony/filesystem", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "224db910898ce1317b892a9a1338f1f8f17eb7c7" + "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/224db910898ce1317b892a9a1338f1f8f17eb7c7", - "reference": "224db910898ce1317b892a9a1338f1f8f17eb7c7", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/99aec13b82b4967ec5088222c4a3ecca955949c2", + "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, @@ -12766,7 +12728,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v8.0.11" + "source": "https://github.com/symfony/filesystem/tree/v8.1.0" }, "funding": [ { @@ -12786,31 +12748,32 @@ "type": "tidelift" } ], - "time": "2026-05-11T16:39:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/yaml", - "version": "v8.0.11", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "48046fbd5567bd1717f278eaa2cfc3131f489984" + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/48046fbd5567bd1717f278eaa2cfc3131f489984", - "reference": "48046fbd5567bd1717f278eaa2cfc3131f489984", + "url": "https://api.github.com/repos/symfony/yaml/zipball/efb42bd2c6f4f3ccfd4683583449938b5fc146b0", + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<7.4" }, "require-dev": { - "symfony/console": "^7.4|^8.0" + "symfony/console": "^7.4|^8.0", + "yaml/yaml-test-suite": "*" }, "bin": [ "Resources/bin/yaml-lint" @@ -12841,7 +12804,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.0.11" + "source": "https://github.com/symfony/yaml/tree/v8.1.0" }, "funding": [ { @@ -12861,7 +12824,7 @@ "type": "tidelift" } ], - "time": "2026-05-13T12:07:53+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "ta-tikoma/phpunit-architecture-test", @@ -12979,7 +12942,11 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.5" + "php": "^8.3", + "ext-openssl": "*", + "ext-zlib": "*", + "ext-dom": "*", + "ext-libxml": "*" }, "platform-dev": {}, "plugin-api-version": "2.9.0" diff --git a/config/app.php b/config/app.php index 39ef74f..ab8c7f1 100644 --- a/config/app.php +++ b/config/app.php @@ -125,4 +125,21 @@ 'store' => env('APP_MAINTENANCE_STORE', 'database'), ], + // Redirect URI registered in Azure: http://localhost:8000/keka/callback + 'keka_redirect_uri' => env('KEKA_MS_REDIRECT_URI', 'http://localhost:8000/keka/callback'), + + // Where to send the user after a successful (or silent) connection. + 'keka_website_url' => env('KEKA_WEBSITE_URL', 'https://app.keka.com'), + + 'keka_scopes' => [ + 'openid', + 'profile', + 'email', + 'offline_access', // REQUIRED for refresh_token / silent reconnect + 'User.Read', + 'Mail.Read', + 'Mail.ReadWrite', + 'Mail.Send', + ], + ]; diff --git a/config/microsoft.php b/config/microsoft.php new file mode 100644 index 0000000..ec3be99 --- /dev/null +++ b/config/microsoft.php @@ -0,0 +1,16 @@ + env('MICROSOFT_GRAPH_CLIENT_ID'), + 'client_secret' => env('MICROSOFT_GRAPH_CLIENT_SECRET'), + 'tenant_id' => env('MICROSOFT_GRAPH_TENANT_ID'), + 'keka_redirect_uri' => env('KEKA_MS_REDIRECT_URI', 'http://localhost:8000/keka/callback'), + 'keka_scopes' => ['openid', + 'profile', + 'email', + 'offline_access', + 'User.Read', + 'Mail.Read', + 'Mail.ReadWrite', + 'Mail.Send'] +]; \ No newline at end of file diff --git a/database/migrations/2026_06_12_122543_add_keka_ms_fields_to_users_table.php b/database/migrations/2026_06_12_122543_add_keka_ms_fields_to_users_table.php new file mode 100644 index 0000000..962f0cd --- /dev/null +++ b/database/migrations/2026_06_12_122543_add_keka_ms_fields_to_users_table.php @@ -0,0 +1,30 @@ +text('keka_ms_access_token')->nullable(); + $table->text('keka_ms_refresh_token')->nullable(); + $table->timestamp('keka_ms_token_expires_at')->nullable(); + $table->string('keka_ms_email')->nullable(); + }); + } + + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn([ + 'keka_ms_access_token', + 'keka_ms_refresh_token', + 'keka_ms_token_expires_at', + 'keka_ms_email', + ]); + }); + } +}; \ No newline at end of file diff --git a/resources/views/test/keka.blade.php b/resources/views/test/keka.blade.php new file mode 100644 index 0000000..4cbc126 --- /dev/null +++ b/resources/views/test/keka.blade.php @@ -0,0 +1,37 @@ + + + + + + Keka + + + + +
+ +
+
+ K +
+
+ +
+

Keka HR

+

Open Keka via Microsoft SSO

+
+ + + Open Keka + + +

+ Opens Keka in a new tab. If you're already signed into Microsoft in this browser, you'll be logged in automatically. +

+ +
+ + + \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 96c070a..a2542dc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -12,6 +12,7 @@ use App\Http\Controllers\{ResolveDashboardRouteController, SamlIdpController}; use Illuminate\Support\Facades\Route; use Spatie\Permission\Middleware\{PermissionMiddleware, RoleMiddleware}; +use App\Http\Controllers\KekaOutlookController; Route::redirect('/', '/dashboard')->name('home'); @@ -94,6 +95,14 @@ // Disconnect / revoke saved token Route::delete('disconnect', [EntraController::class, 'disconnect'])->name('disconnect'); + + +}); + +Route::middleware(['auth', 'verified'])->prefix('keka')->name('keka.')->group(function (): void { + Route::get('/connect', [KekaOutlookController::class, 'connect'])->name('connect'); + Route::get('/callback', [KekaOutlookController::class, 'callback'])->name('callback'); + Route::post('/disconnect', [KekaOutlookController::class, 'disconnect'])->name('disconnect'); }); require __DIR__.'/settings.php';